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 color.alpha = 255; 744 BaseReader<_PixelType>::pixels++; 745 } 746 747 inline void Read(gray_color_value &gray) 748 { 749 rgb_color_value color; 750 Read(color); 751 gray = brightness_for(color.red, color.green, color.blue); 752 } 753 }; 754 755 // RGB16Reader 756 template<typename _PixelType> 757 struct RGB16Reader : public BaseReader<_PixelType> { 758 typedef rgb_color_value preferred_color_value_t; 759 typedef _PixelType pixel_t; 760 761 RGB16Reader(const void *data) : BaseReader<_PixelType>(data) {} 762 763 inline void Read(rgb_color_value &color) 764 { 765 // rg: R[4:0],G[5:3] 766 // gb: G[2:0],B[4:0] 767 const pixel_t &pixel = *BaseReader<_PixelType>::pixels; 768 color.red = pixel.rg & 0xf8; 769 color.green = ((pixel.rg & 0x07) << 5) & ((pixel.gb & 0xe0) >> 3); 770 color.blue = (pixel.gb & 0x1f) << 3; 771 color.red |= color.red >> 5; 772 color.green |= color.green >> 6; 773 color.blue |= color.blue >> 5; 774 color.alpha = 255; 775 BaseReader<_PixelType>::pixels++; 776 } 777 778 inline void Read(gray_color_value &gray) 779 { 780 rgb_color_value color; 781 Read(color); 782 gray = brightness_for(color.red, color.green, color.blue); 783 } 784 }; 785 786 // RGB15Reader 787 template<typename _PixelType> 788 struct RGB15Reader : public BaseReader<_PixelType> { 789 typedef rgb_color_value preferred_color_value_t; 790 typedef _PixelType pixel_t; 791 792 RGB15Reader(const void *data) : BaseReader<_PixelType>(data) {} 793 794 inline void Read(rgb_color_value &color) 795 { 796 // rg: -[0],R[4:0],G[4:3] 797 // gb: G[2:0],B[4:0] 798 const pixel_t &pixel = *BaseReader<_PixelType>::pixels; 799 color.red = (pixel.rg & 0x7c) << 1; 800 color.green = ((pixel.rg & 0x03) << 6) & ((pixel.gb & 0xe0) >> 2); 801 color.blue = (pixel.gb & 0x1f) << 3; 802 color.red |= color.red >> 5; 803 color.green |= color.green >> 5; 804 color.blue |= color.blue >> 5; 805 color.alpha = 255; 806 BaseReader<_PixelType>::pixels++; 807 } 808 809 inline void Read(gray_color_value &gray) 810 { 811 rgb_color_value color; 812 Read(color); 813 gray = brightness_for(color.red, color.green, color.blue); 814 } 815 }; 816 817 // CMAP8Reader 818 struct CMAP8Reader : public BaseReader<uint8> { 819 typedef rgb_color_value preferred_color_value_t; 820 821 CMAP8Reader(const void *data, const PaletteConverter &converter) 822 : BaseReader<uint8>(data), converter(converter) {} 823 824 inline void Read(rgb_color_value &color) 825 { 826 converter.RGB24ColorForIndex(*BaseReader<uint8>::pixels, color.red, color.green, 827 color.blue, color.alpha); 828 BaseReader<uint8>::pixels++; 829 } 830 831 inline void Read(gray_color_value &gray) 832 { 833 gray = converter.GrayColorForIndex(*BaseReader<uint8>::pixels); 834 BaseReader<uint8>::pixels++; 835 } 836 837 const PaletteConverter &converter; 838 }; 839 840 // Gray8Reader 841 struct Gray8Reader : public BaseReader<uint8> { 842 typedef gray_color_value preferred_color_value_t; 843 844 Gray8Reader(const void *data) : BaseReader<uint8>(data) {} 845 846 inline void Read(rgb_color_value &color) 847 { 848 color.red = color.green = color.blue = *BaseReader<uint8>::pixels; 849 color.alpha = 255; 850 BaseReader<uint8>::pixels++; 851 } 852 853 inline void Read(gray_color_value &gray) 854 { 855 gray = *BaseReader<uint8>::pixels; 856 BaseReader<uint8>::pixels++; 857 } 858 }; 859 860 // Gray1Reader 861 struct Gray1Reader : public BaseReader<uint8> { 862 typedef gray_color_value preferred_color_value_t; 863 864 Gray1Reader(const void *data) : BaseReader<uint8>(data), bit(7) {} 865 866 inline void SetTo(const void *data) 867 { 868 pixels = (const pixel_t*)data; 869 bit = 7; 870 } 871 872 inline void NextRow(int32 skip) 873 { 874 if (bit == 7) 875 pixels = (const pixel_t*)((const char*)pixels + skip); 876 else { 877 pixels = (const pixel_t*)((const char*)pixels + skip + 1); 878 bit = 7; 879 } 880 } 881 882 inline void Read(rgb_color_value &color) 883 { 884 if (*pixels & bit_mask(bit)) 885 color.red = color.green = color.blue = 255; 886 else 887 color.red = color.green = color.blue = 0; 888 color.alpha = 255; 889 bit--; 890 if (bit == -1) { 891 pixels++; 892 bit = 7; 893 } 894 } 895 896 inline void Read(gray_color_value &gray) 897 { 898 if (*pixels & bit_mask(bit)) 899 gray = 255; 900 else 901 gray = 0; 902 bit--; 903 if (bit == -1) { 904 pixels++; 905 bit = 7; 906 } 907 } 908 909 int32 bit; 910 }; 911 912 913 // #pragma mark - Writer classes 914 915 916 // BaseWriter 917 template<typename _PixelType> 918 struct BaseWriter { 919 typedef _PixelType pixel_t; 920 921 BaseWriter(void *data) : pixels((pixel_t*)data) {} 922 923 inline void SetTo(void *data) { pixels = (pixel_t*)data; } 924 925 pixel_t *pixels; 926 }; 927 928 929 // RGB32Writer 930 template<typename _PixelType> 931 struct RGB32Writer : public BaseWriter<_PixelType> { 932 typedef rgb_color_value preferred_color_value_t; 933 typedef _PixelType pixel_t; 934 935 RGB32Writer(void *data) : BaseWriter<_PixelType>(data) {} 936 937 inline void Write(const rgb_color_value &color) 938 { 939 pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 940 pixel.red = color.red; 941 pixel.green = color.green; 942 pixel.blue = color.blue; 943 pixel.alpha = color.alpha; 944 BaseWriter<_PixelType>::pixels++; 945 } 946 947 inline void Write(const gray_color_value &gray) 948 { 949 pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 950 pixel.red = gray; 951 pixel.green = gray; 952 pixel.blue = gray; 953 pixel.alpha = 255; 954 BaseWriter<_PixelType>::pixels++; 955 } 956 }; 957 958 // RGB24Writer 959 template<typename _PixelType> 960 struct RGB24Writer : public BaseWriter<_PixelType> { 961 typedef rgb_color_value preferred_color_value_t; 962 typedef _PixelType pixel_t; 963 964 RGB24Writer(void *data) : BaseWriter<_PixelType>(data) {} 965 966 inline void Write(const rgb_color_value &color) 967 { 968 pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 969 pixel.red = color.red; 970 pixel.green = color.green; 971 pixel.blue = color.blue; 972 BaseWriter<_PixelType>::pixels++; 973 } 974 975 inline void Write(const gray_color_value &gray) 976 { 977 pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 978 pixel.red = gray; 979 pixel.green = gray; 980 pixel.blue = gray; 981 BaseWriter<_PixelType>::pixels++; 982 } 983 }; 984 985 // RGB16Writer 986 template<typename _PixelType> 987 struct RGB16Writer : public BaseWriter<_PixelType> { 988 typedef rgb_color_value preferred_color_value_t; 989 typedef _PixelType pixel_t; 990 991 RGB16Writer(void *data) : BaseWriter<_PixelType>(data) {} 992 993 inline void Write(const rgb_color_value &color) 994 { 995 // rg: R[4:0],G[5:3] 996 // gb: G[2:0],B[4:0] 997 pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 998 pixel.rg = (color.red & 0xf8) | (color.green >> 5); 999 pixel.gb = ((color.green & 0x1c) << 3) | (color.blue >> 3); 1000 BaseWriter<_PixelType>::pixels++; 1001 } 1002 1003 inline void Write(const gray_color_value &gray) 1004 { 1005 pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 1006 pixel.rg = (gray & 0xf8) | (gray >> 5); 1007 pixel.gb = ((gray & 0x1c) << 3) | (gray >> 3); 1008 BaseWriter<_PixelType>::pixels++; 1009 } 1010 }; 1011 1012 // RGB15Writer 1013 template<typename _PixelType> 1014 struct RGB15Writer : public BaseWriter<_PixelType> { 1015 typedef rgb_color_value preferred_color_value_t; 1016 typedef _PixelType pixel_t; 1017 1018 RGB15Writer(void *data) : BaseWriter<_PixelType>(data) {} 1019 1020 inline void Write(const rgb_color_value &color) 1021 { 1022 // rg: -[0],R[4:0],G[4:3] 1023 // gb: G[2:0],B[4:0] 1024 pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 1025 pixel.rg = ((color.red & 0xf8) >> 1) | (color.green >> 6); 1026 pixel.gb = ((color.green & 0x38) << 2) | (color.blue >> 3); 1027 BaseWriter<_PixelType>::pixels++; 1028 } 1029 1030 inline void Write(const gray_color_value &gray) 1031 { 1032 pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 1033 pixel.rg = ((gray & 0xf8) >> 1) | (gray >> 6); 1034 pixel.gb = ((gray & 0x38) << 2) | (gray >> 3); 1035 BaseWriter<_PixelType>::pixels++; 1036 } 1037 }; 1038 1039 // CMAP8Writer 1040 struct CMAP8Writer : public BaseWriter<uint8> { 1041 typedef rgb_color_value preferred_color_value_t; 1042 1043 CMAP8Writer(void *data, const PaletteConverter &converter) 1044 : BaseWriter<uint8>(data), converter(converter) {} 1045 1046 inline void Write(const rgb_color_value &color) 1047 { 1048 *pixels = converter.IndexForRGB24(color.red, color.green, color.blue); 1049 pixels++; 1050 } 1051 1052 inline void Write(const gray_color_value &gray) 1053 { 1054 *pixels = converter.IndexForGray(gray); 1055 pixels++; 1056 } 1057 1058 const PaletteConverter &converter; 1059 }; 1060 1061 // Gray8Writer 1062 struct Gray8Writer : public BaseWriter<uint8> { 1063 typedef gray_color_value preferred_color_value_t; 1064 1065 Gray8Writer(void *data) : BaseWriter<uint8>(data) {} 1066 1067 inline void Write(const rgb_color_value &color) 1068 { 1069 *pixels = brightness_for(color.red, color.green, color.blue); 1070 pixels++; 1071 } 1072 1073 inline void Write(const gray_color_value &gray) 1074 { 1075 *pixels = gray; 1076 pixels++; 1077 } 1078 }; 1079 1080 // Gray1Writer 1081 struct Gray1Writer : public BaseWriter<uint8> { 1082 typedef gray_color_value preferred_color_value_t; 1083 1084 Gray1Writer(void *data) : BaseWriter<uint8>(data), bit(7) {} 1085 1086 inline void SetTo(void *data) { pixels = (pixel_t*)data; bit = 7; } 1087 1088 inline void Write(const gray_color_value &gray) 1089 { 1090 *pixels = (*pixels & inverse_bit_mask(bit)) 1091 | (gray & 0x80) >> (7 - bit); 1092 bit--; 1093 if (bit == -1) { 1094 pixels++; 1095 bit = 7; 1096 } 1097 } 1098 1099 inline void Write(const rgb_color_value &color) 1100 { 1101 Write(brightness_for(color.red, color.green, color.blue)); 1102 } 1103 1104 int32 bit; 1105 }; 1106 1107 1108 // set_bits_worker 1109 /*! \brief Worker function that reads bitmap data from one buffer and writes 1110 it (converted) to another one. 1111 \param Reader The pixel reader class. 1112 \param Writer The pixel writer class. 1113 \param color_value_t The color value type used to transport a pixel from 1114 the reader to the writer. 1115 \param inData A pointer to the buffer to be read. 1116 \param inLength The length (in bytes) of the "in" buffer. 1117 \param inBPR The number of bytes per row in the "in" buffer. 1118 \param inRowSkip The number of bytes per row in the "in" buffer serving as 1119 padding. 1120 \param outData A pointer to the buffer to be written to. 1121 \param outLength The length (in bytes) of the "out" buffer. 1122 \param outOffset The offset (in bytes) relative to \a outData from which 1123 the function shall start writing. 1124 \param outBPR The number of bytes per row in the "out" buffer. 1125 \param rawOutBPR The number of bytes per row in the "out" buffer actually 1126 containing bitmap data (i.e. not including the padding). 1127 \param _reader A reader object. The pointer to the data doesn't need to 1128 be initialized. 1129 \param _writer A writer object. The pointer to the data doesn't need to 1130 be initialized. 1131 \return \c B_OK, if everything went fine, an error code otherwise. 1132 */ 1133 template<typename Reader, typename Writer, typename color_value_t> 1134 static 1135 status_t 1136 set_bits_worker(const void *inData, int32 inLength, int32 inBPR, 1137 int32 inRowSkip, void *outData, int32 outLength, 1138 int32 outOffset, int32 outBPR, int32 rawOutBPR, 1139 Reader _reader, Writer _writer) 1140 { 1141 status_t error = B_OK; 1142 Reader reader(_reader); 1143 Writer writer(_writer); 1144 reader.SetTo(inData); 1145 writer.SetTo((char*)outData + outOffset); 1146 const char *inEnd = (const char*)inData + inLength 1147 - sizeof(typename Reader::pixel_t); 1148 const char *inLastRow = (const char*)inData + inLength 1149 - (inBPR - inRowSkip); 1150 const char *outEnd = (const char*)outData + outLength 1151 - sizeof(typename Writer::pixel_t); 1152 char *outRow = (char*)outData + outOffset - outOffset % outBPR; 1153 const char *outRowEnd = outRow + rawOutBPR - sizeof(typename Writer::pixel_t); 1154 while ((const char*)reader.pixels <= inEnd 1155 && (const char*)writer.pixels <= outEnd) { 1156 // process one row 1157 if ((const char*)reader.pixels <= inLastRow) { 1158 // at least a complete row left 1159 while ((const char*)writer.pixels <= outRowEnd) { 1160 color_value_t color; 1161 reader.Read(color); 1162 writer.Write(color); 1163 } 1164 } else { 1165 // no complete row left 1166 // but maybe the complete end of the first row 1167 while ((const char*)reader.pixels <= inEnd 1168 && (const char*)writer.pixels <= outRowEnd) { 1169 color_value_t color; 1170 reader.Read(color); 1171 writer.Write(color); 1172 } 1173 } 1174 // must be here, not in the if-branch (end of first row) 1175 outRow += outBPR; 1176 outRowEnd += outBPR; 1177 reader.NextRow(inRowSkip); 1178 writer.SetTo(outRow); 1179 } 1180 return error; 1181 } 1182 1183 // set_bits_worker_gray1 1184 /*! \brief Worker function that reads bitmap data from one buffer and writes 1185 it (converted) to another one, which uses color space \c B_GRAY1. 1186 \param Reader The pixel reader class. 1187 \param Writer The pixel writer class. 1188 \param color_value_t The color value type used to transport a pixel from 1189 the reader to the writer. 1190 \param inData A pointer to the buffer to be read. 1191 \param inLength The length (in bytes) of the "in" buffer. 1192 \param inBPR The number of bytes per row in the "in" buffer. 1193 \param inRowSkip The number of bytes per row in the "in" buffer serving as 1194 padding. 1195 \param outData A pointer to the buffer to be written to. 1196 \param outLength The length (in bytes) of the "out" buffer. 1197 \param outOffset The offset (in bytes) relative to \a outData from which 1198 the function shall start writing. 1199 \param outBPR The number of bytes per row in the "out" buffer. 1200 \param width The number of pixels per row in "in" and "out" data. 1201 \param _reader A reader object. The pointer to the data doesn't need to 1202 be initialized. 1203 \param _writer A writer object. The pointer to the data doesn't need to 1204 be initialized. 1205 \return \c B_OK, if everything went fine, an error code otherwise. 1206 */ 1207 template<typename Reader, typename Writer, typename color_value_t> 1208 static 1209 status_t 1210 set_bits_worker_gray1(const void *inData, int32 inLength, int32 inBPR, 1211 int32 inRowSkip, void *outData, int32 outLength, 1212 int32 outOffset, int32 outBPR, int32 width, 1213 Reader _reader, Writer _writer) 1214 { 1215 status_t error = B_OK; 1216 Reader reader(_reader); 1217 Writer writer(_writer); 1218 reader.SetTo(inData); 1219 writer.SetTo((char*)outData + outOffset); 1220 const char *inEnd = (const char*)inData + inLength 1221 - sizeof(typename Reader::pixel_t); 1222 const char *inLastRow = (const char*)inData + inLength 1223 - (inBPR - inRowSkip); 1224 const char *outEnd = (const char*)outData + outLength - outBPR; 1225 char *outRow = (char*)outData + outOffset - outOffset % outBPR; 1226 int32 x = max((int32)0, 1227 width - (int32)((char*)outData + outOffset - outRow) * 8) - 1; 1228 while ((const char*)reader.pixels <= inEnd 1229 && (const char*)writer.pixels <= outEnd) { 1230 // process one row 1231 if ((const char*)reader.pixels <= inLastRow) { 1232 // at least a complete row left 1233 while (x >= 0) { 1234 color_value_t color; 1235 reader.Read(color); 1236 writer.Write(color); 1237 x--; 1238 } 1239 } else { 1240 // no complete row left 1241 // but maybe the complete end of the first row 1242 while ((const char*)reader.pixels <= inEnd && x >= 0) { 1243 color_value_t color; 1244 reader.Read(color); 1245 writer.Write(color); 1246 x--; 1247 } 1248 } 1249 // must be here, not in the if-branch (end of first row) 1250 x = width - 1; 1251 outRow += outBPR; 1252 reader.NextRow(inRowSkip); 1253 writer.SetTo(outRow); 1254 } 1255 return error; 1256 } 1257 1258 // set_bits 1259 /*! \brief Helper function that reads bitmap data from one buffer and writes 1260 it (converted) to another one. 1261 \param Reader The pixel reader class. 1262 \param inData A pointer to the buffer to be read. 1263 \param inLength The length (in bytes) of the "in" buffer. 1264 \param inBPR The number of bytes per row in the "in" buffer. 1265 \param inRowSkip The number of bytes per row in the "in" buffer serving as 1266 padding. 1267 \param outData A pointer to the buffer to be written to. 1268 \param outLength The length (in bytes) of the "out" buffer. 1269 \param outOffset The offset (in bytes) relative to \a outData from which 1270 the function shall start writing. 1271 \param outBPR The number of bytes per row in the "out" buffer. 1272 \param rawOutBPR The number of bytes per row in the "out" buffer actually 1273 containing bitmap data (i.e. not including the padding). 1274 \param outColorSpace Color space of the target buffer. 1275 \param width The number of pixels per row in "in" and "out" data. 1276 \param reader A reader object. The pointer to the data doesn't need to 1277 be initialized. 1278 \param paletteConverter Reference to a PaletteConverter to be used, if 1279 a conversion from or to \c B_CMAP8 has to be done. 1280 \return \c B_OK, if everything went fine, an error code otherwise. 1281 */ 1282 template<typename Reader> 1283 static 1284 status_t 1285 set_bits(const void *inData, int32 inLength, int32 inBPR, int32 inRowSkip, 1286 void *outData, int32 outLength, int32 outOffset, int32 outBPR, 1287 int32 rawOutBPR, color_space outColorSpace, int32 width, 1288 Reader reader, const PaletteConverter &paletteConverter) 1289 { 1290 status_t error = B_OK; 1291 switch (outColorSpace) { 1292 // supported 1293 case B_RGB32: case B_RGBA32: 1294 { 1295 typedef RGB32Writer<rgb32_pixel> Writer; 1296 typedef typename Reader::preferred_color_value_t color_value_t; 1297 error = set_bits_worker<Reader, Writer, color_value_t>( 1298 inData, inLength, inBPR, inRowSkip, outData, outLength, 1299 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1300 break; 1301 } 1302 case B_RGB32_BIG: case B_RGBA32_BIG: 1303 { 1304 typedef RGB32Writer<rgb32_big_pixel> Writer; 1305 typedef typename Reader::preferred_color_value_t color_value_t; 1306 error = set_bits_worker<Reader, Writer, color_value_t>( 1307 inData, inLength, inBPR, inRowSkip, outData, outLength, 1308 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1309 break; 1310 } 1311 case B_RGB24: 1312 { 1313 typedef RGB24Writer<rgb24_pixel> Writer; 1314 typedef typename Reader::preferred_color_value_t color_value_t; 1315 error = set_bits_worker<Reader, Writer, color_value_t>( 1316 inData, inLength, inBPR, inRowSkip, outData, outLength, 1317 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1318 break; 1319 } 1320 case B_RGB24_BIG: 1321 { 1322 typedef RGB24Writer<rgb24_big_pixel> Writer; 1323 typedef typename Reader::preferred_color_value_t color_value_t; 1324 error = set_bits_worker<Reader, Writer, color_value_t>( 1325 inData, inLength, inBPR, inRowSkip, outData, outLength, 1326 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1327 break; 1328 } 1329 case B_RGB16: 1330 { 1331 typedef RGB16Writer<rgb16_pixel> Writer; 1332 typedef typename Reader::preferred_color_value_t color_value_t; 1333 error = set_bits_worker<Reader, Writer, color_value_t>( 1334 inData, inLength, inBPR, inRowSkip, outData, outLength, 1335 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1336 break; 1337 } 1338 case B_RGB16_BIG: 1339 { 1340 typedef RGB16Writer<rgb16_big_pixel> Writer; 1341 typedef typename Reader::preferred_color_value_t color_value_t; 1342 error = set_bits_worker<Reader, Writer, color_value_t>( 1343 inData, inLength, inBPR, inRowSkip, outData, outLength, 1344 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1345 break; 1346 } 1347 case B_RGB15: case B_RGBA15: 1348 { 1349 typedef RGB15Writer<rgb16_pixel> Writer; 1350 typedef typename Reader::preferred_color_value_t color_value_t; 1351 error = set_bits_worker<Reader, Writer, color_value_t>( 1352 inData, inLength, inBPR, inRowSkip, outData, outLength, 1353 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1354 break; 1355 } 1356 case B_RGB15_BIG: case B_RGBA15_BIG: 1357 { 1358 typedef RGB15Writer<rgb16_big_pixel> Writer; 1359 typedef typename Reader::preferred_color_value_t color_value_t; 1360 error = set_bits_worker<Reader, Writer, color_value_t>( 1361 inData, inLength, inBPR, inRowSkip, outData, outLength, 1362 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1363 break; 1364 } 1365 case B_CMAP8: 1366 { 1367 typedef CMAP8Writer Writer; 1368 typedef typename Reader::preferred_color_value_t color_value_t; 1369 error = set_bits_worker<Reader, Writer, color_value_t>( 1370 inData, inLength, inBPR, inRowSkip, outData, outLength, 1371 outOffset, outBPR, rawOutBPR, reader, 1372 Writer(outData, paletteConverter)); 1373 break; 1374 } 1375 case B_GRAY8: 1376 { 1377 typedef Gray8Writer Writer; 1378 typedef gray_color_value color_value_t; 1379 error = set_bits_worker<Reader, Writer, color_value_t>( 1380 inData, inLength, inBPR, inRowSkip, outData, outLength, 1381 outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1382 break; 1383 } 1384 case B_GRAY1: 1385 { 1386 typedef Gray1Writer Writer; 1387 typedef gray_color_value color_value_t; 1388 error = set_bits_worker_gray1<Reader, Writer, color_value_t>( 1389 inData, inLength, inBPR, inRowSkip, outData, outLength, 1390 outOffset, outBPR, width, reader, Writer(outData)); 1391 break; 1392 } 1393 // unsupported 1394 case B_NO_COLOR_SPACE: 1395 case B_YUV9: case B_YUV12: 1396 case B_UVL32: case B_UVLA32: 1397 case B_LAB32: case B_LABA32: 1398 case B_HSI32: case B_HSIA32: 1399 case B_HSV32: case B_HSVA32: 1400 case B_HLS32: case B_HLSA32: 1401 case B_CMY32: case B_CMYA32: case B_CMYK32: 1402 case B_UVL24: case B_LAB24: case B_HSI24: 1403 case B_HSV24: case B_HLS24: case B_CMY24: 1404 case B_YCbCr422: case B_YUV422: 1405 case B_YCbCr411: case B_YUV411: 1406 case B_YCbCr444: case B_YUV444: 1407 case B_YCbCr420: case B_YUV420: 1408 default: 1409 error = B_BAD_VALUE; 1410 break; 1411 } 1412 return error; 1413 } 1414 1415 1416 // #pragma mark - Bitmap 1417 1418 1419 /*! \brief Creates and initializes a BBitmap. 1420 \param bounds The bitmap dimensions. 1421 \param flags Creation flags. 1422 \param colorSpace The bitmap's color space. 1423 \param bytesPerRow The number of bytes per row the bitmap should use. 1424 \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate 1425 value. 1426 \param screenID ??? 1427 */ 1428 BBitmap::BBitmap(BRect bounds, uint32 flags, color_space colorSpace, 1429 int32 bytesPerRow, screen_id screenID) 1430 : fBasePtr(NULL), 1431 fSize(0), 1432 fColorSpace(B_NO_COLOR_SPACE), 1433 fBounds(0, 0, -1, -1), 1434 fBytesPerRow(0), 1435 fServerToken(-1), 1436 fToken(-1), 1437 fArea(-1), 1438 fOrigArea(-1), 1439 fFlags(0), 1440 fInitError(B_NO_INIT) 1441 { 1442 InitObject(bounds, colorSpace, flags, bytesPerRow, screenID); 1443 } 1444 1445 1446 /*! \brief Creates and initializes a BBitmap. 1447 \param bounds The bitmap dimensions. 1448 \param colorSpace The bitmap's color space. 1449 \param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if 1450 it shall be possible to attach BView to the bitmap and draw into 1451 it. 1452 \param needsContiguous If \c true a physically contiguous chunk of memory 1453 will be allocated. 1454 */ 1455 BBitmap::BBitmap(BRect bounds, color_space colorSpace, bool acceptsViews, 1456 bool needsContiguous) 1457 : fBasePtr(NULL), 1458 fSize(0), 1459 fColorSpace(B_NO_COLOR_SPACE), 1460 fBounds(0, 0, -1, -1), 1461 fBytesPerRow(0), 1462 fServerToken(-1), 1463 fToken(-1), 1464 fArea(-1), 1465 fOrigArea(-1), 1466 fFlags(0), 1467 fInitError(B_NO_INIT) 1468 { 1469 int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0) 1470 | (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0); 1471 InitObject(bounds, colorSpace, flags, B_ANY_BYTES_PER_ROW, 1472 B_MAIN_SCREEN_ID); 1473 1474 } 1475 1476 1477 /*! \brief Creates a BBitmap as a clone of another bitmap. 1478 \param source The source bitmap. 1479 \param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if 1480 it shall be possible to attach BView to the bitmap and draw into 1481 it. 1482 \param needsContiguous If \c true a physically contiguous chunk of memory 1483 will be allocated. 1484 */ 1485 BBitmap::BBitmap(const BBitmap *source, bool acceptsViews, 1486 bool needsContiguous) 1487 : fBasePtr(NULL), 1488 fSize(0), 1489 fColorSpace(B_NO_COLOR_SPACE), 1490 fBounds(0, 0, -1, -1), 1491 fBytesPerRow(0), 1492 fServerToken(-1), 1493 fToken(-1), 1494 fArea(-1), 1495 fOrigArea(-1), 1496 fFlags(0), 1497 fInitError(B_NO_INIT) 1498 { 1499 if (source && source->IsValid()) { 1500 int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0) 1501 | (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0); 1502 InitObject(source->Bounds(), source->ColorSpace(), flags, 1503 source->BytesPerRow(), B_MAIN_SCREEN_ID); 1504 if (InitCheck() == B_OK) 1505 memcpy(Bits(), source->Bits(), BytesPerRow()); 1506 } 1507 } 1508 1509 1510 /*! \brief Frees all resources associated with this object. */ 1511 BBitmap::~BBitmap() 1512 { 1513 CleanUp(); 1514 } 1515 1516 1517 /*! \brief Unarchives a bitmap from a BMessage. 1518 \param data The archive. 1519 */ 1520 BBitmap::BBitmap(BMessage *data) 1521 : BArchivable(data), 1522 fBasePtr(NULL), 1523 fSize(0), 1524 fColorSpace(B_NO_COLOR_SPACE), 1525 fBounds(0, 0, -1, -1), 1526 fBytesPerRow(0), 1527 fServerToken(-1), 1528 fToken(-1), 1529 fArea(-1), 1530 fOrigArea(-1), 1531 fFlags(0), 1532 fInitError(B_NO_INIT) 1533 { 1534 BRect bounds; 1535 data->FindRect("_frame", &bounds); 1536 1537 color_space cspace; 1538 data->FindInt32("_cspace", (int32 *)&cspace); 1539 1540 int32 flags = 0; 1541 data->FindInt32("_bmflags", &flags); 1542 1543 int32 rowbytes = 0; 1544 data->FindInt32("_rowbytes", &rowbytes); 1545 1546 flags |= B_BITMAP_NO_SERVER_LINK; 1547 flags &= ~B_BITMAP_ACCEPTS_VIEWS; 1548 InitObject(bounds, cspace, flags, rowbytes, B_MAIN_SCREEN_ID); 1549 1550 if (data->HasData("_data", B_RAW_TYPE) && InitCheck() == B_OK) { 1551 ssize_t size = 0; 1552 const void *buffer; 1553 if (data->FindData("_data", B_RAW_TYPE, &buffer, &size) == B_OK) 1554 memcpy(fBasePtr, buffer, size); 1555 } 1556 1557 if (fFlags & B_BITMAP_ACCEPTS_VIEWS) { 1558 // BArchivable *obj; 1559 // BMessage message; 1560 // int i = 0; 1561 // 1562 // while (data->FindMessage("_view", i++, &message) == B_OK) { 1563 // obj = instantiate_object(&message); 1564 // BView *view = dynamic_cast<BView *>(obj); 1565 // 1566 // if (view) 1567 // AddChild(view); 1568 // } 1569 } 1570 } 1571 1572 1573 /*! \brief Instantiates a BBitmap from an archive. 1574 \param data The archive. 1575 \return A bitmap reconstructed from the archive or \c NULL, if an error 1576 occured. 1577 */ 1578 BArchivable * 1579 BBitmap::Instantiate(BMessage *data) 1580 { 1581 if (validate_instantiation(data, "BBitmap")) 1582 return new BBitmap(data); 1583 1584 return NULL; 1585 } 1586 1587 1588 /*! \brief Archives the BBitmap object. 1589 \param data The archive. 1590 \param deep \c true, if child object shall be archived as well, \c false 1591 otherwise. 1592 \return \c B_OK, if everything went fine, an error code otherwise. 1593 */ 1594 status_t 1595 BBitmap::Archive(BMessage *data, bool deep) const 1596 { 1597 BArchivable::Archive(data, deep); 1598 1599 data->AddRect("_frame", fBounds); 1600 data->AddInt32("_cspace", (int32)fColorSpace); 1601 data->AddInt32("_bmflags", fFlags); 1602 data->AddInt32("_rowbytes", fBytesPerRow); 1603 1604 if (deep) { 1605 if (fFlags & B_BITMAP_ACCEPTS_VIEWS) { 1606 // BMessage views; 1607 // for (int32 i = 0; i < CountChildren(); i++) { 1608 // if (ChildAt(i)->Archive(&views, deep)) 1609 // data->AddMessage("_views", &views); 1610 // } 1611 } 1612 // Note: R5 does not archive the data if B_BITMAP_IS_CONTIGNUOUS is 1613 // true and it does save all formats as B_RAW_TYPE and it does save 1614 // the data even if B_BITMAP_ACCEPTS_VIEWS is set (as opposed to 1615 // the BeBook) 1616 1617 data->AddData("_data", B_RAW_TYPE, fBasePtr, fSize); 1618 } 1619 1620 return B_OK; 1621 } 1622 1623 1624 /*! \brief Returns the result from the construction. 1625 \return \c B_OK, if the object is properly initialized, an error code 1626 otherwise. 1627 */ 1628 status_t 1629 BBitmap::InitCheck() const 1630 { 1631 return fInitError; 1632 } 1633 1634 1635 /*! \brief Returns whether or not the BBitmap object is valid. 1636 \return \c true, if the object is properly initialized, \c false otherwise. 1637 */ 1638 bool 1639 BBitmap::IsValid() const 1640 { 1641 return (InitCheck() == B_OK); 1642 } 1643 1644 1645 status_t 1646 BBitmap::LockBits(uint32 *state) 1647 { 1648 return B_ERROR; 1649 } 1650 1651 1652 void 1653 BBitmap::UnlockBits() 1654 { 1655 } 1656 1657 1658 /*! \brief Returns the ID of the area the bitmap data reside in. 1659 \return The ID of the area the bitmap data reside in. 1660 */ 1661 area_id 1662 BBitmap::Area() const 1663 { 1664 return fArea; 1665 } 1666 1667 1668 /*! \brief Returns the pointer to the bitmap data. 1669 \return The pointer to the bitmap data. 1670 */ 1671 void * 1672 BBitmap::Bits() const 1673 { 1674 return fBasePtr; 1675 } 1676 1677 1678 /*! \brief Returns the size of the bitmap data. 1679 \return The size of the bitmap data. 1680 */ 1681 int32 1682 BBitmap::BitsLength() const 1683 { 1684 return fSize; 1685 } 1686 1687 1688 /*! \brief Returns the number of bytes used to store a row of bitmap data. 1689 \return The number of bytes used to store a row of bitmap data. 1690 */ 1691 int32 1692 BBitmap::BytesPerRow() const 1693 { 1694 return fBytesPerRow; 1695 } 1696 1697 1698 /*! \brief Returns the bitmap's color space. 1699 \return The bitmap's color space. 1700 */ 1701 color_space 1702 BBitmap::ColorSpace() const 1703 { 1704 return fColorSpace; 1705 } 1706 1707 1708 /*! \brief Returns the bitmap's dimensions. 1709 \return The bitmap's dimensions. 1710 */ 1711 BRect 1712 BBitmap::Bounds() const 1713 { 1714 return fBounds; 1715 } 1716 1717 1718 /*! \brief Assigns data to the bitmap. 1719 1720 Data are directly written into the bitmap's data buffer, being converted 1721 beforehand, if necessary. Some conversions work rather unintuitively: 1722 - \c B_RGB32: The source buffer is supposed to contain \c B_RGB24_BIG 1723 data without padding at the end of the rows. 1724 - \c B_RGB32: The source buffer is supposed to contain \c B_CMAP8 1725 data without padding at the end of the rows. 1726 - other color spaces: The source buffer is supposed to contain data 1727 according to the specified color space being rowwise padded to int32. 1728 1729 The currently supported source/target color spaces are 1730 \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}. 1731 1732 \note As this methods is apparently a bit strange to use, OBOS introduces 1733 ImportBits() methods, which are recommended to be used instead. 1734 1735 \param data The data to be copied. 1736 \param length The length in bytes of the data to be copied. 1737 \param offset The offset (in bytes) relative to beginning of the bitmap 1738 data specifying the position at which the source data shall be 1739 written. 1740 \param colorSpace Color space of the source data. 1741 */ 1742 void 1743 BBitmap::SetBits(const void *data, int32 length, int32 offset, 1744 color_space colorSpace) 1745 { 1746 status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT); 1747 // check params 1748 if (error == B_OK && (data == NULL || offset > fSize || length < 0)) 1749 error = B_BAD_VALUE; 1750 int32 width = 0; 1751 if (error == B_OK) 1752 width = fBounds.IntegerWidth() + 1; 1753 int32 inBPR = -1; 1754 // tweaks to mimic R5 behavior 1755 if (error == B_OK) { 1756 // B_RGB32 means actually unpadded B_RGB24_BIG 1757 if (colorSpace == B_RGB32) { 1758 colorSpace = B_RGB24_BIG; 1759 inBPR = width * 3; 1760 // If in color space is B_CMAP8, but the bitmap's is another one, 1761 // ignore source data row padding. 1762 } else if (colorSpace == B_CMAP8 && fColorSpace != B_CMAP8) 1763 inBPR = width; 1764 } 1765 // call the sane method, which does the actual work 1766 if (error == B_OK) 1767 error = ImportBits(data, length, inBPR, offset, colorSpace); 1768 } 1769 1770 1771 /*! \brief Assigns data to the bitmap. 1772 1773 Data are directly written into the bitmap's data buffer, being converted 1774 beforehand, if necessary. Unlike for SetBits(), the meaning of 1775 \a colorSpace is exactly the expected one here, i.e. the source buffer 1776 is supposed to contain data of that color space. \a bpr specifies how 1777 many bytes the source contains per row. \c B_ANY_BYTES_PER_ROW can be 1778 supplied, if standard padding to int32 is used. 1779 1780 The currently supported source/target color spaces are 1781 \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}. 1782 1783 \param data The data to be copied. 1784 \param length The length in bytes of the data to be copied. 1785 \param bpr The number of bytes per row in the source data. 1786 \param offset The offset (in bytes) relative to beginning of the bitmap 1787 data specifying the position at which the source data shall be 1788 written. 1789 \param colorSpace Color space of the source data. 1790 \return 1791 - \c B_OK: Everything went fine. 1792 - \c B_BAD_VALUE: \c NULL \a data, invalid \a bpr or \a offset, or 1793 unsupported \a colorSpace. 1794 */ 1795 status_t 1796 BBitmap::ImportBits(const void *data, int32 length, int32 bpr, int32 offset, 1797 color_space colorSpace) 1798 { 1799 status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT); 1800 // check params 1801 if (error == B_OK && (data == NULL || offset > fSize || length < 0)) 1802 error = B_BAD_VALUE; 1803 // get BPR 1804 int32 width = 0; 1805 int32 inRowSkip = 0; 1806 if (error == B_OK) { 1807 width = fBounds.IntegerWidth() + 1; 1808 if (bpr < 0) 1809 bpr = get_bytes_per_row(colorSpace, width); 1810 inRowSkip = bpr - get_raw_bytes_per_row(colorSpace, width); 1811 if (inRowSkip < 0) 1812 error = B_BAD_VALUE; 1813 } 1814 if (error != B_OK) { 1815 // catch error case 1816 } else if (colorSpace == fColorSpace && bpr == fBytesPerRow) { 1817 length = min(length, fSize - offset); 1818 memcpy((char*)fBasePtr + offset, data, length); 1819 } else { 1820 // TODO: Retrieve color map from BScreen, when available: 1821 // PaletteConverter paletteConverter(BScreen().ColorMap()); 1822 const PaletteConverter &paletteConverter = *palette_converter(); 1823 int32 rawOutBPR = get_raw_bytes_per_row(fColorSpace, width); 1824 switch (colorSpace) { 1825 // supported 1826 case B_RGB32: case B_RGBA32: 1827 { 1828 typedef RGB24Reader<rgb32_pixel> Reader; 1829 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1830 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1831 fColorSpace, width, Reader(data), paletteConverter); 1832 break; 1833 } 1834 case B_RGB32_BIG: case B_RGBA32_BIG: 1835 { 1836 typedef RGB24Reader<rgb32_big_pixel> Reader; 1837 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1838 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1839 fColorSpace, width, Reader(data), paletteConverter); 1840 break; 1841 } 1842 case B_RGB24: 1843 { 1844 typedef RGB24Reader<rgb24_pixel> Reader; 1845 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1846 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1847 fColorSpace, width, Reader(data), paletteConverter); 1848 break; 1849 } 1850 case B_RGB24_BIG: 1851 { 1852 typedef RGB24Reader<rgb24_big_pixel> Reader; 1853 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1854 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1855 fColorSpace, width, Reader(data), paletteConverter); 1856 break; 1857 } 1858 case B_RGB16: 1859 { 1860 typedef RGB16Reader<rgb16_pixel> Reader; 1861 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1862 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1863 fColorSpace, width, Reader(data), paletteConverter); 1864 break; 1865 } 1866 case B_RGB16_BIG: 1867 { 1868 typedef RGB16Reader<rgb16_big_pixel> Reader; 1869 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1870 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1871 fColorSpace, width, Reader(data), paletteConverter); 1872 break; 1873 } 1874 case B_RGB15: case B_RGBA15: 1875 { 1876 typedef RGB15Reader<rgb16_pixel> Reader; 1877 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1878 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1879 fColorSpace, width, Reader(data), paletteConverter); 1880 break; 1881 } 1882 case B_RGB15_BIG: case B_RGBA15_BIG: 1883 { 1884 typedef RGB15Reader<rgb16_big_pixel> Reader; 1885 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1886 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1887 fColorSpace, width, Reader(data), paletteConverter); 1888 break; 1889 } 1890 case B_CMAP8: 1891 { 1892 typedef CMAP8Reader Reader; 1893 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1894 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1895 fColorSpace, width, Reader(data, paletteConverter), 1896 paletteConverter); 1897 break; 1898 } 1899 case B_GRAY8: 1900 { 1901 typedef Gray8Reader Reader; 1902 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1903 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1904 fColorSpace, width, Reader(data), paletteConverter); 1905 break; 1906 } 1907 case B_GRAY1: 1908 { 1909 typedef Gray1Reader Reader; 1910 error = set_bits<Reader>(data, length, bpr, inRowSkip, 1911 fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1912 fColorSpace, width, Reader(data), paletteConverter); 1913 break; 1914 } 1915 // unsupported 1916 case B_NO_COLOR_SPACE: 1917 case B_YUV9: case B_YUV12: 1918 case B_UVL32: case B_UVLA32: 1919 case B_LAB32: case B_LABA32: 1920 case B_HSI32: case B_HSIA32: 1921 case B_HSV32: case B_HSVA32: 1922 case B_HLS32: case B_HLSA32: 1923 case B_CMY32: case B_CMYA32: case B_CMYK32: 1924 case B_UVL24: case B_LAB24: case B_HSI24: 1925 case B_HSV24: case B_HLS24: case B_CMY24: 1926 case B_YCbCr422: case B_YUV422: 1927 case B_YCbCr411: case B_YUV411: 1928 case B_YCbCr444: case B_YUV444: 1929 case B_YCbCr420: case B_YUV420: 1930 default: 1931 error = B_BAD_VALUE; 1932 break; 1933 } 1934 } 1935 return error; 1936 } 1937 1938 1939 /*! \briefly Assigns another bitmap's data to this bitmap. 1940 1941 The supplied bitmap must have the exactly same dimensions as this bitmap. 1942 Its data are converted to the color space of this bitmap. 1943 1944 The currently supported source/target color spaces are 1945 \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}. 1946 1947 \param bitmap The source bitmap. 1948 \return 1949 - \c B_OK: Everything went fine. 1950 - \c B_BAD_VALUE: \c NULL \a bitmap, or \a bitmap has other dimensions, 1951 or the conversion from or to one of the color spaces is not supported. 1952 */ 1953 status_t 1954 BBitmap::ImportBits(const BBitmap *bitmap) 1955 { 1956 status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT); 1957 // check param 1958 if (error == B_OK && bitmap == NULL) 1959 error = B_BAD_VALUE; 1960 if (error == B_OK && bitmap->InitCheck() != B_OK) 1961 error = B_BAD_VALUE; 1962 if (error == B_OK && bitmap->Bounds() != fBounds) 1963 error = B_BAD_VALUE; 1964 // set bits 1965 if (error == B_OK) { 1966 error = ImportBits(bitmap->Bits(), bitmap->BitsLength(), 1967 bitmap->BytesPerRow(), 0, bitmap->ColorSpace()); 1968 } 1969 return error; 1970 } 1971 1972 1973 status_t 1974 BBitmap::GetOverlayRestrictions(overlay_restrictions *restrictions) const 1975 { 1976 // TODO: Implement 1977 return B_ERROR; 1978 } 1979 1980 1981 status_t 1982 BBitmap::Perform(perform_code d, void *arg) 1983 { 1984 return BArchivable::Perform(d, arg); 1985 } 1986 1987 1988 // FBC 1989 void BBitmap::_ReservedBitmap1() {} 1990 void BBitmap::_ReservedBitmap2() {} 1991 void BBitmap::_ReservedBitmap3() {} 1992 1993 1994 /*! \brief Privatized copy constructor to prevent usage. 1995 */ 1996 BBitmap::BBitmap(const BBitmap &) 1997 { 1998 } 1999 2000 2001 /*! \brief Privatized assignment operator to prevent usage. 2002 */ 2003 BBitmap & 2004 BBitmap::operator=(const BBitmap &) 2005 { 2006 return *this; 2007 } 2008 2009 2010 char * 2011 BBitmap::get_shared_pointer() const 2012 { 2013 return NULL; // not implemented 2014 } 2015 2016 2017 int32 2018 BBitmap::get_server_token() const 2019 { 2020 return fServerToken; 2021 } 2022 2023 2024 /*! \brief Initializes the bitmap. 2025 \param bounds The bitmap dimensions. 2026 \param colorSpace The bitmap's color space. 2027 \param flags Creation flags. 2028 \param bytesPerRow The number of bytes per row the bitmap should use. 2029 \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate 2030 value. 2031 \param screenID ??? 2032 */ 2033 void 2034 BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags, 2035 int32 bytesPerRow, screen_id screenID) 2036 { 2037 //printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n", 2038 // bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow); 2039 2040 // TODO: Hanlde setting up the offscreen window if we're such a bitmap! 2041 2042 // TODO: Should we handle rounding of the "bounds" here? How does R5 behave? 2043 2044 status_t error = B_OK; 2045 2046 //#ifdef RUN_WITHOUT_APP_SERVER 2047 flags |= B_BITMAP_NO_SERVER_LINK; 2048 //#endif // RUN_WITHOUT_APP_SERVER 2049 flags &= ~B_BITMAP_ACCEPTS_VIEWS; 2050 2051 CleanUp(); 2052 2053 // check params 2054 if (!bounds.IsValid() || !bitmaps_support_space(colorSpace, NULL)) 2055 error = B_BAD_VALUE; 2056 if (error == B_OK) { 2057 int32 bpr = get_bytes_per_row(colorSpace, bounds.IntegerWidth() + 1); 2058 if (bytesPerRow < 0) 2059 bytesPerRow = bpr; 2060 else if (bytesPerRow < bpr) 2061 // NOTE: How does R5 behave? 2062 error = B_BAD_VALUE; 2063 } 2064 // allocate the bitmap buffer 2065 if (error == B_OK) { 2066 // NOTE: Maybe the code would look more robust if the 2067 // "size" was not calculated here when we ask the server 2068 // to allocate the bitmap. -Stephan 2069 int32 size = bytesPerRow * (bounds.IntegerHeight() + 1); 2070 2071 if (flags & B_BITMAP_NO_SERVER_LINK) { 2072 fBasePtr = malloc(size); 2073 if (fBasePtr) { 2074 fSize = size; 2075 fColorSpace = colorSpace; 2076 fBounds = bounds; 2077 fBytesPerRow = bytesPerRow; 2078 fFlags = flags; 2079 } else 2080 error = B_NO_MEMORY; 2081 } else { 2082 // // Ask the server (via our owning application) to create a bitmap. 2083 // BPrivate::AppServerLink link; 2084 // 2085 // // Attach Data: 2086 // // 1) BRect bounds 2087 // // 2) color_space space 2088 // // 3) int32 bitmap_flags 2089 // // 4) int32 bytes_per_row 2090 // // 5) int32 screen_id::id 2091 // link.StartMessage(AS_CREATE_BITMAP); 2092 // link.Attach<BRect>(bounds); 2093 // link.Attach<color_space>(colorSpace); 2094 // link.Attach<int32>((int32)flags); 2095 // link.Attach<int32>(bytesPerRow); 2096 // link.Attach<int32>(screenID.id); 2097 // 2098 // // Reply Code: SERVER_TRUE 2099 // // Reply Data: 2100 // // 1) int32 server token 2101 // // 2) area_id id of the area in which the bitmap data resides 2102 // // 3) int32 area pointer offset used to calculate fBasePtr 2103 // 2104 // // alternatively, if something went wrong 2105 // // Reply Code: SERVER_FALSE 2106 // // Reply Data: 2107 // // None 2108 // int32 code = SERVER_FALSE; 2109 // error = link.FlushWithReply(code); 2110 // 2111 // if (error >= B_OK) { 2112 // // *communication* with server successful 2113 // if (code == SERVER_TRUE) { 2114 // // server side success 2115 // // Get token 2116 // area_id bmparea; 2117 // int32 areaoffset; 2118 // 2119 // link.Read<int32>(&fServerToken); 2120 // link.Read<area_id>(&bmparea); 2121 // link.Read<int32>(&areaoffset); 2122 // 2123 // // Get the area in which the data resides 2124 // fArea = clone_area("shared bitmap area", 2125 // (void**)&fBasePtr, 2126 // B_ANY_ADDRESS, 2127 // B_READ_AREA | B_WRITE_AREA, 2128 // bmparea); 2129 // 2130 // // Jump to the location in the area 2131 // fBasePtr = (int8*)fBasePtr + areaoffset; 2132 // 2133 // fSize = size; 2134 // fColorSpace = colorSpace; 2135 // fBounds = bounds; 2136 // fBytesPerRow = bytesPerRow; 2137 // fFlags = flags; 2138 // } else { 2139 // // server side error, we assume: 2140 // error = B_NO_MEMORY; 2141 // } 2142 // } 2143 // // NOTE: not "else" to handle B_NO_MEMORY on server side! 2144 // if (error < B_OK) { 2145 // fBasePtr = NULL; 2146 // fServerToken = -1; 2147 // fArea = -1; 2148 // // NOTE: why not "0" in case of error? 2149 // fFlags = flags; 2150 // } 2151 } 2152 // fWindow = NULL; 2153 fToken = -1; 2154 fOrigArea = -1; 2155 } 2156 2157 fInitError = error; 2158 // TODO: on success, handle clearing to white if the flags say so. Needs to be 2159 // dependent on color space. 2160 2161 if (fInitError == B_OK) { 2162 if (flags & B_BITMAP_ACCEPTS_VIEWS) { 2163 // fWindow = new BWindow(Bounds(), fServerToken); 2164 // // A BWindow starts life locked and is unlocked 2165 // // in Show(), but this window is never shown and 2166 // // it's message loop is never started. 2167 // fWindow->Unlock(); 2168 } 2169 } 2170 } 2171 2172 2173 /*! \brief Cleans up any memory allocated by the bitmap or 2174 informs the server to do so. 2175 */ 2176 void 2177 BBitmap::CleanUp() 2178 { 2179 if (fBasePtr) { 2180 if (fFlags & B_BITMAP_NO_SERVER_LINK) { 2181 free(fBasePtr); 2182 } else { 2183 // BPrivate::AppServerLink link; 2184 // // AS_DELETE_BITMAP: 2185 // // Attached Data: 2186 // // 1) int32 server token 2187 // 2188 // // Reply Code: SERVER_TRUE if successful, 2189 // // SERVER_FALSE if the buffer was already deleted 2190 // // Reply Data: none 2191 // // status_t freestat; 2192 // int32 code = SERVER_FALSE; 2193 // link.StartMessage(AS_DELETE_BITMAP); 2194 // link.Attach<int32>(fServerToken); 2195 // link.FlushWithReply(code); 2196 // if (code == SERVER_FALSE) { 2197 // // TODO: Find out if "SERVER_FALSE if the buffer 2198 // // was already deleted" is true. If not, maybe we 2199 // // need to take additional action. 2200 // } 2201 // fArea = -1; 2202 // fServerToken = -1; 2203 } 2204 fBasePtr = NULL; 2205 } 2206 } 2207 2208 2209 void 2210 BBitmap::AssertPtr() 2211 { 2212 } 2213 2214