2 * Copyright 2001-2008, Haiku Inc.
3 * Distributed under the terms of the MIT License.
6 * Ingo Weinhold (bonefish@users.sf.net)
7 * DarkWyrm <bpmagic@columbus.rr.com>
8 * Stephan Aßmus <superstippi@gmx.de>
11 /*! BBitmap objects represent off-screen windows that contain bitmap data. */
20 #include <GraphicsDefs.h>
25 // structures defining the pixel layout
34 struct rgb32_big_pixel
{
47 struct rgb24_big_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
{
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
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.
177 get_raw_bytes_per_row(color_space colorSpace
, int32 width
)
180 switch (colorSpace
) {
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
:
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
:
197 case B_RGB16
: case B_RGB15
: case B_RGBA15
:
198 case B_RGB16_BIG
: case B_RGB15_BIG
: case B_RGBA15_BIG
:
201 case B_CMAP8
: case B_GRAY8
:
205 bpr
= (width
+ 7) / 8;
207 case B_YCbCr422
: case B_YUV422
:
208 bpr
= (width
+ 3) / 4 * 8;
210 case B_YCbCr411
: case B_YUV411
:
211 bpr
= (width
+ 3) / 4 * 6;
213 case B_YCbCr444
: case B_YUV444
:
214 bpr
= (width
+ 3) / 4 * 12;
216 case B_YCbCr420
: case B_YUV420
:
217 bpr
= (width
+ 3) / 4 * 6;
220 bpr
= (width
+ 15) / 16 * 18;
222 case B_NO_COLOR_SPACE
:
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.
238 get_bytes_per_row(color_space colorSpace
, int32 width
)
240 int32 bpr
= get_raw_bytes_per_row(colorSpace
, width
);
242 bpr
= (bpr
+ 3) & 0x7ffffffc;
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
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
,
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);
302 inverse_bit_mask(int32 bit
)
304 return ~bit_mask(bit
);
308 // #pragma mark - PaletteConverter
313 /*! \brief Helper class for conversion between RGB and palette colors.
315 class PaletteConverter
{
318 PaletteConverter(const rgb_color
*palette
);
319 PaletteConverter(const color_map
*colorMap
);
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;
343 const color_map
*fColorMap
;
344 color_map
*fOwnColorMap
;
348 } // namespace BPrivate
350 using BPrivate::PaletteConverter
;
354 /*! \brief Creates an uninitialized PaletteConverter.
356 PaletteConverter::PaletteConverter()
364 /*! \brief Creates a PaletteConverter and initializes it to the supplied
366 \param palette The palette being a 256 entry rgb_color array.
368 PaletteConverter::PaletteConverter(const rgb_color
*palette
)
377 /*! \brief Creates a PaletteConverter and initializes it to the supplied
379 \param colorMap The completely initialized color map.
381 PaletteConverter::PaletteConverter(const color_map
*colorMap
)
390 /*! \brief Frees all resources associated with this object.
392 PaletteConverter::~PaletteConverter()
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.
403 PaletteConverter::SetTo(const rgb_color
*palette
)
406 SetTo((const color_map
*)NULL
);
407 status_t error
= (palette
? B_OK
: B_BAD_VALUE
);
410 fOwnColorMap
= new(nothrow
) color_map
;
411 if (fOwnColorMap
== NULL
)
416 fColorMap
= fOwnColorMap
;
418 memcpy(fOwnColorMap
->color_list
, palette
, sizeof(rgb_color
) * 256);
420 for (int32 color
= 0; color
< 32768; color
++) {
422 uint8 red
= (color
& 0x7c00) >> 7;
423 uint8 green
= (color
& 0x3e0) >> 2;
424 uint8 blue
= (color
& 0x1f) << 3;
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
) {
437 closestDistance
= distance
;
440 fOwnColorMap
->index_map
[color
] = closestIndex
;
442 // no need to init inversion map
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.
454 PaletteConverter::SetTo(const color_map
*colorMap
)
462 fColorMap
= colorMap
;
463 fCStatus
= fColorMap
? B_OK
: B_BAD_VALUE
;
468 /*! \brief Returns the result of the last initialization via constructor or
470 \return \c B_OK, if the converter is properly initialized, an error code
474 PaletteConverter::InitCheck() const
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.
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.
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.
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.
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.
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.
567 PaletteConverter::IndexForRGB24(uint8 red
, uint8 green
, uint8 blue
) const
569 return fColorMap
->index_map
[((red
& 0xf8) << 7) | ((green
& 0xf8) << 2)
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.
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]).
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)
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]).
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)
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]).
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)
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
660 \param green Reference to the variable the green component shall be stored
662 \param blue Reference to the variable the blue component shall be stored
666 PaletteConverter::RGB24ColorForIndex(uint8 index
, uint8
&red
, uint8
&green
,
667 uint8
&blue
, uint8
&alpha
) const
669 const rgb_color
&color
= fColorMap
->color_list
[index
];
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.
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
*
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
715 template<typename _PixelType
>
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
;
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
;
746 BaseReader
<_PixelType
>::pixels
++;
749 inline void Read(gray_color_value
&gray
)
751 rgb_color_value color
;
753 gray
= brightness_for(color
.red
, color
.green
, color
.blue
);
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
)
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;
777 BaseReader
<_PixelType
>::pixels
++;
780 inline void Read(gray_color_value
&gray
)
782 rgb_color_value color
;
784 gray
= brightness_for(color
.red
, color
.green
, color
.blue
);
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]
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;
808 BaseReader
<_PixelType
>::pixels
++;
811 inline void Read(gray_color_value
&gray
)
813 rgb_color_value color
;
815 gray
= brightness_for(color
.red
, color
.green
, color
.blue
);
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
;
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
;
852 BaseReader
<uint8
>::pixels
++;
855 inline void Read(gray_color_value
&gray
)
857 gray
= *BaseReader
<uint8
>::pixels
;
858 BaseReader
<uint8
>::pixels
++;
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
;
874 inline void NextRow(int32 skip
)
877 pixels
= (const pixel_t
*)((const char*)pixels
+ skip
);
879 pixels
= (const pixel_t
*)((const char*)pixels
+ skip
+ 1);
884 inline void Read(rgb_color_value
&color
)
886 if (*pixels
& bit_mask(bit
))
887 color
.red
= color
.green
= color
.blue
= 255;
889 color
.red
= color
.green
= color
.blue
= 0;
898 inline void Read(gray_color_value
&gray
)
900 if (*pixels
& bit_mask(bit
))
915 // #pragma mark - Writer classes
919 template<typename _PixelType
>
921 typedef _PixelType pixel_t
;
923 BaseWriter(void *data
) : pixels((pixel_t
*)data
) {}
925 inline void SetTo(void *data
) { pixels
= (pixel_t
*)data
; }
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
;
956 BaseWriter
<_PixelType
>::pixels
++;
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
;
983 BaseWriter
<_PixelType
>::pixels
++;
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
)
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
++;
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
++;
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
);
1054 inline void Write(const gray_color_value
&gray
)
1056 *pixels
= converter
.IndexForGray(gray
);
1060 const PaletteConverter
&converter
;
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
);
1075 inline void Write(const gray_color_value
&gray
)
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
);
1101 inline void Write(const rgb_color_value
&color
)
1103 Write(brightness_for(color
.red
, color
.green
, color
.blue
));
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
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
1131 \param _writer A writer object. The pointer to the data doesn't need to
1133 \return \c B_OK, if everything went fine, an error code otherwise.
1135 template<typename Reader
, typename Writer
, typename color_value_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
) {
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
;
1164 writer
.Write(color
);
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
;
1173 writer
.Write(color
);
1176 // must be here, not in the if-branch (end of first row)
1178 outRowEnd
+= outBPR
;
1179 reader
.NextRow(inRowSkip
);
1180 writer
.SetTo(outRow
);
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
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
1205 \param _writer A writer object. The pointer to the data doesn't need to
1207 \return \c B_OK, if everything went fine, an error code otherwise.
1209 template<typename Reader
, typename Writer
, typename color_value_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
) {
1233 if ((const char*)reader
.pixels
<= inLastRow
) {
1234 // at least a complete row left
1236 color_value_t color
;
1238 writer
.Write(color
);
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
;
1247 writer
.Write(color
);
1251 // must be here, not in the if-branch (end of first row)
1254 reader
.NextRow(inRowSkip
);
1255 writer
.SetTo(outRow
);
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
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
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
>
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
) {
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
:
1411 error
= B_BAD_VALUE
;
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
1430 BBitmap::BBitmap(BRect bounds
, uint32 flags
, color_space colorSpace
,
1431 int32 bytesPerRow
, screen_id screenID
)
1434 fColorSpace(B_NO_COLOR_SPACE
),
1435 fBounds(0, 0, -1, -1),
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
1457 BBitmap::BBitmap(BRect bounds
, color_space colorSpace
, bool acceptsViews
,
1458 bool needsContiguous
)
1461 fColorSpace(B_NO_COLOR_SPACE
),
1462 fBounds(0, 0, -1, -1),
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
,
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
1487 BBitmap::BBitmap(const BBitmap
*source
, bool acceptsViews
,
1488 bool needsContiguous
)
1491 fColorSpace(B_NO_COLOR_SPACE
),
1492 fBounds(0, 0, -1, -1),
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. */
1519 /*! \brief Unarchives a bitmap from a BMessage.
1520 \param data The archive.
1522 BBitmap::BBitmap(BMessage
*data
)
1523 : BArchivable(data
),
1526 fColorSpace(B_NO_COLOR_SPACE
),
1527 fBounds(0, 0, -1, -1),
1534 fInitError(B_NO_INIT
)
1537 data
->FindRect("_frame", &bounds
);
1540 data
->FindInt32("_cspace", (int32
*)&cspace
);
1543 data
->FindInt32("_bmflags", &flags
);
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
) {
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;
1564 // while (data->FindMessage("_view", i++, &message) == B_OK) {
1565 // obj = instantiate_object(&message);
1566 // BView *view = dynamic_cast<BView *>(obj);
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
1581 BBitmap::Instantiate(BMessage
*data
)
1583 if (validate_instantiation(data
, "BBitmap"))
1584 return new BBitmap(data
);
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
1594 \return \c B_OK, if everything went fine, an error code otherwise.
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
);
1607 if (fFlags
& B_BITMAP_ACCEPTS_VIEWS
) {
1609 // for (int32 i = 0; i < CountChildren(); i++) {
1610 // if (ChildAt(i)->Archive(&views, deep))
1611 // data->AddMessage("_views", &views);
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
1619 data
->AddData("_data", B_RAW_TYPE
, fBasePtr
, fSize
);
1626 /*! \brief Returns the result from the construction.
1627 \return \c B_OK, if the object is properly initialized, an error code
1631 BBitmap::InitCheck() const
1637 /*! \brief Returns whether or not the BBitmap object is valid.
1638 \return \c true, if the object is properly initialized, \c false otherwise.
1641 BBitmap::IsValid() const
1643 return (InitCheck() == B_OK
);
1648 BBitmap::LockBits(uint32
*state
)
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.
1664 BBitmap::Area() const
1670 /*! \brief Returns the pointer to the bitmap data.
1671 \return The pointer to the bitmap data.
1674 BBitmap::Bits() const
1680 /*! \brief Returns the size of the bitmap data.
1681 \return The size of the bitmap data.
1684 BBitmap::BitsLength() const
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.
1694 BBitmap::BytesPerRow() const
1696 return fBytesPerRow
;
1700 /*! \brief Returns the bitmap's color space.
1701 \return The bitmap's color space.
1704 BBitmap::ColorSpace() const
1710 /*! \brief Returns the bitmap's dimensions.
1711 \return The bitmap's dimensions.
1714 BBitmap::Bounds() const
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
1742 \param colorSpace Color space of the source data.
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
);
1750 if (error
== B_OK
&& (data
== NULL
|| offset
> fSize
|| length
< 0))
1751 error
= B_BAD_VALUE
;
1754 width
= fBounds
.IntegerWidth() + 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
;
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
)
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
1791 \param colorSpace Color space of the source data.
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.
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
);
1803 if (error
== B_OK
&& (data
== NULL
|| offset
> fSize
|| length
< 0))
1804 error
= B_BAD_VALUE
;
1807 int32 inRowSkip
= 0;
1808 if (error
== B_OK
) {
1809 width
= fBounds
.IntegerWidth() + 1;
1811 bpr
= get_bytes_per_row(colorSpace
, width
);
1812 inRowSkip
= bpr
- get_raw_bytes_per_row(colorSpace
, width
);
1814 error
= B_BAD_VALUE
;
1816 if (error
!= B_OK
) {
1818 } else if (colorSpace
== fColorSpace
&& bpr
== fBytesPerRow
) {
1819 length
= min(length
, fSize
- offset
);
1820 memcpy((char*)fBasePtr
+ offset
, data
, length
);
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
) {
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
),
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
);
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
);
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
:
1933 error
= B_BAD_VALUE
;
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.
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.
1956 BBitmap::ImportBits(const BBitmap
*bitmap
)
1958 status_t error
= (InitCheck() == B_OK
? B_OK
: B_NO_INIT
);
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
;
1967 if (error
== B_OK
) {
1968 error
= ImportBits(bitmap
->Bits(), bitmap
->BitsLength(),
1969 bitmap
->BytesPerRow(), 0, bitmap
->ColorSpace());
1976 BBitmap::GetOverlayRestrictions(overlay_restrictions
*restrictions
) const
1984 BBitmap::Perform(perform_code d
, void *arg
)
1986 return BArchivable::Perform(d
, arg
);
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.
2006 BBitmap::operator=(const BBitmap
&)
2013 BBitmap::get_shared_pointer() const
2015 return NULL
; // not implemented
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
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
;
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)
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
);
2077 fColorSpace
= colorSpace
;
2079 fBytesPerRow
= bytesPerRow
;
2082 error
= B_NO_MEMORY
;
2084 // // Ask the server (via our owning application) to create a bitmap.
2085 // BPrivate::AppServerLink link;
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
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
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
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,
2129 // B_READ_AREA | B_WRITE_AREA,
2132 // // Jump to the location in the area
2133 // fBasePtr = (int8*)fBasePtr + areaoffset;
2136 // fColorSpace = colorSpace;
2137 // fBounds = bounds;
2138 // fBytesPerRow = bytesPerRow;
2141 // // server side error, we assume:
2142 // error = B_NO_MEMORY;
2145 // // NOTE: not "else" to handle B_NO_MEMORY on server side!
2146 // if (error < B_OK) {
2148 // fServerToken = -1;
2150 // // NOTE: why not "0" in case of 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.
2182 if (fFlags
& B_BITMAP_NO_SERVER_LINK
) {
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.
2204 // fServerToken = -1;
2212 BBitmap::AssertPtr()