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