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