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