Assorted whitespace cleanup and typo fixes.
[haiku.git] / src / build / libbe / interface / Bitmap.cpp
blob3f8bb0fea5ec620325bcc7cba7e903d08dfd3bbd
1 /*
2 * Copyright 2001-2008, Haiku Inc.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Ingo Weinhold (bonefish@users.sf.net)
7 * DarkWyrm <bpmagic@columbus.rr.com>
8 * Stephan Aßmus <superstippi@gmx.de>
9 */
11 /*! BBitmap objects represent off-screen windows that contain bitmap data. */
13 #include <algorithm>
14 #include <limits.h>
15 #include <new>
16 #include <stdio.h>
17 #include <stdlib.h>
19 #include <Bitmap.h>
20 #include <GraphicsDefs.h>
21 #include <Locker.h>
22 #include <Message.h>
25 // structures defining the pixel layout
27 struct rgb32_pixel {
28 uint8 blue;
29 uint8 green;
30 uint8 red;
31 uint8 alpha;
34 struct rgb32_big_pixel {
35 uint8 red;
36 uint8 green;
37 uint8 blue;
38 uint8 alpha;
41 struct rgb24_pixel {
42 uint8 blue;
43 uint8 green;
44 uint8 red;
47 struct rgb24_big_pixel {
48 uint8 red;
49 uint8 green;
50 uint8 blue;
53 struct rgb16_pixel {
54 uint8 gb; // G[2:0],B[4:0]
55 uint8 rg; // 16: R[4:0],G[5:3]
56 // 15: -[0],R[4:0],G[4:3]
59 struct rgb16_big_pixel {
60 uint8 rg; // 16: R[4:0],G[5:3]
61 // 15: -[0],R[4:0],G[4:3]
62 uint8 gb; // G[2:0],B[4:0]
65 // types defining what is needed to store a color value
67 struct rgb_color_value {
68 uint8 red;
69 uint8 green;
70 uint8 blue;
71 uint8 alpha;
74 typedef uint8 gray_color_value;
76 // TODO: system palette -- hard-coded for now, when the app server is ready
77 // we should use system_colors() or BScreen::ColorMap().
78 const rgb_color kSystemPalette[] = {
79 { 0, 0, 0, 255 }, { 8, 8, 8, 255 }, { 16, 16, 16, 255 },
80 { 24, 24, 24, 255 }, { 32, 32, 32, 255 }, { 40, 40, 40, 255 },
81 { 48, 48, 48, 255 }, { 56, 56, 56, 255 }, { 64, 64, 64, 255 },
82 { 72, 72, 72, 255 }, { 80, 80, 80, 255 }, { 88, 88, 88, 255 },
83 { 96, 96, 96, 255 }, { 104, 104, 104, 255 }, { 112, 112, 112, 255 },
84 { 120, 120, 120, 255 }, { 128, 128, 128, 255 }, { 136, 136, 136, 255 },
85 { 144, 144, 144, 255 }, { 152, 152, 152, 255 }, { 160, 160, 160, 255 },
86 { 168, 168, 168, 255 }, { 176, 176, 176, 255 }, { 184, 184, 184, 255 },
87 { 192, 192, 192, 255 }, { 200, 200, 200, 255 }, { 208, 208, 208, 255 },
88 { 216, 216, 216, 255 }, { 224, 224, 224, 255 }, { 232, 232, 232, 255 },
89 { 240, 240, 240, 255 }, { 248, 248, 248, 255 }, { 0, 0, 255, 255 },
90 { 0, 0, 229, 255 }, { 0, 0, 204, 255 }, { 0, 0, 179, 255 },
91 { 0, 0, 154, 255 }, { 0, 0, 129, 255 }, { 0, 0, 105, 255 },
92 { 0, 0, 80, 255 }, { 0, 0, 55, 255 }, { 0, 0, 30, 255 },
93 { 255, 0, 0, 255 }, { 228, 0, 0, 255 }, { 203, 0, 0, 255 },
94 { 178, 0, 0, 255 }, { 153, 0, 0, 255 }, { 128, 0, 0, 255 },
95 { 105, 0, 0, 255 }, { 80, 0, 0, 255 }, { 55, 0, 0, 255 },
96 { 30, 0, 0, 255 }, { 0, 255, 0, 255 }, { 0, 228, 0, 255 },
97 { 0, 203, 0, 255 }, { 0, 178, 0, 255 }, { 0, 153, 0, 255 },
98 { 0, 128, 0, 255 }, { 0, 105, 0, 255 }, { 0, 80, 0, 255 },
99 { 0, 55, 0, 255 }, { 0, 30, 0, 255 }, { 0, 152, 51, 255 },
100 { 255, 255, 255, 255 }, { 203, 255, 255, 255 }, { 203, 255, 203, 255 },
101 { 203, 255, 152, 255 }, { 203, 255, 102, 255 }, { 203, 255, 51, 255 },
102 { 203, 255, 0, 255 }, { 152, 255, 255, 255 }, { 152, 255, 203, 255 },
103 { 152, 255, 152, 255 }, { 152, 255, 102, 255 }, { 152, 255, 51, 255 },
104 { 152, 255, 0, 255 }, { 102, 255, 255, 255 }, { 102, 255, 203, 255 },
105 { 102, 255, 152, 255 }, { 102, 255, 102, 255 }, { 102, 255, 51, 255 },
106 { 102, 255, 0, 255 }, { 51, 255, 255, 255 }, { 51, 255, 203, 255 },
107 { 51, 255, 152, 255 }, { 51, 255, 102, 255 }, { 51, 255, 51, 255 },
108 { 51, 255, 0, 255 }, { 255, 152, 255, 255 }, { 255, 152, 203, 255 },
109 { 255, 152, 152, 255 }, { 255, 152, 102, 255 }, { 255, 152, 51, 255 },
110 { 255, 152, 0, 255 }, { 0, 102, 255, 255 }, { 0, 102, 203, 255 },
111 { 203, 203, 255, 255 }, { 203, 203, 203, 255 }, { 203, 203, 152, 255 },
112 { 203, 203, 102, 255 }, { 203, 203, 51, 255 }, { 203, 203, 0, 255 },
113 { 152, 203, 255, 255 }, { 152, 203, 203, 255 }, { 152, 203, 152, 255 },
114 { 152, 203, 102, 255 }, { 152, 203, 51, 255 }, { 152, 203, 0, 255 },
115 { 102, 203, 255, 255 }, { 102, 203, 203, 255 }, { 102, 203, 152, 255 },
116 { 102, 203, 102, 255 }, { 102, 203, 51, 255 }, { 102, 203, 0, 255 },
117 { 51, 203, 255, 255 }, { 51, 203, 203, 255 }, { 51, 203, 152, 255 },
118 { 51, 203, 102, 255 }, { 51, 203, 51, 255 }, { 51, 203, 0, 255 },
119 { 255, 102, 255, 255 }, { 255, 102, 203, 255 }, { 255, 102, 152, 255 },
120 { 255, 102, 102, 255 }, { 255, 102, 51, 255 }, { 255, 102, 0, 255 },
121 { 0, 102, 152, 255 }, { 0, 102, 102, 255 }, { 203, 152, 255, 255 },
122 { 203, 152, 203, 255 }, { 203, 152, 152, 255 }, { 203, 152, 102, 255 },
123 { 203, 152, 51, 255 }, { 203, 152, 0, 255 }, { 152, 152, 255, 255 },
124 { 152, 152, 203, 255 }, { 152, 152, 152, 255 }, { 152, 152, 102, 255 },
125 { 152, 152, 51, 255 }, { 152, 152, 0, 255 }, { 102, 152, 255, 255 },
126 { 102, 152, 203, 255 }, { 102, 152, 152, 255 }, { 102, 152, 102, 255 },
127 { 102, 152, 51, 255 }, { 102, 152, 0, 255 }, { 51, 152, 255, 255 },
128 { 51, 152, 203, 255 }, { 51, 152, 152, 255 }, { 51, 152, 102, 255 },
129 { 51, 152, 51, 255 }, { 51, 152, 0, 255 }, { 230, 134, 0, 255 },
130 { 255, 51, 203, 255 }, { 255, 51, 152, 255 }, { 255, 51, 102, 255 },
131 { 255, 51, 51, 255 }, { 255, 51, 0, 255 }, { 0, 102, 51, 255 },
132 { 0, 102, 0, 255 }, { 203, 102, 255, 255 }, { 203, 102, 203, 255 },
133 { 203, 102, 152, 255 }, { 203, 102, 102, 255 }, { 203, 102, 51, 255 },
134 { 203, 102, 0, 255 }, { 152, 102, 255, 255 }, { 152, 102, 203, 255 },
135 { 152, 102, 152, 255 }, { 152, 102, 102, 255 }, { 152, 102, 51, 255 },
136 { 152, 102, 0, 255 }, { 102, 102, 255, 255 }, { 102, 102, 203, 255 },
137 { 102, 102, 152, 255 }, { 102, 102, 102, 255 }, { 102, 102, 51, 255 },
138 { 102, 102, 0, 255 }, { 51, 102, 255, 255 }, { 51, 102, 203, 255 },
139 { 51, 102, 152, 255 }, { 51, 102, 102, 255 }, { 51, 102, 51, 255 },
140 { 51, 102, 0, 255 }, { 255, 0, 255, 255 }, { 255, 0, 203, 255 },
141 { 255, 0, 152, 255 }, { 255, 0, 102, 255 }, { 255, 0, 51, 255 },
142 { 255, 175, 19, 255 }, { 0, 51, 255, 255 }, { 0, 51, 203, 255 },
143 { 203, 51, 255, 255 }, { 203, 51, 203, 255 }, { 203, 51, 152, 255 },
144 { 203, 51, 102, 255 }, { 203, 51, 51, 255 }, { 203, 51, 0, 255 },
145 { 152, 51, 255, 255 }, { 152, 51, 203, 255 }, { 152, 51, 152, 255 },
146 { 152, 51, 102, 255 }, { 152, 51, 51, 255 }, { 152, 51, 0, 255 },
147 { 102, 51, 255, 255 }, { 102, 51, 203, 255 }, { 102, 51, 152, 255 },
148 { 102, 51, 102, 255 }, { 102, 51, 51, 255 }, { 102, 51, 0, 255 },
149 { 51, 51, 255, 255 }, { 51, 51, 203, 255 }, { 51, 51, 152, 255 },
150 { 51, 51, 102, 255 }, { 51, 51, 51, 255 }, { 51, 51, 0, 255 },
151 { 255, 203, 102, 255 }, { 255, 203, 152, 255 }, { 255, 203, 203, 255 },
152 { 255, 203, 255, 255 }, { 0, 51, 152, 255 }, { 0, 51, 102, 255 },
153 { 0, 51, 51, 255 }, { 0, 51, 0, 255 }, { 203, 0, 255, 255 },
154 { 203, 0, 203, 255 }, { 203, 0, 152, 255 }, { 203, 0, 102, 255 },
155 { 203, 0, 51, 255 }, { 255, 227, 70, 255 }, { 152, 0, 255, 255 },
156 { 152, 0, 203, 255 }, { 152, 0, 152, 255 }, { 152, 0, 102, 255 },
157 { 152, 0, 51, 255 }, { 152, 0, 0, 255 }, { 102, 0, 255, 255 },
158 { 102, 0, 203, 255 }, { 102, 0, 152, 255 }, { 102, 0, 102, 255 },
159 { 102, 0, 51, 255 }, { 102, 0, 0, 255 }, { 51, 0, 255, 255 },
160 { 51, 0, 203, 255 }, { 51, 0, 152, 255 }, { 51, 0, 102, 255 },
161 { 51, 0, 51, 255 }, { 51, 0, 0, 255 }, { 255, 203, 51, 255 },
162 { 255, 203, 0, 255 }, { 255, 255, 0, 255 }, { 255, 255, 51, 255 },
163 { 255, 255, 102, 255 }, { 255, 255, 152, 255 }, { 255, 255, 203, 255 },
164 { 255, 255, 255, 0 } // B_TRANSPARENT_MAGIC_CMAP8
168 /*! \brief Returns the number of bytes per row needed to store the actual
169 bitmap data (not including any padding) given a color space and a
170 row width.
171 \param colorSpace The color space.
172 \param width The width.
173 \return The number of bytes per row needed to store data for a row, or
174 0, if the color space is not supported.
176 static inline int32
177 get_raw_bytes_per_row(color_space colorSpace, int32 width)
179 int32 bpr = 0;
180 switch (colorSpace) {
181 // supported
182 case B_RGB32: case B_RGBA32:
183 case B_RGB32_BIG: case B_RGBA32_BIG:
184 case B_UVL32: case B_UVLA32:
185 case B_LAB32: case B_LABA32:
186 case B_HSI32: case B_HSIA32:
187 case B_HSV32: case B_HSVA32:
188 case B_HLS32: case B_HLSA32:
189 case B_CMY32: case B_CMYA32: case B_CMYK32:
190 bpr = 4 * width;
191 break;
192 case B_RGB24: case B_RGB24_BIG:
193 case B_UVL24: case B_LAB24: case B_HSI24:
194 case B_HSV24: case B_HLS24: case B_CMY24:
195 bpr = 3 * width;
196 break;
197 case B_RGB16: case B_RGB15: case B_RGBA15:
198 case B_RGB16_BIG: case B_RGB15_BIG: case B_RGBA15_BIG:
199 bpr = 2 * width;
200 break;
201 case B_CMAP8: case B_GRAY8:
202 bpr = width;
203 break;
204 case B_GRAY1:
205 bpr = (width + 7) / 8;
206 break;
207 case B_YCbCr422: case B_YUV422:
208 bpr = (width + 3) / 4 * 8;
209 break;
210 case B_YCbCr411: case B_YUV411:
211 bpr = (width + 3) / 4 * 6;
212 break;
213 case B_YCbCr444: case B_YUV444:
214 bpr = (width + 3) / 4 * 12;
215 break;
216 case B_YCbCr420: case B_YUV420:
217 bpr = (width + 3) / 4 * 6;
218 break;
219 case B_YUV9:
220 bpr = (width + 15) / 16 * 18;
221 // unsupported
222 case B_NO_COLOR_SPACE:
223 case B_YUV12:
224 break;
226 return bpr;
230 /*! \brief Returns the number of bytes per row needed to store the bitmap
231 data (including any padding) given a color space and a row width.
232 \param colorSpace The color space.
233 \param width The width.
234 \return The number of bytes per row needed to store data for a row, or
235 0, if the color space is not supported.
237 static inline int32
238 get_bytes_per_row(color_space colorSpace, int32 width)
240 int32 bpr = get_raw_bytes_per_row(colorSpace, width);
241 // align to int32
242 bpr = (bpr + 3) & 0x7ffffffc;
243 return bpr;
247 /*! \brief Returns the brightness of an RGB 24 color.
248 \param red Value of the red component.
249 \param green Value of the green component.
250 \param blue Value of the blue component.
251 \return The brightness for the supplied RGB color as a value between 0
252 and 255.
254 static inline uint8
255 brightness_for(uint8 red, uint8 green, uint8 blue)
257 // brightness = 0.301 * red + 0.586 * green + 0.113 * blue
258 // we use for performance reasons:
259 // brightness = (308 * red + 600 * green + 116 * blue) / 1024
260 return uint8((308 * red + 600 * green + 116 * blue) / 1024);
264 /*! \brief Returns the "distance" between two RGB colors.
266 This functions defines an metric on the RGB color space. The distance
267 between two colors is 0, if and only if the colors are equal.
269 \param red1 Red component of the first color.
270 \param green1 Green component of the first color.
271 \param blue1 Blue component of the first color.
272 \param red2 Red component of the second color.
273 \param green2 Green component of the second color.
274 \param blue2 Blue component of the second color.
275 \return The distance between the given colors.
277 static inline unsigned
278 color_distance(uint8 red1, uint8 green1, uint8 blue1, uint8 red2, uint8 green2,
279 uint8 blue2)
281 // euklidian distance (its square actually)
282 int rd = (int)red1 - (int)red2;
283 int gd = (int)green1 - (int)green2;
284 int bd = (int)blue1 - (int)blue2;
285 // return rd * rd + gd * gd + bd * bd;
287 // distance according to psycho-visual tests
288 int rmean = ((int)red1 + (int)red2) / 2;
289 return (((512 + rmean) * rd * rd) >> 8) + 4 * gd * gd
290 + (((767 - rmean) * bd * bd) >> 8);
294 static inline int32
295 bit_mask(int32 bit)
297 return 1 << bit;
301 static inline int32
302 inverse_bit_mask(int32 bit)
304 return ~bit_mask(bit);
308 // #pragma mark - PaletteConverter
311 namespace BPrivate {
313 /*! \brief Helper class for conversion between RGB and palette colors.
315 class PaletteConverter {
316 public:
317 PaletteConverter();
318 PaletteConverter(const rgb_color *palette);
319 PaletteConverter(const color_map *colorMap);
320 ~PaletteConverter();
322 status_t SetTo(const rgb_color *palette);
323 status_t SetTo(const color_map *colorMap);
324 status_t InitCheck() const;
326 inline uint8 IndexForRGB15(uint16 rgb) const;
327 inline uint8 IndexForRGB15(uint8 red, uint8 green, uint8 blue) const;
328 inline uint8 IndexForRGB16(uint16 rgb) const;
329 inline uint8 IndexForRGB16(uint8 red, uint8 green, uint8 blue) const;
330 inline uint8 IndexForRGB24(uint32 rgb) const;
331 inline uint8 IndexForRGB24(uint8 red, uint8 green, uint8 blue) const;
332 inline uint8 IndexForGray(uint8 gray) const;
334 inline const rgb_color &RGBColorForIndex(uint8 index) const;
335 inline uint16 RGB15ColorForIndex(uint8 index) const;
336 inline uint16 RGB16ColorForIndex(uint8 index) const;
337 inline uint32 RGB24ColorForIndex(uint8 index) const;
338 inline void RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green,
339 uint8 &blue, uint8 &alpha) const;
340 inline uint8 GrayColorForIndex(uint8 index) const;
342 private:
343 const color_map *fColorMap;
344 color_map *fOwnColorMap;
345 status_t fCStatus;
348 } // namespace BPrivate
350 using BPrivate::PaletteConverter;
351 using namespace std;
354 /*! \brief Creates an uninitialized PaletteConverter.
356 PaletteConverter::PaletteConverter()
357 : fColorMap(NULL),
358 fOwnColorMap(NULL),
359 fCStatus(B_NO_INIT)
364 /*! \brief Creates a PaletteConverter and initializes it to the supplied
365 palette.
366 \param palette The palette being a 256 entry rgb_color array.
368 PaletteConverter::PaletteConverter(const rgb_color *palette)
369 : fColorMap(NULL),
370 fOwnColorMap(NULL),
371 fCStatus(B_NO_INIT)
373 SetTo(palette);
377 /*! \brief Creates a PaletteConverter and initializes it to the supplied
378 color map.
379 \param colorMap The completely initialized color map.
381 PaletteConverter::PaletteConverter(const color_map *colorMap)
382 : fColorMap(NULL),
383 fOwnColorMap(NULL),
384 fCStatus(B_NO_INIT)
386 SetTo(colorMap);
390 /*! \brief Frees all resources associated with this object.
392 PaletteConverter::~PaletteConverter()
394 delete fOwnColorMap;
398 /*! \brief Initializes the converter to the supplied palette.
399 \param palette The palette being a 256 entry rgb_color array.
400 \return \c B_OK, if everything went fine, an error code otherwise.
402 status_t
403 PaletteConverter::SetTo(const rgb_color *palette)
405 // cleanup
406 SetTo((const color_map*)NULL);
407 status_t error = (palette ? B_OK : B_BAD_VALUE);
408 // alloc color map
409 if (error == B_OK) {
410 fOwnColorMap = new(nothrow) color_map;
411 if (fOwnColorMap == NULL)
412 error = B_NO_MEMORY;
414 // init color map
415 if (error == B_OK) {
416 fColorMap = fOwnColorMap;
417 // init color list
418 memcpy(fOwnColorMap->color_list, palette, sizeof(rgb_color) * 256);
419 // init index map
420 for (int32 color = 0; color < 32768; color++) {
421 // get components
422 uint8 red = (color & 0x7c00) >> 7;
423 uint8 green = (color & 0x3e0) >> 2;
424 uint8 blue = (color & 0x1f) << 3;
425 red |= red >> 5;
426 green |= green >> 5;
427 blue |= blue >> 5;
428 // find closest color
429 uint8 closestIndex = 0;
430 unsigned closestDistance = UINT_MAX;
431 for (int32 i = 0; i < 256; i++) {
432 const rgb_color &c = fOwnColorMap->color_list[i];
433 unsigned distance = color_distance(red, green, blue,
434 c.red, c.green, c.blue);
435 if (distance < closestDistance) {
436 closestIndex = i;
437 closestDistance = distance;
440 fOwnColorMap->index_map[color] = closestIndex;
442 // no need to init inversion map
444 fCStatus = error;
445 return error;
449 /*! \brief Initializes the converter to the supplied color map.
450 \param colorMap The completely initialized color map.
451 \return \c B_OK, if everything went fine, an error code otherwise.
453 status_t
454 PaletteConverter::SetTo(const color_map *colorMap)
456 // cleanup
457 if (fOwnColorMap) {
458 delete fOwnColorMap;
459 fOwnColorMap = NULL;
461 // set
462 fColorMap = colorMap;
463 fCStatus = fColorMap ? B_OK : B_BAD_VALUE;
464 return fCStatus;
468 /*! \brief Returns the result of the last initialization via constructor or
469 SetTo().
470 \return \c B_OK, if the converter is properly initialized, an error code
471 otherwise.
473 status_t
474 PaletteConverter::InitCheck() const
476 return fCStatus;
480 /*! \brief Returns the palette color index closest to a given RGB 15 color.
482 The object must be properly initialized.
484 \param rgb The RGB 15 color value (R[14:10]G[9:5]B[4:0]).
485 \return The palette color index for the supplied color.
487 inline uint8
488 PaletteConverter::IndexForRGB15(uint16 rgb) const
490 return fColorMap->index_map[rgb];
494 /*! \brief Returns the palette color index closest to a given RGB 15 color.
496 The object must be properly initialized.
498 \param red Red component of the color (R[4:0]).
499 \param green Green component of the color (G[4:0]).
500 \param blue Blue component of the color (B[4:0]).
501 \return The palette color index for the supplied color.
503 inline uint8
504 PaletteConverter::IndexForRGB15(uint8 red, uint8 green, uint8 blue) const
506 // the 5 least significant bits are used
507 return fColorMap->index_map[(red << 10) | (green << 5) | blue];
511 /*! \brief Returns the palette color index closest to a given RGB 16 color.
513 The object must be properly initialized.
515 \param rgb The RGB 16 color value (R[15:11]G[10:5]B[4:0]).
516 \return The palette color index for the supplied color.
518 inline uint8
519 PaletteConverter::IndexForRGB16(uint16 rgb) const
521 return fColorMap->index_map[((rgb >> 1) & 0x7fe0) | (rgb & 0x1f)];
525 /*! \brief Returns the palette color index closest to a given RGB 16 color.
527 The object must be properly initialized.
529 \param red Red component of the color (R[4:0]).
530 \param green Green component of the color (G[5:0]).
531 \param blue Blue component of the color (B[4:0]).
532 \return The palette color index for the supplied color.
534 inline uint8
535 PaletteConverter::IndexForRGB16(uint8 red, uint8 green, uint8 blue) const
537 // the 5 (for red, blue) / 6 (for green) least significant bits are used
538 return fColorMap->index_map[(red << 10) | ((green & 0x3e) << 4) | blue];
542 /*! \brief Returns the palette color index closest to a given RGB 32 color.
544 The object must be properly initialized.
546 \param rgb The RGB 32 color value (R[31:24]G[23:16]B[15:8]).
547 \return The palette color index for the supplied color.
549 inline uint8
550 PaletteConverter::IndexForRGB24(uint32 rgb) const
552 return fColorMap->index_map[((rgb & 0xf8000000) >> 17)
553 | ((rgb & 0xf80000) >> 14) | ((rgb & 0xf800) >> 11)];
557 /*! \brief Returns the palette color index closest to a given RGB 24 color.
559 The object must be properly initialized.
561 \param red Red component of the color.
562 \param green Green component of the color.
563 \param blue Blue component of the color.
564 \return The palette color index for the supplied color.
566 inline uint8
567 PaletteConverter::IndexForRGB24(uint8 red, uint8 green, uint8 blue) const
569 return fColorMap->index_map[((red & 0xf8) << 7) | ((green & 0xf8) << 2)
570 | (blue >> 3)];
574 /*! \brief Returns the palette color index closest to a given Gray 8 color.
576 The object must be properly initialized.
578 \param gray The Gray 8 color value.
579 \return The palette color index for the supplied color.
581 inline uint8
582 PaletteConverter::IndexForGray(uint8 gray) const
584 return IndexForRGB24(gray, gray, gray);
588 /*! \brief Returns the RGB color for a given palette color index.
590 The object must be properly initialized.
592 \param index The palette color index.
593 \return The color for the supplied palette color index.
595 inline const rgb_color &
596 PaletteConverter::RGBColorForIndex(uint8 index) const
598 return fColorMap->color_list[index];
602 /*! \brief Returns the RGB 15 color for a given palette color index.
604 The object must be properly initialized.
606 \param index The palette color index.
607 \return The color for the supplied palette color index
608 (R[14:10]G[9:5]B[4:0]).
610 inline uint16
611 PaletteConverter::RGB15ColorForIndex(uint8 index) const
613 const rgb_color &color = fColorMap->color_list[index];
614 return ((color.red & 0xf8) << 7) | ((color.green & 0xf8) << 2)
615 | (color.blue >> 3);
619 /*! \brief Returns the RGB 16 color for a given palette color index.
621 The object must be properly initialized.
623 \param index The palette color index.
624 \return The color for the supplied palette color index
625 (R[15:11]G[10:5]B[4:0]).
627 inline uint16
628 PaletteConverter::RGB16ColorForIndex(uint8 index) const
630 const rgb_color &color = fColorMap->color_list[index];
631 return ((color.red & 0xf8) << 8) | ((color.green & 0xfc) << 3)
632 | (color.blue >> 3);
636 /*! \brief Returns the RGB 24 color for a given palette color index.
638 The object must be properly initialized.
640 \param index The palette color index.
641 \return The color for the supplied palette color index
642 (R[31:24]G[23:16]B[15:8]).
644 inline uint32
645 PaletteConverter::RGB24ColorForIndex(uint8 index) const
647 const rgb_color &color = fColorMap->color_list[index];
648 return (color.blue << 24) | (color.red << 8) | (color.green << 16)
649 | color.alpha;
653 /*! \brief Returns the RGB 24 color for a given palette color index.
655 The object must be properly initialized.
657 \param index The palette color index.
658 \param red Reference to the variable the red component shall be stored
659 into.
660 \param green Reference to the variable the green component shall be stored
661 into.
662 \param blue Reference to the variable the blue component shall be stored
663 into.
665 inline void
666 PaletteConverter::RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green,
667 uint8 &blue, uint8 &alpha) const
669 const rgb_color &color = fColorMap->color_list[index];
670 red = color.red;
671 green = color.green;
672 blue = color.blue;
673 alpha = color.alpha;
677 /*! \brief Returns the Gray 8 color for a given palette color index.
679 The object must be properly initialized.
681 \param index The palette color index.
682 \return The color for the supplied palette color index.
684 inline uint8
685 PaletteConverter::GrayColorForIndex(uint8 index) const
687 const rgb_color &color = fColorMap->color_list[index];
688 return brightness_for(color.red, color.green, color.blue);
691 // TODO: Remove these and palette_converter() when BScreen is available.
692 static BLocker gPaletteConverterLock;
693 static PaletteConverter gPaletteConverter;
696 /*! \brief Returns a PaletteConverter using the system color palette.
697 \return A PaletteConverter.
699 static const PaletteConverter*
700 palette_converter()
702 if (gPaletteConverterLock.Lock()) {
703 if (gPaletteConverter.InitCheck() != B_OK)
704 gPaletteConverter.SetTo(kSystemPalette);
705 gPaletteConverterLock.Unlock();
707 return &gPaletteConverter;
711 // #pragma mark - Reader classes
714 // BaseReader
715 template<typename _PixelType>
716 struct BaseReader {
717 typedef _PixelType pixel_t;
719 BaseReader(const void *data) : pixels((const pixel_t*)data) {}
721 inline void SetTo(const void *data) { pixels = (const pixel_t*)data; }
723 inline void NextRow(int32 skip)
725 pixels = (const pixel_t*)((const char*)pixels + skip);
728 const pixel_t *pixels;
731 // RGB24Reader
732 template<typename _PixelType>
733 struct RGB24Reader : public BaseReader<_PixelType> {
734 typedef rgb_color_value preferred_color_value_t;
735 typedef _PixelType pixel_t;
737 RGB24Reader(const void *data) : BaseReader<_PixelType>(data) {}
739 inline void Read(rgb_color_value &color)
741 const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
742 color.red = pixel.red;
743 color.green = pixel.green;
744 color.blue = pixel.blue;
745 color.alpha = 255;
746 BaseReader<_PixelType>::pixels++;
749 inline void Read(gray_color_value &gray)
751 rgb_color_value color;
752 Read(color);
753 gray = brightness_for(color.red, color.green, color.blue);
757 // RGB16Reader
758 template<typename _PixelType>
759 struct RGB16Reader : public BaseReader<_PixelType> {
760 typedef rgb_color_value preferred_color_value_t;
761 typedef _PixelType pixel_t;
763 RGB16Reader(const void *data) : BaseReader<_PixelType>(data) {}
765 inline void Read(rgb_color_value &color)
767 // rg: R[4:0],G[5:3]
768 // gb: G[2:0],B[4:0]
769 const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
770 color.red = pixel.rg & 0xf8;
771 color.green = ((pixel.rg & 0x07) << 5) & ((pixel.gb & 0xe0) >> 3);
772 color.blue = (pixel.gb & 0x1f) << 3;
773 color.red |= color.red >> 5;
774 color.green |= color.green >> 6;
775 color.blue |= color.blue >> 5;
776 color.alpha = 255;
777 BaseReader<_PixelType>::pixels++;
780 inline void Read(gray_color_value &gray)
782 rgb_color_value color;
783 Read(color);
784 gray = brightness_for(color.red, color.green, color.blue);
788 // RGB15Reader
789 template<typename _PixelType>
790 struct RGB15Reader : public BaseReader<_PixelType> {
791 typedef rgb_color_value preferred_color_value_t;
792 typedef _PixelType pixel_t;
794 RGB15Reader(const void *data) : BaseReader<_PixelType>(data) {}
796 inline void Read(rgb_color_value &color)
798 // rg: -[0],R[4:0],G[4:3]
799 // gb: G[2:0],B[4:0]
800 const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
801 color.red = (pixel.rg & 0x7c) << 1;
802 color.green = ((pixel.rg & 0x03) << 6) & ((pixel.gb & 0xe0) >> 2);
803 color.blue = (pixel.gb & 0x1f) << 3;
804 color.red |= color.red >> 5;
805 color.green |= color.green >> 5;
806 color.blue |= color.blue >> 5;
807 color.alpha = 255;
808 BaseReader<_PixelType>::pixels++;
811 inline void Read(gray_color_value &gray)
813 rgb_color_value color;
814 Read(color);
815 gray = brightness_for(color.red, color.green, color.blue);
819 // CMAP8Reader
820 struct CMAP8Reader : public BaseReader<uint8> {
821 typedef rgb_color_value preferred_color_value_t;
823 CMAP8Reader(const void *data, const PaletteConverter &converter)
824 : BaseReader<uint8>(data), converter(converter) {}
826 inline void Read(rgb_color_value &color)
828 converter.RGB24ColorForIndex(*BaseReader<uint8>::pixels, color.red, color.green,
829 color.blue, color.alpha);
830 BaseReader<uint8>::pixels++;
833 inline void Read(gray_color_value &gray)
835 gray = converter.GrayColorForIndex(*BaseReader<uint8>::pixels);
836 BaseReader<uint8>::pixels++;
839 const PaletteConverter &converter;
842 // Gray8Reader
843 struct Gray8Reader : public BaseReader<uint8> {
844 typedef gray_color_value preferred_color_value_t;
846 Gray8Reader(const void *data) : BaseReader<uint8>(data) {}
848 inline void Read(rgb_color_value &color)
850 color.red = color.green = color.blue = *BaseReader<uint8>::pixels;
851 color.alpha = 255;
852 BaseReader<uint8>::pixels++;
855 inline void Read(gray_color_value &gray)
857 gray = *BaseReader<uint8>::pixels;
858 BaseReader<uint8>::pixels++;
862 // Gray1Reader
863 struct Gray1Reader : public BaseReader<uint8> {
864 typedef gray_color_value preferred_color_value_t;
866 Gray1Reader(const void *data) : BaseReader<uint8>(data), bit(7) {}
868 inline void SetTo(const void *data)
870 pixels = (const pixel_t*)data;
871 bit = 7;
874 inline void NextRow(int32 skip)
876 if (bit == 7)
877 pixels = (const pixel_t*)((const char*)pixels + skip);
878 else {
879 pixels = (const pixel_t*)((const char*)pixels + skip + 1);
880 bit = 7;
884 inline void Read(rgb_color_value &color)
886 if (*pixels & bit_mask(bit))
887 color.red = color.green = color.blue = 255;
888 else
889 color.red = color.green = color.blue = 0;
890 color.alpha = 255;
891 bit--;
892 if (bit == -1) {
893 pixels++;
894 bit = 7;
898 inline void Read(gray_color_value &gray)
900 if (*pixels & bit_mask(bit))
901 gray = 255;
902 else
903 gray = 0;
904 bit--;
905 if (bit == -1) {
906 pixels++;
907 bit = 7;
911 int32 bit;
915 // #pragma mark - Writer classes
918 // BaseWriter
919 template<typename _PixelType>
920 struct BaseWriter {
921 typedef _PixelType pixel_t;
923 BaseWriter(void *data) : pixels((pixel_t*)data) {}
925 inline void SetTo(void *data) { pixels = (pixel_t*)data; }
927 pixel_t *pixels;
931 // RGB32Writer
932 template<typename _PixelType>
933 struct RGB32Writer : public BaseWriter<_PixelType> {
934 typedef rgb_color_value preferred_color_value_t;
935 typedef _PixelType pixel_t;
937 RGB32Writer(void *data) : BaseWriter<_PixelType>(data) {}
939 inline void Write(const rgb_color_value &color)
941 pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
942 pixel.red = color.red;
943 pixel.green = color.green;
944 pixel.blue = color.blue;
945 pixel.alpha = color.alpha;
946 BaseWriter<_PixelType>::pixels++;
949 inline void Write(const gray_color_value &gray)
951 pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
952 pixel.red = gray;
953 pixel.green = gray;
954 pixel.blue = gray;
955 pixel.alpha = 255;
956 BaseWriter<_PixelType>::pixels++;
960 // RGB24Writer
961 template<typename _PixelType>
962 struct RGB24Writer : public BaseWriter<_PixelType> {
963 typedef rgb_color_value preferred_color_value_t;
964 typedef _PixelType pixel_t;
966 RGB24Writer(void *data) : BaseWriter<_PixelType>(data) {}
968 inline void Write(const rgb_color_value &color)
970 pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
971 pixel.red = color.red;
972 pixel.green = color.green;
973 pixel.blue = color.blue;
974 BaseWriter<_PixelType>::pixels++;
977 inline void Write(const gray_color_value &gray)
979 pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
980 pixel.red = gray;
981 pixel.green = gray;
982 pixel.blue = gray;
983 BaseWriter<_PixelType>::pixels++;
987 // RGB16Writer
988 template<typename _PixelType>
989 struct RGB16Writer : public BaseWriter<_PixelType> {
990 typedef rgb_color_value preferred_color_value_t;
991 typedef _PixelType pixel_t;
993 RGB16Writer(void *data) : BaseWriter<_PixelType>(data) {}
995 inline void Write(const rgb_color_value &color)
997 // rg: R[4:0],G[5:3]
998 // gb: G[2:0],B[4:0]
999 pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1000 pixel.rg = (color.red & 0xf8) | (color.green >> 5);
1001 pixel.gb = ((color.green & 0x1c) << 3) | (color.blue >> 3);
1002 BaseWriter<_PixelType>::pixels++;
1005 inline void Write(const gray_color_value &gray)
1007 pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1008 pixel.rg = (gray & 0xf8) | (gray >> 5);
1009 pixel.gb = ((gray & 0x1c) << 3) | (gray >> 3);
1010 BaseWriter<_PixelType>::pixels++;
1014 // RGB15Writer
1015 template<typename _PixelType>
1016 struct RGB15Writer : public BaseWriter<_PixelType> {
1017 typedef rgb_color_value preferred_color_value_t;
1018 typedef _PixelType pixel_t;
1020 RGB15Writer(void *data) : BaseWriter<_PixelType>(data) {}
1022 inline void Write(const rgb_color_value &color)
1024 // rg: -[0],R[4:0],G[4:3]
1025 // gb: G[2:0],B[4:0]
1026 pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1027 pixel.rg = ((color.red & 0xf8) >> 1) | (color.green >> 6);
1028 pixel.gb = ((color.green & 0x38) << 2) | (color.blue >> 3);
1029 BaseWriter<_PixelType>::pixels++;
1032 inline void Write(const gray_color_value &gray)
1034 pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1035 pixel.rg = ((gray & 0xf8) >> 1) | (gray >> 6);
1036 pixel.gb = ((gray & 0x38) << 2) | (gray >> 3);
1037 BaseWriter<_PixelType>::pixels++;
1041 // CMAP8Writer
1042 struct CMAP8Writer : public BaseWriter<uint8> {
1043 typedef rgb_color_value preferred_color_value_t;
1045 CMAP8Writer(void *data, const PaletteConverter &converter)
1046 : BaseWriter<uint8>(data), converter(converter) {}
1048 inline void Write(const rgb_color_value &color)
1050 *pixels = converter.IndexForRGB24(color.red, color.green, color.blue);
1051 pixels++;
1054 inline void Write(const gray_color_value &gray)
1056 *pixels = converter.IndexForGray(gray);
1057 pixels++;
1060 const PaletteConverter &converter;
1063 // Gray8Writer
1064 struct Gray8Writer : public BaseWriter<uint8> {
1065 typedef gray_color_value preferred_color_value_t;
1067 Gray8Writer(void *data) : BaseWriter<uint8>(data) {}
1069 inline void Write(const rgb_color_value &color)
1071 *pixels = brightness_for(color.red, color.green, color.blue);
1072 pixels++;
1075 inline void Write(const gray_color_value &gray)
1077 *pixels = gray;
1078 pixels++;
1082 // Gray1Writer
1083 struct Gray1Writer : public BaseWriter<uint8> {
1084 typedef gray_color_value preferred_color_value_t;
1086 Gray1Writer(void *data) : BaseWriter<uint8>(data), bit(7) {}
1088 inline void SetTo(void *data) { pixels = (pixel_t*)data; bit = 7; }
1090 inline void Write(const gray_color_value &gray)
1092 *pixels = (*pixels & inverse_bit_mask(bit))
1093 | (gray & 0x80) >> (7 - bit);
1094 bit--;
1095 if (bit == -1) {
1096 pixels++;
1097 bit = 7;
1101 inline void Write(const rgb_color_value &color)
1103 Write(brightness_for(color.red, color.green, color.blue));
1106 int32 bit;
1110 // set_bits_worker
1111 /*! \brief Worker function that reads bitmap data from one buffer and writes
1112 it (converted) to another one.
1113 \param Reader The pixel reader class.
1114 \param Writer The pixel writer class.
1115 \param color_value_t The color value type used to transport a pixel from
1116 the reader to the writer.
1117 \param inData A pointer to the buffer to be read.
1118 \param inLength The length (in bytes) of the "in" buffer.
1119 \param inBPR The number of bytes per row in the "in" buffer.
1120 \param inRowSkip The number of bytes per row in the "in" buffer serving as
1121 padding.
1122 \param outData A pointer to the buffer to be written to.
1123 \param outLength The length (in bytes) of the "out" buffer.
1124 \param outOffset The offset (in bytes) relative to \a outData from which
1125 the function shall start writing.
1126 \param outBPR The number of bytes per row in the "out" buffer.
1127 \param rawOutBPR The number of bytes per row in the "out" buffer actually
1128 containing bitmap data (i.e. not including the padding).
1129 \param _reader A reader object. The pointer to the data doesn't need to
1130 be initialized.
1131 \param _writer A writer object. The pointer to the data doesn't need to
1132 be initialized.
1133 \return \c B_OK, if everything went fine, an error code otherwise.
1135 template<typename Reader, typename Writer, typename color_value_t>
1136 static
1137 status_t
1138 set_bits_worker(const void *inData, int32 inLength, int32 inBPR,
1139 int32 inRowSkip, void *outData, int32 outLength,
1140 int32 outOffset, int32 outBPR, int32 rawOutBPR,
1141 Reader _reader, Writer _writer)
1143 status_t error = B_OK;
1144 Reader reader(_reader);
1145 Writer writer(_writer);
1146 reader.SetTo(inData);
1147 writer.SetTo((char*)outData + outOffset);
1148 const char *inEnd = (const char*)inData + inLength
1149 - sizeof(typename Reader::pixel_t);
1150 const char *inLastRow = (const char*)inData + inLength
1151 - (inBPR - inRowSkip);
1152 const char *outEnd = (const char*)outData + outLength
1153 - sizeof(typename Writer::pixel_t);
1154 char *outRow = (char*)outData + outOffset - outOffset % outBPR;
1155 const char *outRowEnd = outRow + rawOutBPR - sizeof(typename Writer::pixel_t);
1156 while ((const char*)reader.pixels <= inEnd
1157 && (const char*)writer.pixels <= outEnd) {
1158 // process one row
1159 if ((const char*)reader.pixels <= inLastRow) {
1160 // at least a complete row left
1161 while ((const char*)writer.pixels <= outRowEnd) {
1162 color_value_t color;
1163 reader.Read(color);
1164 writer.Write(color);
1166 } else {
1167 // no complete row left
1168 // but maybe the complete end of the first row
1169 while ((const char*)reader.pixels <= inEnd
1170 && (const char*)writer.pixels <= outRowEnd) {
1171 color_value_t color;
1172 reader.Read(color);
1173 writer.Write(color);
1176 // must be here, not in the if-branch (end of first row)
1177 outRow += outBPR;
1178 outRowEnd += outBPR;
1179 reader.NextRow(inRowSkip);
1180 writer.SetTo(outRow);
1182 return error;
1185 // set_bits_worker_gray1
1186 /*! \brief Worker function that reads bitmap data from one buffer and writes
1187 it (converted) to another one, which uses color space \c B_GRAY1.
1188 \param Reader The pixel reader class.
1189 \param Writer The pixel writer class.
1190 \param color_value_t The color value type used to transport a pixel from
1191 the reader to the writer.
1192 \param inData A pointer to the buffer to be read.
1193 \param inLength The length (in bytes) of the "in" buffer.
1194 \param inBPR The number of bytes per row in the "in" buffer.
1195 \param inRowSkip The number of bytes per row in the "in" buffer serving as
1196 padding.
1197 \param outData A pointer to the buffer to be written to.
1198 \param outLength The length (in bytes) of the "out" buffer.
1199 \param outOffset The offset (in bytes) relative to \a outData from which
1200 the function shall start writing.
1201 \param outBPR The number of bytes per row in the "out" buffer.
1202 \param width The number of pixels per row in "in" and "out" data.
1203 \param _reader A reader object. The pointer to the data doesn't need to
1204 be initialized.
1205 \param _writer A writer object. The pointer to the data doesn't need to
1206 be initialized.
1207 \return \c B_OK, if everything went fine, an error code otherwise.
1209 template<typename Reader, typename Writer, typename color_value_t>
1210 static
1211 status_t
1212 set_bits_worker_gray1(const void *inData, int32 inLength, int32 inBPR,
1213 int32 inRowSkip, void *outData, int32 outLength,
1214 int32 outOffset, int32 outBPR, int32 width,
1215 Reader _reader, Writer _writer)
1217 status_t error = B_OK;
1218 Reader reader(_reader);
1219 Writer writer(_writer);
1220 reader.SetTo(inData);
1221 writer.SetTo((char*)outData + outOffset);
1222 const char *inEnd = (const char*)inData + inLength
1223 - sizeof(typename Reader::pixel_t);
1224 const char *inLastRow = (const char*)inData + inLength
1225 - (inBPR - inRowSkip);
1226 const char *outEnd = (const char*)outData + outLength - outBPR;
1227 char *outRow = (char*)outData + outOffset - outOffset % outBPR;
1228 int32 x = max((int32)0,
1229 width - (int32)((char*)outData + outOffset - outRow) * 8) - 1;
1230 while ((const char*)reader.pixels <= inEnd
1231 && (const char*)writer.pixels <= outEnd) {
1232 // process one row
1233 if ((const char*)reader.pixels <= inLastRow) {
1234 // at least a complete row left
1235 while (x >= 0) {
1236 color_value_t color;
1237 reader.Read(color);
1238 writer.Write(color);
1239 x--;
1241 } else {
1242 // no complete row left
1243 // but maybe the complete end of the first row
1244 while ((const char*)reader.pixels <= inEnd && x >= 0) {
1245 color_value_t color;
1246 reader.Read(color);
1247 writer.Write(color);
1248 x--;
1251 // must be here, not in the if-branch (end of first row)
1252 x = width - 1;
1253 outRow += outBPR;
1254 reader.NextRow(inRowSkip);
1255 writer.SetTo(outRow);
1257 return error;
1260 // set_bits
1261 /*! \brief Helper function that reads bitmap data from one buffer and writes
1262 it (converted) to another one.
1263 \param Reader The pixel reader class.
1264 \param inData A pointer to the buffer to be read.
1265 \param inLength The length (in bytes) of the "in" buffer.
1266 \param inBPR The number of bytes per row in the "in" buffer.
1267 \param inRowSkip The number of bytes per row in the "in" buffer serving as
1268 padding.
1269 \param outData A pointer to the buffer to be written to.
1270 \param outLength The length (in bytes) of the "out" buffer.
1271 \param outOffset The offset (in bytes) relative to \a outData from which
1272 the function shall start writing.
1273 \param outBPR The number of bytes per row in the "out" buffer.
1274 \param rawOutBPR The number of bytes per row in the "out" buffer actually
1275 containing bitmap data (i.e. not including the padding).
1276 \param outColorSpace Color space of the target buffer.
1277 \param width The number of pixels per row in "in" and "out" data.
1278 \param reader A reader object. The pointer to the data doesn't need to
1279 be initialized.
1280 \param paletteConverter Reference to a PaletteConverter to be used, if
1281 a conversion from or to \c B_CMAP8 has to be done.
1282 \return \c B_OK, if everything went fine, an error code otherwise.
1284 template<typename Reader>
1285 static
1286 status_t
1287 set_bits(const void *inData, int32 inLength, int32 inBPR, int32 inRowSkip,
1288 void *outData, int32 outLength, int32 outOffset, int32 outBPR,
1289 int32 rawOutBPR, color_space outColorSpace, int32 width,
1290 Reader reader, const PaletteConverter &paletteConverter)
1292 status_t error = B_OK;
1293 switch (outColorSpace) {
1294 // supported
1295 case B_RGB32: case B_RGBA32:
1297 typedef RGB32Writer<rgb32_pixel> Writer;
1298 typedef typename Reader::preferred_color_value_t color_value_t;
1299 error = set_bits_worker<Reader, Writer, color_value_t>(
1300 inData, inLength, inBPR, inRowSkip, outData, outLength,
1301 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1302 break;
1304 case B_RGB32_BIG: case B_RGBA32_BIG:
1306 typedef RGB32Writer<rgb32_big_pixel> Writer;
1307 typedef typename Reader::preferred_color_value_t color_value_t;
1308 error = set_bits_worker<Reader, Writer, color_value_t>(
1309 inData, inLength, inBPR, inRowSkip, outData, outLength,
1310 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1311 break;
1313 case B_RGB24:
1315 typedef RGB24Writer<rgb24_pixel> Writer;
1316 typedef typename Reader::preferred_color_value_t color_value_t;
1317 error = set_bits_worker<Reader, Writer, color_value_t>(
1318 inData, inLength, inBPR, inRowSkip, outData, outLength,
1319 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1320 break;
1322 case B_RGB24_BIG:
1324 typedef RGB24Writer<rgb24_big_pixel> Writer;
1325 typedef typename Reader::preferred_color_value_t color_value_t;
1326 error = set_bits_worker<Reader, Writer, color_value_t>(
1327 inData, inLength, inBPR, inRowSkip, outData, outLength,
1328 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1329 break;
1331 case B_RGB16:
1333 typedef RGB16Writer<rgb16_pixel> Writer;
1334 typedef typename Reader::preferred_color_value_t color_value_t;
1335 error = set_bits_worker<Reader, Writer, color_value_t>(
1336 inData, inLength, inBPR, inRowSkip, outData, outLength,
1337 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1338 break;
1340 case B_RGB16_BIG:
1342 typedef RGB16Writer<rgb16_big_pixel> Writer;
1343 typedef typename Reader::preferred_color_value_t color_value_t;
1344 error = set_bits_worker<Reader, Writer, color_value_t>(
1345 inData, inLength, inBPR, inRowSkip, outData, outLength,
1346 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1347 break;
1349 case B_RGB15: case B_RGBA15:
1351 typedef RGB15Writer<rgb16_pixel> Writer;
1352 typedef typename Reader::preferred_color_value_t color_value_t;
1353 error = set_bits_worker<Reader, Writer, color_value_t>(
1354 inData, inLength, inBPR, inRowSkip, outData, outLength,
1355 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1356 break;
1358 case B_RGB15_BIG: case B_RGBA15_BIG:
1360 typedef RGB15Writer<rgb16_big_pixel> Writer;
1361 typedef typename Reader::preferred_color_value_t color_value_t;
1362 error = set_bits_worker<Reader, Writer, color_value_t>(
1363 inData, inLength, inBPR, inRowSkip, outData, outLength,
1364 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1365 break;
1367 case B_CMAP8:
1369 typedef CMAP8Writer Writer;
1370 typedef typename Reader::preferred_color_value_t color_value_t;
1371 error = set_bits_worker<Reader, Writer, color_value_t>(
1372 inData, inLength, inBPR, inRowSkip, outData, outLength,
1373 outOffset, outBPR, rawOutBPR, reader,
1374 Writer(outData, paletteConverter));
1375 break;
1377 case B_GRAY8:
1379 typedef Gray8Writer Writer;
1380 typedef gray_color_value color_value_t;
1381 error = set_bits_worker<Reader, Writer, color_value_t>(
1382 inData, inLength, inBPR, inRowSkip, outData, outLength,
1383 outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1384 break;
1386 case B_GRAY1:
1388 typedef Gray1Writer Writer;
1389 typedef gray_color_value color_value_t;
1390 error = set_bits_worker_gray1<Reader, Writer, color_value_t>(
1391 inData, inLength, inBPR, inRowSkip, outData, outLength,
1392 outOffset, outBPR, width, reader, Writer(outData));
1393 break;
1395 // unsupported
1396 case B_NO_COLOR_SPACE:
1397 case B_YUV9: case B_YUV12:
1398 case B_UVL32: case B_UVLA32:
1399 case B_LAB32: case B_LABA32:
1400 case B_HSI32: case B_HSIA32:
1401 case B_HSV32: case B_HSVA32:
1402 case B_HLS32: case B_HLSA32:
1403 case B_CMY32: case B_CMYA32: case B_CMYK32:
1404 case B_UVL24: case B_LAB24: case B_HSI24:
1405 case B_HSV24: case B_HLS24: case B_CMY24:
1406 case B_YCbCr422: case B_YUV422:
1407 case B_YCbCr411: case B_YUV411:
1408 case B_YCbCr444: case B_YUV444:
1409 case B_YCbCr420: case B_YUV420:
1410 default:
1411 error = B_BAD_VALUE;
1412 break;
1414 return error;
1418 // #pragma mark - Bitmap
1421 /*! \brief Creates and initializes a BBitmap.
1422 \param bounds The bitmap dimensions.
1423 \param flags Creation flags.
1424 \param colorSpace The bitmap's color space.
1425 \param bytesPerRow The number of bytes per row the bitmap should use.
1426 \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate
1427 value.
1428 \param screenID ???
1430 BBitmap::BBitmap(BRect bounds, uint32 flags, color_space colorSpace,
1431 int32 bytesPerRow, screen_id screenID)
1432 : fBasePtr(NULL),
1433 fSize(0),
1434 fColorSpace(B_NO_COLOR_SPACE),
1435 fBounds(0, 0, -1, -1),
1436 fBytesPerRow(0),
1437 fServerToken(-1),
1438 fToken(-1),
1439 fArea(-1),
1440 fOrigArea(-1),
1441 fFlags(0),
1442 fInitError(B_NO_INIT)
1444 InitObject(bounds, colorSpace, flags, bytesPerRow, screenID);
1448 /*! \brief Creates and initializes a BBitmap.
1449 \param bounds The bitmap dimensions.
1450 \param colorSpace The bitmap's color space.
1451 \param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if
1452 it shall be possible to attach BView to the bitmap and draw into
1454 \param needsContiguous If \c true a physically contiguous chunk of memory
1455 will be allocated.
1457 BBitmap::BBitmap(BRect bounds, color_space colorSpace, bool acceptsViews,
1458 bool needsContiguous)
1459 : fBasePtr(NULL),
1460 fSize(0),
1461 fColorSpace(B_NO_COLOR_SPACE),
1462 fBounds(0, 0, -1, -1),
1463 fBytesPerRow(0),
1464 fServerToken(-1),
1465 fToken(-1),
1466 fArea(-1),
1467 fOrigArea(-1),
1468 fFlags(0),
1469 fInitError(B_NO_INIT)
1471 int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0)
1472 | (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0);
1473 InitObject(bounds, colorSpace, flags, B_ANY_BYTES_PER_ROW,
1474 B_MAIN_SCREEN_ID);
1479 /*! \brief Creates a BBitmap as a clone of another bitmap.
1480 \param source The source bitmap.
1481 \param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if
1482 it shall be possible to attach BView to the bitmap and draw into
1484 \param needsContiguous If \c true a physically contiguous chunk of memory
1485 will be allocated.
1487 BBitmap::BBitmap(const BBitmap *source, bool acceptsViews,
1488 bool needsContiguous)
1489 : fBasePtr(NULL),
1490 fSize(0),
1491 fColorSpace(B_NO_COLOR_SPACE),
1492 fBounds(0, 0, -1, -1),
1493 fBytesPerRow(0),
1494 fServerToken(-1),
1495 fToken(-1),
1496 fArea(-1),
1497 fOrigArea(-1),
1498 fFlags(0),
1499 fInitError(B_NO_INIT)
1501 if (source && source->IsValid()) {
1502 int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0)
1503 | (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0);
1504 InitObject(source->Bounds(), source->ColorSpace(), flags,
1505 source->BytesPerRow(), B_MAIN_SCREEN_ID);
1506 if (InitCheck() == B_OK)
1507 memcpy(Bits(), source->Bits(), BytesPerRow());
1512 /*! \brief Frees all resources associated with this object. */
1513 BBitmap::~BBitmap()
1515 CleanUp();
1519 /*! \brief Unarchives a bitmap from a BMessage.
1520 \param data The archive.
1522 BBitmap::BBitmap(BMessage *data)
1523 : BArchivable(data),
1524 fBasePtr(NULL),
1525 fSize(0),
1526 fColorSpace(B_NO_COLOR_SPACE),
1527 fBounds(0, 0, -1, -1),
1528 fBytesPerRow(0),
1529 fServerToken(-1),
1530 fToken(-1),
1531 fArea(-1),
1532 fOrigArea(-1),
1533 fFlags(0),
1534 fInitError(B_NO_INIT)
1536 BRect bounds;
1537 data->FindRect("_frame", &bounds);
1539 color_space cspace;
1540 data->FindInt32("_cspace", (int32 *)&cspace);
1542 int32 flags = 0;
1543 data->FindInt32("_bmflags", &flags);
1545 int32 rowbytes = 0;
1546 data->FindInt32("_rowbytes", &rowbytes);
1548 flags |= B_BITMAP_NO_SERVER_LINK;
1549 flags &= ~B_BITMAP_ACCEPTS_VIEWS;
1550 InitObject(bounds, cspace, flags, rowbytes, B_MAIN_SCREEN_ID);
1552 if (data->HasData("_data", B_RAW_TYPE) && InitCheck() == B_OK) {
1553 ssize_t size = 0;
1554 const void *buffer;
1555 if (data->FindData("_data", B_RAW_TYPE, &buffer, &size) == B_OK)
1556 memcpy(fBasePtr, buffer, size);
1559 if (fFlags & B_BITMAP_ACCEPTS_VIEWS) {
1560 // BArchivable *obj;
1561 // BMessage message;
1562 // int i = 0;
1564 // while (data->FindMessage("_view", i++, &message) == B_OK) {
1565 // obj = instantiate_object(&message);
1566 // BView *view = dynamic_cast<BView *>(obj);
1568 // if (view)
1569 // AddChild(view);
1570 // }
1575 /*! \brief Instantiates a BBitmap from an archive.
1576 \param data The archive.
1577 \return A bitmap reconstructed from the archive or \c NULL, if an error
1578 occured.
1580 BArchivable *
1581 BBitmap::Instantiate(BMessage *data)
1583 if (validate_instantiation(data, "BBitmap"))
1584 return new BBitmap(data);
1586 return NULL;
1590 /*! \brief Archives the BBitmap object.
1591 \param data The archive.
1592 \param deep \c true, if child object shall be archived as well, \c false
1593 otherwise.
1594 \return \c B_OK, if everything went fine, an error code otherwise.
1596 status_t
1597 BBitmap::Archive(BMessage *data, bool deep) const
1599 BArchivable::Archive(data, deep);
1601 data->AddRect("_frame", fBounds);
1602 data->AddInt32("_cspace", (int32)fColorSpace);
1603 data->AddInt32("_bmflags", fFlags);
1604 data->AddInt32("_rowbytes", fBytesPerRow);
1606 if (deep) {
1607 if (fFlags & B_BITMAP_ACCEPTS_VIEWS) {
1608 // BMessage views;
1609 // for (int32 i = 0; i < CountChildren(); i++) {
1610 // if (ChildAt(i)->Archive(&views, deep))
1611 // data->AddMessage("_views", &views);
1612 // }
1614 // Note: R5 does not archive the data if B_BITMAP_IS_CONTIGNUOUS is
1615 // true and it does save all formats as B_RAW_TYPE and it does save
1616 // the data even if B_BITMAP_ACCEPTS_VIEWS is set (as opposed to
1617 // the BeBook)
1619 data->AddData("_data", B_RAW_TYPE, fBasePtr, fSize);
1622 return B_OK;
1626 /*! \brief Returns the result from the construction.
1627 \return \c B_OK, if the object is properly initialized, an error code
1628 otherwise.
1630 status_t
1631 BBitmap::InitCheck() const
1633 return fInitError;
1637 /*! \brief Returns whether or not the BBitmap object is valid.
1638 \return \c true, if the object is properly initialized, \c false otherwise.
1640 bool
1641 BBitmap::IsValid() const
1643 return (InitCheck() == B_OK);
1647 status_t
1648 BBitmap::LockBits(uint32 *state)
1650 return B_ERROR;
1654 void
1655 BBitmap::UnlockBits()
1660 /*! \brief Returns the ID of the area the bitmap data reside in.
1661 \return The ID of the area the bitmap data reside in.
1663 area_id
1664 BBitmap::Area() const
1666 return fArea;
1670 /*! \brief Returns the pointer to the bitmap data.
1671 \return The pointer to the bitmap data.
1673 void *
1674 BBitmap::Bits() const
1676 return fBasePtr;
1680 /*! \brief Returns the size of the bitmap data.
1681 \return The size of the bitmap data.
1683 int32
1684 BBitmap::BitsLength() const
1686 return fSize;
1690 /*! \brief Returns the number of bytes used to store a row of bitmap data.
1691 \return The number of bytes used to store a row of bitmap data.
1693 int32
1694 BBitmap::BytesPerRow() const
1696 return fBytesPerRow;
1700 /*! \brief Returns the bitmap's color space.
1701 \return The bitmap's color space.
1703 color_space
1704 BBitmap::ColorSpace() const
1706 return fColorSpace;
1710 /*! \brief Returns the bitmap's dimensions.
1711 \return The bitmap's dimensions.
1713 BRect
1714 BBitmap::Bounds() const
1716 return fBounds;
1720 /*! \brief Assigns data to the bitmap.
1722 Data are directly written into the bitmap's data buffer, being converted
1723 beforehand, if necessary. Some conversions work rather unintuitively:
1724 - \c B_RGB32: The source buffer is supposed to contain \c B_RGB24_BIG
1725 data without padding at the end of the rows.
1726 - \c B_RGB32: The source buffer is supposed to contain \c B_CMAP8
1727 data without padding at the end of the rows.
1728 - other color spaces: The source buffer is supposed to contain data
1729 according to the specified color space being rowwise padded to int32.
1731 The currently supported source/target color spaces are
1732 \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1734 \note As this methods is apparently a bit strange to use, OBOS introduces
1735 ImportBits() methods, which are recommended to be used instead.
1737 \param data The data to be copied.
1738 \param length The length in bytes of the data to be copied.
1739 \param offset The offset (in bytes) relative to beginning of the bitmap
1740 data specifying the position at which the source data shall be
1741 written.
1742 \param colorSpace Color space of the source data.
1744 void
1745 BBitmap::SetBits(const void *data, int32 length, int32 offset,
1746 color_space colorSpace)
1748 status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1749 // check params
1750 if (error == B_OK && (data == NULL || offset > fSize || length < 0))
1751 error = B_BAD_VALUE;
1752 int32 width = 0;
1753 if (error == B_OK)
1754 width = fBounds.IntegerWidth() + 1;
1755 int32 inBPR = -1;
1756 // tweaks to mimic R5 behavior
1757 if (error == B_OK) {
1758 // B_RGB32 means actually unpadded B_RGB24_BIG
1759 if (colorSpace == B_RGB32) {
1760 colorSpace = B_RGB24_BIG;
1761 inBPR = width * 3;
1762 // If in color space is B_CMAP8, but the bitmap's is another one,
1763 // ignore source data row padding.
1764 } else if (colorSpace == B_CMAP8 && fColorSpace != B_CMAP8)
1765 inBPR = width;
1767 // call the sane method, which does the actual work
1768 error = ImportBits(data, length, inBPR, offset, colorSpace);
1773 /*! \brief Assigns data to the bitmap.
1775 Data are directly written into the bitmap's data buffer, being converted
1776 beforehand, if necessary. Unlike for SetBits(), the meaning of
1777 \a colorSpace is exactly the expected one here, i.e. the source buffer
1778 is supposed to contain data of that color space. \a bpr specifies how
1779 many bytes the source contains per row. \c B_ANY_BYTES_PER_ROW can be
1780 supplied, if standard padding to int32 is used.
1782 The currently supported source/target color spaces are
1783 \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1785 \param data The data to be copied.
1786 \param length The length in bytes of the data to be copied.
1787 \param bpr The number of bytes per row in the source data.
1788 \param offset The offset (in bytes) relative to beginning of the bitmap
1789 data specifying the position at which the source data shall be
1790 written.
1791 \param colorSpace Color space of the source data.
1792 \return
1793 - \c B_OK: Everything went fine.
1794 - \c B_BAD_VALUE: \c NULL \a data, invalid \a bpr or \a offset, or
1795 unsupported \a colorSpace.
1797 status_t
1798 BBitmap::ImportBits(const void *data, int32 length, int32 bpr, int32 offset,
1799 color_space colorSpace)
1801 status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1802 // check params
1803 if (error == B_OK && (data == NULL || offset > fSize || length < 0))
1804 error = B_BAD_VALUE;
1805 // get BPR
1806 int32 width = 0;
1807 int32 inRowSkip = 0;
1808 if (error == B_OK) {
1809 width = fBounds.IntegerWidth() + 1;
1810 if (bpr < 0)
1811 bpr = get_bytes_per_row(colorSpace, width);
1812 inRowSkip = bpr - get_raw_bytes_per_row(colorSpace, width);
1813 if (inRowSkip < 0)
1814 error = B_BAD_VALUE;
1816 if (error != B_OK) {
1817 // catch error case
1818 } else if (colorSpace == fColorSpace && bpr == fBytesPerRow) {
1819 length = min(length, fSize - offset);
1820 memcpy((char*)fBasePtr + offset, data, length);
1821 } else {
1822 // TODO: Retrieve color map from BScreen, when available:
1823 // PaletteConverter paletteConverter(BScreen().ColorMap());
1824 const PaletteConverter &paletteConverter = *palette_converter();
1825 int32 rawOutBPR = get_raw_bytes_per_row(fColorSpace, width);
1826 switch (colorSpace) {
1827 // supported
1828 case B_RGB32: case B_RGBA32:
1830 typedef RGB24Reader<rgb32_pixel> Reader;
1831 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1832 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1833 fColorSpace, width, Reader(data), paletteConverter);
1834 break;
1836 case B_RGB32_BIG: case B_RGBA32_BIG:
1838 typedef RGB24Reader<rgb32_big_pixel> Reader;
1839 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1840 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1841 fColorSpace, width, Reader(data), paletteConverter);
1842 break;
1844 case B_RGB24:
1846 typedef RGB24Reader<rgb24_pixel> Reader;
1847 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1848 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1849 fColorSpace, width, Reader(data), paletteConverter);
1850 break;
1852 case B_RGB24_BIG:
1854 typedef RGB24Reader<rgb24_big_pixel> Reader;
1855 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1856 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1857 fColorSpace, width, Reader(data), paletteConverter);
1858 break;
1860 case B_RGB16:
1862 typedef RGB16Reader<rgb16_pixel> Reader;
1863 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1864 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1865 fColorSpace, width, Reader(data), paletteConverter);
1866 break;
1868 case B_RGB16_BIG:
1870 typedef RGB16Reader<rgb16_big_pixel> Reader;
1871 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1872 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1873 fColorSpace, width, Reader(data), paletteConverter);
1874 break;
1876 case B_RGB15: case B_RGBA15:
1878 typedef RGB15Reader<rgb16_pixel> Reader;
1879 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1880 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1881 fColorSpace, width, Reader(data), paletteConverter);
1882 break;
1884 case B_RGB15_BIG: case B_RGBA15_BIG:
1886 typedef RGB15Reader<rgb16_big_pixel> Reader;
1887 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1888 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1889 fColorSpace, width, Reader(data), paletteConverter);
1890 break;
1892 case B_CMAP8:
1894 typedef CMAP8Reader Reader;
1895 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1896 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1897 fColorSpace, width, Reader(data, paletteConverter),
1898 paletteConverter);
1899 break;
1901 case B_GRAY8:
1903 typedef Gray8Reader Reader;
1904 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1905 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1906 fColorSpace, width, Reader(data), paletteConverter);
1907 break;
1909 case B_GRAY1:
1911 typedef Gray1Reader Reader;
1912 error = set_bits<Reader>(data, length, bpr, inRowSkip,
1913 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1914 fColorSpace, width, Reader(data), paletteConverter);
1915 break;
1917 // unsupported
1918 case B_NO_COLOR_SPACE:
1919 case B_YUV9: case B_YUV12:
1920 case B_UVL32: case B_UVLA32:
1921 case B_LAB32: case B_LABA32:
1922 case B_HSI32: case B_HSIA32:
1923 case B_HSV32: case B_HSVA32:
1924 case B_HLS32: case B_HLSA32:
1925 case B_CMY32: case B_CMYA32: case B_CMYK32:
1926 case B_UVL24: case B_LAB24: case B_HSI24:
1927 case B_HSV24: case B_HLS24: case B_CMY24:
1928 case B_YCbCr422: case B_YUV422:
1929 case B_YCbCr411: case B_YUV411:
1930 case B_YCbCr444: case B_YUV444:
1931 case B_YCbCr420: case B_YUV420:
1932 default:
1933 error = B_BAD_VALUE;
1934 break;
1937 return error;
1941 /*! \briefly Assigns another bitmap's data to this bitmap.
1943 The supplied bitmap must have the exactly same dimensions as this bitmap.
1944 Its data are converted to the color space of this bitmap.
1946 The currently supported source/target color spaces are
1947 \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1949 \param bitmap The source bitmap.
1950 \return
1951 - \c B_OK: Everything went fine.
1952 - \c B_BAD_VALUE: \c NULL \a bitmap, or \a bitmap has other dimensions,
1953 or the conversion from or to one of the color spaces is not supported.
1955 status_t
1956 BBitmap::ImportBits(const BBitmap *bitmap)
1958 status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1959 // check param
1960 if (error == B_OK && bitmap == NULL)
1961 error = B_BAD_VALUE;
1962 if (error == B_OK && bitmap->InitCheck() != B_OK)
1963 error = B_BAD_VALUE;
1964 if (error == B_OK && bitmap->Bounds() != fBounds)
1965 error = B_BAD_VALUE;
1966 // set bits
1967 if (error == B_OK) {
1968 error = ImportBits(bitmap->Bits(), bitmap->BitsLength(),
1969 bitmap->BytesPerRow(), 0, bitmap->ColorSpace());
1971 return error;
1975 status_t
1976 BBitmap::GetOverlayRestrictions(overlay_restrictions *restrictions) const
1978 // TODO: Implement
1979 return B_ERROR;
1983 status_t
1984 BBitmap::Perform(perform_code d, void *arg)
1986 return BArchivable::Perform(d, arg);
1990 // FBC
1991 void BBitmap::_ReservedBitmap1() {}
1992 void BBitmap::_ReservedBitmap2() {}
1993 void BBitmap::_ReservedBitmap3() {}
1996 /*! \brief Privatized copy constructor to prevent usage.
1998 BBitmap::BBitmap(const BBitmap &)
2003 /*! \brief Privatized assignment operator to prevent usage.
2005 BBitmap &
2006 BBitmap::operator=(const BBitmap &)
2008 return *this;
2012 char *
2013 BBitmap::get_shared_pointer() const
2015 return NULL; // not implemented
2019 int32
2020 BBitmap::get_server_token() const
2022 return fServerToken;
2026 /*! \brief Initializes the bitmap.
2027 \param bounds The bitmap dimensions.
2028 \param colorSpace The bitmap's color space.
2029 \param flags Creation flags.
2030 \param bytesPerRow The number of bytes per row the bitmap should use.
2031 \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate
2032 value.
2033 \param screenID ???
2035 void
2036 BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags,
2037 int32 bytesPerRow, screen_id screenID)
2039 //printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n",
2040 // bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow);
2042 // TODO: Hanlde setting up the offscreen window if we're such a bitmap!
2044 // TODO: Should we handle rounding of the "bounds" here? How does R5 behave?
2046 status_t error = B_OK;
2048 //#ifdef RUN_WITHOUT_APP_SERVER
2049 flags |= B_BITMAP_NO_SERVER_LINK;
2050 //#endif // RUN_WITHOUT_APP_SERVER
2051 flags &= ~B_BITMAP_ACCEPTS_VIEWS;
2053 CleanUp();
2055 // check params
2056 if (!bounds.IsValid() || !bitmaps_support_space(colorSpace, NULL))
2057 error = B_BAD_VALUE;
2058 if (error == B_OK) {
2059 int32 bpr = get_bytes_per_row(colorSpace, bounds.IntegerWidth() + 1);
2060 if (bytesPerRow < 0)
2061 bytesPerRow = bpr;
2062 else if (bytesPerRow < bpr)
2063 // NOTE: How does R5 behave?
2064 error = B_BAD_VALUE;
2066 // allocate the bitmap buffer
2067 if (error == B_OK) {
2068 // NOTE: Maybe the code would look more robust if the
2069 // "size" was not calculated here when we ask the server
2070 // to allocate the bitmap. -Stephan
2071 int32 size = bytesPerRow * (bounds.IntegerHeight() + 1);
2073 if (flags & B_BITMAP_NO_SERVER_LINK) {
2074 fBasePtr = malloc(size);
2075 if (fBasePtr) {
2076 fSize = size;
2077 fColorSpace = colorSpace;
2078 fBounds = bounds;
2079 fBytesPerRow = bytesPerRow;
2080 fFlags = flags;
2081 } else
2082 error = B_NO_MEMORY;
2083 } else {
2084 // // Ask the server (via our owning application) to create a bitmap.
2085 // BPrivate::AppServerLink link;
2087 // // Attach Data:
2088 // // 1) BRect bounds
2089 // // 2) color_space space
2090 // // 3) int32 bitmap_flags
2091 // // 4) int32 bytes_per_row
2092 // // 5) int32 screen_id::id
2093 // link.StartMessage(AS_CREATE_BITMAP);
2094 // link.Attach<BRect>(bounds);
2095 // link.Attach<color_space>(colorSpace);
2096 // link.Attach<int32>((int32)flags);
2097 // link.Attach<int32>(bytesPerRow);
2098 // link.Attach<int32>(screenID.id);
2100 // // Reply Code: SERVER_TRUE
2101 // // Reply Data:
2102 // // 1) int32 server token
2103 // // 2) area_id id of the area in which the bitmap data resides
2104 // // 3) int32 area pointer offset used to calculate fBasePtr
2106 // // alternatively, if something went wrong
2107 // // Reply Code: SERVER_FALSE
2108 // // Reply Data:
2109 // // None
2110 // int32 code = SERVER_FALSE;
2111 // error = link.FlushWithReply(code);
2113 // if (error >= B_OK) {
2114 // // *communication* with server successful
2115 // if (code == SERVER_TRUE) {
2116 // // server side success
2117 // // Get token
2118 // area_id bmparea;
2119 // int32 areaoffset;
2121 // link.Read<int32>(&fServerToken);
2122 // link.Read<area_id>(&bmparea);
2123 // link.Read<int32>(&areaoffset);
2125 // // Get the area in which the data resides
2126 // fArea = clone_area("shared bitmap area",
2127 // (void**)&fBasePtr,
2128 // B_ANY_ADDRESS,
2129 // B_READ_AREA | B_WRITE_AREA,
2130 // bmparea);
2132 // // Jump to the location in the area
2133 // fBasePtr = (int8*)fBasePtr + areaoffset;
2135 // fSize = size;
2136 // fColorSpace = colorSpace;
2137 // fBounds = bounds;
2138 // fBytesPerRow = bytesPerRow;
2139 // fFlags = flags;
2140 // } else {
2141 // // server side error, we assume:
2142 // error = B_NO_MEMORY;
2143 // }
2144 // }
2145 // // NOTE: not "else" to handle B_NO_MEMORY on server side!
2146 // if (error < B_OK) {
2147 // fBasePtr = NULL;
2148 // fServerToken = -1;
2149 // fArea = -1;
2150 // // NOTE: why not "0" in case of error?
2151 // fFlags = flags;
2152 // }
2154 // fWindow = NULL;
2155 fToken = -1;
2156 fOrigArea = -1;
2159 fInitError = error;
2160 // TODO: on success, handle clearing to white if the flags say so. Needs to be
2161 // dependent on color space.
2163 if (fInitError == B_OK) {
2164 if (flags & B_BITMAP_ACCEPTS_VIEWS) {
2165 // fWindow = new BWindow(Bounds(), fServerToken);
2166 // // A BWindow starts life locked and is unlocked
2167 // // in Show(), but this window is never shown and
2168 // // it's message loop is never started.
2169 // fWindow->Unlock();
2175 /*! \brief Cleans up any memory allocated by the bitmap or
2176 informs the server to do so.
2178 void
2179 BBitmap::CleanUp()
2181 if (fBasePtr) {
2182 if (fFlags & B_BITMAP_NO_SERVER_LINK) {
2183 free(fBasePtr);
2184 } else {
2185 // BPrivate::AppServerLink link;
2186 // // AS_DELETE_BITMAP:
2187 // // Attached Data:
2188 // // 1) int32 server token
2190 // // Reply Code: SERVER_TRUE if successful,
2191 // // SERVER_FALSE if the buffer was already deleted
2192 // // Reply Data: none
2193 // // status_t freestat;
2194 // int32 code = SERVER_FALSE;
2195 // link.StartMessage(AS_DELETE_BITMAP);
2196 // link.Attach<int32>(fServerToken);
2197 // link.FlushWithReply(code);
2198 // if (code == SERVER_FALSE) {
2199 // // TODO: Find out if "SERVER_FALSE if the buffer
2200 // // was already deleted" is true. If not, maybe we
2201 // // need to take additional action.
2202 // }
2203 // fArea = -1;
2204 // fServerToken = -1;
2206 fBasePtr = NULL;
2211 void
2212 BBitmap::AssertPtr()