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