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