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
get_raw_bytes_per_row(color_space colorSpace,int32 width)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
182bb187c91SJérôme Duval case B_RGBA64: case B_RGBA64_BIG:
183bb187c91SJérôme Duval bpr = 8 * width;
184bb187c91SJérôme Duval break;
185bb187c91SJérôme Duval case B_RGB48: case B_RGB48_BIG:
186bb187c91SJérôme Duval bpr = 6 * width;
187bb187c91SJérôme Duval break;
188338b8dc3SIngo Weinhold case B_RGB32: case B_RGBA32:
189338b8dc3SIngo Weinhold case B_RGB32_BIG: case B_RGBA32_BIG:
190338b8dc3SIngo Weinhold case B_UVL32: case B_UVLA32:
191338b8dc3SIngo Weinhold case B_LAB32: case B_LABA32:
192338b8dc3SIngo Weinhold case B_HSI32: case B_HSIA32:
193338b8dc3SIngo Weinhold case B_HSV32: case B_HSVA32:
194338b8dc3SIngo Weinhold case B_HLS32: case B_HLSA32:
195338b8dc3SIngo Weinhold case B_CMY32: case B_CMYA32: case B_CMYK32:
196338b8dc3SIngo Weinhold bpr = 4 * width;
197338b8dc3SIngo Weinhold break;
198338b8dc3SIngo Weinhold case B_RGB24: case B_RGB24_BIG:
199338b8dc3SIngo Weinhold case B_UVL24: case B_LAB24: case B_HSI24:
200338b8dc3SIngo Weinhold case B_HSV24: case B_HLS24: case B_CMY24:
201338b8dc3SIngo Weinhold bpr = 3 * width;
202338b8dc3SIngo Weinhold break;
203338b8dc3SIngo Weinhold case B_RGB16: case B_RGB15: case B_RGBA15:
204338b8dc3SIngo Weinhold case B_RGB16_BIG: case B_RGB15_BIG: case B_RGBA15_BIG:
205338b8dc3SIngo Weinhold bpr = 2 * width;
206338b8dc3SIngo Weinhold break;
207338b8dc3SIngo Weinhold case B_CMAP8: case B_GRAY8:
208338b8dc3SIngo Weinhold bpr = width;
209338b8dc3SIngo Weinhold break;
210338b8dc3SIngo Weinhold case B_GRAY1:
211338b8dc3SIngo Weinhold bpr = (width + 7) / 8;
212338b8dc3SIngo Weinhold break;
213338b8dc3SIngo Weinhold case B_YCbCr422: case B_YUV422:
214338b8dc3SIngo Weinhold bpr = (width + 3) / 4 * 8;
215338b8dc3SIngo Weinhold break;
216338b8dc3SIngo Weinhold case B_YCbCr411: case B_YUV411:
217338b8dc3SIngo Weinhold bpr = (width + 3) / 4 * 6;
218338b8dc3SIngo Weinhold break;
219338b8dc3SIngo Weinhold case B_YCbCr444: case B_YUV444:
220338b8dc3SIngo Weinhold bpr = (width + 3) / 4 * 12;
221338b8dc3SIngo Weinhold break;
222338b8dc3SIngo Weinhold case B_YCbCr420: case B_YUV420:
223338b8dc3SIngo Weinhold bpr = (width + 3) / 4 * 6;
224338b8dc3SIngo Weinhold break;
225487d015aSAdrien Destugues case B_YUV9:
226487d015aSAdrien Destugues bpr = (width + 15) / 16 * 18;
227338b8dc3SIngo Weinhold // unsupported
228338b8dc3SIngo Weinhold case B_NO_COLOR_SPACE:
229487d015aSAdrien Destugues case B_YUV12:
230338b8dc3SIngo Weinhold break;
231338b8dc3SIngo Weinhold }
232338b8dc3SIngo Weinhold return bpr;
233338b8dc3SIngo Weinhold }
234338b8dc3SIngo Weinhold
23564b2d169SAxel Dörfler
236338b8dc3SIngo Weinhold /*! \brief Returns the number of bytes per row needed to store the bitmap
237338b8dc3SIngo Weinhold data (including any padding) given a color space and a row width.
238338b8dc3SIngo Weinhold \param colorSpace The color space.
239338b8dc3SIngo Weinhold \param width The width.
240338b8dc3SIngo Weinhold \return The number of bytes per row needed to store data for a row, or
241338b8dc3SIngo Weinhold 0, if the color space is not supported.
242338b8dc3SIngo Weinhold */
24364b2d169SAxel Dörfler static inline int32
get_bytes_per_row(color_space colorSpace,int32 width)244338b8dc3SIngo Weinhold get_bytes_per_row(color_space colorSpace, int32 width)
245338b8dc3SIngo Weinhold {
246338b8dc3SIngo Weinhold int32 bpr = get_raw_bytes_per_row(colorSpace, width);
247338b8dc3SIngo Weinhold // align to int32
248338b8dc3SIngo Weinhold bpr = (bpr + 3) & 0x7ffffffc;
249338b8dc3SIngo Weinhold return bpr;
250338b8dc3SIngo Weinhold }
251338b8dc3SIngo Weinhold
25264b2d169SAxel Dörfler
253338b8dc3SIngo Weinhold /*! \brief Returns the brightness of an RGB 24 color.
254338b8dc3SIngo Weinhold \param red Value of the red component.
255338b8dc3SIngo Weinhold \param green Value of the green component.
256338b8dc3SIngo Weinhold \param blue Value of the blue component.
257338b8dc3SIngo Weinhold \return The brightness for the supplied RGB color as a value between 0
258338b8dc3SIngo Weinhold and 255.
259338b8dc3SIngo Weinhold */
26064b2d169SAxel Dörfler static inline uint8
brightness_for(uint8 red,uint8 green,uint8 blue)261338b8dc3SIngo Weinhold brightness_for(uint8 red, uint8 green, uint8 blue)
262338b8dc3SIngo Weinhold {
263338b8dc3SIngo Weinhold // brightness = 0.301 * red + 0.586 * green + 0.113 * blue
264338b8dc3SIngo Weinhold // we use for performance reasons:
265338b8dc3SIngo Weinhold // brightness = (308 * red + 600 * green + 116 * blue) / 1024
266338b8dc3SIngo Weinhold return uint8((308 * red + 600 * green + 116 * blue) / 1024);
267338b8dc3SIngo Weinhold }
268338b8dc3SIngo Weinhold
26964b2d169SAxel Dörfler
270338b8dc3SIngo Weinhold /*! \brief Returns the "distance" between two RGB colors.
271338b8dc3SIngo Weinhold
272338b8dc3SIngo Weinhold This functions defines an metric on the RGB color space. The distance
273338b8dc3SIngo Weinhold between two colors is 0, if and only if the colors are equal.
274338b8dc3SIngo Weinhold
275338b8dc3SIngo Weinhold \param red1 Red component of the first color.
276338b8dc3SIngo Weinhold \param green1 Green component of the first color.
277338b8dc3SIngo Weinhold \param blue1 Blue component of the first color.
278338b8dc3SIngo Weinhold \param red2 Red component of the second color.
279338b8dc3SIngo Weinhold \param green2 Green component of the second color.
280338b8dc3SIngo Weinhold \param blue2 Blue component of the second color.
281338b8dc3SIngo Weinhold \return The distance between the given colors.
282338b8dc3SIngo Weinhold */
28364b2d169SAxel Dörfler static inline unsigned
color_distance(uint8 red1,uint8 green1,uint8 blue1,uint8 red2,uint8 green2,uint8 blue2)28464b2d169SAxel Dörfler color_distance(uint8 red1, uint8 green1, uint8 blue1, uint8 red2, uint8 green2,
28564b2d169SAxel Dörfler uint8 blue2)
286338b8dc3SIngo Weinhold {
287338b8dc3SIngo Weinhold // euklidian distance (its square actually)
288338b8dc3SIngo Weinhold int rd = (int)red1 - (int)red2;
289338b8dc3SIngo Weinhold int gd = (int)green1 - (int)green2;
290338b8dc3SIngo Weinhold int bd = (int)blue1 - (int)blue2;
291338b8dc3SIngo Weinhold // return rd * rd + gd * gd + bd * bd;
292338b8dc3SIngo Weinhold
293338b8dc3SIngo Weinhold // distance according to psycho-visual tests
294338b8dc3SIngo Weinhold int rmean = ((int)red1 + (int)red2) / 2;
29564b2d169SAxel Dörfler return (((512 + rmean) * rd * rd) >> 8) + 4 * gd * gd
296338b8dc3SIngo Weinhold + (((767 - rmean) * bd * bd) >> 8);
297338b8dc3SIngo Weinhold }
298338b8dc3SIngo Weinhold
29964b2d169SAxel Dörfler
30064b2d169SAxel Dörfler static inline int32
bit_mask(int32 bit)30164b2d169SAxel Dörfler bit_mask(int32 bit)
30264b2d169SAxel Dörfler {
30364b2d169SAxel Dörfler return 1 << bit;
30464b2d169SAxel Dörfler }
305338b8dc3SIngo Weinhold
306338b8dc3SIngo Weinhold
30764b2d169SAxel Dörfler static inline int32
inverse_bit_mask(int32 bit)30864b2d169SAxel Dörfler inverse_bit_mask(int32 bit)
30964b2d169SAxel Dörfler {
31064b2d169SAxel Dörfler return ~bit_mask(bit);
31164b2d169SAxel Dörfler }
31264b2d169SAxel Dörfler
31364b2d169SAxel Dörfler
31464b2d169SAxel Dörfler // #pragma mark - PaletteConverter
31564b2d169SAxel Dörfler
316338b8dc3SIngo Weinhold
317338b8dc3SIngo Weinhold namespace BPrivate {
318338b8dc3SIngo Weinhold
319338b8dc3SIngo Weinhold /*! \brief Helper class for conversion between RGB and palette colors.
320338b8dc3SIngo Weinhold */
321338b8dc3SIngo Weinhold class PaletteConverter {
322338b8dc3SIngo Weinhold public:
323338b8dc3SIngo Weinhold PaletteConverter();
324338b8dc3SIngo Weinhold PaletteConverter(const rgb_color *palette);
325338b8dc3SIngo Weinhold PaletteConverter(const color_map *colorMap);
326338b8dc3SIngo Weinhold ~PaletteConverter();
327338b8dc3SIngo Weinhold
328338b8dc3SIngo Weinhold status_t SetTo(const rgb_color *palette);
329338b8dc3SIngo Weinhold status_t SetTo(const color_map *colorMap);
330338b8dc3SIngo Weinhold status_t InitCheck() const;
331338b8dc3SIngo Weinhold
332338b8dc3SIngo Weinhold inline uint8 IndexForRGB15(uint16 rgb) const;
333338b8dc3SIngo Weinhold inline uint8 IndexForRGB15(uint8 red, uint8 green, uint8 blue) const;
334338b8dc3SIngo Weinhold inline uint8 IndexForRGB16(uint16 rgb) const;
335338b8dc3SIngo Weinhold inline uint8 IndexForRGB16(uint8 red, uint8 green, uint8 blue) const;
336338b8dc3SIngo Weinhold inline uint8 IndexForRGB24(uint32 rgb) const;
337338b8dc3SIngo Weinhold inline uint8 IndexForRGB24(uint8 red, uint8 green, uint8 blue) const;
338338b8dc3SIngo Weinhold inline uint8 IndexForGray(uint8 gray) const;
339338b8dc3SIngo Weinhold
340338b8dc3SIngo Weinhold inline const rgb_color &RGBColorForIndex(uint8 index) const;
341338b8dc3SIngo Weinhold inline uint16 RGB15ColorForIndex(uint8 index) const;
342338b8dc3SIngo Weinhold inline uint16 RGB16ColorForIndex(uint8 index) const;
343338b8dc3SIngo Weinhold inline uint32 RGB24ColorForIndex(uint8 index) const;
344338b8dc3SIngo Weinhold inline void RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green,
345338b8dc3SIngo Weinhold uint8 &blue, uint8 &alpha) const;
346338b8dc3SIngo Weinhold inline uint8 GrayColorForIndex(uint8 index) const;
347338b8dc3SIngo Weinhold
348338b8dc3SIngo Weinhold private:
349338b8dc3SIngo Weinhold const color_map *fColorMap;
350338b8dc3SIngo Weinhold color_map *fOwnColorMap;
351338b8dc3SIngo Weinhold status_t fCStatus;
352338b8dc3SIngo Weinhold };
353338b8dc3SIngo Weinhold
354338b8dc3SIngo Weinhold } // namespace BPrivate
355338b8dc3SIngo Weinhold
356338b8dc3SIngo Weinhold using BPrivate::PaletteConverter;
357338b8dc3SIngo Weinhold using namespace std;
358338b8dc3SIngo Weinhold
35964b2d169SAxel Dörfler
360338b8dc3SIngo Weinhold /*! \brief Creates an uninitialized PaletteConverter.
361338b8dc3SIngo Weinhold */
PaletteConverter()362338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter()
363338b8dc3SIngo Weinhold : fColorMap(NULL),
364338b8dc3SIngo Weinhold fOwnColorMap(NULL),
365338b8dc3SIngo Weinhold fCStatus(B_NO_INIT)
366338b8dc3SIngo Weinhold {
367338b8dc3SIngo Weinhold }
368338b8dc3SIngo Weinhold
36964b2d169SAxel Dörfler
370338b8dc3SIngo Weinhold /*! \brief Creates a PaletteConverter and initializes it to the supplied
371338b8dc3SIngo Weinhold palette.
372338b8dc3SIngo Weinhold \param palette The palette being a 256 entry rgb_color array.
373338b8dc3SIngo Weinhold */
PaletteConverter(const rgb_color * palette)374338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter(const rgb_color *palette)
375338b8dc3SIngo Weinhold : fColorMap(NULL),
376338b8dc3SIngo Weinhold fOwnColorMap(NULL),
377338b8dc3SIngo Weinhold fCStatus(B_NO_INIT)
378338b8dc3SIngo Weinhold {
379338b8dc3SIngo Weinhold SetTo(palette);
380338b8dc3SIngo Weinhold }
381338b8dc3SIngo Weinhold
38264b2d169SAxel Dörfler
383338b8dc3SIngo Weinhold /*! \brief Creates a PaletteConverter and initializes it to the supplied
384338b8dc3SIngo Weinhold color map.
385338b8dc3SIngo Weinhold \param colorMap The completely initialized color map.
386338b8dc3SIngo Weinhold */
PaletteConverter(const color_map * colorMap)387338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter(const color_map *colorMap)
388338b8dc3SIngo Weinhold : fColorMap(NULL),
389338b8dc3SIngo Weinhold fOwnColorMap(NULL),
390338b8dc3SIngo Weinhold fCStatus(B_NO_INIT)
391338b8dc3SIngo Weinhold {
392338b8dc3SIngo Weinhold SetTo(colorMap);
393338b8dc3SIngo Weinhold }
394338b8dc3SIngo Weinhold
39564b2d169SAxel Dörfler
396338b8dc3SIngo Weinhold /*! \brief Frees all resources associated with this object.
397338b8dc3SIngo Weinhold */
~PaletteConverter()398338b8dc3SIngo Weinhold PaletteConverter::~PaletteConverter()
399338b8dc3SIngo Weinhold {
400338b8dc3SIngo Weinhold delete fOwnColorMap;
401338b8dc3SIngo Weinhold }
402338b8dc3SIngo Weinhold
40364b2d169SAxel Dörfler
404338b8dc3SIngo Weinhold /*! \brief Initializes the converter to the supplied palette.
405338b8dc3SIngo Weinhold \param palette The palette being a 256 entry rgb_color array.
406338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise.
407338b8dc3SIngo Weinhold */
408338b8dc3SIngo Weinhold status_t
SetTo(const rgb_color * palette)409338b8dc3SIngo Weinhold PaletteConverter::SetTo(const rgb_color *palette)
410338b8dc3SIngo Weinhold {
411338b8dc3SIngo Weinhold // cleanup
412338b8dc3SIngo Weinhold SetTo((const color_map*)NULL);
413338b8dc3SIngo Weinhold status_t error = (palette ? B_OK : B_BAD_VALUE);
414338b8dc3SIngo Weinhold // alloc color map
415338b8dc3SIngo Weinhold if (error == B_OK) {
416338b8dc3SIngo Weinhold fOwnColorMap = new(nothrow) color_map;
417338b8dc3SIngo Weinhold if (fOwnColorMap == NULL)
418338b8dc3SIngo Weinhold error = B_NO_MEMORY;
419338b8dc3SIngo Weinhold }
420338b8dc3SIngo Weinhold // init color map
421338b8dc3SIngo Weinhold if (error == B_OK) {
422338b8dc3SIngo Weinhold fColorMap = fOwnColorMap;
423338b8dc3SIngo Weinhold // init color list
424338b8dc3SIngo Weinhold memcpy(fOwnColorMap->color_list, palette, sizeof(rgb_color) * 256);
425338b8dc3SIngo Weinhold // init index map
426338b8dc3SIngo Weinhold for (int32 color = 0; color < 32768; color++) {
427338b8dc3SIngo Weinhold // get components
428338b8dc3SIngo Weinhold uint8 red = (color & 0x7c00) >> 7;
429338b8dc3SIngo Weinhold uint8 green = (color & 0x3e0) >> 2;
430338b8dc3SIngo Weinhold uint8 blue = (color & 0x1f) << 3;
431338b8dc3SIngo Weinhold red |= red >> 5;
432338b8dc3SIngo Weinhold green |= green >> 5;
433338b8dc3SIngo Weinhold blue |= blue >> 5;
434338b8dc3SIngo Weinhold // find closest color
435338b8dc3SIngo Weinhold uint8 closestIndex = 0;
436338b8dc3SIngo Weinhold unsigned closestDistance = UINT_MAX;
437338b8dc3SIngo Weinhold for (int32 i = 0; i < 256; i++) {
438338b8dc3SIngo Weinhold const rgb_color &c = fOwnColorMap->color_list[i];
439338b8dc3SIngo Weinhold unsigned distance = color_distance(red, green, blue,
440338b8dc3SIngo Weinhold c.red, c.green, c.blue);
441338b8dc3SIngo Weinhold if (distance < closestDistance) {
442338b8dc3SIngo Weinhold closestIndex = i;
443338b8dc3SIngo Weinhold closestDistance = distance;
444338b8dc3SIngo Weinhold }
445338b8dc3SIngo Weinhold }
446338b8dc3SIngo Weinhold fOwnColorMap->index_map[color] = closestIndex;
447338b8dc3SIngo Weinhold }
448338b8dc3SIngo Weinhold // no need to init inversion map
449338b8dc3SIngo Weinhold }
450338b8dc3SIngo Weinhold fCStatus = error;
451338b8dc3SIngo Weinhold return error;
452338b8dc3SIngo Weinhold }
453338b8dc3SIngo Weinhold
45464b2d169SAxel Dörfler
455338b8dc3SIngo Weinhold /*! \brief Initializes the converter to the supplied color map.
456338b8dc3SIngo Weinhold \param colorMap The completely initialized color map.
457338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise.
458338b8dc3SIngo Weinhold */
459338b8dc3SIngo Weinhold status_t
SetTo(const color_map * colorMap)460338b8dc3SIngo Weinhold PaletteConverter::SetTo(const color_map *colorMap)
461338b8dc3SIngo Weinhold {
462338b8dc3SIngo Weinhold // cleanup
463338b8dc3SIngo Weinhold if (fOwnColorMap) {
464338b8dc3SIngo Weinhold delete fOwnColorMap;
465338b8dc3SIngo Weinhold fOwnColorMap = NULL;
466338b8dc3SIngo Weinhold }
467338b8dc3SIngo Weinhold // set
468338b8dc3SIngo Weinhold fColorMap = colorMap;
46964b2d169SAxel Dörfler fCStatus = fColorMap ? B_OK : B_BAD_VALUE;
470338b8dc3SIngo Weinhold return fCStatus;
471338b8dc3SIngo Weinhold }
472338b8dc3SIngo Weinhold
47364b2d169SAxel Dörfler
474338b8dc3SIngo Weinhold /*! \brief Returns the result of the last initialization via constructor or
475338b8dc3SIngo Weinhold SetTo().
476338b8dc3SIngo Weinhold \return \c B_OK, if the converter is properly initialized, an error code
477338b8dc3SIngo Weinhold otherwise.
478338b8dc3SIngo Weinhold */
479338b8dc3SIngo Weinhold status_t
InitCheck() const480338b8dc3SIngo Weinhold PaletteConverter::InitCheck() const
481338b8dc3SIngo Weinhold {
482338b8dc3SIngo Weinhold return fCStatus;
483338b8dc3SIngo Weinhold }
484338b8dc3SIngo Weinhold
48564b2d169SAxel Dörfler
486338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 15 color.
487338b8dc3SIngo Weinhold
488338b8dc3SIngo Weinhold The object must be properly initialized.
489338b8dc3SIngo Weinhold
490338b8dc3SIngo Weinhold \param rgb The RGB 15 color value (R[14:10]G[9:5]B[4:0]).
491338b8dc3SIngo Weinhold \return The palette color index for the supplied color.
492338b8dc3SIngo Weinhold */
49364b2d169SAxel Dörfler inline uint8
IndexForRGB15(uint16 rgb) const494338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB15(uint16 rgb) const
495338b8dc3SIngo Weinhold {
496338b8dc3SIngo Weinhold return fColorMap->index_map[rgb];
497338b8dc3SIngo Weinhold }
498338b8dc3SIngo Weinhold
49964b2d169SAxel Dörfler
500338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 15 color.
501338b8dc3SIngo Weinhold
502338b8dc3SIngo Weinhold The object must be properly initialized.
503338b8dc3SIngo Weinhold
504338b8dc3SIngo Weinhold \param red Red component of the color (R[4:0]).
505338b8dc3SIngo Weinhold \param green Green component of the color (G[4:0]).
506338b8dc3SIngo Weinhold \param blue Blue component of the color (B[4:0]).
507338b8dc3SIngo Weinhold \return The palette color index for the supplied color.
508338b8dc3SIngo Weinhold */
50964b2d169SAxel Dörfler inline uint8
IndexForRGB15(uint8 red,uint8 green,uint8 blue) const510338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB15(uint8 red, uint8 green, uint8 blue) const
511338b8dc3SIngo Weinhold {
512338b8dc3SIngo Weinhold // the 5 least significant bits are used
513338b8dc3SIngo Weinhold return fColorMap->index_map[(red << 10) | (green << 5) | blue];
514338b8dc3SIngo Weinhold }
515338b8dc3SIngo Weinhold
51664b2d169SAxel Dörfler
517338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 16 color.
518338b8dc3SIngo Weinhold
519338b8dc3SIngo Weinhold The object must be properly initialized.
520338b8dc3SIngo Weinhold
521338b8dc3SIngo Weinhold \param rgb The RGB 16 color value (R[15:11]G[10:5]B[4:0]).
522338b8dc3SIngo Weinhold \return The palette color index for the supplied color.
523338b8dc3SIngo Weinhold */
52464b2d169SAxel Dörfler inline uint8
IndexForRGB16(uint16 rgb) const525338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB16(uint16 rgb) const
526338b8dc3SIngo Weinhold {
52764b2d169SAxel Dörfler return fColorMap->index_map[((rgb >> 1) & 0x7fe0) | (rgb & 0x1f)];
528338b8dc3SIngo Weinhold }
529338b8dc3SIngo Weinhold
53064b2d169SAxel Dörfler
531338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 16 color.
532338b8dc3SIngo Weinhold
533338b8dc3SIngo Weinhold The object must be properly initialized.
534338b8dc3SIngo Weinhold
535338b8dc3SIngo Weinhold \param red Red component of the color (R[4:0]).
536338b8dc3SIngo Weinhold \param green Green component of the color (G[5:0]).
537338b8dc3SIngo Weinhold \param blue Blue component of the color (B[4:0]).
538338b8dc3SIngo Weinhold \return The palette color index for the supplied color.
539338b8dc3SIngo Weinhold */
54064b2d169SAxel Dörfler inline uint8
IndexForRGB16(uint8 red,uint8 green,uint8 blue) const541338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB16(uint8 red, uint8 green, uint8 blue) const
542338b8dc3SIngo Weinhold {
543338b8dc3SIngo Weinhold // the 5 (for red, blue) / 6 (for green) least significant bits are used
544338b8dc3SIngo Weinhold return fColorMap->index_map[(red << 10) | ((green & 0x3e) << 4) | blue];
545338b8dc3SIngo Weinhold }
546338b8dc3SIngo Weinhold
54764b2d169SAxel Dörfler
548338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 32 color.
549338b8dc3SIngo Weinhold
550338b8dc3SIngo Weinhold The object must be properly initialized.
551338b8dc3SIngo Weinhold
552338b8dc3SIngo Weinhold \param rgb The RGB 32 color value (R[31:24]G[23:16]B[15:8]).
553338b8dc3SIngo Weinhold \return The palette color index for the supplied color.
554338b8dc3SIngo Weinhold */
55564b2d169SAxel Dörfler inline uint8
IndexForRGB24(uint32 rgb) const556338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB24(uint32 rgb) const
557338b8dc3SIngo Weinhold {
558338b8dc3SIngo Weinhold return fColorMap->index_map[((rgb & 0xf8000000) >> 17)
55964b2d169SAxel Dörfler | ((rgb & 0xf80000) >> 14) | ((rgb & 0xf800) >> 11)];
560338b8dc3SIngo Weinhold }
561338b8dc3SIngo Weinhold
56264b2d169SAxel Dörfler
563338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 24 color.
564338b8dc3SIngo Weinhold
565338b8dc3SIngo Weinhold The object must be properly initialized.
566338b8dc3SIngo Weinhold
567338b8dc3SIngo Weinhold \param red Red component of the color.
568338b8dc3SIngo Weinhold \param green Green component of the color.
569338b8dc3SIngo Weinhold \param blue Blue component of the color.
570338b8dc3SIngo Weinhold \return The palette color index for the supplied color.
571338b8dc3SIngo Weinhold */
57264b2d169SAxel Dörfler inline uint8
IndexForRGB24(uint8 red,uint8 green,uint8 blue) const573338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB24(uint8 red, uint8 green, uint8 blue) const
574338b8dc3SIngo Weinhold {
57564b2d169SAxel Dörfler return fColorMap->index_map[((red & 0xf8) << 7) | ((green & 0xf8) << 2)
576338b8dc3SIngo Weinhold | (blue >> 3)];
577338b8dc3SIngo Weinhold }
578338b8dc3SIngo Weinhold
57964b2d169SAxel Dörfler
580338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given Gray 8 color.
581338b8dc3SIngo Weinhold
582338b8dc3SIngo Weinhold The object must be properly initialized.
583338b8dc3SIngo Weinhold
584338b8dc3SIngo Weinhold \param gray The Gray 8 color value.
585338b8dc3SIngo Weinhold \return The palette color index for the supplied color.
586338b8dc3SIngo Weinhold */
58764b2d169SAxel Dörfler inline uint8
IndexForGray(uint8 gray) const588338b8dc3SIngo Weinhold PaletteConverter::IndexForGray(uint8 gray) const
589338b8dc3SIngo Weinhold {
590338b8dc3SIngo Weinhold return IndexForRGB24(gray, gray, gray);
591338b8dc3SIngo Weinhold }
592338b8dc3SIngo Weinhold
59364b2d169SAxel Dörfler
594338b8dc3SIngo Weinhold /*! \brief Returns the RGB color for a given palette color index.
595338b8dc3SIngo Weinhold
596338b8dc3SIngo Weinhold The object must be properly initialized.
597338b8dc3SIngo Weinhold
598338b8dc3SIngo Weinhold \param index The palette color index.
599338b8dc3SIngo Weinhold \return The color for the supplied palette color index.
600338b8dc3SIngo Weinhold */
60164b2d169SAxel Dörfler inline const rgb_color &
RGBColorForIndex(uint8 index) const602338b8dc3SIngo Weinhold PaletteConverter::RGBColorForIndex(uint8 index) const
603338b8dc3SIngo Weinhold {
604338b8dc3SIngo Weinhold return fColorMap->color_list[index];
605338b8dc3SIngo Weinhold }
606338b8dc3SIngo Weinhold
60764b2d169SAxel Dörfler
608338b8dc3SIngo Weinhold /*! \brief Returns the RGB 15 color for a given palette color index.
609338b8dc3SIngo Weinhold
610338b8dc3SIngo Weinhold The object must be properly initialized.
611338b8dc3SIngo Weinhold
612338b8dc3SIngo Weinhold \param index The palette color index.
613338b8dc3SIngo Weinhold \return The color for the supplied palette color index
614338b8dc3SIngo Weinhold (R[14:10]G[9:5]B[4:0]).
615338b8dc3SIngo Weinhold */
61664b2d169SAxel Dörfler inline uint16
RGB15ColorForIndex(uint8 index) const617338b8dc3SIngo Weinhold PaletteConverter::RGB15ColorForIndex(uint8 index) const
618338b8dc3SIngo Weinhold {
619338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index];
62064b2d169SAxel Dörfler return ((color.red & 0xf8) << 7) | ((color.green & 0xf8) << 2)
621338b8dc3SIngo Weinhold | (color.blue >> 3);
622338b8dc3SIngo Weinhold }
623338b8dc3SIngo Weinhold
62464b2d169SAxel Dörfler
625338b8dc3SIngo Weinhold /*! \brief Returns the RGB 16 color for a given palette color index.
626338b8dc3SIngo Weinhold
627338b8dc3SIngo Weinhold The object must be properly initialized.
628338b8dc3SIngo Weinhold
629338b8dc3SIngo Weinhold \param index The palette color index.
630338b8dc3SIngo Weinhold \return The color for the supplied palette color index
631338b8dc3SIngo Weinhold (R[15:11]G[10:5]B[4:0]).
632338b8dc3SIngo Weinhold */
63364b2d169SAxel Dörfler inline uint16
RGB16ColorForIndex(uint8 index) const634338b8dc3SIngo Weinhold PaletteConverter::RGB16ColorForIndex(uint8 index) const
635338b8dc3SIngo Weinhold {
636338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index];
63764b2d169SAxel Dörfler return ((color.red & 0xf8) << 8) | ((color.green & 0xfc) << 3)
638338b8dc3SIngo Weinhold | (color.blue >> 3);
639338b8dc3SIngo Weinhold }
640338b8dc3SIngo Weinhold
64164b2d169SAxel Dörfler
642338b8dc3SIngo Weinhold /*! \brief Returns the RGB 24 color for a given palette color index.
643338b8dc3SIngo Weinhold
644338b8dc3SIngo Weinhold The object must be properly initialized.
645338b8dc3SIngo Weinhold
646338b8dc3SIngo Weinhold \param index The palette color index.
647338b8dc3SIngo Weinhold \return The color for the supplied palette color index
648338b8dc3SIngo Weinhold (R[31:24]G[23:16]B[15:8]).
649338b8dc3SIngo Weinhold */
65064b2d169SAxel Dörfler inline uint32
RGB24ColorForIndex(uint8 index) const651338b8dc3SIngo Weinhold PaletteConverter::RGB24ColorForIndex(uint8 index) const
652338b8dc3SIngo Weinhold {
653338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index];
65464b2d169SAxel Dörfler return (color.blue << 24) | (color.red << 8) | (color.green << 16)
65564b2d169SAxel Dörfler | color.alpha;
656338b8dc3SIngo Weinhold }
657338b8dc3SIngo Weinhold
65864b2d169SAxel Dörfler
659338b8dc3SIngo Weinhold /*! \brief Returns the RGB 24 color for a given palette color index.
660338b8dc3SIngo Weinhold
661338b8dc3SIngo Weinhold The object must be properly initialized.
662338b8dc3SIngo Weinhold
663338b8dc3SIngo Weinhold \param index The palette color index.
664338b8dc3SIngo Weinhold \param red Reference to the variable the red component shall be stored
665338b8dc3SIngo Weinhold into.
666338b8dc3SIngo Weinhold \param green Reference to the variable the green component shall be stored
667338b8dc3SIngo Weinhold into.
668338b8dc3SIngo Weinhold \param blue Reference to the variable the blue component shall be stored
669338b8dc3SIngo Weinhold into.
670338b8dc3SIngo Weinhold */
67164b2d169SAxel Dörfler inline void
RGB24ColorForIndex(uint8 index,uint8 & red,uint8 & green,uint8 & blue,uint8 & alpha) const672338b8dc3SIngo Weinhold PaletteConverter::RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green,
673338b8dc3SIngo Weinhold uint8 &blue, uint8 &alpha) const
674338b8dc3SIngo Weinhold {
675338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index];
676338b8dc3SIngo Weinhold red = color.red;
677338b8dc3SIngo Weinhold green = color.green;
678338b8dc3SIngo Weinhold blue = color.blue;
679338b8dc3SIngo Weinhold alpha = color.alpha;
680338b8dc3SIngo Weinhold }
681338b8dc3SIngo Weinhold
68264b2d169SAxel Dörfler
683338b8dc3SIngo Weinhold /*! \brief Returns the Gray 8 color for a given palette color index.
684338b8dc3SIngo Weinhold
685338b8dc3SIngo Weinhold The object must be properly initialized.
686338b8dc3SIngo Weinhold
687338b8dc3SIngo Weinhold \param index The palette color index.
688338b8dc3SIngo Weinhold \return The color for the supplied palette color index.
689338b8dc3SIngo Weinhold */
69064b2d169SAxel Dörfler inline uint8
GrayColorForIndex(uint8 index) const691338b8dc3SIngo Weinhold PaletteConverter::GrayColorForIndex(uint8 index) const
692338b8dc3SIngo Weinhold {
693338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index];
694338b8dc3SIngo Weinhold return brightness_for(color.red, color.green, color.blue);
695338b8dc3SIngo Weinhold }
696338b8dc3SIngo Weinhold
697338b8dc3SIngo Weinhold // TODO: Remove these and palette_converter() when BScreen is available.
698338b8dc3SIngo Weinhold static BLocker gPaletteConverterLock;
699338b8dc3SIngo Weinhold static PaletteConverter gPaletteConverter;
700338b8dc3SIngo Weinhold
70164b2d169SAxel Dörfler
702338b8dc3SIngo Weinhold /*! \brief Returns a PaletteConverter using the system color palette.
703338b8dc3SIngo Weinhold \return A PaletteConverter.
704338b8dc3SIngo Weinhold */
70564b2d169SAxel Dörfler static const PaletteConverter*
palette_converter()706338b8dc3SIngo Weinhold palette_converter()
707338b8dc3SIngo Weinhold {
708338b8dc3SIngo Weinhold if (gPaletteConverterLock.Lock()) {
709338b8dc3SIngo Weinhold if (gPaletteConverter.InitCheck() != B_OK)
710338b8dc3SIngo Weinhold gPaletteConverter.SetTo(kSystemPalette);
711338b8dc3SIngo Weinhold gPaletteConverterLock.Unlock();
712338b8dc3SIngo Weinhold }
713338b8dc3SIngo Weinhold return &gPaletteConverter;
714338b8dc3SIngo Weinhold }
715338b8dc3SIngo Weinhold
716338b8dc3SIngo Weinhold
71764b2d169SAxel Dörfler // #pragma mark - Reader classes
718338b8dc3SIngo Weinhold
719338b8dc3SIngo Weinhold
720338b8dc3SIngo Weinhold // BaseReader
721338b8dc3SIngo Weinhold template<typename _PixelType>
722338b8dc3SIngo Weinhold struct BaseReader {
723338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
724338b8dc3SIngo Weinhold
BaseReaderBaseReader725338b8dc3SIngo Weinhold BaseReader(const void *data) : pixels((const pixel_t*)data) {}
726338b8dc3SIngo Weinhold
SetToBaseReader727338b8dc3SIngo Weinhold inline void SetTo(const void *data) { pixels = (const pixel_t*)data; }
728338b8dc3SIngo Weinhold
NextRowBaseReader729338b8dc3SIngo Weinhold inline void NextRow(int32 skip)
730338b8dc3SIngo Weinhold {
731338b8dc3SIngo Weinhold pixels = (const pixel_t*)((const char*)pixels + skip);
732338b8dc3SIngo Weinhold }
733338b8dc3SIngo Weinhold
734338b8dc3SIngo Weinhold const pixel_t *pixels;
735338b8dc3SIngo Weinhold };
736338b8dc3SIngo Weinhold
737338b8dc3SIngo Weinhold // RGB24Reader
738338b8dc3SIngo Weinhold template<typename _PixelType>
739338b8dc3SIngo Weinhold struct RGB24Reader : public BaseReader<_PixelType> {
740338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
741338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
742338b8dc3SIngo Weinhold
RGB24ReaderRGB24Reader743338b8dc3SIngo Weinhold RGB24Reader(const void *data) : BaseReader<_PixelType>(data) {}
744338b8dc3SIngo Weinhold
ReadRGB24Reader745338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color)
746338b8dc3SIngo Weinhold {
747338b8dc3SIngo Weinhold const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
748338b8dc3SIngo Weinhold color.red = pixel.red;
749338b8dc3SIngo Weinhold color.green = pixel.green;
750338b8dc3SIngo Weinhold color.blue = pixel.blue;
75163d557f0SMichael Lotz color.alpha = 255;
752338b8dc3SIngo Weinhold BaseReader<_PixelType>::pixels++;
753338b8dc3SIngo Weinhold }
754338b8dc3SIngo Weinhold
ReadRGB24Reader755338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray)
756338b8dc3SIngo Weinhold {
757338b8dc3SIngo Weinhold rgb_color_value color;
758338b8dc3SIngo Weinhold Read(color);
759338b8dc3SIngo Weinhold gray = brightness_for(color.red, color.green, color.blue);
760338b8dc3SIngo Weinhold }
761338b8dc3SIngo Weinhold };
762338b8dc3SIngo Weinhold
763338b8dc3SIngo Weinhold // RGB16Reader
764338b8dc3SIngo Weinhold template<typename _PixelType>
765338b8dc3SIngo Weinhold struct RGB16Reader : public BaseReader<_PixelType> {
766338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
767338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
768338b8dc3SIngo Weinhold
RGB16ReaderRGB16Reader769338b8dc3SIngo Weinhold RGB16Reader(const void *data) : BaseReader<_PixelType>(data) {}
770338b8dc3SIngo Weinhold
ReadRGB16Reader771338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color)
772338b8dc3SIngo Weinhold {
773338b8dc3SIngo Weinhold // rg: R[4:0],G[5:3]
774338b8dc3SIngo Weinhold // gb: G[2:0],B[4:0]
775338b8dc3SIngo Weinhold const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
776338b8dc3SIngo Weinhold color.red = pixel.rg & 0xf8;
777338b8dc3SIngo Weinhold color.green = ((pixel.rg & 0x07) << 5) & ((pixel.gb & 0xe0) >> 3);
778338b8dc3SIngo Weinhold color.blue = (pixel.gb & 0x1f) << 3;
779338b8dc3SIngo Weinhold color.red |= color.red >> 5;
780338b8dc3SIngo Weinhold color.green |= color.green >> 6;
781338b8dc3SIngo Weinhold color.blue |= color.blue >> 5;
78263d557f0SMichael Lotz color.alpha = 255;
783338b8dc3SIngo Weinhold BaseReader<_PixelType>::pixels++;
784338b8dc3SIngo Weinhold }
785338b8dc3SIngo Weinhold
ReadRGB16Reader786338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray)
787338b8dc3SIngo Weinhold {
788338b8dc3SIngo Weinhold rgb_color_value color;
789338b8dc3SIngo Weinhold Read(color);
790338b8dc3SIngo Weinhold gray = brightness_for(color.red, color.green, color.blue);
791338b8dc3SIngo Weinhold }
792338b8dc3SIngo Weinhold };
793338b8dc3SIngo Weinhold
794338b8dc3SIngo Weinhold // RGB15Reader
795338b8dc3SIngo Weinhold template<typename _PixelType>
796338b8dc3SIngo Weinhold struct RGB15Reader : public BaseReader<_PixelType> {
797338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
798338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
799338b8dc3SIngo Weinhold
RGB15ReaderRGB15Reader800338b8dc3SIngo Weinhold RGB15Reader(const void *data) : BaseReader<_PixelType>(data) {}
801338b8dc3SIngo Weinhold
ReadRGB15Reader802338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color)
803338b8dc3SIngo Weinhold {
804338b8dc3SIngo Weinhold // rg: -[0],R[4:0],G[4:3]
805338b8dc3SIngo Weinhold // gb: G[2:0],B[4:0]
806338b8dc3SIngo Weinhold const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
807338b8dc3SIngo Weinhold color.red = (pixel.rg & 0x7c) << 1;
808338b8dc3SIngo Weinhold color.green = ((pixel.rg & 0x03) << 6) & ((pixel.gb & 0xe0) >> 2);
809338b8dc3SIngo Weinhold color.blue = (pixel.gb & 0x1f) << 3;
810338b8dc3SIngo Weinhold color.red |= color.red >> 5;
811338b8dc3SIngo Weinhold color.green |= color.green >> 5;
812338b8dc3SIngo Weinhold color.blue |= color.blue >> 5;
81363d557f0SMichael Lotz color.alpha = 255;
814338b8dc3SIngo Weinhold BaseReader<_PixelType>::pixels++;
815338b8dc3SIngo Weinhold }
816338b8dc3SIngo Weinhold
ReadRGB15Reader817338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray)
818338b8dc3SIngo Weinhold {
819338b8dc3SIngo Weinhold rgb_color_value color;
820338b8dc3SIngo Weinhold Read(color);
821338b8dc3SIngo Weinhold gray = brightness_for(color.red, color.green, color.blue);
822338b8dc3SIngo Weinhold }
823338b8dc3SIngo Weinhold };
824338b8dc3SIngo Weinhold
825338b8dc3SIngo Weinhold // CMAP8Reader
826338b8dc3SIngo Weinhold struct CMAP8Reader : public BaseReader<uint8> {
827338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
828338b8dc3SIngo Weinhold
CMAP8ReaderCMAP8Reader829338b8dc3SIngo Weinhold CMAP8Reader(const void *data, const PaletteConverter &converter)
830338b8dc3SIngo Weinhold : BaseReader<uint8>(data), converter(converter) {}
831338b8dc3SIngo Weinhold
ReadCMAP8Reader832338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color)
833338b8dc3SIngo Weinhold {
834338b8dc3SIngo Weinhold converter.RGB24ColorForIndex(*BaseReader<uint8>::pixels, color.red, color.green,
835338b8dc3SIngo Weinhold color.blue, color.alpha);
836338b8dc3SIngo Weinhold BaseReader<uint8>::pixels++;
837338b8dc3SIngo Weinhold }
838338b8dc3SIngo Weinhold
ReadCMAP8Reader839338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray)
840338b8dc3SIngo Weinhold {
841338b8dc3SIngo Weinhold gray = converter.GrayColorForIndex(*BaseReader<uint8>::pixels);
842338b8dc3SIngo Weinhold BaseReader<uint8>::pixels++;
843338b8dc3SIngo Weinhold }
844338b8dc3SIngo Weinhold
845338b8dc3SIngo Weinhold const PaletteConverter &converter;
846338b8dc3SIngo Weinhold };
847338b8dc3SIngo Weinhold
848338b8dc3SIngo Weinhold // Gray8Reader
849338b8dc3SIngo Weinhold struct Gray8Reader : public BaseReader<uint8> {
850338b8dc3SIngo Weinhold typedef gray_color_value preferred_color_value_t;
851338b8dc3SIngo Weinhold
Gray8ReaderGray8Reader852338b8dc3SIngo Weinhold Gray8Reader(const void *data) : BaseReader<uint8>(data) {}
853338b8dc3SIngo Weinhold
ReadGray8Reader854338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color)
855338b8dc3SIngo Weinhold {
856338b8dc3SIngo Weinhold color.red = color.green = color.blue = *BaseReader<uint8>::pixels;
85763d557f0SMichael Lotz color.alpha = 255;
858338b8dc3SIngo Weinhold BaseReader<uint8>::pixels++;
859338b8dc3SIngo Weinhold }
860338b8dc3SIngo Weinhold
ReadGray8Reader861338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray)
862338b8dc3SIngo Weinhold {
863338b8dc3SIngo Weinhold gray = *BaseReader<uint8>::pixels;
864338b8dc3SIngo Weinhold BaseReader<uint8>::pixels++;
865338b8dc3SIngo Weinhold }
866338b8dc3SIngo Weinhold };
867338b8dc3SIngo Weinhold
868338b8dc3SIngo Weinhold // Gray1Reader
869338b8dc3SIngo Weinhold struct Gray1Reader : public BaseReader<uint8> {
870338b8dc3SIngo Weinhold typedef gray_color_value preferred_color_value_t;
871338b8dc3SIngo Weinhold
Gray1ReaderGray1Reader872338b8dc3SIngo Weinhold Gray1Reader(const void *data) : BaseReader<uint8>(data), bit(7) {}
873338b8dc3SIngo Weinhold
SetToGray1Reader874338b8dc3SIngo Weinhold inline void SetTo(const void *data)
875338b8dc3SIngo Weinhold {
876338b8dc3SIngo Weinhold pixels = (const pixel_t*)data;
877338b8dc3SIngo Weinhold bit = 7;
878338b8dc3SIngo Weinhold }
879338b8dc3SIngo Weinhold
NextRowGray1Reader880338b8dc3SIngo Weinhold inline void NextRow(int32 skip)
881338b8dc3SIngo Weinhold {
882338b8dc3SIngo Weinhold if (bit == 7)
883338b8dc3SIngo Weinhold pixels = (const pixel_t*)((const char*)pixels + skip);
884338b8dc3SIngo Weinhold else {
885338b8dc3SIngo Weinhold pixels = (const pixel_t*)((const char*)pixels + skip + 1);
886338b8dc3SIngo Weinhold bit = 7;
887338b8dc3SIngo Weinhold }
888338b8dc3SIngo Weinhold }
889338b8dc3SIngo Weinhold
ReadGray1Reader890338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color)
891338b8dc3SIngo Weinhold {
892338b8dc3SIngo Weinhold if (*pixels & bit_mask(bit))
893338b8dc3SIngo Weinhold color.red = color.green = color.blue = 255;
894338b8dc3SIngo Weinhold else
895338b8dc3SIngo Weinhold color.red = color.green = color.blue = 0;
89663d557f0SMichael Lotz color.alpha = 255;
897338b8dc3SIngo Weinhold bit--;
898338b8dc3SIngo Weinhold if (bit == -1) {
899338b8dc3SIngo Weinhold pixels++;
900338b8dc3SIngo Weinhold bit = 7;
901338b8dc3SIngo Weinhold }
902338b8dc3SIngo Weinhold }
903338b8dc3SIngo Weinhold
ReadGray1Reader904338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray)
905338b8dc3SIngo Weinhold {
906338b8dc3SIngo Weinhold if (*pixels & bit_mask(bit))
907338b8dc3SIngo Weinhold gray = 255;
908338b8dc3SIngo Weinhold else
909338b8dc3SIngo Weinhold gray = 0;
910338b8dc3SIngo Weinhold bit--;
911338b8dc3SIngo Weinhold if (bit == -1) {
912338b8dc3SIngo Weinhold pixels++;
913338b8dc3SIngo Weinhold bit = 7;
914338b8dc3SIngo Weinhold }
915338b8dc3SIngo Weinhold }
916338b8dc3SIngo Weinhold
917338b8dc3SIngo Weinhold int32 bit;
918338b8dc3SIngo Weinhold };
919338b8dc3SIngo Weinhold
920338b8dc3SIngo Weinhold
92164b2d169SAxel Dörfler // #pragma mark - Writer classes
92264b2d169SAxel Dörfler
923338b8dc3SIngo Weinhold
924338b8dc3SIngo Weinhold // BaseWriter
925338b8dc3SIngo Weinhold template<typename _PixelType>
926338b8dc3SIngo Weinhold struct BaseWriter {
927338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
928338b8dc3SIngo Weinhold
BaseWriterBaseWriter929338b8dc3SIngo Weinhold BaseWriter(void *data) : pixels((pixel_t*)data) {}
930338b8dc3SIngo Weinhold
SetToBaseWriter931338b8dc3SIngo Weinhold inline void SetTo(void *data) { pixels = (pixel_t*)data; }
932338b8dc3SIngo Weinhold
933338b8dc3SIngo Weinhold pixel_t *pixels;
934338b8dc3SIngo Weinhold };
935338b8dc3SIngo Weinhold
936338b8dc3SIngo Weinhold
937338b8dc3SIngo Weinhold // RGB32Writer
938338b8dc3SIngo Weinhold template<typename _PixelType>
939338b8dc3SIngo Weinhold struct RGB32Writer : public BaseWriter<_PixelType> {
940338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
941338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
942338b8dc3SIngo Weinhold
RGB32WriterRGB32Writer943338b8dc3SIngo Weinhold RGB32Writer(void *data) : BaseWriter<_PixelType>(data) {}
944338b8dc3SIngo Weinhold
WriteRGB32Writer945338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color)
946338b8dc3SIngo Weinhold {
947338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
948338b8dc3SIngo Weinhold pixel.red = color.red;
949338b8dc3SIngo Weinhold pixel.green = color.green;
950338b8dc3SIngo Weinhold pixel.blue = color.blue;
951338b8dc3SIngo Weinhold pixel.alpha = color.alpha;
952338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++;
953338b8dc3SIngo Weinhold }
954338b8dc3SIngo Weinhold
WriteRGB32Writer955338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray)
956338b8dc3SIngo Weinhold {
957338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
958338b8dc3SIngo Weinhold pixel.red = gray;
959338b8dc3SIngo Weinhold pixel.green = gray;
960338b8dc3SIngo Weinhold pixel.blue = gray;
961338b8dc3SIngo Weinhold pixel.alpha = 255;
962338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++;
963338b8dc3SIngo Weinhold }
964338b8dc3SIngo Weinhold };
965338b8dc3SIngo Weinhold
966338b8dc3SIngo Weinhold // RGB24Writer
967338b8dc3SIngo Weinhold template<typename _PixelType>
968338b8dc3SIngo Weinhold struct RGB24Writer : public BaseWriter<_PixelType> {
969338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
970338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
971338b8dc3SIngo Weinhold
RGB24WriterRGB24Writer972338b8dc3SIngo Weinhold RGB24Writer(void *data) : BaseWriter<_PixelType>(data) {}
973338b8dc3SIngo Weinhold
WriteRGB24Writer974338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color)
975338b8dc3SIngo Weinhold {
976338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
977338b8dc3SIngo Weinhold pixel.red = color.red;
978338b8dc3SIngo Weinhold pixel.green = color.green;
979338b8dc3SIngo Weinhold pixel.blue = color.blue;
980338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++;
981338b8dc3SIngo Weinhold }
982338b8dc3SIngo Weinhold
WriteRGB24Writer983338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray)
984338b8dc3SIngo Weinhold {
985338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
986338b8dc3SIngo Weinhold pixel.red = gray;
987338b8dc3SIngo Weinhold pixel.green = gray;
988338b8dc3SIngo Weinhold pixel.blue = gray;
989338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++;
990338b8dc3SIngo Weinhold }
991338b8dc3SIngo Weinhold };
992338b8dc3SIngo Weinhold
993338b8dc3SIngo Weinhold // RGB16Writer
994338b8dc3SIngo Weinhold template<typename _PixelType>
995338b8dc3SIngo Weinhold struct RGB16Writer : public BaseWriter<_PixelType> {
996338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
997338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
998338b8dc3SIngo Weinhold
RGB16WriterRGB16Writer999338b8dc3SIngo Weinhold RGB16Writer(void *data) : BaseWriter<_PixelType>(data) {}
1000338b8dc3SIngo Weinhold
WriteRGB16Writer1001338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color)
1002338b8dc3SIngo Weinhold {
1003338b8dc3SIngo Weinhold // rg: R[4:0],G[5:3]
1004338b8dc3SIngo Weinhold // gb: G[2:0],B[4:0]
1005338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1006338b8dc3SIngo Weinhold pixel.rg = (color.red & 0xf8) | (color.green >> 5);
1007338b8dc3SIngo Weinhold pixel.gb = ((color.green & 0x1c) << 3) | (color.blue >> 3);
1008338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++;
1009338b8dc3SIngo Weinhold }
1010338b8dc3SIngo Weinhold
WriteRGB16Writer1011338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray)
1012338b8dc3SIngo Weinhold {
1013338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1014338b8dc3SIngo Weinhold pixel.rg = (gray & 0xf8) | (gray >> 5);
1015338b8dc3SIngo Weinhold pixel.gb = ((gray & 0x1c) << 3) | (gray >> 3);
1016338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++;
1017338b8dc3SIngo Weinhold }
1018338b8dc3SIngo Weinhold };
1019338b8dc3SIngo Weinhold
1020338b8dc3SIngo Weinhold // RGB15Writer
1021338b8dc3SIngo Weinhold template<typename _PixelType>
1022338b8dc3SIngo Weinhold struct RGB15Writer : public BaseWriter<_PixelType> {
1023338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
1024338b8dc3SIngo Weinhold typedef _PixelType pixel_t;
1025338b8dc3SIngo Weinhold
RGB15WriterRGB15Writer1026338b8dc3SIngo Weinhold RGB15Writer(void *data) : BaseWriter<_PixelType>(data) {}
1027338b8dc3SIngo Weinhold
WriteRGB15Writer1028338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color)
1029338b8dc3SIngo Weinhold {
1030338b8dc3SIngo Weinhold // rg: -[0],R[4:0],G[4:3]
1031338b8dc3SIngo Weinhold // gb: G[2:0],B[4:0]
1032338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1033338b8dc3SIngo Weinhold pixel.rg = ((color.red & 0xf8) >> 1) | (color.green >> 6);
1034338b8dc3SIngo Weinhold pixel.gb = ((color.green & 0x38) << 2) | (color.blue >> 3);
1035338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++;
1036338b8dc3SIngo Weinhold }
1037338b8dc3SIngo Weinhold
WriteRGB15Writer1038338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray)
1039338b8dc3SIngo Weinhold {
1040338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1041338b8dc3SIngo Weinhold pixel.rg = ((gray & 0xf8) >> 1) | (gray >> 6);
1042338b8dc3SIngo Weinhold pixel.gb = ((gray & 0x38) << 2) | (gray >> 3);
1043338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++;
1044338b8dc3SIngo Weinhold }
1045338b8dc3SIngo Weinhold };
1046338b8dc3SIngo Weinhold
1047338b8dc3SIngo Weinhold // CMAP8Writer
1048338b8dc3SIngo Weinhold struct CMAP8Writer : public BaseWriter<uint8> {
1049338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t;
1050338b8dc3SIngo Weinhold
CMAP8WriterCMAP8Writer1051338b8dc3SIngo Weinhold CMAP8Writer(void *data, const PaletteConverter &converter)
1052338b8dc3SIngo Weinhold : BaseWriter<uint8>(data), converter(converter) {}
1053338b8dc3SIngo Weinhold
WriteCMAP8Writer1054338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color)
1055338b8dc3SIngo Weinhold {
1056338b8dc3SIngo Weinhold *pixels = converter.IndexForRGB24(color.red, color.green, color.blue);
1057338b8dc3SIngo Weinhold pixels++;
1058338b8dc3SIngo Weinhold }
1059338b8dc3SIngo Weinhold
WriteCMAP8Writer1060338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray)
1061338b8dc3SIngo Weinhold {
1062338b8dc3SIngo Weinhold *pixels = converter.IndexForGray(gray);
1063338b8dc3SIngo Weinhold pixels++;
1064338b8dc3SIngo Weinhold }
1065338b8dc3SIngo Weinhold
1066338b8dc3SIngo Weinhold const PaletteConverter &converter;
1067338b8dc3SIngo Weinhold };
1068338b8dc3SIngo Weinhold
1069338b8dc3SIngo Weinhold // Gray8Writer
1070338b8dc3SIngo Weinhold struct Gray8Writer : public BaseWriter<uint8> {
1071338b8dc3SIngo Weinhold typedef gray_color_value preferred_color_value_t;
1072338b8dc3SIngo Weinhold
Gray8WriterGray8Writer1073338b8dc3SIngo Weinhold Gray8Writer(void *data) : BaseWriter<uint8>(data) {}
1074338b8dc3SIngo Weinhold
WriteGray8Writer1075338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color)
1076338b8dc3SIngo Weinhold {
1077338b8dc3SIngo Weinhold *pixels = brightness_for(color.red, color.green, color.blue);
1078338b8dc3SIngo Weinhold pixels++;
1079338b8dc3SIngo Weinhold }
1080338b8dc3SIngo Weinhold
WriteGray8Writer1081338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray)
1082338b8dc3SIngo Weinhold {
1083338b8dc3SIngo Weinhold *pixels = gray;
1084338b8dc3SIngo Weinhold pixels++;
1085338b8dc3SIngo Weinhold }
1086338b8dc3SIngo Weinhold };
1087338b8dc3SIngo Weinhold
1088338b8dc3SIngo Weinhold // Gray1Writer
1089338b8dc3SIngo Weinhold struct Gray1Writer : public BaseWriter<uint8> {
1090338b8dc3SIngo Weinhold typedef gray_color_value preferred_color_value_t;
1091338b8dc3SIngo Weinhold
Gray1WriterGray1Writer1092338b8dc3SIngo Weinhold Gray1Writer(void *data) : BaseWriter<uint8>(data), bit(7) {}
1093338b8dc3SIngo Weinhold
SetToGray1Writer1094338b8dc3SIngo Weinhold inline void SetTo(void *data) { pixels = (pixel_t*)data; bit = 7; }
1095338b8dc3SIngo Weinhold
WriteGray1Writer1096338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray)
1097338b8dc3SIngo Weinhold {
1098338b8dc3SIngo Weinhold *pixels = (*pixels & inverse_bit_mask(bit))
1099338b8dc3SIngo Weinhold | (gray & 0x80) >> (7 - bit);
1100338b8dc3SIngo Weinhold bit--;
1101338b8dc3SIngo Weinhold if (bit == -1) {
1102338b8dc3SIngo Weinhold pixels++;
1103338b8dc3SIngo Weinhold bit = 7;
1104338b8dc3SIngo Weinhold }
1105338b8dc3SIngo Weinhold }
1106338b8dc3SIngo Weinhold
WriteGray1Writer1107338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color)
1108338b8dc3SIngo Weinhold {
1109338b8dc3SIngo Weinhold Write(brightness_for(color.red, color.green, color.blue));
1110338b8dc3SIngo Weinhold }
1111338b8dc3SIngo Weinhold
1112338b8dc3SIngo Weinhold int32 bit;
1113338b8dc3SIngo Weinhold };
1114338b8dc3SIngo Weinhold
1115338b8dc3SIngo Weinhold
1116338b8dc3SIngo Weinhold // set_bits_worker
1117338b8dc3SIngo Weinhold /*! \brief Worker function that reads bitmap data from one buffer and writes
1118338b8dc3SIngo Weinhold it (converted) to another one.
1119338b8dc3SIngo Weinhold \param Reader The pixel reader class.
1120338b8dc3SIngo Weinhold \param Writer The pixel writer class.
1121338b8dc3SIngo Weinhold \param color_value_t The color value type used to transport a pixel from
1122338b8dc3SIngo Weinhold the reader to the writer.
1123338b8dc3SIngo Weinhold \param inData A pointer to the buffer to be read.
1124338b8dc3SIngo Weinhold \param inLength The length (in bytes) of the "in" buffer.
1125338b8dc3SIngo Weinhold \param inBPR The number of bytes per row in the "in" buffer.
1126338b8dc3SIngo Weinhold \param inRowSkip The number of bytes per row in the "in" buffer serving as
1127338b8dc3SIngo Weinhold padding.
1128338b8dc3SIngo Weinhold \param outData A pointer to the buffer to be written to.
1129338b8dc3SIngo Weinhold \param outLength The length (in bytes) of the "out" buffer.
1130338b8dc3SIngo Weinhold \param outOffset The offset (in bytes) relative to \a outData from which
1131338b8dc3SIngo Weinhold the function shall start writing.
1132338b8dc3SIngo Weinhold \param outBPR The number of bytes per row in the "out" buffer.
1133338b8dc3SIngo Weinhold \param rawOutBPR The number of bytes per row in the "out" buffer actually
1134338b8dc3SIngo Weinhold containing bitmap data (i.e. not including the padding).
1135338b8dc3SIngo Weinhold \param _reader A reader object. The pointer to the data doesn't need to
1136338b8dc3SIngo Weinhold be initialized.
1137338b8dc3SIngo Weinhold \param _writer A writer object. The pointer to the data doesn't need to
1138338b8dc3SIngo Weinhold be initialized.
1139338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise.
1140338b8dc3SIngo Weinhold */
1141338b8dc3SIngo Weinhold template<typename Reader, typename Writer, typename color_value_t>
1142338b8dc3SIngo Weinhold static
1143338b8dc3SIngo Weinhold status_t
set_bits_worker(const void * inData,int32 inLength,int32 inBPR,int32 inRowSkip,void * outData,int32 outLength,int32 outOffset,int32 outBPR,int32 rawOutBPR,Reader _reader,Writer _writer)1144338b8dc3SIngo Weinhold set_bits_worker(const void *inData, int32 inLength, int32 inBPR,
1145338b8dc3SIngo Weinhold int32 inRowSkip, void *outData, int32 outLength,
1146338b8dc3SIngo Weinhold int32 outOffset, int32 outBPR, int32 rawOutBPR,
1147338b8dc3SIngo Weinhold Reader _reader, Writer _writer)
1148338b8dc3SIngo Weinhold {
1149338b8dc3SIngo Weinhold status_t error = B_OK;
1150338b8dc3SIngo Weinhold Reader reader(_reader);
1151338b8dc3SIngo Weinhold Writer writer(_writer);
1152338b8dc3SIngo Weinhold reader.SetTo(inData);
1153338b8dc3SIngo Weinhold writer.SetTo((char*)outData + outOffset);
1154338b8dc3SIngo Weinhold const char *inEnd = (const char*)inData + inLength
1155338b8dc3SIngo Weinhold - sizeof(typename Reader::pixel_t);
1156338b8dc3SIngo Weinhold const char *inLastRow = (const char*)inData + inLength
1157338b8dc3SIngo Weinhold - (inBPR - inRowSkip);
1158338b8dc3SIngo Weinhold const char *outEnd = (const char*)outData + outLength
1159338b8dc3SIngo Weinhold - sizeof(typename Writer::pixel_t);
1160338b8dc3SIngo Weinhold char *outRow = (char*)outData + outOffset - outOffset % outBPR;
1161338b8dc3SIngo Weinhold const char *outRowEnd = outRow + rawOutBPR - sizeof(typename Writer::pixel_t);
1162338b8dc3SIngo Weinhold while ((const char*)reader.pixels <= inEnd
1163338b8dc3SIngo Weinhold && (const char*)writer.pixels <= outEnd) {
1164338b8dc3SIngo Weinhold // process one row
1165338b8dc3SIngo Weinhold if ((const char*)reader.pixels <= inLastRow) {
1166338b8dc3SIngo Weinhold // at least a complete row left
1167338b8dc3SIngo Weinhold while ((const char*)writer.pixels <= outRowEnd) {
1168338b8dc3SIngo Weinhold color_value_t color;
1169338b8dc3SIngo Weinhold reader.Read(color);
1170338b8dc3SIngo Weinhold writer.Write(color);
1171338b8dc3SIngo Weinhold }
1172338b8dc3SIngo Weinhold } else {
1173338b8dc3SIngo Weinhold // no complete row left
1174338b8dc3SIngo Weinhold // but maybe the complete end of the first row
1175338b8dc3SIngo Weinhold while ((const char*)reader.pixels <= inEnd
1176338b8dc3SIngo Weinhold && (const char*)writer.pixels <= outRowEnd) {
1177338b8dc3SIngo Weinhold color_value_t color;
1178338b8dc3SIngo Weinhold reader.Read(color);
1179338b8dc3SIngo Weinhold writer.Write(color);
1180338b8dc3SIngo Weinhold }
1181338b8dc3SIngo Weinhold }
1182338b8dc3SIngo Weinhold // must be here, not in the if-branch (end of first row)
1183338b8dc3SIngo Weinhold outRow += outBPR;
1184338b8dc3SIngo Weinhold outRowEnd += outBPR;
1185338b8dc3SIngo Weinhold reader.NextRow(inRowSkip);
1186338b8dc3SIngo Weinhold writer.SetTo(outRow);
1187338b8dc3SIngo Weinhold }
1188338b8dc3SIngo Weinhold return error;
1189338b8dc3SIngo Weinhold }
1190338b8dc3SIngo Weinhold
1191338b8dc3SIngo Weinhold // set_bits_worker_gray1
1192338b8dc3SIngo Weinhold /*! \brief Worker function that reads bitmap data from one buffer and writes
1193338b8dc3SIngo Weinhold it (converted) to another one, which uses color space \c B_GRAY1.
1194338b8dc3SIngo Weinhold \param Reader The pixel reader class.
1195338b8dc3SIngo Weinhold \param Writer The pixel writer class.
1196338b8dc3SIngo Weinhold \param color_value_t The color value type used to transport a pixel from
1197338b8dc3SIngo Weinhold the reader to the writer.
1198338b8dc3SIngo Weinhold \param inData A pointer to the buffer to be read.
1199338b8dc3SIngo Weinhold \param inLength The length (in bytes) of the "in" buffer.
1200338b8dc3SIngo Weinhold \param inBPR The number of bytes per row in the "in" buffer.
1201338b8dc3SIngo Weinhold \param inRowSkip The number of bytes per row in the "in" buffer serving as
1202338b8dc3SIngo Weinhold padding.
1203338b8dc3SIngo Weinhold \param outData A pointer to the buffer to be written to.
1204338b8dc3SIngo Weinhold \param outLength The length (in bytes) of the "out" buffer.
1205338b8dc3SIngo Weinhold \param outOffset The offset (in bytes) relative to \a outData from which
1206338b8dc3SIngo Weinhold the function shall start writing.
1207338b8dc3SIngo Weinhold \param outBPR The number of bytes per row in the "out" buffer.
1208338b8dc3SIngo Weinhold \param width The number of pixels per row in "in" and "out" data.
1209338b8dc3SIngo Weinhold \param _reader A reader object. The pointer to the data doesn't need to
1210338b8dc3SIngo Weinhold be initialized.
1211338b8dc3SIngo Weinhold \param _writer A writer object. The pointer to the data doesn't need to
1212338b8dc3SIngo Weinhold be initialized.
1213338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise.
1214338b8dc3SIngo Weinhold */
1215338b8dc3SIngo Weinhold template<typename Reader, typename Writer, typename color_value_t>
1216338b8dc3SIngo Weinhold static
1217338b8dc3SIngo Weinhold status_t
set_bits_worker_gray1(const void * inData,int32 inLength,int32 inBPR,int32 inRowSkip,void * outData,int32 outLength,int32 outOffset,int32 outBPR,int32 width,Reader _reader,Writer _writer)1218338b8dc3SIngo Weinhold set_bits_worker_gray1(const void *inData, int32 inLength, int32 inBPR,
1219338b8dc3SIngo Weinhold int32 inRowSkip, void *outData, int32 outLength,
1220338b8dc3SIngo Weinhold int32 outOffset, int32 outBPR, int32 width,
1221338b8dc3SIngo Weinhold Reader _reader, Writer _writer)
1222338b8dc3SIngo Weinhold {
1223338b8dc3SIngo Weinhold status_t error = B_OK;
1224338b8dc3SIngo Weinhold Reader reader(_reader);
1225338b8dc3SIngo Weinhold Writer writer(_writer);
1226338b8dc3SIngo Weinhold reader.SetTo(inData);
1227338b8dc3SIngo Weinhold writer.SetTo((char*)outData + outOffset);
1228338b8dc3SIngo Weinhold const char *inEnd = (const char*)inData + inLength
1229338b8dc3SIngo Weinhold - sizeof(typename Reader::pixel_t);
1230338b8dc3SIngo Weinhold const char *inLastRow = (const char*)inData + inLength
1231338b8dc3SIngo Weinhold - (inBPR - inRowSkip);
1232338b8dc3SIngo Weinhold const char *outEnd = (const char*)outData + outLength - outBPR;
1233338b8dc3SIngo Weinhold char *outRow = (char*)outData + outOffset - outOffset % outBPR;
1234a8a03488SIngo Weinhold int32 x = max((int32)0,
1235a8a03488SIngo Weinhold width - (int32)((char*)outData + outOffset - outRow) * 8) - 1;
1236338b8dc3SIngo Weinhold while ((const char*)reader.pixels <= inEnd
1237338b8dc3SIngo Weinhold && (const char*)writer.pixels <= outEnd) {
1238338b8dc3SIngo Weinhold // process one row
1239338b8dc3SIngo Weinhold if ((const char*)reader.pixels <= inLastRow) {
1240338b8dc3SIngo Weinhold // at least a complete row left
1241338b8dc3SIngo Weinhold while (x >= 0) {
1242338b8dc3SIngo Weinhold color_value_t color;
1243338b8dc3SIngo Weinhold reader.Read(color);
1244338b8dc3SIngo Weinhold writer.Write(color);
1245338b8dc3SIngo Weinhold x--;
1246338b8dc3SIngo Weinhold }
1247338b8dc3SIngo Weinhold } else {
1248338b8dc3SIngo Weinhold // no complete row left
1249338b8dc3SIngo Weinhold // but maybe the complete end of the first row
1250338b8dc3SIngo Weinhold while ((const char*)reader.pixels <= inEnd && x >= 0) {
1251338b8dc3SIngo Weinhold color_value_t color;
1252338b8dc3SIngo Weinhold reader.Read(color);
1253338b8dc3SIngo Weinhold writer.Write(color);
1254338b8dc3SIngo Weinhold x--;
1255338b8dc3SIngo Weinhold }
1256338b8dc3SIngo Weinhold }
1257338b8dc3SIngo Weinhold // must be here, not in the if-branch (end of first row)
1258338b8dc3SIngo Weinhold x = width - 1;
1259338b8dc3SIngo Weinhold outRow += outBPR;
1260338b8dc3SIngo Weinhold reader.NextRow(inRowSkip);
1261338b8dc3SIngo Weinhold writer.SetTo(outRow);
1262338b8dc3SIngo Weinhold }
1263338b8dc3SIngo Weinhold return error;
1264338b8dc3SIngo Weinhold }
1265338b8dc3SIngo Weinhold
1266338b8dc3SIngo Weinhold // set_bits
1267338b8dc3SIngo Weinhold /*! \brief Helper function that reads bitmap data from one buffer and writes
1268338b8dc3SIngo Weinhold it (converted) to another one.
1269338b8dc3SIngo Weinhold \param Reader The pixel reader class.
1270338b8dc3SIngo Weinhold \param inData A pointer to the buffer to be read.
1271338b8dc3SIngo Weinhold \param inLength The length (in bytes) of the "in" buffer.
1272338b8dc3SIngo Weinhold \param inBPR The number of bytes per row in the "in" buffer.
1273338b8dc3SIngo Weinhold \param inRowSkip The number of bytes per row in the "in" buffer serving as
1274338b8dc3SIngo Weinhold padding.
1275338b8dc3SIngo Weinhold \param outData A pointer to the buffer to be written to.
1276338b8dc3SIngo Weinhold \param outLength The length (in bytes) of the "out" buffer.
1277338b8dc3SIngo Weinhold \param outOffset The offset (in bytes) relative to \a outData from which
1278338b8dc3SIngo Weinhold the function shall start writing.
1279338b8dc3SIngo Weinhold \param outBPR The number of bytes per row in the "out" buffer.
1280338b8dc3SIngo Weinhold \param rawOutBPR The number of bytes per row in the "out" buffer actually
1281338b8dc3SIngo Weinhold containing bitmap data (i.e. not including the padding).
1282338b8dc3SIngo Weinhold \param outColorSpace Color space of the target buffer.
1283338b8dc3SIngo Weinhold \param width The number of pixels per row in "in" and "out" data.
1284338b8dc3SIngo Weinhold \param reader A reader object. The pointer to the data doesn't need to
1285338b8dc3SIngo Weinhold be initialized.
1286338b8dc3SIngo Weinhold \param paletteConverter Reference to a PaletteConverter to be used, if
1287338b8dc3SIngo Weinhold a conversion from or to \c B_CMAP8 has to be done.
1288338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise.
1289338b8dc3SIngo Weinhold */
1290338b8dc3SIngo Weinhold template<typename Reader>
1291338b8dc3SIngo Weinhold static
1292338b8dc3SIngo Weinhold status_t
set_bits(const void * inData,int32 inLength,int32 inBPR,int32 inRowSkip,void * outData,int32 outLength,int32 outOffset,int32 outBPR,int32 rawOutBPR,color_space outColorSpace,int32 width,Reader reader,const PaletteConverter & paletteConverter)1293338b8dc3SIngo Weinhold set_bits(const void *inData, int32 inLength, int32 inBPR, int32 inRowSkip,
1294338b8dc3SIngo Weinhold void *outData, int32 outLength, int32 outOffset, int32 outBPR,
1295338b8dc3SIngo Weinhold int32 rawOutBPR, color_space outColorSpace, int32 width,
1296338b8dc3SIngo Weinhold Reader reader, const PaletteConverter &paletteConverter)
1297338b8dc3SIngo Weinhold {
1298338b8dc3SIngo Weinhold status_t error = B_OK;
1299338b8dc3SIngo Weinhold switch (outColorSpace) {
1300338b8dc3SIngo Weinhold // supported
1301338b8dc3SIngo Weinhold case B_RGB32: case B_RGBA32:
1302338b8dc3SIngo Weinhold {
1303338b8dc3SIngo Weinhold typedef RGB32Writer<rgb32_pixel> Writer;
1304338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1305338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1306338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1307338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1308338b8dc3SIngo Weinhold break;
1309338b8dc3SIngo Weinhold }
1310338b8dc3SIngo Weinhold case B_RGB32_BIG: case B_RGBA32_BIG:
1311338b8dc3SIngo Weinhold {
1312338b8dc3SIngo Weinhold typedef RGB32Writer<rgb32_big_pixel> Writer;
1313338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1314338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1315338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1316338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1317338b8dc3SIngo Weinhold break;
1318338b8dc3SIngo Weinhold }
1319338b8dc3SIngo Weinhold case B_RGB24:
1320338b8dc3SIngo Weinhold {
1321338b8dc3SIngo Weinhold typedef RGB24Writer<rgb24_pixel> Writer;
1322338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1323338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1324338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1325338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1326338b8dc3SIngo Weinhold break;
1327338b8dc3SIngo Weinhold }
1328338b8dc3SIngo Weinhold case B_RGB24_BIG:
1329338b8dc3SIngo Weinhold {
1330338b8dc3SIngo Weinhold typedef RGB24Writer<rgb24_big_pixel> Writer;
1331338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1332338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1333338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1334338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1335338b8dc3SIngo Weinhold break;
1336338b8dc3SIngo Weinhold }
1337338b8dc3SIngo Weinhold case B_RGB16:
1338338b8dc3SIngo Weinhold {
1339338b8dc3SIngo Weinhold typedef RGB16Writer<rgb16_pixel> Writer;
1340338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1341338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1342338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1343338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1344338b8dc3SIngo Weinhold break;
1345338b8dc3SIngo Weinhold }
1346338b8dc3SIngo Weinhold case B_RGB16_BIG:
1347338b8dc3SIngo Weinhold {
1348338b8dc3SIngo Weinhold typedef RGB16Writer<rgb16_big_pixel> Writer;
1349338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1350338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1351338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1352338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1353338b8dc3SIngo Weinhold break;
1354338b8dc3SIngo Weinhold }
1355338b8dc3SIngo Weinhold case B_RGB15: case B_RGBA15:
1356338b8dc3SIngo Weinhold {
1357338b8dc3SIngo Weinhold typedef RGB15Writer<rgb16_pixel> Writer;
1358338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1359338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1360338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1361338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1362338b8dc3SIngo Weinhold break;
1363338b8dc3SIngo Weinhold }
1364338b8dc3SIngo Weinhold case B_RGB15_BIG: case B_RGBA15_BIG:
1365338b8dc3SIngo Weinhold {
1366338b8dc3SIngo Weinhold typedef RGB15Writer<rgb16_big_pixel> Writer;
1367338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1368338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1369338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1370338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1371338b8dc3SIngo Weinhold break;
1372338b8dc3SIngo Weinhold }
1373338b8dc3SIngo Weinhold case B_CMAP8:
1374338b8dc3SIngo Weinhold {
1375338b8dc3SIngo Weinhold typedef CMAP8Writer Writer;
1376338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t;
1377338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1378338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1379338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader,
1380338b8dc3SIngo Weinhold Writer(outData, paletteConverter));
1381338b8dc3SIngo Weinhold break;
1382338b8dc3SIngo Weinhold }
1383338b8dc3SIngo Weinhold case B_GRAY8:
1384338b8dc3SIngo Weinhold {
1385338b8dc3SIngo Weinhold typedef Gray8Writer Writer;
1386338b8dc3SIngo Weinhold typedef gray_color_value color_value_t;
1387338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>(
1388338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1389338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1390338b8dc3SIngo Weinhold break;
1391338b8dc3SIngo Weinhold }
1392338b8dc3SIngo Weinhold case B_GRAY1:
1393338b8dc3SIngo Weinhold {
1394338b8dc3SIngo Weinhold typedef Gray1Writer Writer;
1395338b8dc3SIngo Weinhold typedef gray_color_value color_value_t;
1396338b8dc3SIngo Weinhold error = set_bits_worker_gray1<Reader, Writer, color_value_t>(
1397338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength,
1398338b8dc3SIngo Weinhold outOffset, outBPR, width, reader, Writer(outData));
1399338b8dc3SIngo Weinhold break;
1400338b8dc3SIngo Weinhold }
1401338b8dc3SIngo Weinhold // unsupported
1402338b8dc3SIngo Weinhold case B_NO_COLOR_SPACE:
1403338b8dc3SIngo Weinhold case B_YUV9: case B_YUV12:
1404338b8dc3SIngo Weinhold case B_UVL32: case B_UVLA32:
1405338b8dc3SIngo Weinhold case B_LAB32: case B_LABA32:
1406338b8dc3SIngo Weinhold case B_HSI32: case B_HSIA32:
1407338b8dc3SIngo Weinhold case B_HSV32: case B_HSVA32:
1408338b8dc3SIngo Weinhold case B_HLS32: case B_HLSA32:
1409338b8dc3SIngo Weinhold case B_CMY32: case B_CMYA32: case B_CMYK32:
1410338b8dc3SIngo Weinhold case B_UVL24: case B_LAB24: case B_HSI24:
1411338b8dc3SIngo Weinhold case B_HSV24: case B_HLS24: case B_CMY24:
1412338b8dc3SIngo Weinhold case B_YCbCr422: case B_YUV422:
1413338b8dc3SIngo Weinhold case B_YCbCr411: case B_YUV411:
1414338b8dc3SIngo Weinhold case B_YCbCr444: case B_YUV444:
1415338b8dc3SIngo Weinhold case B_YCbCr420: case B_YUV420:
1416338b8dc3SIngo Weinhold default:
1417338b8dc3SIngo Weinhold error = B_BAD_VALUE;
1418338b8dc3SIngo Weinhold break;
1419338b8dc3SIngo Weinhold }
1420338b8dc3SIngo Weinhold return error;
1421338b8dc3SIngo Weinhold }
1422338b8dc3SIngo Weinhold
142364b2d169SAxel Dörfler
142464b2d169SAxel Dörfler // #pragma mark - Bitmap
142564b2d169SAxel Dörfler
142664b2d169SAxel Dörfler
142764b2d169SAxel Dörfler /*! \brief Creates and initializes a BBitmap.
142864b2d169SAxel Dörfler \param bounds The bitmap dimensions.
142964b2d169SAxel Dörfler \param flags Creation flags.
143064b2d169SAxel Dörfler \param colorSpace The bitmap's color space.
143164b2d169SAxel Dörfler \param bytesPerRow The number of bytes per row the bitmap should use.
143264b2d169SAxel Dörfler \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate
143364b2d169SAxel Dörfler value.
143464b2d169SAxel Dörfler \param screenID ???
143564b2d169SAxel Dörfler */
BBitmap(BRect bounds,uint32 flags,color_space colorSpace,int32 bytesPerRow,screen_id screenID)143664b2d169SAxel Dörfler BBitmap::BBitmap(BRect bounds, uint32 flags, color_space colorSpace,
143764b2d169SAxel Dörfler int32 bytesPerRow, screen_id screenID)
143864b2d169SAxel Dörfler : fBasePtr(NULL),
143964b2d169SAxel Dörfler fSize(0),
144064b2d169SAxel Dörfler fColorSpace(B_NO_COLOR_SPACE),
144164b2d169SAxel Dörfler fBounds(0, 0, -1, -1),
144264b2d169SAxel Dörfler fBytesPerRow(0),
144364b2d169SAxel Dörfler fServerToken(-1),
144464b2d169SAxel Dörfler fToken(-1),
144564b2d169SAxel Dörfler fArea(-1),
144664b2d169SAxel Dörfler fOrigArea(-1),
144764b2d169SAxel Dörfler fFlags(0),
144864b2d169SAxel Dörfler fInitError(B_NO_INIT)
144964b2d169SAxel Dörfler {
145064b2d169SAxel Dörfler InitObject(bounds, colorSpace, flags, bytesPerRow, screenID);
145164b2d169SAxel Dörfler }
145264b2d169SAxel Dörfler
145364b2d169SAxel Dörfler
145464b2d169SAxel Dörfler /*! \brief Creates and initializes a BBitmap.
145564b2d169SAxel Dörfler \param bounds The bitmap dimensions.
145664b2d169SAxel Dörfler \param colorSpace The bitmap's color space.
145764b2d169SAxel Dörfler \param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if
145864b2d169SAxel Dörfler it shall be possible to attach BView to the bitmap and draw into
145964b2d169SAxel Dörfler it.
146064b2d169SAxel Dörfler \param needsContiguous If \c true a physically contiguous chunk of memory
146164b2d169SAxel Dörfler will be allocated.
146264b2d169SAxel Dörfler */
BBitmap(BRect bounds,color_space colorSpace,bool acceptsViews,bool needsContiguous)146364b2d169SAxel Dörfler BBitmap::BBitmap(BRect bounds, color_space colorSpace, bool acceptsViews,
146464b2d169SAxel Dörfler bool needsContiguous)
146564b2d169SAxel Dörfler : fBasePtr(NULL),
146664b2d169SAxel Dörfler fSize(0),
146764b2d169SAxel Dörfler fColorSpace(B_NO_COLOR_SPACE),
146864b2d169SAxel Dörfler fBounds(0, 0, -1, -1),
146964b2d169SAxel Dörfler fBytesPerRow(0),
147064b2d169SAxel Dörfler fServerToken(-1),
147164b2d169SAxel Dörfler fToken(-1),
147264b2d169SAxel Dörfler fArea(-1),
147364b2d169SAxel Dörfler fOrigArea(-1),
147464b2d169SAxel Dörfler fFlags(0),
147564b2d169SAxel Dörfler fInitError(B_NO_INIT)
147664b2d169SAxel Dörfler {
147764b2d169SAxel Dörfler int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0)
147864b2d169SAxel Dörfler | (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0);
147964b2d169SAxel Dörfler InitObject(bounds, colorSpace, flags, B_ANY_BYTES_PER_ROW,
148064b2d169SAxel Dörfler B_MAIN_SCREEN_ID);
148164b2d169SAxel Dörfler
148264b2d169SAxel Dörfler }
148364b2d169SAxel Dörfler
148464b2d169SAxel Dörfler
148564b2d169SAxel Dörfler /*! \brief Creates a BBitmap as a clone of another bitmap.
148664b2d169SAxel Dörfler \param source The source bitmap.
148764b2d169SAxel Dörfler \param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if
148864b2d169SAxel Dörfler it shall be possible to attach BView to the bitmap and draw into
148964b2d169SAxel Dörfler it.
149064b2d169SAxel Dörfler \param needsContiguous If \c true a physically contiguous chunk of memory
149164b2d169SAxel Dörfler will be allocated.
149264b2d169SAxel Dörfler */
BBitmap(const BBitmap * source,bool acceptsViews,bool needsContiguous)149364b2d169SAxel Dörfler BBitmap::BBitmap(const BBitmap *source, bool acceptsViews,
149464b2d169SAxel Dörfler bool needsContiguous)
149564b2d169SAxel Dörfler : fBasePtr(NULL),
149664b2d169SAxel Dörfler fSize(0),
149764b2d169SAxel Dörfler fColorSpace(B_NO_COLOR_SPACE),
149864b2d169SAxel Dörfler fBounds(0, 0, -1, -1),
149964b2d169SAxel Dörfler fBytesPerRow(0),
150064b2d169SAxel Dörfler fServerToken(-1),
150164b2d169SAxel Dörfler fToken(-1),
150264b2d169SAxel Dörfler fArea(-1),
150364b2d169SAxel Dörfler fOrigArea(-1),
150464b2d169SAxel Dörfler fFlags(0),
150564b2d169SAxel Dörfler fInitError(B_NO_INIT)
150664b2d169SAxel Dörfler {
150764b2d169SAxel Dörfler if (source && source->IsValid()) {
150864b2d169SAxel Dörfler int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0)
150964b2d169SAxel Dörfler | (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0);
151064b2d169SAxel Dörfler InitObject(source->Bounds(), source->ColorSpace(), flags,
151164b2d169SAxel Dörfler source->BytesPerRow(), B_MAIN_SCREEN_ID);
151264b2d169SAxel Dörfler if (InitCheck() == B_OK)
151364b2d169SAxel Dörfler memcpy(Bits(), source->Bits(), BytesPerRow());
151464b2d169SAxel Dörfler }
151564b2d169SAxel Dörfler }
151664b2d169SAxel Dörfler
151764b2d169SAxel Dörfler
151864b2d169SAxel Dörfler /*! \brief Frees all resources associated with this object. */
~BBitmap()151964b2d169SAxel Dörfler BBitmap::~BBitmap()
152064b2d169SAxel Dörfler {
152164b2d169SAxel Dörfler CleanUp();
152264b2d169SAxel Dörfler }
152364b2d169SAxel Dörfler
152464b2d169SAxel Dörfler
152564b2d169SAxel Dörfler /*! \brief Unarchives a bitmap from a BMessage.
152664b2d169SAxel Dörfler \param data The archive.
152764b2d169SAxel Dörfler */
BBitmap(BMessage * data)152864b2d169SAxel Dörfler BBitmap::BBitmap(BMessage *data)
152964b2d169SAxel Dörfler : BArchivable(data),
153064b2d169SAxel Dörfler fBasePtr(NULL),
153164b2d169SAxel Dörfler fSize(0),
153264b2d169SAxel Dörfler fColorSpace(B_NO_COLOR_SPACE),
153364b2d169SAxel Dörfler fBounds(0, 0, -1, -1),
153464b2d169SAxel Dörfler fBytesPerRow(0),
153564b2d169SAxel Dörfler fServerToken(-1),
153664b2d169SAxel Dörfler fToken(-1),
153764b2d169SAxel Dörfler fArea(-1),
153864b2d169SAxel Dörfler fOrigArea(-1),
153964b2d169SAxel Dörfler fFlags(0),
154064b2d169SAxel Dörfler fInitError(B_NO_INIT)
154164b2d169SAxel Dörfler {
154264b2d169SAxel Dörfler BRect bounds;
154364b2d169SAxel Dörfler data->FindRect("_frame", &bounds);
154464b2d169SAxel Dörfler
154564b2d169SAxel Dörfler color_space cspace;
154664b2d169SAxel Dörfler data->FindInt32("_cspace", (int32 *)&cspace);
154764b2d169SAxel Dörfler
154864b2d169SAxel Dörfler int32 flags = 0;
154964b2d169SAxel Dörfler data->FindInt32("_bmflags", &flags);
155064b2d169SAxel Dörfler
155164b2d169SAxel Dörfler int32 rowbytes = 0;
155264b2d169SAxel Dörfler data->FindInt32("_rowbytes", &rowbytes);
155364b2d169SAxel Dörfler
155464b2d169SAxel Dörfler flags |= B_BITMAP_NO_SERVER_LINK;
155564b2d169SAxel Dörfler flags &= ~B_BITMAP_ACCEPTS_VIEWS;
155664b2d169SAxel Dörfler InitObject(bounds, cspace, flags, rowbytes, B_MAIN_SCREEN_ID);
155764b2d169SAxel Dörfler
155864b2d169SAxel Dörfler if (data->HasData("_data", B_RAW_TYPE) && InitCheck() == B_OK) {
155964b2d169SAxel Dörfler ssize_t size = 0;
156064b2d169SAxel Dörfler const void *buffer;
156164b2d169SAxel Dörfler if (data->FindData("_data", B_RAW_TYPE, &buffer, &size) == B_OK)
156264b2d169SAxel Dörfler memcpy(fBasePtr, buffer, size);
156364b2d169SAxel Dörfler }
156464b2d169SAxel Dörfler
156564b2d169SAxel Dörfler if (fFlags & B_BITMAP_ACCEPTS_VIEWS) {
156664b2d169SAxel Dörfler // BArchivable *obj;
156764b2d169SAxel Dörfler // BMessage message;
156864b2d169SAxel Dörfler // int i = 0;
156964b2d169SAxel Dörfler //
157064b2d169SAxel Dörfler // while (data->FindMessage("_view", i++, &message) == B_OK) {
157164b2d169SAxel Dörfler // obj = instantiate_object(&message);
157264b2d169SAxel Dörfler // BView *view = dynamic_cast<BView *>(obj);
157364b2d169SAxel Dörfler //
157464b2d169SAxel Dörfler // if (view)
157564b2d169SAxel Dörfler // AddChild(view);
157664b2d169SAxel Dörfler // }
157764b2d169SAxel Dörfler }
157864b2d169SAxel Dörfler }
157964b2d169SAxel Dörfler
158064b2d169SAxel Dörfler
158164b2d169SAxel Dörfler /*! \brief Instantiates a BBitmap from an archive.
158264b2d169SAxel Dörfler \param data The archive.
158364b2d169SAxel Dörfler \return A bitmap reconstructed from the archive or \c NULL, if an error
158464b2d169SAxel Dörfler occured.
158564b2d169SAxel Dörfler */
158664b2d169SAxel Dörfler BArchivable *
Instantiate(BMessage * data)158764b2d169SAxel Dörfler BBitmap::Instantiate(BMessage *data)
158864b2d169SAxel Dörfler {
158964b2d169SAxel Dörfler if (validate_instantiation(data, "BBitmap"))
159064b2d169SAxel Dörfler return new BBitmap(data);
159164b2d169SAxel Dörfler
159264b2d169SAxel Dörfler return NULL;
159364b2d169SAxel Dörfler }
159464b2d169SAxel Dörfler
159564b2d169SAxel Dörfler
159664b2d169SAxel Dörfler /*! \brief Archives the BBitmap object.
159764b2d169SAxel Dörfler \param data The archive.
159864b2d169SAxel Dörfler \param deep \c true, if child object shall be archived as well, \c false
159964b2d169SAxel Dörfler otherwise.
160064b2d169SAxel Dörfler \return \c B_OK, if everything went fine, an error code otherwise.
160164b2d169SAxel Dörfler */
160264b2d169SAxel Dörfler status_t
Archive(BMessage * data,bool deep) const160364b2d169SAxel Dörfler BBitmap::Archive(BMessage *data, bool deep) const
160464b2d169SAxel Dörfler {
160564b2d169SAxel Dörfler BArchivable::Archive(data, deep);
160664b2d169SAxel Dörfler
160764b2d169SAxel Dörfler data->AddRect("_frame", fBounds);
160864b2d169SAxel Dörfler data->AddInt32("_cspace", (int32)fColorSpace);
160964b2d169SAxel Dörfler data->AddInt32("_bmflags", fFlags);
161064b2d169SAxel Dörfler data->AddInt32("_rowbytes", fBytesPerRow);
161164b2d169SAxel Dörfler
161264b2d169SAxel Dörfler if (deep) {
161364b2d169SAxel Dörfler if (fFlags & B_BITMAP_ACCEPTS_VIEWS) {
161464b2d169SAxel Dörfler // BMessage views;
161564b2d169SAxel Dörfler // for (int32 i = 0; i < CountChildren(); i++) {
161664b2d169SAxel Dörfler // if (ChildAt(i)->Archive(&views, deep))
161764b2d169SAxel Dörfler // data->AddMessage("_views", &views);
161864b2d169SAxel Dörfler // }
161964b2d169SAxel Dörfler }
162064b2d169SAxel Dörfler // Note: R5 does not archive the data if B_BITMAP_IS_CONTIGNUOUS is
162164b2d169SAxel Dörfler // true and it does save all formats as B_RAW_TYPE and it does save
162264b2d169SAxel Dörfler // the data even if B_BITMAP_ACCEPTS_VIEWS is set (as opposed to
162364b2d169SAxel Dörfler // the BeBook)
162464b2d169SAxel Dörfler
162564b2d169SAxel Dörfler data->AddData("_data", B_RAW_TYPE, fBasePtr, fSize);
162664b2d169SAxel Dörfler }
162764b2d169SAxel Dörfler
162864b2d169SAxel Dörfler return B_OK;
162964b2d169SAxel Dörfler }
163064b2d169SAxel Dörfler
163164b2d169SAxel Dörfler
163264b2d169SAxel Dörfler /*! \brief Returns the result from the construction.
163364b2d169SAxel Dörfler \return \c B_OK, if the object is properly initialized, an error code
163464b2d169SAxel Dörfler otherwise.
163564b2d169SAxel Dörfler */
163664b2d169SAxel Dörfler status_t
InitCheck() const163764b2d169SAxel Dörfler BBitmap::InitCheck() const
163864b2d169SAxel Dörfler {
163964b2d169SAxel Dörfler return fInitError;
164064b2d169SAxel Dörfler }
164164b2d169SAxel Dörfler
164264b2d169SAxel Dörfler
164364b2d169SAxel Dörfler /*! \brief Returns whether or not the BBitmap object is valid.
164464b2d169SAxel Dörfler \return \c true, if the object is properly initialized, \c false otherwise.
164564b2d169SAxel Dörfler */
164664b2d169SAxel Dörfler bool
IsValid() const164764b2d169SAxel Dörfler BBitmap::IsValid() const
164864b2d169SAxel Dörfler {
164964b2d169SAxel Dörfler return (InitCheck() == B_OK);
165064b2d169SAxel Dörfler }
165164b2d169SAxel Dörfler
165264b2d169SAxel Dörfler
165364b2d169SAxel Dörfler status_t
LockBits(uint32 * state)165464b2d169SAxel Dörfler BBitmap::LockBits(uint32 *state)
165564b2d169SAxel Dörfler {
165664b2d169SAxel Dörfler return B_ERROR;
165764b2d169SAxel Dörfler }
165864b2d169SAxel Dörfler
165964b2d169SAxel Dörfler
166064b2d169SAxel Dörfler void
UnlockBits()166164b2d169SAxel Dörfler BBitmap::UnlockBits()
166264b2d169SAxel Dörfler {
166364b2d169SAxel Dörfler }
166464b2d169SAxel Dörfler
166564b2d169SAxel Dörfler
166664b2d169SAxel Dörfler /*! \brief Returns the ID of the area the bitmap data reside in.
166764b2d169SAxel Dörfler \return The ID of the area the bitmap data reside in.
166864b2d169SAxel Dörfler */
166964b2d169SAxel Dörfler area_id
Area() const167064b2d169SAxel Dörfler BBitmap::Area() const
167164b2d169SAxel Dörfler {
167264b2d169SAxel Dörfler return fArea;
167364b2d169SAxel Dörfler }
167464b2d169SAxel Dörfler
167564b2d169SAxel Dörfler
167664b2d169SAxel Dörfler /*! \brief Returns the pointer to the bitmap data.
167764b2d169SAxel Dörfler \return The pointer to the bitmap data.
167864b2d169SAxel Dörfler */
167964b2d169SAxel Dörfler void *
Bits() const168064b2d169SAxel Dörfler BBitmap::Bits() const
168164b2d169SAxel Dörfler {
168264b2d169SAxel Dörfler return fBasePtr;
168364b2d169SAxel Dörfler }
168464b2d169SAxel Dörfler
168564b2d169SAxel Dörfler
168664b2d169SAxel Dörfler /*! \brief Returns the size of the bitmap data.
168764b2d169SAxel Dörfler \return The size of the bitmap data.
168864b2d169SAxel Dörfler */
168964b2d169SAxel Dörfler int32
BitsLength() const169064b2d169SAxel Dörfler BBitmap::BitsLength() const
169164b2d169SAxel Dörfler {
169264b2d169SAxel Dörfler return fSize;
169364b2d169SAxel Dörfler }
169464b2d169SAxel Dörfler
169564b2d169SAxel Dörfler
169664b2d169SAxel Dörfler /*! \brief Returns the number of bytes used to store a row of bitmap data.
169764b2d169SAxel Dörfler \return The number of bytes used to store a row of bitmap data.
169864b2d169SAxel Dörfler */
169964b2d169SAxel Dörfler int32
BytesPerRow() const170064b2d169SAxel Dörfler BBitmap::BytesPerRow() const
170164b2d169SAxel Dörfler {
170264b2d169SAxel Dörfler return fBytesPerRow;
170364b2d169SAxel Dörfler }
170464b2d169SAxel Dörfler
170564b2d169SAxel Dörfler
170664b2d169SAxel Dörfler /*! \brief Returns the bitmap's color space.
170764b2d169SAxel Dörfler \return The bitmap's color space.
170864b2d169SAxel Dörfler */
170964b2d169SAxel Dörfler color_space
ColorSpace() const171064b2d169SAxel Dörfler BBitmap::ColorSpace() const
171164b2d169SAxel Dörfler {
171264b2d169SAxel Dörfler return fColorSpace;
171364b2d169SAxel Dörfler }
171464b2d169SAxel Dörfler
171564b2d169SAxel Dörfler
171664b2d169SAxel Dörfler /*! \brief Returns the bitmap's dimensions.
171764b2d169SAxel Dörfler \return The bitmap's dimensions.
171864b2d169SAxel Dörfler */
171964b2d169SAxel Dörfler BRect
Bounds() const172064b2d169SAxel Dörfler BBitmap::Bounds() const
172164b2d169SAxel Dörfler {
172264b2d169SAxel Dörfler return fBounds;
172364b2d169SAxel Dörfler }
172464b2d169SAxel Dörfler
172564b2d169SAxel Dörfler
1726338b8dc3SIngo Weinhold /*! \brief Assigns data to the bitmap.
1727338b8dc3SIngo Weinhold
1728338b8dc3SIngo Weinhold Data are directly written into the bitmap's data buffer, being converted
1729338b8dc3SIngo Weinhold beforehand, if necessary. Some conversions work rather unintuitively:
1730338b8dc3SIngo Weinhold - \c B_RGB32: The source buffer is supposed to contain \c B_RGB24_BIG
1731338b8dc3SIngo Weinhold data without padding at the end of the rows.
1732338b8dc3SIngo Weinhold - \c B_RGB32: The source buffer is supposed to contain \c B_CMAP8
1733338b8dc3SIngo Weinhold data without padding at the end of the rows.
1734338b8dc3SIngo Weinhold - other color spaces: The source buffer is supposed to contain data
1735338b8dc3SIngo Weinhold according to the specified color space being rowwise padded to int32.
1736338b8dc3SIngo Weinhold
1737338b8dc3SIngo Weinhold The currently supported source/target color spaces are
1738338b8dc3SIngo Weinhold \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1739338b8dc3SIngo Weinhold
1740*2ca13760SColdfirex \note As this methods is apparently a bit strange to use, Haiku introduces
1741338b8dc3SIngo Weinhold ImportBits() methods, which are recommended to be used instead.
1742338b8dc3SIngo Weinhold
1743338b8dc3SIngo Weinhold \param data The data to be copied.
1744338b8dc3SIngo Weinhold \param length The length in bytes of the data to be copied.
1745338b8dc3SIngo Weinhold \param offset The offset (in bytes) relative to beginning of the bitmap
1746338b8dc3SIngo Weinhold data specifying the position at which the source data shall be
1747338b8dc3SIngo Weinhold written.
1748338b8dc3SIngo Weinhold \param colorSpace Color space of the source data.
1749338b8dc3SIngo Weinhold */
1750338b8dc3SIngo Weinhold void
SetBits(const void * data,int32 length,int32 offset,color_space colorSpace)1751338b8dc3SIngo Weinhold BBitmap::SetBits(const void *data, int32 length, int32 offset,
1752338b8dc3SIngo Weinhold color_space colorSpace)
1753338b8dc3SIngo Weinhold {
1754338b8dc3SIngo Weinhold status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1755338b8dc3SIngo Weinhold // check params
1756338b8dc3SIngo Weinhold if (error == B_OK && (data == NULL || offset > fSize || length < 0))
1757338b8dc3SIngo Weinhold error = B_BAD_VALUE;
1758338b8dc3SIngo Weinhold int32 width = 0;
1759338b8dc3SIngo Weinhold if (error == B_OK)
1760338b8dc3SIngo Weinhold width = fBounds.IntegerWidth() + 1;
1761338b8dc3SIngo Weinhold int32 inBPR = -1;
1762338b8dc3SIngo Weinhold // tweaks to mimic R5 behavior
1763338b8dc3SIngo Weinhold if (error == B_OK) {
1764338b8dc3SIngo Weinhold // B_RGB32 means actually unpadded B_RGB24_BIG
1765338b8dc3SIngo Weinhold if (colorSpace == B_RGB32) {
1766338b8dc3SIngo Weinhold colorSpace = B_RGB24_BIG;
1767338b8dc3SIngo Weinhold inBPR = width * 3;
1768338b8dc3SIngo Weinhold // If in color space is B_CMAP8, but the bitmap's is another one,
1769338b8dc3SIngo Weinhold // ignore source data row padding.
1770338b8dc3SIngo Weinhold } else if (colorSpace == B_CMAP8 && fColorSpace != B_CMAP8)
1771338b8dc3SIngo Weinhold inBPR = width;
1772487d015aSAdrien Destugues
1773338b8dc3SIngo Weinhold // call the sane method, which does the actual work
1774338b8dc3SIngo Weinhold error = ImportBits(data, length, inBPR, offset, colorSpace);
1775338b8dc3SIngo Weinhold }
1776487d015aSAdrien Destugues }
1777338b8dc3SIngo Weinhold
177864b2d169SAxel Dörfler
1779338b8dc3SIngo Weinhold /*! \brief Assigns data to the bitmap.
1780338b8dc3SIngo Weinhold
1781338b8dc3SIngo Weinhold Data are directly written into the bitmap's data buffer, being converted
1782338b8dc3SIngo Weinhold beforehand, if necessary. Unlike for SetBits(), the meaning of
1783338b8dc3SIngo Weinhold \a colorSpace is exactly the expected one here, i.e. the source buffer
1784338b8dc3SIngo Weinhold is supposed to contain data of that color space. \a bpr specifies how
1785338b8dc3SIngo Weinhold many bytes the source contains per row. \c B_ANY_BYTES_PER_ROW can be
1786338b8dc3SIngo Weinhold supplied, if standard padding to int32 is used.
1787338b8dc3SIngo Weinhold
1788338b8dc3SIngo Weinhold The currently supported source/target color spaces are
1789338b8dc3SIngo Weinhold \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1790338b8dc3SIngo Weinhold
1791338b8dc3SIngo Weinhold \param data The data to be copied.
1792338b8dc3SIngo Weinhold \param length The length in bytes of the data to be copied.
1793338b8dc3SIngo Weinhold \param bpr The number of bytes per row in the source data.
1794338b8dc3SIngo Weinhold \param offset The offset (in bytes) relative to beginning of the bitmap
1795338b8dc3SIngo Weinhold data specifying the position at which the source data shall be
1796338b8dc3SIngo Weinhold written.
1797338b8dc3SIngo Weinhold \param colorSpace Color space of the source data.
1798338b8dc3SIngo Weinhold \return
1799338b8dc3SIngo Weinhold - \c B_OK: Everything went fine.
1800338b8dc3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a data, invalid \a bpr or \a offset, or
1801338b8dc3SIngo Weinhold unsupported \a colorSpace.
1802338b8dc3SIngo Weinhold */
1803338b8dc3SIngo Weinhold status_t
ImportBits(const void * data,int32 length,int32 bpr,int32 offset,color_space colorSpace)1804338b8dc3SIngo Weinhold BBitmap::ImportBits(const void *data, int32 length, int32 bpr, int32 offset,
1805338b8dc3SIngo Weinhold color_space colorSpace)
1806338b8dc3SIngo Weinhold {
1807338b8dc3SIngo Weinhold status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1808338b8dc3SIngo Weinhold // check params
1809338b8dc3SIngo Weinhold if (error == B_OK && (data == NULL || offset > fSize || length < 0))
1810338b8dc3SIngo Weinhold error = B_BAD_VALUE;
1811338b8dc3SIngo Weinhold // get BPR
1812338b8dc3SIngo Weinhold int32 width = 0;
1813338b8dc3SIngo Weinhold int32 inRowSkip = 0;
1814338b8dc3SIngo Weinhold if (error == B_OK) {
1815338b8dc3SIngo Weinhold width = fBounds.IntegerWidth() + 1;
1816338b8dc3SIngo Weinhold if (bpr < 0)
1817338b8dc3SIngo Weinhold bpr = get_bytes_per_row(colorSpace, width);
1818338b8dc3SIngo Weinhold inRowSkip = bpr - get_raw_bytes_per_row(colorSpace, width);
1819338b8dc3SIngo Weinhold if (inRowSkip < 0)
1820338b8dc3SIngo Weinhold error = B_BAD_VALUE;
1821338b8dc3SIngo Weinhold }
1822338b8dc3SIngo Weinhold if (error != B_OK) {
1823338b8dc3SIngo Weinhold // catch error case
1824338b8dc3SIngo Weinhold } else if (colorSpace == fColorSpace && bpr == fBytesPerRow) {
1825338b8dc3SIngo Weinhold length = min(length, fSize - offset);
1826338b8dc3SIngo Weinhold memcpy((char*)fBasePtr + offset, data, length);
1827338b8dc3SIngo Weinhold } else {
1828338b8dc3SIngo Weinhold // TODO: Retrieve color map from BScreen, when available:
1829338b8dc3SIngo Weinhold // PaletteConverter paletteConverter(BScreen().ColorMap());
1830338b8dc3SIngo Weinhold const PaletteConverter &paletteConverter = *palette_converter();
1831338b8dc3SIngo Weinhold int32 rawOutBPR = get_raw_bytes_per_row(fColorSpace, width);
1832338b8dc3SIngo Weinhold switch (colorSpace) {
1833338b8dc3SIngo Weinhold // supported
1834338b8dc3SIngo Weinhold case B_RGB32: case B_RGBA32:
1835338b8dc3SIngo Weinhold {
1836338b8dc3SIngo Weinhold typedef RGB24Reader<rgb32_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_RGB32_BIG: case B_RGBA32_BIG:
1843338b8dc3SIngo Weinhold {
1844338b8dc3SIngo Weinhold typedef RGB24Reader<rgb32_big_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:
1851338b8dc3SIngo Weinhold {
1852338b8dc3SIngo Weinhold typedef RGB24Reader<rgb24_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_RGB24_BIG:
1859338b8dc3SIngo Weinhold {
1860338b8dc3SIngo Weinhold typedef RGB24Reader<rgb24_big_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:
1867338b8dc3SIngo Weinhold {
1868338b8dc3SIngo Weinhold typedef RGB16Reader<rgb16_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_RGB16_BIG:
1875338b8dc3SIngo Weinhold {
1876338b8dc3SIngo Weinhold typedef RGB16Reader<rgb16_big_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: case B_RGBA15:
1883338b8dc3SIngo Weinhold {
1884338b8dc3SIngo Weinhold typedef RGB15Reader<rgb16_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_RGB15_BIG: case B_RGBA15_BIG:
1891338b8dc3SIngo Weinhold {
1892338b8dc3SIngo Weinhold typedef RGB15Reader<rgb16_big_pixel> 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 break;
1897338b8dc3SIngo Weinhold }
1898338b8dc3SIngo Weinhold case B_CMAP8:
1899338b8dc3SIngo Weinhold {
1900338b8dc3SIngo Weinhold typedef CMAP8Reader Reader;
1901338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip,
1902338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1903338b8dc3SIngo Weinhold fColorSpace, width, Reader(data, paletteConverter),
1904338b8dc3SIngo Weinhold paletteConverter);
1905338b8dc3SIngo Weinhold break;
1906338b8dc3SIngo Weinhold }
1907338b8dc3SIngo Weinhold case B_GRAY8:
1908338b8dc3SIngo Weinhold {
1909338b8dc3SIngo Weinhold typedef Gray8Reader 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 case B_GRAY1:
1916338b8dc3SIngo Weinhold {
1917338b8dc3SIngo Weinhold typedef Gray1Reader Reader;
1918338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip,
1919338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1920338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter);
1921338b8dc3SIngo Weinhold break;
1922338b8dc3SIngo Weinhold }
1923338b8dc3SIngo Weinhold // unsupported
1924338b8dc3SIngo Weinhold case B_NO_COLOR_SPACE:
1925338b8dc3SIngo Weinhold case B_YUV9: case B_YUV12:
1926338b8dc3SIngo Weinhold case B_UVL32: case B_UVLA32:
1927338b8dc3SIngo Weinhold case B_LAB32: case B_LABA32:
1928338b8dc3SIngo Weinhold case B_HSI32: case B_HSIA32:
1929338b8dc3SIngo Weinhold case B_HSV32: case B_HSVA32:
1930338b8dc3SIngo Weinhold case B_HLS32: case B_HLSA32:
1931338b8dc3SIngo Weinhold case B_CMY32: case B_CMYA32: case B_CMYK32:
1932338b8dc3SIngo Weinhold case B_UVL24: case B_LAB24: case B_HSI24:
1933338b8dc3SIngo Weinhold case B_HSV24: case B_HLS24: case B_CMY24:
1934338b8dc3SIngo Weinhold case B_YCbCr422: case B_YUV422:
1935338b8dc3SIngo Weinhold case B_YCbCr411: case B_YUV411:
1936338b8dc3SIngo Weinhold case B_YCbCr444: case B_YUV444:
1937338b8dc3SIngo Weinhold case B_YCbCr420: case B_YUV420:
1938338b8dc3SIngo Weinhold default:
1939338b8dc3SIngo Weinhold error = B_BAD_VALUE;
1940338b8dc3SIngo Weinhold break;
1941338b8dc3SIngo Weinhold }
1942338b8dc3SIngo Weinhold }
1943338b8dc3SIngo Weinhold return error;
1944338b8dc3SIngo Weinhold }
1945338b8dc3SIngo Weinhold
194664b2d169SAxel Dörfler
1947338b8dc3SIngo Weinhold /*! \briefly Assigns another bitmap's data to this bitmap.
1948338b8dc3SIngo Weinhold
1949338b8dc3SIngo Weinhold The supplied bitmap must have the exactly same dimensions as this bitmap.
1950338b8dc3SIngo Weinhold Its data are converted to the color space of this bitmap.
1951338b8dc3SIngo Weinhold
1952338b8dc3SIngo Weinhold The currently supported source/target color spaces are
1953338b8dc3SIngo Weinhold \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1954338b8dc3SIngo Weinhold
1955338b8dc3SIngo Weinhold \param bitmap The source bitmap.
1956338b8dc3SIngo Weinhold \return
1957338b8dc3SIngo Weinhold - \c B_OK: Everything went fine.
1958338b8dc3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a bitmap, or \a bitmap has other dimensions,
1959338b8dc3SIngo Weinhold or the conversion from or to one of the color spaces is not supported.
1960338b8dc3SIngo Weinhold */
1961338b8dc3SIngo Weinhold status_t
ImportBits(const BBitmap * bitmap)1962338b8dc3SIngo Weinhold BBitmap::ImportBits(const BBitmap *bitmap)
1963338b8dc3SIngo Weinhold {
1964338b8dc3SIngo Weinhold status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1965338b8dc3SIngo Weinhold // check param
1966338b8dc3SIngo Weinhold if (error == B_OK && bitmap == NULL)
1967338b8dc3SIngo Weinhold error = B_BAD_VALUE;
1968338b8dc3SIngo Weinhold if (error == B_OK && bitmap->InitCheck() != B_OK)
1969338b8dc3SIngo Weinhold error = B_BAD_VALUE;
1970338b8dc3SIngo Weinhold if (error == B_OK && bitmap->Bounds() != fBounds)
1971338b8dc3SIngo Weinhold error = B_BAD_VALUE;
1972338b8dc3SIngo Weinhold // set bits
1973338b8dc3SIngo Weinhold if (error == B_OK) {
1974338b8dc3SIngo Weinhold error = ImportBits(bitmap->Bits(), bitmap->BitsLength(),
1975338b8dc3SIngo Weinhold bitmap->BytesPerRow(), 0, bitmap->ColorSpace());
1976338b8dc3SIngo Weinhold }
1977338b8dc3SIngo Weinhold return error;
1978338b8dc3SIngo Weinhold }
1979338b8dc3SIngo Weinhold
198064b2d169SAxel Dörfler
1981338b8dc3SIngo Weinhold status_t
GetOverlayRestrictions(overlay_restrictions * restrictions) const1982338b8dc3SIngo Weinhold BBitmap::GetOverlayRestrictions(overlay_restrictions *restrictions) const
1983338b8dc3SIngo Weinhold {
1984338b8dc3SIngo Weinhold // TODO: Implement
1985338b8dc3SIngo Weinhold return B_ERROR;
1986338b8dc3SIngo Weinhold }
1987338b8dc3SIngo Weinhold
198864b2d169SAxel Dörfler
1989338b8dc3SIngo Weinhold status_t
Perform(perform_code d,void * arg)1990338b8dc3SIngo Weinhold BBitmap::Perform(perform_code d, void *arg)
1991338b8dc3SIngo Weinhold {
1992338b8dc3SIngo Weinhold return BArchivable::Perform(d, arg);
1993338b8dc3SIngo Weinhold }
1994338b8dc3SIngo Weinhold
199564b2d169SAxel Dörfler
1996338b8dc3SIngo Weinhold // FBC
_ReservedBitmap1()1997338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap1() {}
_ReservedBitmap2()1998338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap2() {}
_ReservedBitmap3()1999338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap3() {}
2000338b8dc3SIngo Weinhold
200164b2d169SAxel Dörfler
2002338b8dc3SIngo Weinhold /*! \brief Privatized copy constructor to prevent usage.
2003338b8dc3SIngo Weinhold */
BBitmap(const BBitmap &)2004338b8dc3SIngo Weinhold BBitmap::BBitmap(const BBitmap &)
2005338b8dc3SIngo Weinhold {
2006338b8dc3SIngo Weinhold }
2007338b8dc3SIngo Weinhold
200864b2d169SAxel Dörfler
2009338b8dc3SIngo Weinhold /*! \brief Privatized assignment operator to prevent usage.
2010338b8dc3SIngo Weinhold */
2011338b8dc3SIngo Weinhold BBitmap &
operator =(const BBitmap &)2012338b8dc3SIngo Weinhold BBitmap::operator=(const BBitmap &)
2013338b8dc3SIngo Weinhold {
2014338b8dc3SIngo Weinhold return *this;
2015338b8dc3SIngo Weinhold }
2016338b8dc3SIngo Weinhold
201764b2d169SAxel Dörfler
2018338b8dc3SIngo Weinhold char *
get_shared_pointer() const2019338b8dc3SIngo Weinhold BBitmap::get_shared_pointer() const
2020338b8dc3SIngo Weinhold {
2021338b8dc3SIngo Weinhold return NULL; // not implemented
2022338b8dc3SIngo Weinhold }
2023338b8dc3SIngo Weinhold
202464b2d169SAxel Dörfler
2025338b8dc3SIngo Weinhold int32
get_server_token() const2026338b8dc3SIngo Weinhold BBitmap::get_server_token() const
2027338b8dc3SIngo Weinhold {
2028338b8dc3SIngo Weinhold return fServerToken;
2029338b8dc3SIngo Weinhold }
2030338b8dc3SIngo Weinhold
203164b2d169SAxel Dörfler
2032338b8dc3SIngo Weinhold /*! \brief Initializes the bitmap.
2033338b8dc3SIngo Weinhold \param bounds The bitmap dimensions.
2034338b8dc3SIngo Weinhold \param colorSpace The bitmap's color space.
2035338b8dc3SIngo Weinhold \param flags Creation flags.
2036338b8dc3SIngo Weinhold \param bytesPerRow The number of bytes per row the bitmap should use.
2037338b8dc3SIngo Weinhold \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate
2038338b8dc3SIngo Weinhold value.
2039338b8dc3SIngo Weinhold \param screenID ???
2040338b8dc3SIngo Weinhold */
2041338b8dc3SIngo Weinhold void
InitObject(BRect bounds,color_space colorSpace,uint32 flags,int32 bytesPerRow,screen_id screenID)2042338b8dc3SIngo Weinhold BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags,
2043338b8dc3SIngo Weinhold int32 bytesPerRow, screen_id screenID)
2044338b8dc3SIngo Weinhold {
2045338b8dc3SIngo Weinhold //printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n",
2046338b8dc3SIngo Weinhold // bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow);
2047338b8dc3SIngo Weinhold
2048338b8dc3SIngo Weinhold // TODO: Hanlde setting up the offscreen window if we're such a bitmap!
2049338b8dc3SIngo Weinhold
2050338b8dc3SIngo Weinhold // TODO: Should we handle rounding of the "bounds" here? How does R5 behave?
2051338b8dc3SIngo Weinhold
2052338b8dc3SIngo Weinhold status_t error = B_OK;
2053338b8dc3SIngo Weinhold
2054338b8dc3SIngo Weinhold //#ifdef RUN_WITHOUT_APP_SERVER
2055338b8dc3SIngo Weinhold flags |= B_BITMAP_NO_SERVER_LINK;
2056338b8dc3SIngo Weinhold //#endif // RUN_WITHOUT_APP_SERVER
2057338b8dc3SIngo Weinhold flags &= ~B_BITMAP_ACCEPTS_VIEWS;
2058338b8dc3SIngo Weinhold
2059338b8dc3SIngo Weinhold CleanUp();
2060338b8dc3SIngo Weinhold
2061338b8dc3SIngo Weinhold // check params
2062338b8dc3SIngo Weinhold if (!bounds.IsValid() || !bitmaps_support_space(colorSpace, NULL))
2063338b8dc3SIngo Weinhold error = B_BAD_VALUE;
2064338b8dc3SIngo Weinhold if (error == B_OK) {
2065338b8dc3SIngo Weinhold int32 bpr = get_bytes_per_row(colorSpace, bounds.IntegerWidth() + 1);
2066338b8dc3SIngo Weinhold if (bytesPerRow < 0)
2067338b8dc3SIngo Weinhold bytesPerRow = bpr;
2068338b8dc3SIngo Weinhold else if (bytesPerRow < bpr)
2069338b8dc3SIngo Weinhold // NOTE: How does R5 behave?
2070338b8dc3SIngo Weinhold error = B_BAD_VALUE;
2071338b8dc3SIngo Weinhold }
2072338b8dc3SIngo Weinhold // allocate the bitmap buffer
2073338b8dc3SIngo Weinhold if (error == B_OK) {
2074338b8dc3SIngo Weinhold // NOTE: Maybe the code would look more robust if the
2075338b8dc3SIngo Weinhold // "size" was not calculated here when we ask the server
2076338b8dc3SIngo Weinhold // to allocate the bitmap. -Stephan
2077338b8dc3SIngo Weinhold int32 size = bytesPerRow * (bounds.IntegerHeight() + 1);
2078338b8dc3SIngo Weinhold
2079338b8dc3SIngo Weinhold if (flags & B_BITMAP_NO_SERVER_LINK) {
2080338b8dc3SIngo Weinhold fBasePtr = malloc(size);
2081338b8dc3SIngo Weinhold if (fBasePtr) {
2082338b8dc3SIngo Weinhold fSize = size;
2083338b8dc3SIngo Weinhold fColorSpace = colorSpace;
2084338b8dc3SIngo Weinhold fBounds = bounds;
2085338b8dc3SIngo Weinhold fBytesPerRow = bytesPerRow;
2086338b8dc3SIngo Weinhold fFlags = flags;
2087338b8dc3SIngo Weinhold } else
2088338b8dc3SIngo Weinhold error = B_NO_MEMORY;
2089338b8dc3SIngo Weinhold } else {
2090338b8dc3SIngo Weinhold // // Ask the server (via our owning application) to create a bitmap.
2091338b8dc3SIngo Weinhold // BPrivate::AppServerLink link;
2092338b8dc3SIngo Weinhold //
2093338b8dc3SIngo Weinhold // // Attach Data:
2094338b8dc3SIngo Weinhold // // 1) BRect bounds
2095338b8dc3SIngo Weinhold // // 2) color_space space
2096338b8dc3SIngo Weinhold // // 3) int32 bitmap_flags
2097338b8dc3SIngo Weinhold // // 4) int32 bytes_per_row
2098338b8dc3SIngo Weinhold // // 5) int32 screen_id::id
2099338b8dc3SIngo Weinhold // link.StartMessage(AS_CREATE_BITMAP);
2100338b8dc3SIngo Weinhold // link.Attach<BRect>(bounds);
2101338b8dc3SIngo Weinhold // link.Attach<color_space>(colorSpace);
2102338b8dc3SIngo Weinhold // link.Attach<int32>((int32)flags);
2103338b8dc3SIngo Weinhold // link.Attach<int32>(bytesPerRow);
2104338b8dc3SIngo Weinhold // link.Attach<int32>(screenID.id);
2105338b8dc3SIngo Weinhold //
2106338b8dc3SIngo Weinhold // // Reply Code: SERVER_TRUE
2107338b8dc3SIngo Weinhold // // Reply Data:
2108338b8dc3SIngo Weinhold // // 1) int32 server token
2109338b8dc3SIngo Weinhold // // 2) area_id id of the area in which the bitmap data resides
2110338b8dc3SIngo Weinhold // // 3) int32 area pointer offset used to calculate fBasePtr
2111338b8dc3SIngo Weinhold //
2112338b8dc3SIngo Weinhold // // alternatively, if something went wrong
2113338b8dc3SIngo Weinhold // // Reply Code: SERVER_FALSE
2114338b8dc3SIngo Weinhold // // Reply Data:
2115338b8dc3SIngo Weinhold // // None
2116338b8dc3SIngo Weinhold // int32 code = SERVER_FALSE;
2117338b8dc3SIngo Weinhold // error = link.FlushWithReply(code);
2118338b8dc3SIngo Weinhold //
2119338b8dc3SIngo Weinhold // if (error >= B_OK) {
2120338b8dc3SIngo Weinhold // // *communication* with server successful
2121338b8dc3SIngo Weinhold // if (code == SERVER_TRUE) {
2122338b8dc3SIngo Weinhold // // server side success
2123338b8dc3SIngo Weinhold // // Get token
2124338b8dc3SIngo Weinhold // area_id bmparea;
2125338b8dc3SIngo Weinhold // int32 areaoffset;
2126338b8dc3SIngo Weinhold //
2127338b8dc3SIngo Weinhold // link.Read<int32>(&fServerToken);
2128338b8dc3SIngo Weinhold // link.Read<area_id>(&bmparea);
2129338b8dc3SIngo Weinhold // link.Read<int32>(&areaoffset);
2130338b8dc3SIngo Weinhold //
2131338b8dc3SIngo Weinhold // // Get the area in which the data resides
2132338b8dc3SIngo Weinhold // fArea = clone_area("shared bitmap area",
2133338b8dc3SIngo Weinhold // (void**)&fBasePtr,
2134338b8dc3SIngo Weinhold // B_ANY_ADDRESS,
2135338b8dc3SIngo Weinhold // B_READ_AREA | B_WRITE_AREA,
2136338b8dc3SIngo Weinhold // bmparea);
2137338b8dc3SIngo Weinhold //
2138338b8dc3SIngo Weinhold // // Jump to the location in the area
2139338b8dc3SIngo Weinhold // fBasePtr = (int8*)fBasePtr + areaoffset;
2140338b8dc3SIngo Weinhold //
2141338b8dc3SIngo Weinhold // fSize = size;
2142338b8dc3SIngo Weinhold // fColorSpace = colorSpace;
2143338b8dc3SIngo Weinhold // fBounds = bounds;
2144338b8dc3SIngo Weinhold // fBytesPerRow = bytesPerRow;
2145338b8dc3SIngo Weinhold // fFlags = flags;
2146338b8dc3SIngo Weinhold // } else {
2147338b8dc3SIngo Weinhold // // server side error, we assume:
2148338b8dc3SIngo Weinhold // error = B_NO_MEMORY;
2149338b8dc3SIngo Weinhold // }
2150338b8dc3SIngo Weinhold // }
2151338b8dc3SIngo Weinhold // // NOTE: not "else" to handle B_NO_MEMORY on server side!
2152338b8dc3SIngo Weinhold // if (error < B_OK) {
2153338b8dc3SIngo Weinhold // fBasePtr = NULL;
2154338b8dc3SIngo Weinhold // fServerToken = -1;
2155338b8dc3SIngo Weinhold // fArea = -1;
2156338b8dc3SIngo Weinhold // // NOTE: why not "0" in case of error?
2157338b8dc3SIngo Weinhold // fFlags = flags;
2158338b8dc3SIngo Weinhold // }
2159338b8dc3SIngo Weinhold }
2160338b8dc3SIngo Weinhold // fWindow = NULL;
2161338b8dc3SIngo Weinhold fToken = -1;
2162338b8dc3SIngo Weinhold fOrigArea = -1;
2163338b8dc3SIngo Weinhold }
2164338b8dc3SIngo Weinhold
2165338b8dc3SIngo Weinhold fInitError = error;
2166338b8dc3SIngo Weinhold // TODO: on success, handle clearing to white if the flags say so. Needs to be
2167338b8dc3SIngo Weinhold // dependent on color space.
2168338b8dc3SIngo Weinhold
2169338b8dc3SIngo Weinhold if (fInitError == B_OK) {
2170338b8dc3SIngo Weinhold if (flags & B_BITMAP_ACCEPTS_VIEWS) {
2171338b8dc3SIngo Weinhold // fWindow = new BWindow(Bounds(), fServerToken);
2172338b8dc3SIngo Weinhold // // A BWindow starts life locked and is unlocked
2173338b8dc3SIngo Weinhold // // in Show(), but this window is never shown and
2174338b8dc3SIngo Weinhold // // it's message loop is never started.
2175338b8dc3SIngo Weinhold // fWindow->Unlock();
2176338b8dc3SIngo Weinhold }
2177338b8dc3SIngo Weinhold }
2178338b8dc3SIngo Weinhold }
2179338b8dc3SIngo Weinhold
218064b2d169SAxel Dörfler
2181338b8dc3SIngo Weinhold /*! \brief Cleans up any memory allocated by the bitmap or
2182338b8dc3SIngo Weinhold informs the server to do so.
2183338b8dc3SIngo Weinhold */
2184338b8dc3SIngo Weinhold void
CleanUp()2185338b8dc3SIngo Weinhold BBitmap::CleanUp()
2186338b8dc3SIngo Weinhold {
2187338b8dc3SIngo Weinhold if (fBasePtr) {
2188338b8dc3SIngo Weinhold if (fFlags & B_BITMAP_NO_SERVER_LINK) {
2189338b8dc3SIngo Weinhold free(fBasePtr);
2190338b8dc3SIngo Weinhold } else {
2191338b8dc3SIngo Weinhold // BPrivate::AppServerLink link;
2192338b8dc3SIngo Weinhold // // AS_DELETE_BITMAP:
2193338b8dc3SIngo Weinhold // // Attached Data:
2194338b8dc3SIngo Weinhold // // 1) int32 server token
2195338b8dc3SIngo Weinhold //
2196338b8dc3SIngo Weinhold // // Reply Code: SERVER_TRUE if successful,
2197338b8dc3SIngo Weinhold // // SERVER_FALSE if the buffer was already deleted
2198338b8dc3SIngo Weinhold // // Reply Data: none
2199338b8dc3SIngo Weinhold // // status_t freestat;
2200338b8dc3SIngo Weinhold // int32 code = SERVER_FALSE;
2201338b8dc3SIngo Weinhold // link.StartMessage(AS_DELETE_BITMAP);
2202338b8dc3SIngo Weinhold // link.Attach<int32>(fServerToken);
2203338b8dc3SIngo Weinhold // link.FlushWithReply(code);
2204338b8dc3SIngo Weinhold // if (code == SERVER_FALSE) {
2205338b8dc3SIngo Weinhold // // TODO: Find out if "SERVER_FALSE if the buffer
2206338b8dc3SIngo Weinhold // // was already deleted" is true. If not, maybe we
2207338b8dc3SIngo Weinhold // // need to take additional action.
2208338b8dc3SIngo Weinhold // }
2209338b8dc3SIngo Weinhold // fArea = -1;
2210338b8dc3SIngo Weinhold // fServerToken = -1;
2211338b8dc3SIngo Weinhold }
2212338b8dc3SIngo Weinhold fBasePtr = NULL;
2213338b8dc3SIngo Weinhold }
2214338b8dc3SIngo Weinhold }
2215338b8dc3SIngo Weinhold
221664b2d169SAxel Dörfler
2217338b8dc3SIngo Weinhold void
AssertPtr()2218338b8dc3SIngo Weinhold BBitmap::AssertPtr()
2219338b8dc3SIngo Weinhold {
2220338b8dc3SIngo Weinhold }
2221338b8dc3SIngo Weinhold
2222