1338b8dc3SIngo Weinhold /* 264b2d169SAxel Dörfler * Copyright 2001-2008, Haiku Inc. 3338b8dc3SIngo Weinhold * Distributed under the terms of the MIT License. 4338b8dc3SIngo Weinhold * 5338b8dc3SIngo Weinhold * Authors: 6338b8dc3SIngo Weinhold * Ingo Weinhold (bonefish@users.sf.net) 7338b8dc3SIngo Weinhold * DarkWyrm <bpmagic@columbus.rr.com> 8338b8dc3SIngo Weinhold * Stephan Aßmus <superstippi@gmx.de> 9338b8dc3SIngo Weinhold */ 10338b8dc3SIngo Weinhold 1164b2d169SAxel Dörfler /*! BBitmap objects represent off-screen windows that contain bitmap data. */ 12338b8dc3SIngo Weinhold 13338b8dc3SIngo Weinhold #include <algorithm> 14338b8dc3SIngo Weinhold #include <limits.h> 15338b8dc3SIngo Weinhold #include <new> 16338b8dc3SIngo Weinhold #include <stdio.h> 17338b8dc3SIngo Weinhold #include <stdlib.h> 18338b8dc3SIngo Weinhold 19338b8dc3SIngo Weinhold #include <Bitmap.h> 20338b8dc3SIngo Weinhold #include <GraphicsDefs.h> 21338b8dc3SIngo Weinhold #include <Locker.h> 22338b8dc3SIngo Weinhold #include <Message.h> 23338b8dc3SIngo Weinhold 24338b8dc3SIngo Weinhold 2564b2d169SAxel Dörfler // structures defining the pixel layout 2664b2d169SAxel Dörfler 2764b2d169SAxel Dörfler struct rgb32_pixel { 2864b2d169SAxel Dörfler uint8 blue; 2964b2d169SAxel Dörfler uint8 green; 3064b2d169SAxel Dörfler uint8 red; 3164b2d169SAxel Dörfler uint8 alpha; 3264b2d169SAxel Dörfler }; 3364b2d169SAxel Dörfler 3464b2d169SAxel Dörfler struct rgb32_big_pixel { 3564b2d169SAxel Dörfler uint8 red; 3664b2d169SAxel Dörfler uint8 green; 3764b2d169SAxel Dörfler uint8 blue; 3864b2d169SAxel Dörfler uint8 alpha; 3964b2d169SAxel Dörfler }; 4064b2d169SAxel Dörfler 4164b2d169SAxel Dörfler struct rgb24_pixel { 4264b2d169SAxel Dörfler uint8 blue; 4364b2d169SAxel Dörfler uint8 green; 4464b2d169SAxel Dörfler uint8 red; 4564b2d169SAxel Dörfler }; 4664b2d169SAxel Dörfler 4764b2d169SAxel Dörfler struct rgb24_big_pixel { 4864b2d169SAxel Dörfler uint8 red; 4964b2d169SAxel Dörfler uint8 green; 5064b2d169SAxel Dörfler uint8 blue; 5164b2d169SAxel Dörfler }; 5264b2d169SAxel Dörfler 5364b2d169SAxel Dörfler struct rgb16_pixel { 5464b2d169SAxel Dörfler uint8 gb; // G[2:0],B[4:0] 5564b2d169SAxel Dörfler uint8 rg; // 16: R[4:0],G[5:3] 5664b2d169SAxel Dörfler // 15: -[0],R[4:0],G[4:3] 5764b2d169SAxel Dörfler }; 5864b2d169SAxel Dörfler 5964b2d169SAxel Dörfler struct rgb16_big_pixel { 6064b2d169SAxel Dörfler uint8 rg; // 16: R[4:0],G[5:3] 6164b2d169SAxel Dörfler // 15: -[0],R[4:0],G[4:3] 6264b2d169SAxel Dörfler uint8 gb; // G[2:0],B[4:0] 6364b2d169SAxel Dörfler }; 6464b2d169SAxel Dörfler 6564b2d169SAxel Dörfler // types defining what is needed to store a color value 6664b2d169SAxel Dörfler 6764b2d169SAxel Dörfler struct rgb_color_value { 6864b2d169SAxel Dörfler uint8 red; 6964b2d169SAxel Dörfler uint8 green; 7064b2d169SAxel Dörfler uint8 blue; 7164b2d169SAxel Dörfler uint8 alpha; 7264b2d169SAxel Dörfler }; 7364b2d169SAxel Dörfler 7464b2d169SAxel Dörfler typedef uint8 gray_color_value; 7564b2d169SAxel Dörfler 76338b8dc3SIngo Weinhold // TODO: system palette -- hard-coded for now, when the app server is ready 77338b8dc3SIngo Weinhold // we should use system_colors() or BScreen::ColorMap(). 78338b8dc3SIngo Weinhold const rgb_color kSystemPalette[] = { 79338b8dc3SIngo Weinhold { 0, 0, 0, 255 }, { 8, 8, 8, 255 }, { 16, 16, 16, 255 }, 80338b8dc3SIngo Weinhold { 24, 24, 24, 255 }, { 32, 32, 32, 255 }, { 40, 40, 40, 255 }, 81338b8dc3SIngo Weinhold { 48, 48, 48, 255 }, { 56, 56, 56, 255 }, { 64, 64, 64, 255 }, 82338b8dc3SIngo Weinhold { 72, 72, 72, 255 }, { 80, 80, 80, 255 }, { 88, 88, 88, 255 }, 83338b8dc3SIngo Weinhold { 96, 96, 96, 255 }, { 104, 104, 104, 255 }, { 112, 112, 112, 255 }, 84338b8dc3SIngo Weinhold { 120, 120, 120, 255 }, { 128, 128, 128, 255 }, { 136, 136, 136, 255 }, 85338b8dc3SIngo Weinhold { 144, 144, 144, 255 }, { 152, 152, 152, 255 }, { 160, 160, 160, 255 }, 86338b8dc3SIngo Weinhold { 168, 168, 168, 255 }, { 176, 176, 176, 255 }, { 184, 184, 184, 255 }, 87338b8dc3SIngo Weinhold { 192, 192, 192, 255 }, { 200, 200, 200, 255 }, { 208, 208, 208, 255 }, 88338b8dc3SIngo Weinhold { 216, 216, 216, 255 }, { 224, 224, 224, 255 }, { 232, 232, 232, 255 }, 89338b8dc3SIngo Weinhold { 240, 240, 240, 255 }, { 248, 248, 248, 255 }, { 0, 0, 255, 255 }, 90338b8dc3SIngo Weinhold { 0, 0, 229, 255 }, { 0, 0, 204, 255 }, { 0, 0, 179, 255 }, 91338b8dc3SIngo Weinhold { 0, 0, 154, 255 }, { 0, 0, 129, 255 }, { 0, 0, 105, 255 }, 92338b8dc3SIngo Weinhold { 0, 0, 80, 255 }, { 0, 0, 55, 255 }, { 0, 0, 30, 255 }, 93338b8dc3SIngo Weinhold { 255, 0, 0, 255 }, { 228, 0, 0, 255 }, { 203, 0, 0, 255 }, 94338b8dc3SIngo Weinhold { 178, 0, 0, 255 }, { 153, 0, 0, 255 }, { 128, 0, 0, 255 }, 95338b8dc3SIngo Weinhold { 105, 0, 0, 255 }, { 80, 0, 0, 255 }, { 55, 0, 0, 255 }, 96338b8dc3SIngo Weinhold { 30, 0, 0, 255 }, { 0, 255, 0, 255 }, { 0, 228, 0, 255 }, 97338b8dc3SIngo Weinhold { 0, 203, 0, 255 }, { 0, 178, 0, 255 }, { 0, 153, 0, 255 }, 98338b8dc3SIngo Weinhold { 0, 128, 0, 255 }, { 0, 105, 0, 255 }, { 0, 80, 0, 255 }, 99338b8dc3SIngo Weinhold { 0, 55, 0, 255 }, { 0, 30, 0, 255 }, { 0, 152, 51, 255 }, 100338b8dc3SIngo Weinhold { 255, 255, 255, 255 }, { 203, 255, 255, 255 }, { 203, 255, 203, 255 }, 101338b8dc3SIngo Weinhold { 203, 255, 152, 255 }, { 203, 255, 102, 255 }, { 203, 255, 51, 255 }, 102338b8dc3SIngo Weinhold { 203, 255, 0, 255 }, { 152, 255, 255, 255 }, { 152, 255, 203, 255 }, 103338b8dc3SIngo Weinhold { 152, 255, 152, 255 }, { 152, 255, 102, 255 }, { 152, 255, 51, 255 }, 104338b8dc3SIngo Weinhold { 152, 255, 0, 255 }, { 102, 255, 255, 255 }, { 102, 255, 203, 255 }, 105338b8dc3SIngo Weinhold { 102, 255, 152, 255 }, { 102, 255, 102, 255 }, { 102, 255, 51, 255 }, 106338b8dc3SIngo Weinhold { 102, 255, 0, 255 }, { 51, 255, 255, 255 }, { 51, 255, 203, 255 }, 107338b8dc3SIngo Weinhold { 51, 255, 152, 255 }, { 51, 255, 102, 255 }, { 51, 255, 51, 255 }, 108338b8dc3SIngo Weinhold { 51, 255, 0, 255 }, { 255, 152, 255, 255 }, { 255, 152, 203, 255 }, 109338b8dc3SIngo Weinhold { 255, 152, 152, 255 }, { 255, 152, 102, 255 }, { 255, 152, 51, 255 }, 110338b8dc3SIngo Weinhold { 255, 152, 0, 255 }, { 0, 102, 255, 255 }, { 0, 102, 203, 255 }, 111338b8dc3SIngo Weinhold { 203, 203, 255, 255 }, { 203, 203, 203, 255 }, { 203, 203, 152, 255 }, 112338b8dc3SIngo Weinhold { 203, 203, 102, 255 }, { 203, 203, 51, 255 }, { 203, 203, 0, 255 }, 113338b8dc3SIngo Weinhold { 152, 203, 255, 255 }, { 152, 203, 203, 255 }, { 152, 203, 152, 255 }, 114338b8dc3SIngo Weinhold { 152, 203, 102, 255 }, { 152, 203, 51, 255 }, { 152, 203, 0, 255 }, 115338b8dc3SIngo Weinhold { 102, 203, 255, 255 }, { 102, 203, 203, 255 }, { 102, 203, 152, 255 }, 116338b8dc3SIngo Weinhold { 102, 203, 102, 255 }, { 102, 203, 51, 255 }, { 102, 203, 0, 255 }, 117338b8dc3SIngo Weinhold { 51, 203, 255, 255 }, { 51, 203, 203, 255 }, { 51, 203, 152, 255 }, 118338b8dc3SIngo Weinhold { 51, 203, 102, 255 }, { 51, 203, 51, 255 }, { 51, 203, 0, 255 }, 119338b8dc3SIngo Weinhold { 255, 102, 255, 255 }, { 255, 102, 203, 255 }, { 255, 102, 152, 255 }, 120338b8dc3SIngo Weinhold { 255, 102, 102, 255 }, { 255, 102, 51, 255 }, { 255, 102, 0, 255 }, 121338b8dc3SIngo Weinhold { 0, 102, 152, 255 }, { 0, 102, 102, 255 }, { 203, 152, 255, 255 }, 122338b8dc3SIngo Weinhold { 203, 152, 203, 255 }, { 203, 152, 152, 255 }, { 203, 152, 102, 255 }, 123338b8dc3SIngo Weinhold { 203, 152, 51, 255 }, { 203, 152, 0, 255 }, { 152, 152, 255, 255 }, 124338b8dc3SIngo Weinhold { 152, 152, 203, 255 }, { 152, 152, 152, 255 }, { 152, 152, 102, 255 }, 125338b8dc3SIngo Weinhold { 152, 152, 51, 255 }, { 152, 152, 0, 255 }, { 102, 152, 255, 255 }, 126338b8dc3SIngo Weinhold { 102, 152, 203, 255 }, { 102, 152, 152, 255 }, { 102, 152, 102, 255 }, 127338b8dc3SIngo Weinhold { 102, 152, 51, 255 }, { 102, 152, 0, 255 }, { 51, 152, 255, 255 }, 128338b8dc3SIngo Weinhold { 51, 152, 203, 255 }, { 51, 152, 152, 255 }, { 51, 152, 102, 255 }, 129338b8dc3SIngo Weinhold { 51, 152, 51, 255 }, { 51, 152, 0, 255 }, { 230, 134, 0, 255 }, 130338b8dc3SIngo Weinhold { 255, 51, 203, 255 }, { 255, 51, 152, 255 }, { 255, 51, 102, 255 }, 131338b8dc3SIngo Weinhold { 255, 51, 51, 255 }, { 255, 51, 0, 255 }, { 0, 102, 51, 255 }, 132338b8dc3SIngo Weinhold { 0, 102, 0, 255 }, { 203, 102, 255, 255 }, { 203, 102, 203, 255 }, 133338b8dc3SIngo Weinhold { 203, 102, 152, 255 }, { 203, 102, 102, 255 }, { 203, 102, 51, 255 }, 134338b8dc3SIngo Weinhold { 203, 102, 0, 255 }, { 152, 102, 255, 255 }, { 152, 102, 203, 255 }, 135338b8dc3SIngo Weinhold { 152, 102, 152, 255 }, { 152, 102, 102, 255 }, { 152, 102, 51, 255 }, 136338b8dc3SIngo Weinhold { 152, 102, 0, 255 }, { 102, 102, 255, 255 }, { 102, 102, 203, 255 }, 137338b8dc3SIngo Weinhold { 102, 102, 152, 255 }, { 102, 102, 102, 255 }, { 102, 102, 51, 255 }, 138338b8dc3SIngo Weinhold { 102, 102, 0, 255 }, { 51, 102, 255, 255 }, { 51, 102, 203, 255 }, 139338b8dc3SIngo Weinhold { 51, 102, 152, 255 }, { 51, 102, 102, 255 }, { 51, 102, 51, 255 }, 140338b8dc3SIngo Weinhold { 51, 102, 0, 255 }, { 255, 0, 255, 255 }, { 255, 0, 203, 255 }, 141338b8dc3SIngo Weinhold { 255, 0, 152, 255 }, { 255, 0, 102, 255 }, { 255, 0, 51, 255 }, 142338b8dc3SIngo Weinhold { 255, 175, 19, 255 }, { 0, 51, 255, 255 }, { 0, 51, 203, 255 }, 143338b8dc3SIngo Weinhold { 203, 51, 255, 255 }, { 203, 51, 203, 255 }, { 203, 51, 152, 255 }, 144338b8dc3SIngo Weinhold { 203, 51, 102, 255 }, { 203, 51, 51, 255 }, { 203, 51, 0, 255 }, 145338b8dc3SIngo Weinhold { 152, 51, 255, 255 }, { 152, 51, 203, 255 }, { 152, 51, 152, 255 }, 146338b8dc3SIngo Weinhold { 152, 51, 102, 255 }, { 152, 51, 51, 255 }, { 152, 51, 0, 255 }, 147338b8dc3SIngo Weinhold { 102, 51, 255, 255 }, { 102, 51, 203, 255 }, { 102, 51, 152, 255 }, 148338b8dc3SIngo Weinhold { 102, 51, 102, 255 }, { 102, 51, 51, 255 }, { 102, 51, 0, 255 }, 149338b8dc3SIngo Weinhold { 51, 51, 255, 255 }, { 51, 51, 203, 255 }, { 51, 51, 152, 255 }, 150338b8dc3SIngo Weinhold { 51, 51, 102, 255 }, { 51, 51, 51, 255 }, { 51, 51, 0, 255 }, 151338b8dc3SIngo Weinhold { 255, 203, 102, 255 }, { 255, 203, 152, 255 }, { 255, 203, 203, 255 }, 152338b8dc3SIngo Weinhold { 255, 203, 255, 255 }, { 0, 51, 152, 255 }, { 0, 51, 102, 255 }, 153338b8dc3SIngo Weinhold { 0, 51, 51, 255 }, { 0, 51, 0, 255 }, { 203, 0, 255, 255 }, 154338b8dc3SIngo Weinhold { 203, 0, 203, 255 }, { 203, 0, 152, 255 }, { 203, 0, 102, 255 }, 155338b8dc3SIngo Weinhold { 203, 0, 51, 255 }, { 255, 227, 70, 255 }, { 152, 0, 255, 255 }, 156338b8dc3SIngo Weinhold { 152, 0, 203, 255 }, { 152, 0, 152, 255 }, { 152, 0, 102, 255 }, 157338b8dc3SIngo Weinhold { 152, 0, 51, 255 }, { 152, 0, 0, 255 }, { 102, 0, 255, 255 }, 158338b8dc3SIngo Weinhold { 102, 0, 203, 255 }, { 102, 0, 152, 255 }, { 102, 0, 102, 255 }, 159338b8dc3SIngo Weinhold { 102, 0, 51, 255 }, { 102, 0, 0, 255 }, { 51, 0, 255, 255 }, 160338b8dc3SIngo Weinhold { 51, 0, 203, 255 }, { 51, 0, 152, 255 }, { 51, 0, 102, 255 }, 161338b8dc3SIngo Weinhold { 51, 0, 51, 255 }, { 51, 0, 0, 255 }, { 255, 203, 51, 255 }, 162338b8dc3SIngo Weinhold { 255, 203, 0, 255 }, { 255, 255, 0, 255 }, { 255, 255, 51, 255 }, 163338b8dc3SIngo Weinhold { 255, 255, 102, 255 }, { 255, 255, 152, 255 }, { 255, 255, 203, 255 }, 164338b8dc3SIngo Weinhold { 255, 255, 255, 0 } // B_TRANSPARENT_MAGIC_CMAP8 165338b8dc3SIngo Weinhold }; 166338b8dc3SIngo Weinhold 167338b8dc3SIngo Weinhold 168338b8dc3SIngo Weinhold /*! \brief Returns the number of bytes per row needed to store the actual 169338b8dc3SIngo Weinhold bitmap data (not including any padding) given a color space and a 170338b8dc3SIngo Weinhold row width. 171338b8dc3SIngo Weinhold \param colorSpace The color space. 172338b8dc3SIngo Weinhold \param width The width. 173338b8dc3SIngo Weinhold \return The number of bytes per row needed to store data for a row, or 174338b8dc3SIngo Weinhold 0, if the color space is not supported. 175338b8dc3SIngo Weinhold */ 17664b2d169SAxel Dörfler static inline int32 177338b8dc3SIngo Weinhold get_raw_bytes_per_row(color_space colorSpace, int32 width) 178338b8dc3SIngo Weinhold { 179338b8dc3SIngo Weinhold int32 bpr = 0; 180338b8dc3SIngo Weinhold switch (colorSpace) { 181338b8dc3SIngo Weinhold // supported 182338b8dc3SIngo Weinhold case B_RGB32: case B_RGBA32: 183338b8dc3SIngo Weinhold case B_RGB32_BIG: case B_RGBA32_BIG: 184338b8dc3SIngo Weinhold case B_UVL32: case B_UVLA32: 185338b8dc3SIngo Weinhold case B_LAB32: case B_LABA32: 186338b8dc3SIngo Weinhold case B_HSI32: case B_HSIA32: 187338b8dc3SIngo Weinhold case B_HSV32: case B_HSVA32: 188338b8dc3SIngo Weinhold case B_HLS32: case B_HLSA32: 189338b8dc3SIngo Weinhold case B_CMY32: case B_CMYA32: case B_CMYK32: 190338b8dc3SIngo Weinhold bpr = 4 * width; 191338b8dc3SIngo Weinhold break; 192338b8dc3SIngo Weinhold case B_RGB24: case B_RGB24_BIG: 193338b8dc3SIngo Weinhold case B_UVL24: case B_LAB24: case B_HSI24: 194338b8dc3SIngo Weinhold case B_HSV24: case B_HLS24: case B_CMY24: 195338b8dc3SIngo Weinhold bpr = 3 * width; 196338b8dc3SIngo Weinhold break; 197338b8dc3SIngo Weinhold case B_RGB16: case B_RGB15: case B_RGBA15: 198338b8dc3SIngo Weinhold case B_RGB16_BIG: case B_RGB15_BIG: case B_RGBA15_BIG: 199338b8dc3SIngo Weinhold bpr = 2 * width; 200338b8dc3SIngo Weinhold break; 201338b8dc3SIngo Weinhold case B_CMAP8: case B_GRAY8: 202338b8dc3SIngo Weinhold bpr = width; 203338b8dc3SIngo Weinhold break; 204338b8dc3SIngo Weinhold case B_GRAY1: 205338b8dc3SIngo Weinhold bpr = (width + 7) / 8; 206338b8dc3SIngo Weinhold break; 207338b8dc3SIngo Weinhold case B_YCbCr422: case B_YUV422: 208338b8dc3SIngo Weinhold bpr = (width + 3) / 4 * 8; 209338b8dc3SIngo Weinhold break; 210338b8dc3SIngo Weinhold case B_YCbCr411: case B_YUV411: 211338b8dc3SIngo Weinhold bpr = (width + 3) / 4 * 6; 212338b8dc3SIngo Weinhold break; 213338b8dc3SIngo Weinhold case B_YCbCr444: case B_YUV444: 214338b8dc3SIngo Weinhold bpr = (width + 3) / 4 * 12; 215338b8dc3SIngo Weinhold break; 216338b8dc3SIngo Weinhold case B_YCbCr420: case B_YUV420: 217338b8dc3SIngo Weinhold bpr = (width + 3) / 4 * 6; 218338b8dc3SIngo Weinhold break; 219338b8dc3SIngo Weinhold // unsupported 220338b8dc3SIngo Weinhold case B_NO_COLOR_SPACE: 221338b8dc3SIngo Weinhold case B_YUV9: case B_YUV12: 222338b8dc3SIngo Weinhold break; 223338b8dc3SIngo Weinhold } 224338b8dc3SIngo Weinhold return bpr; 225338b8dc3SIngo Weinhold } 226338b8dc3SIngo Weinhold 22764b2d169SAxel Dörfler 228338b8dc3SIngo Weinhold /*! \brief Returns the number of bytes per row needed to store the bitmap 229338b8dc3SIngo Weinhold data (including any padding) given a color space and a row width. 230338b8dc3SIngo Weinhold \param colorSpace The color space. 231338b8dc3SIngo Weinhold \param width The width. 232338b8dc3SIngo Weinhold \return The number of bytes per row needed to store data for a row, or 233338b8dc3SIngo Weinhold 0, if the color space is not supported. 234338b8dc3SIngo Weinhold */ 23564b2d169SAxel Dörfler static inline int32 236338b8dc3SIngo Weinhold get_bytes_per_row(color_space colorSpace, int32 width) 237338b8dc3SIngo Weinhold { 238338b8dc3SIngo Weinhold int32 bpr = get_raw_bytes_per_row(colorSpace, width); 239338b8dc3SIngo Weinhold // align to int32 240338b8dc3SIngo Weinhold bpr = (bpr + 3) & 0x7ffffffc; 241338b8dc3SIngo Weinhold return bpr; 242338b8dc3SIngo Weinhold } 243338b8dc3SIngo Weinhold 24464b2d169SAxel Dörfler 245338b8dc3SIngo Weinhold /*! \brief Returns the brightness of an RGB 24 color. 246338b8dc3SIngo Weinhold \param red Value of the red component. 247338b8dc3SIngo Weinhold \param green Value of the green component. 248338b8dc3SIngo Weinhold \param blue Value of the blue component. 249338b8dc3SIngo Weinhold \return The brightness for the supplied RGB color as a value between 0 250338b8dc3SIngo Weinhold and 255. 251338b8dc3SIngo Weinhold */ 25264b2d169SAxel Dörfler static inline uint8 253338b8dc3SIngo Weinhold brightness_for(uint8 red, uint8 green, uint8 blue) 254338b8dc3SIngo Weinhold { 255338b8dc3SIngo Weinhold // brightness = 0.301 * red + 0.586 * green + 0.113 * blue 256338b8dc3SIngo Weinhold // we use for performance reasons: 257338b8dc3SIngo Weinhold // brightness = (308 * red + 600 * green + 116 * blue) / 1024 258338b8dc3SIngo Weinhold return uint8((308 * red + 600 * green + 116 * blue) / 1024); 259338b8dc3SIngo Weinhold } 260338b8dc3SIngo Weinhold 26164b2d169SAxel Dörfler 262338b8dc3SIngo Weinhold /*! \brief Returns the "distance" between two RGB colors. 263338b8dc3SIngo Weinhold 264338b8dc3SIngo Weinhold This functions defines an metric on the RGB color space. The distance 265338b8dc3SIngo Weinhold between two colors is 0, if and only if the colors are equal. 266338b8dc3SIngo Weinhold 267338b8dc3SIngo Weinhold \param red1 Red component of the first color. 268338b8dc3SIngo Weinhold \param green1 Green component of the first color. 269338b8dc3SIngo Weinhold \param blue1 Blue component of the first color. 270338b8dc3SIngo Weinhold \param red2 Red component of the second color. 271338b8dc3SIngo Weinhold \param green2 Green component of the second color. 272338b8dc3SIngo Weinhold \param blue2 Blue component of the second color. 273338b8dc3SIngo Weinhold \return The distance between the given colors. 274338b8dc3SIngo Weinhold */ 27564b2d169SAxel Dörfler static inline unsigned 27664b2d169SAxel Dörfler color_distance(uint8 red1, uint8 green1, uint8 blue1, uint8 red2, uint8 green2, 27764b2d169SAxel Dörfler uint8 blue2) 278338b8dc3SIngo Weinhold { 279338b8dc3SIngo Weinhold // euklidian distance (its square actually) 280338b8dc3SIngo Weinhold int rd = (int)red1 - (int)red2; 281338b8dc3SIngo Weinhold int gd = (int)green1 - (int)green2; 282338b8dc3SIngo Weinhold int bd = (int)blue1 - (int)blue2; 283338b8dc3SIngo Weinhold // return rd * rd + gd * gd + bd * bd; 284338b8dc3SIngo Weinhold 285338b8dc3SIngo Weinhold // distance according to psycho-visual tests 286338b8dc3SIngo Weinhold int rmean = ((int)red1 + (int)red2) / 2; 28764b2d169SAxel Dörfler return (((512 + rmean) * rd * rd) >> 8) + 4 * gd * gd 288338b8dc3SIngo Weinhold + (((767 - rmean) * bd * bd) >> 8); 289338b8dc3SIngo Weinhold } 290338b8dc3SIngo Weinhold 29164b2d169SAxel Dörfler 29264b2d169SAxel Dörfler static inline int32 29364b2d169SAxel Dörfler bit_mask(int32 bit) 29464b2d169SAxel Dörfler { 29564b2d169SAxel Dörfler return 1 << bit; 29664b2d169SAxel Dörfler } 297338b8dc3SIngo Weinhold 298338b8dc3SIngo Weinhold 29964b2d169SAxel Dörfler static inline int32 30064b2d169SAxel Dörfler inverse_bit_mask(int32 bit) 30164b2d169SAxel Dörfler { 30264b2d169SAxel Dörfler return ~bit_mask(bit); 30364b2d169SAxel Dörfler } 30464b2d169SAxel Dörfler 30564b2d169SAxel Dörfler 30664b2d169SAxel Dörfler // #pragma mark - PaletteConverter 30764b2d169SAxel Dörfler 308338b8dc3SIngo Weinhold 309338b8dc3SIngo Weinhold namespace BPrivate { 310338b8dc3SIngo Weinhold 311338b8dc3SIngo Weinhold /*! \brief Helper class for conversion between RGB and palette colors. 312338b8dc3SIngo Weinhold */ 313338b8dc3SIngo Weinhold class PaletteConverter { 314338b8dc3SIngo Weinhold public: 315338b8dc3SIngo Weinhold PaletteConverter(); 316338b8dc3SIngo Weinhold PaletteConverter(const rgb_color *palette); 317338b8dc3SIngo Weinhold PaletteConverter(const color_map *colorMap); 318338b8dc3SIngo Weinhold ~PaletteConverter(); 319338b8dc3SIngo Weinhold 320338b8dc3SIngo Weinhold status_t SetTo(const rgb_color *palette); 321338b8dc3SIngo Weinhold status_t SetTo(const color_map *colorMap); 322338b8dc3SIngo Weinhold status_t InitCheck() const; 323338b8dc3SIngo Weinhold 324338b8dc3SIngo Weinhold inline uint8 IndexForRGB15(uint16 rgb) const; 325338b8dc3SIngo Weinhold inline uint8 IndexForRGB15(uint8 red, uint8 green, uint8 blue) const; 326338b8dc3SIngo Weinhold inline uint8 IndexForRGB16(uint16 rgb) const; 327338b8dc3SIngo Weinhold inline uint8 IndexForRGB16(uint8 red, uint8 green, uint8 blue) const; 328338b8dc3SIngo Weinhold inline uint8 IndexForRGB24(uint32 rgb) const; 329338b8dc3SIngo Weinhold inline uint8 IndexForRGB24(uint8 red, uint8 green, uint8 blue) const; 330338b8dc3SIngo Weinhold inline uint8 IndexForGray(uint8 gray) const; 331338b8dc3SIngo Weinhold 332338b8dc3SIngo Weinhold inline const rgb_color &RGBColorForIndex(uint8 index) const; 333338b8dc3SIngo Weinhold inline uint16 RGB15ColorForIndex(uint8 index) const; 334338b8dc3SIngo Weinhold inline uint16 RGB16ColorForIndex(uint8 index) const; 335338b8dc3SIngo Weinhold inline uint32 RGB24ColorForIndex(uint8 index) const; 336338b8dc3SIngo Weinhold inline void RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green, 337338b8dc3SIngo Weinhold uint8 &blue, uint8 &alpha) const; 338338b8dc3SIngo Weinhold inline uint8 GrayColorForIndex(uint8 index) const; 339338b8dc3SIngo Weinhold 340338b8dc3SIngo Weinhold private: 341338b8dc3SIngo Weinhold const color_map *fColorMap; 342338b8dc3SIngo Weinhold color_map *fOwnColorMap; 343338b8dc3SIngo Weinhold status_t fCStatus; 344338b8dc3SIngo Weinhold }; 345338b8dc3SIngo Weinhold 346338b8dc3SIngo Weinhold } // namespace BPrivate 347338b8dc3SIngo Weinhold 348338b8dc3SIngo Weinhold using BPrivate::PaletteConverter; 349338b8dc3SIngo Weinhold using namespace std; 350338b8dc3SIngo Weinhold 35164b2d169SAxel Dörfler 352338b8dc3SIngo Weinhold /*! \brief Creates an uninitialized PaletteConverter. 353338b8dc3SIngo Weinhold */ 354338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter() 355338b8dc3SIngo Weinhold : fColorMap(NULL), 356338b8dc3SIngo Weinhold fOwnColorMap(NULL), 357338b8dc3SIngo Weinhold fCStatus(B_NO_INIT) 358338b8dc3SIngo Weinhold { 359338b8dc3SIngo Weinhold } 360338b8dc3SIngo Weinhold 36164b2d169SAxel Dörfler 362338b8dc3SIngo Weinhold /*! \brief Creates a PaletteConverter and initializes it to the supplied 363338b8dc3SIngo Weinhold palette. 364338b8dc3SIngo Weinhold \param palette The palette being a 256 entry rgb_color array. 365338b8dc3SIngo Weinhold */ 366338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter(const rgb_color *palette) 367338b8dc3SIngo Weinhold : fColorMap(NULL), 368338b8dc3SIngo Weinhold fOwnColorMap(NULL), 369338b8dc3SIngo Weinhold fCStatus(B_NO_INIT) 370338b8dc3SIngo Weinhold { 371338b8dc3SIngo Weinhold SetTo(palette); 372338b8dc3SIngo Weinhold } 373338b8dc3SIngo Weinhold 37464b2d169SAxel Dörfler 375338b8dc3SIngo Weinhold /*! \brief Creates a PaletteConverter and initializes it to the supplied 376338b8dc3SIngo Weinhold color map. 377338b8dc3SIngo Weinhold \param colorMap The completely initialized color map. 378338b8dc3SIngo Weinhold */ 379338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter(const color_map *colorMap) 380338b8dc3SIngo Weinhold : fColorMap(NULL), 381338b8dc3SIngo Weinhold fOwnColorMap(NULL), 382338b8dc3SIngo Weinhold fCStatus(B_NO_INIT) 383338b8dc3SIngo Weinhold { 384338b8dc3SIngo Weinhold SetTo(colorMap); 385338b8dc3SIngo Weinhold } 386338b8dc3SIngo Weinhold 38764b2d169SAxel Dörfler 388338b8dc3SIngo Weinhold /*! \brief Frees all resources associated with this object. 389338b8dc3SIngo Weinhold */ 390338b8dc3SIngo Weinhold PaletteConverter::~PaletteConverter() 391338b8dc3SIngo Weinhold { 392338b8dc3SIngo Weinhold delete fOwnColorMap; 393338b8dc3SIngo Weinhold } 394338b8dc3SIngo Weinhold 39564b2d169SAxel Dörfler 396338b8dc3SIngo Weinhold /*! \brief Initializes the converter to the supplied palette. 397338b8dc3SIngo Weinhold \param palette The palette being a 256 entry rgb_color array. 398338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise. 399338b8dc3SIngo Weinhold */ 400338b8dc3SIngo Weinhold status_t 401338b8dc3SIngo Weinhold PaletteConverter::SetTo(const rgb_color *palette) 402338b8dc3SIngo Weinhold { 403338b8dc3SIngo Weinhold // cleanup 404338b8dc3SIngo Weinhold SetTo((const color_map*)NULL); 405338b8dc3SIngo Weinhold status_t error = (palette ? B_OK : B_BAD_VALUE); 406338b8dc3SIngo Weinhold // alloc color map 407338b8dc3SIngo Weinhold if (error == B_OK) { 408338b8dc3SIngo Weinhold fOwnColorMap = new(nothrow) color_map; 409338b8dc3SIngo Weinhold if (fOwnColorMap == NULL) 410338b8dc3SIngo Weinhold error = B_NO_MEMORY; 411338b8dc3SIngo Weinhold } 412338b8dc3SIngo Weinhold // init color map 413338b8dc3SIngo Weinhold if (error == B_OK) { 414338b8dc3SIngo Weinhold fColorMap = fOwnColorMap; 415338b8dc3SIngo Weinhold // init color list 416338b8dc3SIngo Weinhold memcpy(fOwnColorMap->color_list, palette, sizeof(rgb_color) * 256); 417338b8dc3SIngo Weinhold // init index map 418338b8dc3SIngo Weinhold for (int32 color = 0; color < 32768; color++) { 419338b8dc3SIngo Weinhold // get components 420338b8dc3SIngo Weinhold uint8 red = (color & 0x7c00) >> 7; 421338b8dc3SIngo Weinhold uint8 green = (color & 0x3e0) >> 2; 422338b8dc3SIngo Weinhold uint8 blue = (color & 0x1f) << 3; 423338b8dc3SIngo Weinhold red |= red >> 5; 424338b8dc3SIngo Weinhold green |= green >> 5; 425338b8dc3SIngo Weinhold blue |= blue >> 5; 426338b8dc3SIngo Weinhold // find closest color 427338b8dc3SIngo Weinhold uint8 closestIndex = 0; 428338b8dc3SIngo Weinhold unsigned closestDistance = UINT_MAX; 429338b8dc3SIngo Weinhold for (int32 i = 0; i < 256; i++) { 430338b8dc3SIngo Weinhold const rgb_color &c = fOwnColorMap->color_list[i]; 431338b8dc3SIngo Weinhold unsigned distance = color_distance(red, green, blue, 432338b8dc3SIngo Weinhold c.red, c.green, c.blue); 433338b8dc3SIngo Weinhold if (distance < closestDistance) { 434338b8dc3SIngo Weinhold closestIndex = i; 435338b8dc3SIngo Weinhold closestDistance = distance; 436338b8dc3SIngo Weinhold } 437338b8dc3SIngo Weinhold } 438338b8dc3SIngo Weinhold fOwnColorMap->index_map[color] = closestIndex; 439338b8dc3SIngo Weinhold } 440338b8dc3SIngo Weinhold // no need to init inversion map 441338b8dc3SIngo Weinhold } 442338b8dc3SIngo Weinhold fCStatus = error; 443338b8dc3SIngo Weinhold return error; 444338b8dc3SIngo Weinhold } 445338b8dc3SIngo Weinhold 44664b2d169SAxel Dörfler 447338b8dc3SIngo Weinhold /*! \brief Initializes the converter to the supplied color map. 448338b8dc3SIngo Weinhold \param colorMap The completely initialized color map. 449338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise. 450338b8dc3SIngo Weinhold */ 451338b8dc3SIngo Weinhold status_t 452338b8dc3SIngo Weinhold PaletteConverter::SetTo(const color_map *colorMap) 453338b8dc3SIngo Weinhold { 454338b8dc3SIngo Weinhold // cleanup 455338b8dc3SIngo Weinhold if (fOwnColorMap) { 456338b8dc3SIngo Weinhold delete fOwnColorMap; 457338b8dc3SIngo Weinhold fOwnColorMap = NULL; 458338b8dc3SIngo Weinhold } 459338b8dc3SIngo Weinhold // set 460338b8dc3SIngo Weinhold fColorMap = colorMap; 46164b2d169SAxel Dörfler fCStatus = fColorMap ? B_OK : B_BAD_VALUE; 462338b8dc3SIngo Weinhold return fCStatus; 463338b8dc3SIngo Weinhold } 464338b8dc3SIngo Weinhold 46564b2d169SAxel Dörfler 466338b8dc3SIngo Weinhold /*! \brief Returns the result of the last initialization via constructor or 467338b8dc3SIngo Weinhold SetTo(). 468338b8dc3SIngo Weinhold \return \c B_OK, if the converter is properly initialized, an error code 469338b8dc3SIngo Weinhold otherwise. 470338b8dc3SIngo Weinhold */ 471338b8dc3SIngo Weinhold status_t 472338b8dc3SIngo Weinhold PaletteConverter::InitCheck() const 473338b8dc3SIngo Weinhold { 474338b8dc3SIngo Weinhold return fCStatus; 475338b8dc3SIngo Weinhold } 476338b8dc3SIngo Weinhold 47764b2d169SAxel Dörfler 478338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 15 color. 479338b8dc3SIngo Weinhold 480338b8dc3SIngo Weinhold The object must be properly initialized. 481338b8dc3SIngo Weinhold 482338b8dc3SIngo Weinhold \param rgb The RGB 15 color value (R[14:10]G[9:5]B[4:0]). 483338b8dc3SIngo Weinhold \return The palette color index for the supplied color. 484338b8dc3SIngo Weinhold */ 48564b2d169SAxel Dörfler inline uint8 486338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB15(uint16 rgb) const 487338b8dc3SIngo Weinhold { 488338b8dc3SIngo Weinhold return fColorMap->index_map[rgb]; 489338b8dc3SIngo Weinhold } 490338b8dc3SIngo Weinhold 49164b2d169SAxel Dörfler 492338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 15 color. 493338b8dc3SIngo Weinhold 494338b8dc3SIngo Weinhold The object must be properly initialized. 495338b8dc3SIngo Weinhold 496338b8dc3SIngo Weinhold \param red Red component of the color (R[4:0]). 497338b8dc3SIngo Weinhold \param green Green component of the color (G[4:0]). 498338b8dc3SIngo Weinhold \param blue Blue component of the color (B[4:0]). 499338b8dc3SIngo Weinhold \return The palette color index for the supplied color. 500338b8dc3SIngo Weinhold */ 50164b2d169SAxel Dörfler inline uint8 502338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB15(uint8 red, uint8 green, uint8 blue) const 503338b8dc3SIngo Weinhold { 504338b8dc3SIngo Weinhold // the 5 least significant bits are used 505338b8dc3SIngo Weinhold return fColorMap->index_map[(red << 10) | (green << 5) | blue]; 506338b8dc3SIngo Weinhold } 507338b8dc3SIngo Weinhold 50864b2d169SAxel Dörfler 509338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 16 color. 510338b8dc3SIngo Weinhold 511338b8dc3SIngo Weinhold The object must be properly initialized. 512338b8dc3SIngo Weinhold 513338b8dc3SIngo Weinhold \param rgb The RGB 16 color value (R[15:11]G[10:5]B[4:0]). 514338b8dc3SIngo Weinhold \return The palette color index for the supplied color. 515338b8dc3SIngo Weinhold */ 51664b2d169SAxel Dörfler inline uint8 517338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB16(uint16 rgb) const 518338b8dc3SIngo Weinhold { 51964b2d169SAxel Dörfler return fColorMap->index_map[((rgb >> 1) & 0x7fe0) | (rgb & 0x1f)]; 520338b8dc3SIngo Weinhold } 521338b8dc3SIngo Weinhold 52264b2d169SAxel Dörfler 523338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 16 color. 524338b8dc3SIngo Weinhold 525338b8dc3SIngo Weinhold The object must be properly initialized. 526338b8dc3SIngo Weinhold 527338b8dc3SIngo Weinhold \param red Red component of the color (R[4:0]). 528338b8dc3SIngo Weinhold \param green Green component of the color (G[5:0]). 529338b8dc3SIngo Weinhold \param blue Blue component of the color (B[4:0]). 530338b8dc3SIngo Weinhold \return The palette color index for the supplied color. 531338b8dc3SIngo Weinhold */ 53264b2d169SAxel Dörfler inline uint8 533338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB16(uint8 red, uint8 green, uint8 blue) const 534338b8dc3SIngo Weinhold { 535338b8dc3SIngo Weinhold // the 5 (for red, blue) / 6 (for green) least significant bits are used 536338b8dc3SIngo Weinhold return fColorMap->index_map[(red << 10) | ((green & 0x3e) << 4) | blue]; 537338b8dc3SIngo Weinhold } 538338b8dc3SIngo Weinhold 53964b2d169SAxel Dörfler 540338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 32 color. 541338b8dc3SIngo Weinhold 542338b8dc3SIngo Weinhold The object must be properly initialized. 543338b8dc3SIngo Weinhold 544338b8dc3SIngo Weinhold \param rgb The RGB 32 color value (R[31:24]G[23:16]B[15:8]). 545338b8dc3SIngo Weinhold \return The palette color index for the supplied color. 546338b8dc3SIngo Weinhold */ 54764b2d169SAxel Dörfler inline uint8 548338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB24(uint32 rgb) const 549338b8dc3SIngo Weinhold { 550338b8dc3SIngo Weinhold return fColorMap->index_map[((rgb & 0xf8000000) >> 17) 55164b2d169SAxel Dörfler | ((rgb & 0xf80000) >> 14) | ((rgb & 0xf800) >> 11)]; 552338b8dc3SIngo Weinhold } 553338b8dc3SIngo Weinhold 55464b2d169SAxel Dörfler 555338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given RGB 24 color. 556338b8dc3SIngo Weinhold 557338b8dc3SIngo Weinhold The object must be properly initialized. 558338b8dc3SIngo Weinhold 559338b8dc3SIngo Weinhold \param red Red component of the color. 560338b8dc3SIngo Weinhold \param green Green component of the color. 561338b8dc3SIngo Weinhold \param blue Blue component of the color. 562338b8dc3SIngo Weinhold \return The palette color index for the supplied color. 563338b8dc3SIngo Weinhold */ 56464b2d169SAxel Dörfler inline uint8 565338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB24(uint8 red, uint8 green, uint8 blue) const 566338b8dc3SIngo Weinhold { 56764b2d169SAxel Dörfler return fColorMap->index_map[((red & 0xf8) << 7) | ((green & 0xf8) << 2) 568338b8dc3SIngo Weinhold | (blue >> 3)]; 569338b8dc3SIngo Weinhold } 570338b8dc3SIngo Weinhold 57164b2d169SAxel Dörfler 572338b8dc3SIngo Weinhold /*! \brief Returns the palette color index closest to a given Gray 8 color. 573338b8dc3SIngo Weinhold 574338b8dc3SIngo Weinhold The object must be properly initialized. 575338b8dc3SIngo Weinhold 576338b8dc3SIngo Weinhold \param gray The Gray 8 color value. 577338b8dc3SIngo Weinhold \return The palette color index for the supplied color. 578338b8dc3SIngo Weinhold */ 57964b2d169SAxel Dörfler inline uint8 580338b8dc3SIngo Weinhold PaletteConverter::IndexForGray(uint8 gray) const 581338b8dc3SIngo Weinhold { 582338b8dc3SIngo Weinhold return IndexForRGB24(gray, gray, gray); 583338b8dc3SIngo Weinhold } 584338b8dc3SIngo Weinhold 58564b2d169SAxel Dörfler 586338b8dc3SIngo Weinhold /*! \brief Returns the RGB color for a given palette color index. 587338b8dc3SIngo Weinhold 588338b8dc3SIngo Weinhold The object must be properly initialized. 589338b8dc3SIngo Weinhold 590338b8dc3SIngo Weinhold \param index The palette color index. 591338b8dc3SIngo Weinhold \return The color for the supplied palette color index. 592338b8dc3SIngo Weinhold */ 59364b2d169SAxel Dörfler inline const rgb_color & 594338b8dc3SIngo Weinhold PaletteConverter::RGBColorForIndex(uint8 index) const 595338b8dc3SIngo Weinhold { 596338b8dc3SIngo Weinhold return fColorMap->color_list[index]; 597338b8dc3SIngo Weinhold } 598338b8dc3SIngo Weinhold 59964b2d169SAxel Dörfler 600338b8dc3SIngo Weinhold /*! \brief Returns the RGB 15 color for a given palette color index. 601338b8dc3SIngo Weinhold 602338b8dc3SIngo Weinhold The object must be properly initialized. 603338b8dc3SIngo Weinhold 604338b8dc3SIngo Weinhold \param index The palette color index. 605338b8dc3SIngo Weinhold \return The color for the supplied palette color index 606338b8dc3SIngo Weinhold (R[14:10]G[9:5]B[4:0]). 607338b8dc3SIngo Weinhold */ 60864b2d169SAxel Dörfler inline uint16 609338b8dc3SIngo Weinhold PaletteConverter::RGB15ColorForIndex(uint8 index) const 610338b8dc3SIngo Weinhold { 611338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index]; 61264b2d169SAxel Dörfler return ((color.red & 0xf8) << 7) | ((color.green & 0xf8) << 2) 613338b8dc3SIngo Weinhold | (color.blue >> 3); 614338b8dc3SIngo Weinhold } 615338b8dc3SIngo Weinhold 61664b2d169SAxel Dörfler 617338b8dc3SIngo Weinhold /*! \brief Returns the RGB 16 color for a given palette color index. 618338b8dc3SIngo Weinhold 619338b8dc3SIngo Weinhold The object must be properly initialized. 620338b8dc3SIngo Weinhold 621338b8dc3SIngo Weinhold \param index The palette color index. 622338b8dc3SIngo Weinhold \return The color for the supplied palette color index 623338b8dc3SIngo Weinhold (R[15:11]G[10:5]B[4:0]). 624338b8dc3SIngo Weinhold */ 62564b2d169SAxel Dörfler inline uint16 626338b8dc3SIngo Weinhold PaletteConverter::RGB16ColorForIndex(uint8 index) const 627338b8dc3SIngo Weinhold { 628338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index]; 62964b2d169SAxel Dörfler return ((color.red & 0xf8) << 8) | ((color.green & 0xfc) << 3) 630338b8dc3SIngo Weinhold | (color.blue >> 3); 631338b8dc3SIngo Weinhold } 632338b8dc3SIngo Weinhold 63364b2d169SAxel Dörfler 634338b8dc3SIngo Weinhold /*! \brief Returns the RGB 24 color for a given palette color index. 635338b8dc3SIngo Weinhold 636338b8dc3SIngo Weinhold The object must be properly initialized. 637338b8dc3SIngo Weinhold 638338b8dc3SIngo Weinhold \param index The palette color index. 639338b8dc3SIngo Weinhold \return The color for the supplied palette color index 640338b8dc3SIngo Weinhold (R[31:24]G[23:16]B[15:8]). 641338b8dc3SIngo Weinhold */ 64264b2d169SAxel Dörfler inline uint32 643338b8dc3SIngo Weinhold PaletteConverter::RGB24ColorForIndex(uint8 index) const 644338b8dc3SIngo Weinhold { 645338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index]; 64664b2d169SAxel Dörfler return (color.blue << 24) | (color.red << 8) | (color.green << 16) 64764b2d169SAxel Dörfler | color.alpha; 648338b8dc3SIngo Weinhold } 649338b8dc3SIngo Weinhold 65064b2d169SAxel Dörfler 651338b8dc3SIngo Weinhold /*! \brief Returns the RGB 24 color for a given palette color index. 652338b8dc3SIngo Weinhold 653338b8dc3SIngo Weinhold The object must be properly initialized. 654338b8dc3SIngo Weinhold 655338b8dc3SIngo Weinhold \param index The palette color index. 656338b8dc3SIngo Weinhold \param red Reference to the variable the red component shall be stored 657338b8dc3SIngo Weinhold into. 658338b8dc3SIngo Weinhold \param green Reference to the variable the green component shall be stored 659338b8dc3SIngo Weinhold into. 660338b8dc3SIngo Weinhold \param blue Reference to the variable the blue component shall be stored 661338b8dc3SIngo Weinhold into. 662338b8dc3SIngo Weinhold */ 66364b2d169SAxel Dörfler inline void 664338b8dc3SIngo Weinhold PaletteConverter::RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green, 665338b8dc3SIngo Weinhold uint8 &blue, uint8 &alpha) const 666338b8dc3SIngo Weinhold { 667338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index]; 668338b8dc3SIngo Weinhold red = color.red; 669338b8dc3SIngo Weinhold green = color.green; 670338b8dc3SIngo Weinhold blue = color.blue; 671338b8dc3SIngo Weinhold alpha = color.alpha; 672338b8dc3SIngo Weinhold } 673338b8dc3SIngo Weinhold 67464b2d169SAxel Dörfler 675338b8dc3SIngo Weinhold /*! \brief Returns the Gray 8 color for a given palette color index. 676338b8dc3SIngo Weinhold 677338b8dc3SIngo Weinhold The object must be properly initialized. 678338b8dc3SIngo Weinhold 679338b8dc3SIngo Weinhold \param index The palette color index. 680338b8dc3SIngo Weinhold \return The color for the supplied palette color index. 681338b8dc3SIngo Weinhold */ 68264b2d169SAxel Dörfler inline uint8 683338b8dc3SIngo Weinhold PaletteConverter::GrayColorForIndex(uint8 index) const 684338b8dc3SIngo Weinhold { 685338b8dc3SIngo Weinhold const rgb_color &color = fColorMap->color_list[index]; 686338b8dc3SIngo Weinhold return brightness_for(color.red, color.green, color.blue); 687338b8dc3SIngo Weinhold } 688338b8dc3SIngo Weinhold 689338b8dc3SIngo Weinhold // TODO: Remove these and palette_converter() when BScreen is available. 690338b8dc3SIngo Weinhold static BLocker gPaletteConverterLock; 691338b8dc3SIngo Weinhold static PaletteConverter gPaletteConverter; 692338b8dc3SIngo Weinhold 69364b2d169SAxel Dörfler 694338b8dc3SIngo Weinhold /*! \brief Returns a PaletteConverter using the system color palette. 695338b8dc3SIngo Weinhold \return A PaletteConverter. 696338b8dc3SIngo Weinhold */ 69764b2d169SAxel Dörfler static const PaletteConverter* 698338b8dc3SIngo Weinhold palette_converter() 699338b8dc3SIngo Weinhold { 700338b8dc3SIngo Weinhold if (gPaletteConverterLock.Lock()) { 701338b8dc3SIngo Weinhold if (gPaletteConverter.InitCheck() != B_OK) 702338b8dc3SIngo Weinhold gPaletteConverter.SetTo(kSystemPalette); 703338b8dc3SIngo Weinhold gPaletteConverterLock.Unlock(); 704338b8dc3SIngo Weinhold } 705338b8dc3SIngo Weinhold return &gPaletteConverter; 706338b8dc3SIngo Weinhold } 707338b8dc3SIngo Weinhold 708338b8dc3SIngo Weinhold 70964b2d169SAxel Dörfler // #pragma mark - Reader classes 710338b8dc3SIngo Weinhold 711338b8dc3SIngo Weinhold 712338b8dc3SIngo Weinhold // BaseReader 713338b8dc3SIngo Weinhold template<typename _PixelType> 714338b8dc3SIngo Weinhold struct BaseReader { 715338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 716338b8dc3SIngo Weinhold 717338b8dc3SIngo Weinhold BaseReader(const void *data) : pixels((const pixel_t*)data) {} 718338b8dc3SIngo Weinhold 719338b8dc3SIngo Weinhold inline void SetTo(const void *data) { pixels = (const pixel_t*)data; } 720338b8dc3SIngo Weinhold 721338b8dc3SIngo Weinhold inline void NextRow(int32 skip) 722338b8dc3SIngo Weinhold { 723338b8dc3SIngo Weinhold pixels = (const pixel_t*)((const char*)pixels + skip); 724338b8dc3SIngo Weinhold } 725338b8dc3SIngo Weinhold 726338b8dc3SIngo Weinhold const pixel_t *pixels; 727338b8dc3SIngo Weinhold }; 728338b8dc3SIngo Weinhold 729338b8dc3SIngo Weinhold // RGB24Reader 730338b8dc3SIngo Weinhold template<typename _PixelType> 731338b8dc3SIngo Weinhold struct RGB24Reader : public BaseReader<_PixelType> { 732338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 733338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 734338b8dc3SIngo Weinhold 735338b8dc3SIngo Weinhold RGB24Reader(const void *data) : BaseReader<_PixelType>(data) {} 736338b8dc3SIngo Weinhold 737338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color) 738338b8dc3SIngo Weinhold { 739338b8dc3SIngo Weinhold const pixel_t &pixel = *BaseReader<_PixelType>::pixels; 740338b8dc3SIngo Weinhold color.red = pixel.red; 741338b8dc3SIngo Weinhold color.green = pixel.green; 742338b8dc3SIngo Weinhold color.blue = pixel.blue; 74363d557f0SMichael Lotz color.alpha = 255; 744338b8dc3SIngo Weinhold BaseReader<_PixelType>::pixels++; 745338b8dc3SIngo Weinhold } 746338b8dc3SIngo Weinhold 747338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray) 748338b8dc3SIngo Weinhold { 749338b8dc3SIngo Weinhold rgb_color_value color; 750338b8dc3SIngo Weinhold Read(color); 751338b8dc3SIngo Weinhold gray = brightness_for(color.red, color.green, color.blue); 752338b8dc3SIngo Weinhold } 753338b8dc3SIngo Weinhold }; 754338b8dc3SIngo Weinhold 755338b8dc3SIngo Weinhold // RGB16Reader 756338b8dc3SIngo Weinhold template<typename _PixelType> 757338b8dc3SIngo Weinhold struct RGB16Reader : public BaseReader<_PixelType> { 758338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 759338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 760338b8dc3SIngo Weinhold 761338b8dc3SIngo Weinhold RGB16Reader(const void *data) : BaseReader<_PixelType>(data) {} 762338b8dc3SIngo Weinhold 763338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color) 764338b8dc3SIngo Weinhold { 765338b8dc3SIngo Weinhold // rg: R[4:0],G[5:3] 766338b8dc3SIngo Weinhold // gb: G[2:0],B[4:0] 767338b8dc3SIngo Weinhold const pixel_t &pixel = *BaseReader<_PixelType>::pixels; 768338b8dc3SIngo Weinhold color.red = pixel.rg & 0xf8; 769338b8dc3SIngo Weinhold color.green = ((pixel.rg & 0x07) << 5) & ((pixel.gb & 0xe0) >> 3); 770338b8dc3SIngo Weinhold color.blue = (pixel.gb & 0x1f) << 3; 771338b8dc3SIngo Weinhold color.red |= color.red >> 5; 772338b8dc3SIngo Weinhold color.green |= color.green >> 6; 773338b8dc3SIngo Weinhold color.blue |= color.blue >> 5; 77463d557f0SMichael Lotz color.alpha = 255; 775338b8dc3SIngo Weinhold BaseReader<_PixelType>::pixels++; 776338b8dc3SIngo Weinhold } 777338b8dc3SIngo Weinhold 778338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray) 779338b8dc3SIngo Weinhold { 780338b8dc3SIngo Weinhold rgb_color_value color; 781338b8dc3SIngo Weinhold Read(color); 782338b8dc3SIngo Weinhold gray = brightness_for(color.red, color.green, color.blue); 783338b8dc3SIngo Weinhold } 784338b8dc3SIngo Weinhold }; 785338b8dc3SIngo Weinhold 786338b8dc3SIngo Weinhold // RGB15Reader 787338b8dc3SIngo Weinhold template<typename _PixelType> 788338b8dc3SIngo Weinhold struct RGB15Reader : public BaseReader<_PixelType> { 789338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 790338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 791338b8dc3SIngo Weinhold 792338b8dc3SIngo Weinhold RGB15Reader(const void *data) : BaseReader<_PixelType>(data) {} 793338b8dc3SIngo Weinhold 794338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color) 795338b8dc3SIngo Weinhold { 796338b8dc3SIngo Weinhold // rg: -[0],R[4:0],G[4:3] 797338b8dc3SIngo Weinhold // gb: G[2:0],B[4:0] 798338b8dc3SIngo Weinhold const pixel_t &pixel = *BaseReader<_PixelType>::pixels; 799338b8dc3SIngo Weinhold color.red = (pixel.rg & 0x7c) << 1; 800338b8dc3SIngo Weinhold color.green = ((pixel.rg & 0x03) << 6) & ((pixel.gb & 0xe0) >> 2); 801338b8dc3SIngo Weinhold color.blue = (pixel.gb & 0x1f) << 3; 802338b8dc3SIngo Weinhold color.red |= color.red >> 5; 803338b8dc3SIngo Weinhold color.green |= color.green >> 5; 804338b8dc3SIngo Weinhold color.blue |= color.blue >> 5; 80563d557f0SMichael Lotz color.alpha = 255; 806338b8dc3SIngo Weinhold BaseReader<_PixelType>::pixels++; 807338b8dc3SIngo Weinhold } 808338b8dc3SIngo Weinhold 809338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray) 810338b8dc3SIngo Weinhold { 811338b8dc3SIngo Weinhold rgb_color_value color; 812338b8dc3SIngo Weinhold Read(color); 813338b8dc3SIngo Weinhold gray = brightness_for(color.red, color.green, color.blue); 814338b8dc3SIngo Weinhold } 815338b8dc3SIngo Weinhold }; 816338b8dc3SIngo Weinhold 817338b8dc3SIngo Weinhold // CMAP8Reader 818338b8dc3SIngo Weinhold struct CMAP8Reader : public BaseReader<uint8> { 819338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 820338b8dc3SIngo Weinhold 821338b8dc3SIngo Weinhold CMAP8Reader(const void *data, const PaletteConverter &converter) 822338b8dc3SIngo Weinhold : BaseReader<uint8>(data), converter(converter) {} 823338b8dc3SIngo Weinhold 824338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color) 825338b8dc3SIngo Weinhold { 826338b8dc3SIngo Weinhold converter.RGB24ColorForIndex(*BaseReader<uint8>::pixels, color.red, color.green, 827338b8dc3SIngo Weinhold color.blue, color.alpha); 828338b8dc3SIngo Weinhold BaseReader<uint8>::pixels++; 829338b8dc3SIngo Weinhold } 830338b8dc3SIngo Weinhold 831338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray) 832338b8dc3SIngo Weinhold { 833338b8dc3SIngo Weinhold gray = converter.GrayColorForIndex(*BaseReader<uint8>::pixels); 834338b8dc3SIngo Weinhold BaseReader<uint8>::pixels++; 835338b8dc3SIngo Weinhold } 836338b8dc3SIngo Weinhold 837338b8dc3SIngo Weinhold const PaletteConverter &converter; 838338b8dc3SIngo Weinhold }; 839338b8dc3SIngo Weinhold 840338b8dc3SIngo Weinhold // Gray8Reader 841338b8dc3SIngo Weinhold struct Gray8Reader : public BaseReader<uint8> { 842338b8dc3SIngo Weinhold typedef gray_color_value preferred_color_value_t; 843338b8dc3SIngo Weinhold 844338b8dc3SIngo Weinhold Gray8Reader(const void *data) : BaseReader<uint8>(data) {} 845338b8dc3SIngo Weinhold 846338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color) 847338b8dc3SIngo Weinhold { 848338b8dc3SIngo Weinhold color.red = color.green = color.blue = *BaseReader<uint8>::pixels; 84963d557f0SMichael Lotz color.alpha = 255; 850338b8dc3SIngo Weinhold BaseReader<uint8>::pixels++; 851338b8dc3SIngo Weinhold } 852338b8dc3SIngo Weinhold 853338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray) 854338b8dc3SIngo Weinhold { 855338b8dc3SIngo Weinhold gray = *BaseReader<uint8>::pixels; 856338b8dc3SIngo Weinhold BaseReader<uint8>::pixels++; 857338b8dc3SIngo Weinhold } 858338b8dc3SIngo Weinhold }; 859338b8dc3SIngo Weinhold 860338b8dc3SIngo Weinhold // Gray1Reader 861338b8dc3SIngo Weinhold struct Gray1Reader : public BaseReader<uint8> { 862338b8dc3SIngo Weinhold typedef gray_color_value preferred_color_value_t; 863338b8dc3SIngo Weinhold 864338b8dc3SIngo Weinhold Gray1Reader(const void *data) : BaseReader<uint8>(data), bit(7) {} 865338b8dc3SIngo Weinhold 866338b8dc3SIngo Weinhold inline void SetTo(const void *data) 867338b8dc3SIngo Weinhold { 868338b8dc3SIngo Weinhold pixels = (const pixel_t*)data; 869338b8dc3SIngo Weinhold bit = 7; 870338b8dc3SIngo Weinhold } 871338b8dc3SIngo Weinhold 872338b8dc3SIngo Weinhold inline void NextRow(int32 skip) 873338b8dc3SIngo Weinhold { 874338b8dc3SIngo Weinhold if (bit == 7) 875338b8dc3SIngo Weinhold pixels = (const pixel_t*)((const char*)pixels + skip); 876338b8dc3SIngo Weinhold else { 877338b8dc3SIngo Weinhold pixels = (const pixel_t*)((const char*)pixels + skip + 1); 878338b8dc3SIngo Weinhold bit = 7; 879338b8dc3SIngo Weinhold } 880338b8dc3SIngo Weinhold } 881338b8dc3SIngo Weinhold 882338b8dc3SIngo Weinhold inline void Read(rgb_color_value &color) 883338b8dc3SIngo Weinhold { 884338b8dc3SIngo Weinhold if (*pixels & bit_mask(bit)) 885338b8dc3SIngo Weinhold color.red = color.green = color.blue = 255; 886338b8dc3SIngo Weinhold else 887338b8dc3SIngo Weinhold color.red = color.green = color.blue = 0; 88863d557f0SMichael Lotz color.alpha = 255; 889338b8dc3SIngo Weinhold bit--; 890338b8dc3SIngo Weinhold if (bit == -1) { 891338b8dc3SIngo Weinhold pixels++; 892338b8dc3SIngo Weinhold bit = 7; 893338b8dc3SIngo Weinhold } 894338b8dc3SIngo Weinhold } 895338b8dc3SIngo Weinhold 896338b8dc3SIngo Weinhold inline void Read(gray_color_value &gray) 897338b8dc3SIngo Weinhold { 898338b8dc3SIngo Weinhold if (*pixels & bit_mask(bit)) 899338b8dc3SIngo Weinhold gray = 255; 900338b8dc3SIngo Weinhold else 901338b8dc3SIngo Weinhold gray = 0; 902338b8dc3SIngo Weinhold bit--; 903338b8dc3SIngo Weinhold if (bit == -1) { 904338b8dc3SIngo Weinhold pixels++; 905338b8dc3SIngo Weinhold bit = 7; 906338b8dc3SIngo Weinhold } 907338b8dc3SIngo Weinhold } 908338b8dc3SIngo Weinhold 909338b8dc3SIngo Weinhold int32 bit; 910338b8dc3SIngo Weinhold }; 911338b8dc3SIngo Weinhold 912338b8dc3SIngo Weinhold 91364b2d169SAxel Dörfler // #pragma mark - Writer classes 91464b2d169SAxel Dörfler 915338b8dc3SIngo Weinhold 916338b8dc3SIngo Weinhold // BaseWriter 917338b8dc3SIngo Weinhold template<typename _PixelType> 918338b8dc3SIngo Weinhold struct BaseWriter { 919338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 920338b8dc3SIngo Weinhold 921338b8dc3SIngo Weinhold BaseWriter(void *data) : pixels((pixel_t*)data) {} 922338b8dc3SIngo Weinhold 923338b8dc3SIngo Weinhold inline void SetTo(void *data) { pixels = (pixel_t*)data; } 924338b8dc3SIngo Weinhold 925338b8dc3SIngo Weinhold pixel_t *pixels; 926338b8dc3SIngo Weinhold }; 927338b8dc3SIngo Weinhold 928338b8dc3SIngo Weinhold 929338b8dc3SIngo Weinhold // RGB32Writer 930338b8dc3SIngo Weinhold template<typename _PixelType> 931338b8dc3SIngo Weinhold struct RGB32Writer : public BaseWriter<_PixelType> { 932338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 933338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 934338b8dc3SIngo Weinhold 935338b8dc3SIngo Weinhold RGB32Writer(void *data) : BaseWriter<_PixelType>(data) {} 936338b8dc3SIngo Weinhold 937338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color) 938338b8dc3SIngo Weinhold { 939338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 940338b8dc3SIngo Weinhold pixel.red = color.red; 941338b8dc3SIngo Weinhold pixel.green = color.green; 942338b8dc3SIngo Weinhold pixel.blue = color.blue; 943338b8dc3SIngo Weinhold pixel.alpha = color.alpha; 944338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++; 945338b8dc3SIngo Weinhold } 946338b8dc3SIngo Weinhold 947338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray) 948338b8dc3SIngo Weinhold { 949338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 950338b8dc3SIngo Weinhold pixel.red = gray; 951338b8dc3SIngo Weinhold pixel.green = gray; 952338b8dc3SIngo Weinhold pixel.blue = gray; 953338b8dc3SIngo Weinhold pixel.alpha = 255; 954338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++; 955338b8dc3SIngo Weinhold } 956338b8dc3SIngo Weinhold }; 957338b8dc3SIngo Weinhold 958338b8dc3SIngo Weinhold // RGB24Writer 959338b8dc3SIngo Weinhold template<typename _PixelType> 960338b8dc3SIngo Weinhold struct RGB24Writer : public BaseWriter<_PixelType> { 961338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 962338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 963338b8dc3SIngo Weinhold 964338b8dc3SIngo Weinhold RGB24Writer(void *data) : BaseWriter<_PixelType>(data) {} 965338b8dc3SIngo Weinhold 966338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color) 967338b8dc3SIngo Weinhold { 968338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 969338b8dc3SIngo Weinhold pixel.red = color.red; 970338b8dc3SIngo Weinhold pixel.green = color.green; 971338b8dc3SIngo Weinhold pixel.blue = color.blue; 972338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++; 973338b8dc3SIngo Weinhold } 974338b8dc3SIngo Weinhold 975338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray) 976338b8dc3SIngo Weinhold { 977338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 978338b8dc3SIngo Weinhold pixel.red = gray; 979338b8dc3SIngo Weinhold pixel.green = gray; 980338b8dc3SIngo Weinhold pixel.blue = gray; 981338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++; 982338b8dc3SIngo Weinhold } 983338b8dc3SIngo Weinhold }; 984338b8dc3SIngo Weinhold 985338b8dc3SIngo Weinhold // RGB16Writer 986338b8dc3SIngo Weinhold template<typename _PixelType> 987338b8dc3SIngo Weinhold struct RGB16Writer : public BaseWriter<_PixelType> { 988338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 989338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 990338b8dc3SIngo Weinhold 991338b8dc3SIngo Weinhold RGB16Writer(void *data) : BaseWriter<_PixelType>(data) {} 992338b8dc3SIngo Weinhold 993338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color) 994338b8dc3SIngo Weinhold { 995338b8dc3SIngo Weinhold // rg: R[4:0],G[5:3] 996338b8dc3SIngo Weinhold // gb: G[2:0],B[4:0] 997338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 998338b8dc3SIngo Weinhold pixel.rg = (color.red & 0xf8) | (color.green >> 5); 999338b8dc3SIngo Weinhold pixel.gb = ((color.green & 0x1c) << 3) | (color.blue >> 3); 1000338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++; 1001338b8dc3SIngo Weinhold } 1002338b8dc3SIngo Weinhold 1003338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray) 1004338b8dc3SIngo Weinhold { 1005338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 1006338b8dc3SIngo Weinhold pixel.rg = (gray & 0xf8) | (gray >> 5); 1007338b8dc3SIngo Weinhold pixel.gb = ((gray & 0x1c) << 3) | (gray >> 3); 1008338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++; 1009338b8dc3SIngo Weinhold } 1010338b8dc3SIngo Weinhold }; 1011338b8dc3SIngo Weinhold 1012338b8dc3SIngo Weinhold // RGB15Writer 1013338b8dc3SIngo Weinhold template<typename _PixelType> 1014338b8dc3SIngo Weinhold struct RGB15Writer : public BaseWriter<_PixelType> { 1015338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 1016338b8dc3SIngo Weinhold typedef _PixelType pixel_t; 1017338b8dc3SIngo Weinhold 1018338b8dc3SIngo Weinhold RGB15Writer(void *data) : BaseWriter<_PixelType>(data) {} 1019338b8dc3SIngo Weinhold 1020338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color) 1021338b8dc3SIngo Weinhold { 1022338b8dc3SIngo Weinhold // rg: -[0],R[4:0],G[4:3] 1023338b8dc3SIngo Weinhold // gb: G[2:0],B[4:0] 1024338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 1025338b8dc3SIngo Weinhold pixel.rg = ((color.red & 0xf8) >> 1) | (color.green >> 6); 1026338b8dc3SIngo Weinhold pixel.gb = ((color.green & 0x38) << 2) | (color.blue >> 3); 1027338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++; 1028338b8dc3SIngo Weinhold } 1029338b8dc3SIngo Weinhold 1030338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray) 1031338b8dc3SIngo Weinhold { 1032338b8dc3SIngo Weinhold pixel_t &pixel = *BaseWriter<_PixelType>::pixels; 1033338b8dc3SIngo Weinhold pixel.rg = ((gray & 0xf8) >> 1) | (gray >> 6); 1034338b8dc3SIngo Weinhold pixel.gb = ((gray & 0x38) << 2) | (gray >> 3); 1035338b8dc3SIngo Weinhold BaseWriter<_PixelType>::pixels++; 1036338b8dc3SIngo Weinhold } 1037338b8dc3SIngo Weinhold }; 1038338b8dc3SIngo Weinhold 1039338b8dc3SIngo Weinhold // CMAP8Writer 1040338b8dc3SIngo Weinhold struct CMAP8Writer : public BaseWriter<uint8> { 1041338b8dc3SIngo Weinhold typedef rgb_color_value preferred_color_value_t; 1042338b8dc3SIngo Weinhold 1043338b8dc3SIngo Weinhold CMAP8Writer(void *data, const PaletteConverter &converter) 1044338b8dc3SIngo Weinhold : BaseWriter<uint8>(data), converter(converter) {} 1045338b8dc3SIngo Weinhold 1046338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color) 1047338b8dc3SIngo Weinhold { 1048338b8dc3SIngo Weinhold *pixels = converter.IndexForRGB24(color.red, color.green, color.blue); 1049338b8dc3SIngo Weinhold pixels++; 1050338b8dc3SIngo Weinhold } 1051338b8dc3SIngo Weinhold 1052338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray) 1053338b8dc3SIngo Weinhold { 1054338b8dc3SIngo Weinhold *pixels = converter.IndexForGray(gray); 1055338b8dc3SIngo Weinhold pixels++; 1056338b8dc3SIngo Weinhold } 1057338b8dc3SIngo Weinhold 1058338b8dc3SIngo Weinhold const PaletteConverter &converter; 1059338b8dc3SIngo Weinhold }; 1060338b8dc3SIngo Weinhold 1061338b8dc3SIngo Weinhold // Gray8Writer 1062338b8dc3SIngo Weinhold struct Gray8Writer : public BaseWriter<uint8> { 1063338b8dc3SIngo Weinhold typedef gray_color_value preferred_color_value_t; 1064338b8dc3SIngo Weinhold 1065338b8dc3SIngo Weinhold Gray8Writer(void *data) : BaseWriter<uint8>(data) {} 1066338b8dc3SIngo Weinhold 1067338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color) 1068338b8dc3SIngo Weinhold { 1069338b8dc3SIngo Weinhold *pixels = brightness_for(color.red, color.green, color.blue); 1070338b8dc3SIngo Weinhold pixels++; 1071338b8dc3SIngo Weinhold } 1072338b8dc3SIngo Weinhold 1073338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray) 1074338b8dc3SIngo Weinhold { 1075338b8dc3SIngo Weinhold *pixels = gray; 1076338b8dc3SIngo Weinhold pixels++; 1077338b8dc3SIngo Weinhold } 1078338b8dc3SIngo Weinhold }; 1079338b8dc3SIngo Weinhold 1080338b8dc3SIngo Weinhold // Gray1Writer 1081338b8dc3SIngo Weinhold struct Gray1Writer : public BaseWriter<uint8> { 1082338b8dc3SIngo Weinhold typedef gray_color_value preferred_color_value_t; 1083338b8dc3SIngo Weinhold 1084338b8dc3SIngo Weinhold Gray1Writer(void *data) : BaseWriter<uint8>(data), bit(7) {} 1085338b8dc3SIngo Weinhold 1086338b8dc3SIngo Weinhold inline void SetTo(void *data) { pixels = (pixel_t*)data; bit = 7; } 1087338b8dc3SIngo Weinhold 1088338b8dc3SIngo Weinhold inline void Write(const gray_color_value &gray) 1089338b8dc3SIngo Weinhold { 1090338b8dc3SIngo Weinhold *pixels = (*pixels & inverse_bit_mask(bit)) 1091338b8dc3SIngo Weinhold | (gray & 0x80) >> (7 - bit); 1092338b8dc3SIngo Weinhold bit--; 1093338b8dc3SIngo Weinhold if (bit == -1) { 1094338b8dc3SIngo Weinhold pixels++; 1095338b8dc3SIngo Weinhold bit = 7; 1096338b8dc3SIngo Weinhold } 1097338b8dc3SIngo Weinhold } 1098338b8dc3SIngo Weinhold 1099338b8dc3SIngo Weinhold inline void Write(const rgb_color_value &color) 1100338b8dc3SIngo Weinhold { 1101338b8dc3SIngo Weinhold Write(brightness_for(color.red, color.green, color.blue)); 1102338b8dc3SIngo Weinhold } 1103338b8dc3SIngo Weinhold 1104338b8dc3SIngo Weinhold int32 bit; 1105338b8dc3SIngo Weinhold }; 1106338b8dc3SIngo Weinhold 1107338b8dc3SIngo Weinhold 1108338b8dc3SIngo Weinhold // set_bits_worker 1109338b8dc3SIngo Weinhold /*! \brief Worker function that reads bitmap data from one buffer and writes 1110338b8dc3SIngo Weinhold it (converted) to another one. 1111338b8dc3SIngo Weinhold \param Reader The pixel reader class. 1112338b8dc3SIngo Weinhold \param Writer The pixel writer class. 1113338b8dc3SIngo Weinhold \param color_value_t The color value type used to transport a pixel from 1114338b8dc3SIngo Weinhold the reader to the writer. 1115338b8dc3SIngo Weinhold \param inData A pointer to the buffer to be read. 1116338b8dc3SIngo Weinhold \param inLength The length (in bytes) of the "in" buffer. 1117338b8dc3SIngo Weinhold \param inBPR The number of bytes per row in the "in" buffer. 1118338b8dc3SIngo Weinhold \param inRowSkip The number of bytes per row in the "in" buffer serving as 1119338b8dc3SIngo Weinhold padding. 1120338b8dc3SIngo Weinhold \param outData A pointer to the buffer to be written to. 1121338b8dc3SIngo Weinhold \param outLength The length (in bytes) of the "out" buffer. 1122338b8dc3SIngo Weinhold \param outOffset The offset (in bytes) relative to \a outData from which 1123338b8dc3SIngo Weinhold the function shall start writing. 1124338b8dc3SIngo Weinhold \param outBPR The number of bytes per row in the "out" buffer. 1125338b8dc3SIngo Weinhold \param rawOutBPR The number of bytes per row in the "out" buffer actually 1126338b8dc3SIngo Weinhold containing bitmap data (i.e. not including the padding). 1127338b8dc3SIngo Weinhold \param _reader A reader object. The pointer to the data doesn't need to 1128338b8dc3SIngo Weinhold be initialized. 1129338b8dc3SIngo Weinhold \param _writer A writer object. The pointer to the data doesn't need to 1130338b8dc3SIngo Weinhold be initialized. 1131338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise. 1132338b8dc3SIngo Weinhold */ 1133338b8dc3SIngo Weinhold template<typename Reader, typename Writer, typename color_value_t> 1134338b8dc3SIngo Weinhold static 1135338b8dc3SIngo Weinhold status_t 1136338b8dc3SIngo Weinhold set_bits_worker(const void *inData, int32 inLength, int32 inBPR, 1137338b8dc3SIngo Weinhold int32 inRowSkip, void *outData, int32 outLength, 1138338b8dc3SIngo Weinhold int32 outOffset, int32 outBPR, int32 rawOutBPR, 1139338b8dc3SIngo Weinhold Reader _reader, Writer _writer) 1140338b8dc3SIngo Weinhold { 1141338b8dc3SIngo Weinhold status_t error = B_OK; 1142338b8dc3SIngo Weinhold Reader reader(_reader); 1143338b8dc3SIngo Weinhold Writer writer(_writer); 1144338b8dc3SIngo Weinhold reader.SetTo(inData); 1145338b8dc3SIngo Weinhold writer.SetTo((char*)outData + outOffset); 1146338b8dc3SIngo Weinhold const char *inEnd = (const char*)inData + inLength 1147338b8dc3SIngo Weinhold - sizeof(typename Reader::pixel_t); 1148338b8dc3SIngo Weinhold const char *inLastRow = (const char*)inData + inLength 1149338b8dc3SIngo Weinhold - (inBPR - inRowSkip); 1150338b8dc3SIngo Weinhold const char *outEnd = (const char*)outData + outLength 1151338b8dc3SIngo Weinhold - sizeof(typename Writer::pixel_t); 1152338b8dc3SIngo Weinhold char *outRow = (char*)outData + outOffset - outOffset % outBPR; 1153338b8dc3SIngo Weinhold const char *outRowEnd = outRow + rawOutBPR - sizeof(typename Writer::pixel_t); 1154338b8dc3SIngo Weinhold while ((const char*)reader.pixels <= inEnd 1155338b8dc3SIngo Weinhold && (const char*)writer.pixels <= outEnd) { 1156338b8dc3SIngo Weinhold // process one row 1157338b8dc3SIngo Weinhold if ((const char*)reader.pixels <= inLastRow) { 1158338b8dc3SIngo Weinhold // at least a complete row left 1159338b8dc3SIngo Weinhold while ((const char*)writer.pixels <= outRowEnd) { 1160338b8dc3SIngo Weinhold color_value_t color; 1161338b8dc3SIngo Weinhold reader.Read(color); 1162338b8dc3SIngo Weinhold writer.Write(color); 1163338b8dc3SIngo Weinhold } 1164338b8dc3SIngo Weinhold } else { 1165338b8dc3SIngo Weinhold // no complete row left 1166338b8dc3SIngo Weinhold // but maybe the complete end of the first row 1167338b8dc3SIngo Weinhold while ((const char*)reader.pixels <= inEnd 1168338b8dc3SIngo Weinhold && (const char*)writer.pixels <= outRowEnd) { 1169338b8dc3SIngo Weinhold color_value_t color; 1170338b8dc3SIngo Weinhold reader.Read(color); 1171338b8dc3SIngo Weinhold writer.Write(color); 1172338b8dc3SIngo Weinhold } 1173338b8dc3SIngo Weinhold } 1174338b8dc3SIngo Weinhold // must be here, not in the if-branch (end of first row) 1175338b8dc3SIngo Weinhold outRow += outBPR; 1176338b8dc3SIngo Weinhold outRowEnd += outBPR; 1177338b8dc3SIngo Weinhold reader.NextRow(inRowSkip); 1178338b8dc3SIngo Weinhold writer.SetTo(outRow); 1179338b8dc3SIngo Weinhold } 1180338b8dc3SIngo Weinhold return error; 1181338b8dc3SIngo Weinhold } 1182338b8dc3SIngo Weinhold 1183338b8dc3SIngo Weinhold // set_bits_worker_gray1 1184338b8dc3SIngo Weinhold /*! \brief Worker function that reads bitmap data from one buffer and writes 1185338b8dc3SIngo Weinhold it (converted) to another one, which uses color space \c B_GRAY1. 1186338b8dc3SIngo Weinhold \param Reader The pixel reader class. 1187338b8dc3SIngo Weinhold \param Writer The pixel writer class. 1188338b8dc3SIngo Weinhold \param color_value_t The color value type used to transport a pixel from 1189338b8dc3SIngo Weinhold the reader to the writer. 1190338b8dc3SIngo Weinhold \param inData A pointer to the buffer to be read. 1191338b8dc3SIngo Weinhold \param inLength The length (in bytes) of the "in" buffer. 1192338b8dc3SIngo Weinhold \param inBPR The number of bytes per row in the "in" buffer. 1193338b8dc3SIngo Weinhold \param inRowSkip The number of bytes per row in the "in" buffer serving as 1194338b8dc3SIngo Weinhold padding. 1195338b8dc3SIngo Weinhold \param outData A pointer to the buffer to be written to. 1196338b8dc3SIngo Weinhold \param outLength The length (in bytes) of the "out" buffer. 1197338b8dc3SIngo Weinhold \param outOffset The offset (in bytes) relative to \a outData from which 1198338b8dc3SIngo Weinhold the function shall start writing. 1199338b8dc3SIngo Weinhold \param outBPR The number of bytes per row in the "out" buffer. 1200338b8dc3SIngo Weinhold \param width The number of pixels per row in "in" and "out" data. 1201338b8dc3SIngo Weinhold \param _reader A reader object. The pointer to the data doesn't need to 1202338b8dc3SIngo Weinhold be initialized. 1203338b8dc3SIngo Weinhold \param _writer A writer object. The pointer to the data doesn't need to 1204338b8dc3SIngo Weinhold be initialized. 1205338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise. 1206338b8dc3SIngo Weinhold */ 1207338b8dc3SIngo Weinhold template<typename Reader, typename Writer, typename color_value_t> 1208338b8dc3SIngo Weinhold static 1209338b8dc3SIngo Weinhold status_t 1210338b8dc3SIngo Weinhold set_bits_worker_gray1(const void *inData, int32 inLength, int32 inBPR, 1211338b8dc3SIngo Weinhold int32 inRowSkip, void *outData, int32 outLength, 1212338b8dc3SIngo Weinhold int32 outOffset, int32 outBPR, int32 width, 1213338b8dc3SIngo Weinhold Reader _reader, Writer _writer) 1214338b8dc3SIngo Weinhold { 1215338b8dc3SIngo Weinhold status_t error = B_OK; 1216338b8dc3SIngo Weinhold Reader reader(_reader); 1217338b8dc3SIngo Weinhold Writer writer(_writer); 1218338b8dc3SIngo Weinhold reader.SetTo(inData); 1219338b8dc3SIngo Weinhold writer.SetTo((char*)outData + outOffset); 1220338b8dc3SIngo Weinhold const char *inEnd = (const char*)inData + inLength 1221338b8dc3SIngo Weinhold - sizeof(typename Reader::pixel_t); 1222338b8dc3SIngo Weinhold const char *inLastRow = (const char*)inData + inLength 1223338b8dc3SIngo Weinhold - (inBPR - inRowSkip); 1224338b8dc3SIngo Weinhold const char *outEnd = (const char*)outData + outLength - outBPR; 1225338b8dc3SIngo Weinhold char *outRow = (char*)outData + outOffset - outOffset % outBPR; 1226*a8a03488SIngo Weinhold int32 x = max((int32)0, 1227*a8a03488SIngo Weinhold width - (int32)((char*)outData + outOffset - outRow) * 8) - 1; 1228338b8dc3SIngo Weinhold while ((const char*)reader.pixels <= inEnd 1229338b8dc3SIngo Weinhold && (const char*)writer.pixels <= outEnd) { 1230338b8dc3SIngo Weinhold // process one row 1231338b8dc3SIngo Weinhold if ((const char*)reader.pixels <= inLastRow) { 1232338b8dc3SIngo Weinhold // at least a complete row left 1233338b8dc3SIngo Weinhold while (x >= 0) { 1234338b8dc3SIngo Weinhold color_value_t color; 1235338b8dc3SIngo Weinhold reader.Read(color); 1236338b8dc3SIngo Weinhold writer.Write(color); 1237338b8dc3SIngo Weinhold x--; 1238338b8dc3SIngo Weinhold } 1239338b8dc3SIngo Weinhold } else { 1240338b8dc3SIngo Weinhold // no complete row left 1241338b8dc3SIngo Weinhold // but maybe the complete end of the first row 1242338b8dc3SIngo Weinhold while ((const char*)reader.pixels <= inEnd && x >= 0) { 1243338b8dc3SIngo Weinhold color_value_t color; 1244338b8dc3SIngo Weinhold reader.Read(color); 1245338b8dc3SIngo Weinhold writer.Write(color); 1246338b8dc3SIngo Weinhold x--; 1247338b8dc3SIngo Weinhold } 1248338b8dc3SIngo Weinhold } 1249338b8dc3SIngo Weinhold // must be here, not in the if-branch (end of first row) 1250338b8dc3SIngo Weinhold x = width - 1; 1251338b8dc3SIngo Weinhold outRow += outBPR; 1252338b8dc3SIngo Weinhold reader.NextRow(inRowSkip); 1253338b8dc3SIngo Weinhold writer.SetTo(outRow); 1254338b8dc3SIngo Weinhold } 1255338b8dc3SIngo Weinhold return error; 1256338b8dc3SIngo Weinhold } 1257338b8dc3SIngo Weinhold 1258338b8dc3SIngo Weinhold // set_bits 1259338b8dc3SIngo Weinhold /*! \brief Helper function that reads bitmap data from one buffer and writes 1260338b8dc3SIngo Weinhold it (converted) to another one. 1261338b8dc3SIngo Weinhold \param Reader The pixel reader class. 1262338b8dc3SIngo Weinhold \param inData A pointer to the buffer to be read. 1263338b8dc3SIngo Weinhold \param inLength The length (in bytes) of the "in" buffer. 1264338b8dc3SIngo Weinhold \param inBPR The number of bytes per row in the "in" buffer. 1265338b8dc3SIngo Weinhold \param inRowSkip The number of bytes per row in the "in" buffer serving as 1266338b8dc3SIngo Weinhold padding. 1267338b8dc3SIngo Weinhold \param outData A pointer to the buffer to be written to. 1268338b8dc3SIngo Weinhold \param outLength The length (in bytes) of the "out" buffer. 1269338b8dc3SIngo Weinhold \param outOffset The offset (in bytes) relative to \a outData from which 1270338b8dc3SIngo Weinhold the function shall start writing. 1271338b8dc3SIngo Weinhold \param outBPR The number of bytes per row in the "out" buffer. 1272338b8dc3SIngo Weinhold \param rawOutBPR The number of bytes per row in the "out" buffer actually 1273338b8dc3SIngo Weinhold containing bitmap data (i.e. not including the padding). 1274338b8dc3SIngo Weinhold \param outColorSpace Color space of the target buffer. 1275338b8dc3SIngo Weinhold \param width The number of pixels per row in "in" and "out" data. 1276338b8dc3SIngo Weinhold \param reader A reader object. The pointer to the data doesn't need to 1277338b8dc3SIngo Weinhold be initialized. 1278338b8dc3SIngo Weinhold \param paletteConverter Reference to a PaletteConverter to be used, if 1279338b8dc3SIngo Weinhold a conversion from or to \c B_CMAP8 has to be done. 1280338b8dc3SIngo Weinhold \return \c B_OK, if everything went fine, an error code otherwise. 1281338b8dc3SIngo Weinhold */ 1282338b8dc3SIngo Weinhold template<typename Reader> 1283338b8dc3SIngo Weinhold static 1284338b8dc3SIngo Weinhold status_t 1285338b8dc3SIngo Weinhold set_bits(const void *inData, int32 inLength, int32 inBPR, int32 inRowSkip, 1286338b8dc3SIngo Weinhold void *outData, int32 outLength, int32 outOffset, int32 outBPR, 1287338b8dc3SIngo Weinhold int32 rawOutBPR, color_space outColorSpace, int32 width, 1288338b8dc3SIngo Weinhold Reader reader, const PaletteConverter &paletteConverter) 1289338b8dc3SIngo Weinhold { 1290338b8dc3SIngo Weinhold status_t error = B_OK; 1291338b8dc3SIngo Weinhold switch (outColorSpace) { 1292338b8dc3SIngo Weinhold // supported 1293338b8dc3SIngo Weinhold case B_RGB32: case B_RGBA32: 1294338b8dc3SIngo Weinhold { 1295338b8dc3SIngo Weinhold typedef RGB32Writer<rgb32_pixel> Writer; 1296338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1297338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1298338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1299338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1300338b8dc3SIngo Weinhold break; 1301338b8dc3SIngo Weinhold } 1302338b8dc3SIngo Weinhold case B_RGB32_BIG: case B_RGBA32_BIG: 1303338b8dc3SIngo Weinhold { 1304338b8dc3SIngo Weinhold typedef RGB32Writer<rgb32_big_pixel> Writer; 1305338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1306338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1307338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1308338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1309338b8dc3SIngo Weinhold break; 1310338b8dc3SIngo Weinhold } 1311338b8dc3SIngo Weinhold case B_RGB24: 1312338b8dc3SIngo Weinhold { 1313338b8dc3SIngo Weinhold typedef RGB24Writer<rgb24_pixel> Writer; 1314338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1315338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1316338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1317338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1318338b8dc3SIngo Weinhold break; 1319338b8dc3SIngo Weinhold } 1320338b8dc3SIngo Weinhold case B_RGB24_BIG: 1321338b8dc3SIngo Weinhold { 1322338b8dc3SIngo Weinhold typedef RGB24Writer<rgb24_big_pixel> Writer; 1323338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1324338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1325338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1326338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1327338b8dc3SIngo Weinhold break; 1328338b8dc3SIngo Weinhold } 1329338b8dc3SIngo Weinhold case B_RGB16: 1330338b8dc3SIngo Weinhold { 1331338b8dc3SIngo Weinhold typedef RGB16Writer<rgb16_pixel> Writer; 1332338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1333338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1334338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1335338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1336338b8dc3SIngo Weinhold break; 1337338b8dc3SIngo Weinhold } 1338338b8dc3SIngo Weinhold case B_RGB16_BIG: 1339338b8dc3SIngo Weinhold { 1340338b8dc3SIngo Weinhold typedef RGB16Writer<rgb16_big_pixel> Writer; 1341338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1342338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1343338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1344338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1345338b8dc3SIngo Weinhold break; 1346338b8dc3SIngo Weinhold } 1347338b8dc3SIngo Weinhold case B_RGB15: case B_RGBA15: 1348338b8dc3SIngo Weinhold { 1349338b8dc3SIngo Weinhold typedef RGB15Writer<rgb16_pixel> Writer; 1350338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1351338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1352338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1353338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1354338b8dc3SIngo Weinhold break; 1355338b8dc3SIngo Weinhold } 1356338b8dc3SIngo Weinhold case B_RGB15_BIG: case B_RGBA15_BIG: 1357338b8dc3SIngo Weinhold { 1358338b8dc3SIngo Weinhold typedef RGB15Writer<rgb16_big_pixel> Writer; 1359338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1360338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1361338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1362338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1363338b8dc3SIngo Weinhold break; 1364338b8dc3SIngo Weinhold } 1365338b8dc3SIngo Weinhold case B_CMAP8: 1366338b8dc3SIngo Weinhold { 1367338b8dc3SIngo Weinhold typedef CMAP8Writer Writer; 1368338b8dc3SIngo Weinhold typedef typename Reader::preferred_color_value_t color_value_t; 1369338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1370338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1371338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, 1372338b8dc3SIngo Weinhold Writer(outData, paletteConverter)); 1373338b8dc3SIngo Weinhold break; 1374338b8dc3SIngo Weinhold } 1375338b8dc3SIngo Weinhold case B_GRAY8: 1376338b8dc3SIngo Weinhold { 1377338b8dc3SIngo Weinhold typedef Gray8Writer Writer; 1378338b8dc3SIngo Weinhold typedef gray_color_value color_value_t; 1379338b8dc3SIngo Weinhold error = set_bits_worker<Reader, Writer, color_value_t>( 1380338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1381338b8dc3SIngo Weinhold outOffset, outBPR, rawOutBPR, reader, Writer(outData)); 1382338b8dc3SIngo Weinhold break; 1383338b8dc3SIngo Weinhold } 1384338b8dc3SIngo Weinhold case B_GRAY1: 1385338b8dc3SIngo Weinhold { 1386338b8dc3SIngo Weinhold typedef Gray1Writer Writer; 1387338b8dc3SIngo Weinhold typedef gray_color_value color_value_t; 1388338b8dc3SIngo Weinhold error = set_bits_worker_gray1<Reader, Writer, color_value_t>( 1389338b8dc3SIngo Weinhold inData, inLength, inBPR, inRowSkip, outData, outLength, 1390338b8dc3SIngo Weinhold outOffset, outBPR, width, reader, Writer(outData)); 1391338b8dc3SIngo Weinhold break; 1392338b8dc3SIngo Weinhold } 1393338b8dc3SIngo Weinhold // unsupported 1394338b8dc3SIngo Weinhold case B_NO_COLOR_SPACE: 1395338b8dc3SIngo Weinhold case B_YUV9: case B_YUV12: 1396338b8dc3SIngo Weinhold case B_UVL32: case B_UVLA32: 1397338b8dc3SIngo Weinhold case B_LAB32: case B_LABA32: 1398338b8dc3SIngo Weinhold case B_HSI32: case B_HSIA32: 1399338b8dc3SIngo Weinhold case B_HSV32: case B_HSVA32: 1400338b8dc3SIngo Weinhold case B_HLS32: case B_HLSA32: 1401338b8dc3SIngo Weinhold case B_CMY32: case B_CMYA32: case B_CMYK32: 1402338b8dc3SIngo Weinhold case B_UVL24: case B_LAB24: case B_HSI24: 1403338b8dc3SIngo Weinhold case B_HSV24: case B_HLS24: case B_CMY24: 1404338b8dc3SIngo Weinhold case B_YCbCr422: case B_YUV422: 1405338b8dc3SIngo Weinhold case B_YCbCr411: case B_YUV411: 1406338b8dc3SIngo Weinhold case B_YCbCr444: case B_YUV444: 1407338b8dc3SIngo Weinhold case B_YCbCr420: case B_YUV420: 1408338b8dc3SIngo Weinhold default: 1409338b8dc3SIngo Weinhold error = B_BAD_VALUE; 1410338b8dc3SIngo Weinhold break; 1411338b8dc3SIngo Weinhold } 1412338b8dc3SIngo Weinhold return error; 1413338b8dc3SIngo Weinhold } 1414338b8dc3SIngo Weinhold 141564b2d169SAxel Dörfler 141664b2d169SAxel Dörfler // #pragma mark - Bitmap 141764b2d169SAxel Dörfler 141864b2d169SAxel Dörfler 141964b2d169SAxel Dörfler /*! \brief Creates and initializes a BBitmap. 142064b2d169SAxel Dörfler \param bounds The bitmap dimensions. 142164b2d169SAxel Dörfler \param flags Creation flags. 142264b2d169SAxel Dörfler \param colorSpace The bitmap's color space. 142364b2d169SAxel Dörfler \param bytesPerRow The number of bytes per row the bitmap should use. 142464b2d169SAxel Dörfler \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate 142564b2d169SAxel Dörfler value. 142664b2d169SAxel Dörfler \param screenID ??? 142764b2d169SAxel Dörfler */ 142864b2d169SAxel Dörfler BBitmap::BBitmap(BRect bounds, uint32 flags, color_space colorSpace, 142964b2d169SAxel Dörfler int32 bytesPerRow, screen_id screenID) 143064b2d169SAxel Dörfler : fBasePtr(NULL), 143164b2d169SAxel Dörfler fSize(0), 143264b2d169SAxel Dörfler fColorSpace(B_NO_COLOR_SPACE), 143364b2d169SAxel Dörfler fBounds(0, 0, -1, -1), 143464b2d169SAxel Dörfler fBytesPerRow(0), 143564b2d169SAxel Dörfler fServerToken(-1), 143664b2d169SAxel Dörfler fToken(-1), 143764b2d169SAxel Dörfler fArea(-1), 143864b2d169SAxel Dörfler fOrigArea(-1), 143964b2d169SAxel Dörfler fFlags(0), 144064b2d169SAxel Dörfler fInitError(B_NO_INIT) 144164b2d169SAxel Dörfler { 144264b2d169SAxel Dörfler InitObject(bounds, colorSpace, flags, bytesPerRow, screenID); 144364b2d169SAxel Dörfler } 144464b2d169SAxel Dörfler 144564b2d169SAxel Dörfler 144664b2d169SAxel Dörfler /*! \brief Creates and initializes a BBitmap. 144764b2d169SAxel Dörfler \param bounds The bitmap dimensions. 144864b2d169SAxel Dörfler \param colorSpace The bitmap's color space. 144964b2d169SAxel Dörfler \param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if 145064b2d169SAxel Dörfler it shall be possible to attach BView to the bitmap and draw into 145164b2d169SAxel Dörfler it. 145264b2d169SAxel Dörfler \param needsContiguous If \c true a physically contiguous chunk of memory 145364b2d169SAxel Dörfler will be allocated. 145464b2d169SAxel Dörfler */ 145564b2d169SAxel Dörfler BBitmap::BBitmap(BRect bounds, color_space colorSpace, bool acceptsViews, 145664b2d169SAxel Dörfler bool needsContiguous) 145764b2d169SAxel Dörfler : fBasePtr(NULL), 145864b2d169SAxel Dörfler fSize(0), 145964b2d169SAxel Dörfler fColorSpace(B_NO_COLOR_SPACE), 146064b2d169SAxel Dörfler fBounds(0, 0, -1, -1), 146164b2d169SAxel Dörfler fBytesPerRow(0), 146264b2d169SAxel Dörfler fServerToken(-1), 146364b2d169SAxel Dörfler fToken(-1), 146464b2d169SAxel Dörfler fArea(-1), 146564b2d169SAxel Dörfler fOrigArea(-1), 146664b2d169SAxel Dörfler fFlags(0), 146764b2d169SAxel Dörfler fInitError(B_NO_INIT) 146864b2d169SAxel Dörfler { 146964b2d169SAxel Dörfler int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0) 147064b2d169SAxel Dörfler | (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0); 147164b2d169SAxel Dörfler InitObject(bounds, colorSpace, flags, B_ANY_BYTES_PER_ROW, 147264b2d169SAxel Dörfler B_MAIN_SCREEN_ID); 147364b2d169SAxel Dörfler 147464b2d169SAxel Dörfler } 147564b2d169SAxel Dörfler 147664b2d169SAxel Dörfler 147764b2d169SAxel Dörfler /*! \brief Creates a BBitmap as a clone of another bitmap. 147864b2d169SAxel Dörfler \param source The source bitmap. 147964b2d169SAxel Dörfler \param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if 148064b2d169SAxel Dörfler it shall be possible to attach BView to the bitmap and draw into 148164b2d169SAxel Dörfler it. 148264b2d169SAxel Dörfler \param needsContiguous If \c true a physically contiguous chunk of memory 148364b2d169SAxel Dörfler will be allocated. 148464b2d169SAxel Dörfler */ 148564b2d169SAxel Dörfler BBitmap::BBitmap(const BBitmap *source, bool acceptsViews, 148664b2d169SAxel Dörfler bool needsContiguous) 148764b2d169SAxel Dörfler : fBasePtr(NULL), 148864b2d169SAxel Dörfler fSize(0), 148964b2d169SAxel Dörfler fColorSpace(B_NO_COLOR_SPACE), 149064b2d169SAxel Dörfler fBounds(0, 0, -1, -1), 149164b2d169SAxel Dörfler fBytesPerRow(0), 149264b2d169SAxel Dörfler fServerToken(-1), 149364b2d169SAxel Dörfler fToken(-1), 149464b2d169SAxel Dörfler fArea(-1), 149564b2d169SAxel Dörfler fOrigArea(-1), 149664b2d169SAxel Dörfler fFlags(0), 149764b2d169SAxel Dörfler fInitError(B_NO_INIT) 149864b2d169SAxel Dörfler { 149964b2d169SAxel Dörfler if (source && source->IsValid()) { 150064b2d169SAxel Dörfler int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0) 150164b2d169SAxel Dörfler | (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0); 150264b2d169SAxel Dörfler InitObject(source->Bounds(), source->ColorSpace(), flags, 150364b2d169SAxel Dörfler source->BytesPerRow(), B_MAIN_SCREEN_ID); 150464b2d169SAxel Dörfler if (InitCheck() == B_OK) 150564b2d169SAxel Dörfler memcpy(Bits(), source->Bits(), BytesPerRow()); 150664b2d169SAxel Dörfler } 150764b2d169SAxel Dörfler } 150864b2d169SAxel Dörfler 150964b2d169SAxel Dörfler 151064b2d169SAxel Dörfler /*! \brief Frees all resources associated with this object. */ 151164b2d169SAxel Dörfler BBitmap::~BBitmap() 151264b2d169SAxel Dörfler { 151364b2d169SAxel Dörfler CleanUp(); 151464b2d169SAxel Dörfler } 151564b2d169SAxel Dörfler 151664b2d169SAxel Dörfler 151764b2d169SAxel Dörfler /*! \brief Unarchives a bitmap from a BMessage. 151864b2d169SAxel Dörfler \param data The archive. 151964b2d169SAxel Dörfler */ 152064b2d169SAxel Dörfler BBitmap::BBitmap(BMessage *data) 152164b2d169SAxel Dörfler : BArchivable(data), 152264b2d169SAxel Dörfler fBasePtr(NULL), 152364b2d169SAxel Dörfler fSize(0), 152464b2d169SAxel Dörfler fColorSpace(B_NO_COLOR_SPACE), 152564b2d169SAxel Dörfler fBounds(0, 0, -1, -1), 152664b2d169SAxel Dörfler fBytesPerRow(0), 152764b2d169SAxel Dörfler fServerToken(-1), 152864b2d169SAxel Dörfler fToken(-1), 152964b2d169SAxel Dörfler fArea(-1), 153064b2d169SAxel Dörfler fOrigArea(-1), 153164b2d169SAxel Dörfler fFlags(0), 153264b2d169SAxel Dörfler fInitError(B_NO_INIT) 153364b2d169SAxel Dörfler { 153464b2d169SAxel Dörfler BRect bounds; 153564b2d169SAxel Dörfler data->FindRect("_frame", &bounds); 153664b2d169SAxel Dörfler 153764b2d169SAxel Dörfler color_space cspace; 153864b2d169SAxel Dörfler data->FindInt32("_cspace", (int32 *)&cspace); 153964b2d169SAxel Dörfler 154064b2d169SAxel Dörfler int32 flags = 0; 154164b2d169SAxel Dörfler data->FindInt32("_bmflags", &flags); 154264b2d169SAxel Dörfler 154364b2d169SAxel Dörfler int32 rowbytes = 0; 154464b2d169SAxel Dörfler data->FindInt32("_rowbytes", &rowbytes); 154564b2d169SAxel Dörfler 154664b2d169SAxel Dörfler flags |= B_BITMAP_NO_SERVER_LINK; 154764b2d169SAxel Dörfler flags &= ~B_BITMAP_ACCEPTS_VIEWS; 154864b2d169SAxel Dörfler InitObject(bounds, cspace, flags, rowbytes, B_MAIN_SCREEN_ID); 154964b2d169SAxel Dörfler 155064b2d169SAxel Dörfler if (data->HasData("_data", B_RAW_TYPE) && InitCheck() == B_OK) { 155164b2d169SAxel Dörfler ssize_t size = 0; 155264b2d169SAxel Dörfler const void *buffer; 155364b2d169SAxel Dörfler if (data->FindData("_data", B_RAW_TYPE, &buffer, &size) == B_OK) 155464b2d169SAxel Dörfler memcpy(fBasePtr, buffer, size); 155564b2d169SAxel Dörfler } 155664b2d169SAxel Dörfler 155764b2d169SAxel Dörfler if (fFlags & B_BITMAP_ACCEPTS_VIEWS) { 155864b2d169SAxel Dörfler // BArchivable *obj; 155964b2d169SAxel Dörfler // BMessage message; 156064b2d169SAxel Dörfler // int i = 0; 156164b2d169SAxel Dörfler // 156264b2d169SAxel Dörfler // while (data->FindMessage("_view", i++, &message) == B_OK) { 156364b2d169SAxel Dörfler // obj = instantiate_object(&message); 156464b2d169SAxel Dörfler // BView *view = dynamic_cast<BView *>(obj); 156564b2d169SAxel Dörfler // 156664b2d169SAxel Dörfler // if (view) 156764b2d169SAxel Dörfler // AddChild(view); 156864b2d169SAxel Dörfler // } 156964b2d169SAxel Dörfler } 157064b2d169SAxel Dörfler } 157164b2d169SAxel Dörfler 157264b2d169SAxel Dörfler 157364b2d169SAxel Dörfler /*! \brief Instantiates a BBitmap from an archive. 157464b2d169SAxel Dörfler \param data The archive. 157564b2d169SAxel Dörfler \return A bitmap reconstructed from the archive or \c NULL, if an error 157664b2d169SAxel Dörfler occured. 157764b2d169SAxel Dörfler */ 157864b2d169SAxel Dörfler BArchivable * 157964b2d169SAxel Dörfler BBitmap::Instantiate(BMessage *data) 158064b2d169SAxel Dörfler { 158164b2d169SAxel Dörfler if (validate_instantiation(data, "BBitmap")) 158264b2d169SAxel Dörfler return new BBitmap(data); 158364b2d169SAxel Dörfler 158464b2d169SAxel Dörfler return NULL; 158564b2d169SAxel Dörfler } 158664b2d169SAxel Dörfler 158764b2d169SAxel Dörfler 158864b2d169SAxel Dörfler /*! \brief Archives the BBitmap object. 158964b2d169SAxel Dörfler \param data The archive. 159064b2d169SAxel Dörfler \param deep \c true, if child object shall be archived as well, \c false 159164b2d169SAxel Dörfler otherwise. 159264b2d169SAxel Dörfler \return \c B_OK, if everything went fine, an error code otherwise. 159364b2d169SAxel Dörfler */ 159464b2d169SAxel Dörfler status_t 159564b2d169SAxel Dörfler BBitmap::Archive(BMessage *data, bool deep) const 159664b2d169SAxel Dörfler { 159764b2d169SAxel Dörfler BArchivable::Archive(data, deep); 159864b2d169SAxel Dörfler 159964b2d169SAxel Dörfler data->AddRect("_frame", fBounds); 160064b2d169SAxel Dörfler data->AddInt32("_cspace", (int32)fColorSpace); 160164b2d169SAxel Dörfler data->AddInt32("_bmflags", fFlags); 160264b2d169SAxel Dörfler data->AddInt32("_rowbytes", fBytesPerRow); 160364b2d169SAxel Dörfler 160464b2d169SAxel Dörfler if (deep) { 160564b2d169SAxel Dörfler if (fFlags & B_BITMAP_ACCEPTS_VIEWS) { 160664b2d169SAxel Dörfler // BMessage views; 160764b2d169SAxel Dörfler // for (int32 i = 0; i < CountChildren(); i++) { 160864b2d169SAxel Dörfler // if (ChildAt(i)->Archive(&views, deep)) 160964b2d169SAxel Dörfler // data->AddMessage("_views", &views); 161064b2d169SAxel Dörfler // } 161164b2d169SAxel Dörfler } 161264b2d169SAxel Dörfler // Note: R5 does not archive the data if B_BITMAP_IS_CONTIGNUOUS is 161364b2d169SAxel Dörfler // true and it does save all formats as B_RAW_TYPE and it does save 161464b2d169SAxel Dörfler // the data even if B_BITMAP_ACCEPTS_VIEWS is set (as opposed to 161564b2d169SAxel Dörfler // the BeBook) 161664b2d169SAxel Dörfler 161764b2d169SAxel Dörfler data->AddData("_data", B_RAW_TYPE, fBasePtr, fSize); 161864b2d169SAxel Dörfler } 161964b2d169SAxel Dörfler 162064b2d169SAxel Dörfler return B_OK; 162164b2d169SAxel Dörfler } 162264b2d169SAxel Dörfler 162364b2d169SAxel Dörfler 162464b2d169SAxel Dörfler /*! \brief Returns the result from the construction. 162564b2d169SAxel Dörfler \return \c B_OK, if the object is properly initialized, an error code 162664b2d169SAxel Dörfler otherwise. 162764b2d169SAxel Dörfler */ 162864b2d169SAxel Dörfler status_t 162964b2d169SAxel Dörfler BBitmap::InitCheck() const 163064b2d169SAxel Dörfler { 163164b2d169SAxel Dörfler return fInitError; 163264b2d169SAxel Dörfler } 163364b2d169SAxel Dörfler 163464b2d169SAxel Dörfler 163564b2d169SAxel Dörfler /*! \brief Returns whether or not the BBitmap object is valid. 163664b2d169SAxel Dörfler \return \c true, if the object is properly initialized, \c false otherwise. 163764b2d169SAxel Dörfler */ 163864b2d169SAxel Dörfler bool 163964b2d169SAxel Dörfler BBitmap::IsValid() const 164064b2d169SAxel Dörfler { 164164b2d169SAxel Dörfler return (InitCheck() == B_OK); 164264b2d169SAxel Dörfler } 164364b2d169SAxel Dörfler 164464b2d169SAxel Dörfler 164564b2d169SAxel Dörfler status_t 164664b2d169SAxel Dörfler BBitmap::LockBits(uint32 *state) 164764b2d169SAxel Dörfler { 164864b2d169SAxel Dörfler return B_ERROR; 164964b2d169SAxel Dörfler } 165064b2d169SAxel Dörfler 165164b2d169SAxel Dörfler 165264b2d169SAxel Dörfler void 165364b2d169SAxel Dörfler BBitmap::UnlockBits() 165464b2d169SAxel Dörfler { 165564b2d169SAxel Dörfler } 165664b2d169SAxel Dörfler 165764b2d169SAxel Dörfler 165864b2d169SAxel Dörfler /*! \brief Returns the ID of the area the bitmap data reside in. 165964b2d169SAxel Dörfler \return The ID of the area the bitmap data reside in. 166064b2d169SAxel Dörfler */ 166164b2d169SAxel Dörfler area_id 166264b2d169SAxel Dörfler BBitmap::Area() const 166364b2d169SAxel Dörfler { 166464b2d169SAxel Dörfler return fArea; 166564b2d169SAxel Dörfler } 166664b2d169SAxel Dörfler 166764b2d169SAxel Dörfler 166864b2d169SAxel Dörfler /*! \brief Returns the pointer to the bitmap data. 166964b2d169SAxel Dörfler \return The pointer to the bitmap data. 167064b2d169SAxel Dörfler */ 167164b2d169SAxel Dörfler void * 167264b2d169SAxel Dörfler BBitmap::Bits() const 167364b2d169SAxel Dörfler { 167464b2d169SAxel Dörfler return fBasePtr; 167564b2d169SAxel Dörfler } 167664b2d169SAxel Dörfler 167764b2d169SAxel Dörfler 167864b2d169SAxel Dörfler /*! \brief Returns the size of the bitmap data. 167964b2d169SAxel Dörfler \return The size of the bitmap data. 168064b2d169SAxel Dörfler */ 168164b2d169SAxel Dörfler int32 168264b2d169SAxel Dörfler BBitmap::BitsLength() const 168364b2d169SAxel Dörfler { 168464b2d169SAxel Dörfler return fSize; 168564b2d169SAxel Dörfler } 168664b2d169SAxel Dörfler 168764b2d169SAxel Dörfler 168864b2d169SAxel Dörfler /*! \brief Returns the number of bytes used to store a row of bitmap data. 168964b2d169SAxel Dörfler \return The number of bytes used to store a row of bitmap data. 169064b2d169SAxel Dörfler */ 169164b2d169SAxel Dörfler int32 169264b2d169SAxel Dörfler BBitmap::BytesPerRow() const 169364b2d169SAxel Dörfler { 169464b2d169SAxel Dörfler return fBytesPerRow; 169564b2d169SAxel Dörfler } 169664b2d169SAxel Dörfler 169764b2d169SAxel Dörfler 169864b2d169SAxel Dörfler /*! \brief Returns the bitmap's color space. 169964b2d169SAxel Dörfler \return The bitmap's color space. 170064b2d169SAxel Dörfler */ 170164b2d169SAxel Dörfler color_space 170264b2d169SAxel Dörfler BBitmap::ColorSpace() const 170364b2d169SAxel Dörfler { 170464b2d169SAxel Dörfler return fColorSpace; 170564b2d169SAxel Dörfler } 170664b2d169SAxel Dörfler 170764b2d169SAxel Dörfler 170864b2d169SAxel Dörfler /*! \brief Returns the bitmap's dimensions. 170964b2d169SAxel Dörfler \return The bitmap's dimensions. 171064b2d169SAxel Dörfler */ 171164b2d169SAxel Dörfler BRect 171264b2d169SAxel Dörfler BBitmap::Bounds() const 171364b2d169SAxel Dörfler { 171464b2d169SAxel Dörfler return fBounds; 171564b2d169SAxel Dörfler } 171664b2d169SAxel Dörfler 171764b2d169SAxel Dörfler 1718338b8dc3SIngo Weinhold /*! \brief Assigns data to the bitmap. 1719338b8dc3SIngo Weinhold 1720338b8dc3SIngo Weinhold Data are directly written into the bitmap's data buffer, being converted 1721338b8dc3SIngo Weinhold beforehand, if necessary. Some conversions work rather unintuitively: 1722338b8dc3SIngo Weinhold - \c B_RGB32: The source buffer is supposed to contain \c B_RGB24_BIG 1723338b8dc3SIngo Weinhold data without padding at the end of the rows. 1724338b8dc3SIngo Weinhold - \c B_RGB32: The source buffer is supposed to contain \c B_CMAP8 1725338b8dc3SIngo Weinhold data without padding at the end of the rows. 1726338b8dc3SIngo Weinhold - other color spaces: The source buffer is supposed to contain data 1727338b8dc3SIngo Weinhold according to the specified color space being rowwise padded to int32. 1728338b8dc3SIngo Weinhold 1729338b8dc3SIngo Weinhold The currently supported source/target color spaces are 1730338b8dc3SIngo Weinhold \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}. 1731338b8dc3SIngo Weinhold 1732338b8dc3SIngo Weinhold \note As this methods is apparently a bit strange to use, OBOS introduces 1733338b8dc3SIngo Weinhold ImportBits() methods, which are recommended to be used instead. 1734338b8dc3SIngo Weinhold 1735338b8dc3SIngo Weinhold \param data The data to be copied. 1736338b8dc3SIngo Weinhold \param length The length in bytes of the data to be copied. 1737338b8dc3SIngo Weinhold \param offset The offset (in bytes) relative to beginning of the bitmap 1738338b8dc3SIngo Weinhold data specifying the position at which the source data shall be 1739338b8dc3SIngo Weinhold written. 1740338b8dc3SIngo Weinhold \param colorSpace Color space of the source data. 1741338b8dc3SIngo Weinhold */ 1742338b8dc3SIngo Weinhold void 1743338b8dc3SIngo Weinhold BBitmap::SetBits(const void *data, int32 length, int32 offset, 1744338b8dc3SIngo Weinhold color_space colorSpace) 1745338b8dc3SIngo Weinhold { 1746338b8dc3SIngo Weinhold status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT); 1747338b8dc3SIngo Weinhold // check params 1748338b8dc3SIngo Weinhold if (error == B_OK && (data == NULL || offset > fSize || length < 0)) 1749338b8dc3SIngo Weinhold error = B_BAD_VALUE; 1750338b8dc3SIngo Weinhold int32 width = 0; 1751338b8dc3SIngo Weinhold if (error == B_OK) 1752338b8dc3SIngo Weinhold width = fBounds.IntegerWidth() + 1; 1753338b8dc3SIngo Weinhold int32 inBPR = -1; 1754338b8dc3SIngo Weinhold // tweaks to mimic R5 behavior 1755338b8dc3SIngo Weinhold if (error == B_OK) { 1756338b8dc3SIngo Weinhold // B_RGB32 means actually unpadded B_RGB24_BIG 1757338b8dc3SIngo Weinhold if (colorSpace == B_RGB32) { 1758338b8dc3SIngo Weinhold colorSpace = B_RGB24_BIG; 1759338b8dc3SIngo Weinhold inBPR = width * 3; 1760338b8dc3SIngo Weinhold // If in color space is B_CMAP8, but the bitmap's is another one, 1761338b8dc3SIngo Weinhold // ignore source data row padding. 1762338b8dc3SIngo Weinhold } else if (colorSpace == B_CMAP8 && fColorSpace != B_CMAP8) 1763338b8dc3SIngo Weinhold inBPR = width; 1764338b8dc3SIngo Weinhold } 1765338b8dc3SIngo Weinhold // call the sane method, which does the actual work 1766338b8dc3SIngo Weinhold if (error == B_OK) 1767338b8dc3SIngo Weinhold error = ImportBits(data, length, inBPR, offset, colorSpace); 1768338b8dc3SIngo Weinhold } 1769338b8dc3SIngo Weinhold 177064b2d169SAxel Dörfler 1771338b8dc3SIngo Weinhold /*! \brief Assigns data to the bitmap. 1772338b8dc3SIngo Weinhold 1773338b8dc3SIngo Weinhold Data are directly written into the bitmap's data buffer, being converted 1774338b8dc3SIngo Weinhold beforehand, if necessary. Unlike for SetBits(), the meaning of 1775338b8dc3SIngo Weinhold \a colorSpace is exactly the expected one here, i.e. the source buffer 1776338b8dc3SIngo Weinhold is supposed to contain data of that color space. \a bpr specifies how 1777338b8dc3SIngo Weinhold many bytes the source contains per row. \c B_ANY_BYTES_PER_ROW can be 1778338b8dc3SIngo Weinhold supplied, if standard padding to int32 is used. 1779338b8dc3SIngo Weinhold 1780338b8dc3SIngo Weinhold The currently supported source/target color spaces are 1781338b8dc3SIngo Weinhold \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}. 1782338b8dc3SIngo Weinhold 1783338b8dc3SIngo Weinhold \param data The data to be copied. 1784338b8dc3SIngo Weinhold \param length The length in bytes of the data to be copied. 1785338b8dc3SIngo Weinhold \param bpr The number of bytes per row in the source data. 1786338b8dc3SIngo Weinhold \param offset The offset (in bytes) relative to beginning of the bitmap 1787338b8dc3SIngo Weinhold data specifying the position at which the source data shall be 1788338b8dc3SIngo Weinhold written. 1789338b8dc3SIngo Weinhold \param colorSpace Color space of the source data. 1790338b8dc3SIngo Weinhold \return 1791338b8dc3SIngo Weinhold - \c B_OK: Everything went fine. 1792338b8dc3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a data, invalid \a bpr or \a offset, or 1793338b8dc3SIngo Weinhold unsupported \a colorSpace. 1794338b8dc3SIngo Weinhold */ 1795338b8dc3SIngo Weinhold status_t 1796338b8dc3SIngo Weinhold BBitmap::ImportBits(const void *data, int32 length, int32 bpr, int32 offset, 1797338b8dc3SIngo Weinhold color_space colorSpace) 1798338b8dc3SIngo Weinhold { 1799338b8dc3SIngo Weinhold status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT); 1800338b8dc3SIngo Weinhold // check params 1801338b8dc3SIngo Weinhold if (error == B_OK && (data == NULL || offset > fSize || length < 0)) 1802338b8dc3SIngo Weinhold error = B_BAD_VALUE; 1803338b8dc3SIngo Weinhold // get BPR 1804338b8dc3SIngo Weinhold int32 width = 0; 1805338b8dc3SIngo Weinhold int32 inRowSkip = 0; 1806338b8dc3SIngo Weinhold if (error == B_OK) { 1807338b8dc3SIngo Weinhold width = fBounds.IntegerWidth() + 1; 1808338b8dc3SIngo Weinhold if (bpr < 0) 1809338b8dc3SIngo Weinhold bpr = get_bytes_per_row(colorSpace, width); 1810338b8dc3SIngo Weinhold inRowSkip = bpr - get_raw_bytes_per_row(colorSpace, width); 1811338b8dc3SIngo Weinhold if (inRowSkip < 0) 1812338b8dc3SIngo Weinhold error = B_BAD_VALUE; 1813338b8dc3SIngo Weinhold } 1814338b8dc3SIngo Weinhold if (error != B_OK) { 1815338b8dc3SIngo Weinhold // catch error case 1816338b8dc3SIngo Weinhold } else if (colorSpace == fColorSpace && bpr == fBytesPerRow) { 1817338b8dc3SIngo Weinhold length = min(length, fSize - offset); 1818338b8dc3SIngo Weinhold memcpy((char*)fBasePtr + offset, data, length); 1819338b8dc3SIngo Weinhold } else { 1820338b8dc3SIngo Weinhold // TODO: Retrieve color map from BScreen, when available: 1821338b8dc3SIngo Weinhold // PaletteConverter paletteConverter(BScreen().ColorMap()); 1822338b8dc3SIngo Weinhold const PaletteConverter &paletteConverter = *palette_converter(); 1823338b8dc3SIngo Weinhold int32 rawOutBPR = get_raw_bytes_per_row(fColorSpace, width); 1824338b8dc3SIngo Weinhold switch (colorSpace) { 1825338b8dc3SIngo Weinhold // supported 1826338b8dc3SIngo Weinhold case B_RGB32: case B_RGBA32: 1827338b8dc3SIngo Weinhold { 1828338b8dc3SIngo Weinhold typedef RGB24Reader<rgb32_pixel> Reader; 1829338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1830338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1831338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1832338b8dc3SIngo Weinhold break; 1833338b8dc3SIngo Weinhold } 1834338b8dc3SIngo Weinhold case B_RGB32_BIG: case B_RGBA32_BIG: 1835338b8dc3SIngo Weinhold { 1836338b8dc3SIngo Weinhold typedef RGB24Reader<rgb32_big_pixel> Reader; 1837338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1838338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1839338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1840338b8dc3SIngo Weinhold break; 1841338b8dc3SIngo Weinhold } 1842338b8dc3SIngo Weinhold case B_RGB24: 1843338b8dc3SIngo Weinhold { 1844338b8dc3SIngo Weinhold typedef RGB24Reader<rgb24_pixel> Reader; 1845338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1846338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1847338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1848338b8dc3SIngo Weinhold break; 1849338b8dc3SIngo Weinhold } 1850338b8dc3SIngo Weinhold case B_RGB24_BIG: 1851338b8dc3SIngo Weinhold { 1852338b8dc3SIngo Weinhold typedef RGB24Reader<rgb24_big_pixel> Reader; 1853338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1854338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1855338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1856338b8dc3SIngo Weinhold break; 1857338b8dc3SIngo Weinhold } 1858338b8dc3SIngo Weinhold case B_RGB16: 1859338b8dc3SIngo Weinhold { 1860338b8dc3SIngo Weinhold typedef RGB16Reader<rgb16_pixel> Reader; 1861338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1862338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1863338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1864338b8dc3SIngo Weinhold break; 1865338b8dc3SIngo Weinhold } 1866338b8dc3SIngo Weinhold case B_RGB16_BIG: 1867338b8dc3SIngo Weinhold { 1868338b8dc3SIngo Weinhold typedef RGB16Reader<rgb16_big_pixel> Reader; 1869338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1870338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1871338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1872338b8dc3SIngo Weinhold break; 1873338b8dc3SIngo Weinhold } 1874338b8dc3SIngo Weinhold case B_RGB15: case B_RGBA15: 1875338b8dc3SIngo Weinhold { 1876338b8dc3SIngo Weinhold typedef RGB15Reader<rgb16_pixel> Reader; 1877338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1878338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1879338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1880338b8dc3SIngo Weinhold break; 1881338b8dc3SIngo Weinhold } 1882338b8dc3SIngo Weinhold case B_RGB15_BIG: case B_RGBA15_BIG: 1883338b8dc3SIngo Weinhold { 1884338b8dc3SIngo Weinhold typedef RGB15Reader<rgb16_big_pixel> Reader; 1885338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1886338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1887338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1888338b8dc3SIngo Weinhold break; 1889338b8dc3SIngo Weinhold } 1890338b8dc3SIngo Weinhold case B_CMAP8: 1891338b8dc3SIngo Weinhold { 1892338b8dc3SIngo Weinhold typedef CMAP8Reader Reader; 1893338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1894338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1895338b8dc3SIngo Weinhold fColorSpace, width, Reader(data, paletteConverter), 1896338b8dc3SIngo Weinhold paletteConverter); 1897338b8dc3SIngo Weinhold break; 1898338b8dc3SIngo Weinhold } 1899338b8dc3SIngo Weinhold case B_GRAY8: 1900338b8dc3SIngo Weinhold { 1901338b8dc3SIngo Weinhold typedef Gray8Reader Reader; 1902338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1903338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1904338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1905338b8dc3SIngo Weinhold break; 1906338b8dc3SIngo Weinhold } 1907338b8dc3SIngo Weinhold case B_GRAY1: 1908338b8dc3SIngo Weinhold { 1909338b8dc3SIngo Weinhold typedef Gray1Reader Reader; 1910338b8dc3SIngo Weinhold error = set_bits<Reader>(data, length, bpr, inRowSkip, 1911338b8dc3SIngo Weinhold fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR, 1912338b8dc3SIngo Weinhold fColorSpace, width, Reader(data), paletteConverter); 1913338b8dc3SIngo Weinhold break; 1914338b8dc3SIngo Weinhold } 1915338b8dc3SIngo Weinhold // unsupported 1916338b8dc3SIngo Weinhold case B_NO_COLOR_SPACE: 1917338b8dc3SIngo Weinhold case B_YUV9: case B_YUV12: 1918338b8dc3SIngo Weinhold case B_UVL32: case B_UVLA32: 1919338b8dc3SIngo Weinhold case B_LAB32: case B_LABA32: 1920338b8dc3SIngo Weinhold case B_HSI32: case B_HSIA32: 1921338b8dc3SIngo Weinhold case B_HSV32: case B_HSVA32: 1922338b8dc3SIngo Weinhold case B_HLS32: case B_HLSA32: 1923338b8dc3SIngo Weinhold case B_CMY32: case B_CMYA32: case B_CMYK32: 1924338b8dc3SIngo Weinhold case B_UVL24: case B_LAB24: case B_HSI24: 1925338b8dc3SIngo Weinhold case B_HSV24: case B_HLS24: case B_CMY24: 1926338b8dc3SIngo Weinhold case B_YCbCr422: case B_YUV422: 1927338b8dc3SIngo Weinhold case B_YCbCr411: case B_YUV411: 1928338b8dc3SIngo Weinhold case B_YCbCr444: case B_YUV444: 1929338b8dc3SIngo Weinhold case B_YCbCr420: case B_YUV420: 1930338b8dc3SIngo Weinhold default: 1931338b8dc3SIngo Weinhold error = B_BAD_VALUE; 1932338b8dc3SIngo Weinhold break; 1933338b8dc3SIngo Weinhold } 1934338b8dc3SIngo Weinhold } 1935338b8dc3SIngo Weinhold return error; 1936338b8dc3SIngo Weinhold } 1937338b8dc3SIngo Weinhold 193864b2d169SAxel Dörfler 1939338b8dc3SIngo Weinhold /*! \briefly Assigns another bitmap's data to this bitmap. 1940338b8dc3SIngo Weinhold 1941338b8dc3SIngo Weinhold The supplied bitmap must have the exactly same dimensions as this bitmap. 1942338b8dc3SIngo Weinhold Its data are converted to the color space of this bitmap. 1943338b8dc3SIngo Weinhold 1944338b8dc3SIngo Weinhold The currently supported source/target color spaces are 1945338b8dc3SIngo Weinhold \c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}. 1946338b8dc3SIngo Weinhold 1947338b8dc3SIngo Weinhold \param bitmap The source bitmap. 1948338b8dc3SIngo Weinhold \return 1949338b8dc3SIngo Weinhold - \c B_OK: Everything went fine. 1950338b8dc3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a bitmap, or \a bitmap has other dimensions, 1951338b8dc3SIngo Weinhold or the conversion from or to one of the color spaces is not supported. 1952338b8dc3SIngo Weinhold */ 1953338b8dc3SIngo Weinhold status_t 1954338b8dc3SIngo Weinhold BBitmap::ImportBits(const BBitmap *bitmap) 1955338b8dc3SIngo Weinhold { 1956338b8dc3SIngo Weinhold status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT); 1957338b8dc3SIngo Weinhold // check param 1958338b8dc3SIngo Weinhold if (error == B_OK && bitmap == NULL) 1959338b8dc3SIngo Weinhold error = B_BAD_VALUE; 1960338b8dc3SIngo Weinhold if (error == B_OK && bitmap->InitCheck() != B_OK) 1961338b8dc3SIngo Weinhold error = B_BAD_VALUE; 1962338b8dc3SIngo Weinhold if (error == B_OK && bitmap->Bounds() != fBounds) 1963338b8dc3SIngo Weinhold error = B_BAD_VALUE; 1964338b8dc3SIngo Weinhold // set bits 1965338b8dc3SIngo Weinhold if (error == B_OK) { 1966338b8dc3SIngo Weinhold error = ImportBits(bitmap->Bits(), bitmap->BitsLength(), 1967338b8dc3SIngo Weinhold bitmap->BytesPerRow(), 0, bitmap->ColorSpace()); 1968338b8dc3SIngo Weinhold } 1969338b8dc3SIngo Weinhold return error; 1970338b8dc3SIngo Weinhold } 1971338b8dc3SIngo Weinhold 197264b2d169SAxel Dörfler 1973338b8dc3SIngo Weinhold status_t 1974338b8dc3SIngo Weinhold BBitmap::GetOverlayRestrictions(overlay_restrictions *restrictions) const 1975338b8dc3SIngo Weinhold { 1976338b8dc3SIngo Weinhold // TODO: Implement 1977338b8dc3SIngo Weinhold return B_ERROR; 1978338b8dc3SIngo Weinhold } 1979338b8dc3SIngo Weinhold 198064b2d169SAxel Dörfler 1981338b8dc3SIngo Weinhold status_t 1982338b8dc3SIngo Weinhold BBitmap::Perform(perform_code d, void *arg) 1983338b8dc3SIngo Weinhold { 1984338b8dc3SIngo Weinhold return BArchivable::Perform(d, arg); 1985338b8dc3SIngo Weinhold } 1986338b8dc3SIngo Weinhold 198764b2d169SAxel Dörfler 1988338b8dc3SIngo Weinhold // FBC 1989338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap1() {} 1990338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap2() {} 1991338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap3() {} 1992338b8dc3SIngo Weinhold 199364b2d169SAxel Dörfler 1994338b8dc3SIngo Weinhold /*! \brief Privatized copy constructor to prevent usage. 1995338b8dc3SIngo Weinhold */ 1996338b8dc3SIngo Weinhold BBitmap::BBitmap(const BBitmap &) 1997338b8dc3SIngo Weinhold { 1998338b8dc3SIngo Weinhold } 1999338b8dc3SIngo Weinhold 200064b2d169SAxel Dörfler 2001338b8dc3SIngo Weinhold /*! \brief Privatized assignment operator to prevent usage. 2002338b8dc3SIngo Weinhold */ 2003338b8dc3SIngo Weinhold BBitmap & 2004338b8dc3SIngo Weinhold BBitmap::operator=(const BBitmap &) 2005338b8dc3SIngo Weinhold { 2006338b8dc3SIngo Weinhold return *this; 2007338b8dc3SIngo Weinhold } 2008338b8dc3SIngo Weinhold 200964b2d169SAxel Dörfler 2010338b8dc3SIngo Weinhold char * 2011338b8dc3SIngo Weinhold BBitmap::get_shared_pointer() const 2012338b8dc3SIngo Weinhold { 2013338b8dc3SIngo Weinhold return NULL; // not implemented 2014338b8dc3SIngo Weinhold } 2015338b8dc3SIngo Weinhold 201664b2d169SAxel Dörfler 2017338b8dc3SIngo Weinhold int32 2018338b8dc3SIngo Weinhold BBitmap::get_server_token() const 2019338b8dc3SIngo Weinhold { 2020338b8dc3SIngo Weinhold return fServerToken; 2021338b8dc3SIngo Weinhold } 2022338b8dc3SIngo Weinhold 202364b2d169SAxel Dörfler 2024338b8dc3SIngo Weinhold /*! \brief Initializes the bitmap. 2025338b8dc3SIngo Weinhold \param bounds The bitmap dimensions. 2026338b8dc3SIngo Weinhold \param colorSpace The bitmap's color space. 2027338b8dc3SIngo Weinhold \param flags Creation flags. 2028338b8dc3SIngo Weinhold \param bytesPerRow The number of bytes per row the bitmap should use. 2029338b8dc3SIngo Weinhold \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate 2030338b8dc3SIngo Weinhold value. 2031338b8dc3SIngo Weinhold \param screenID ??? 2032338b8dc3SIngo Weinhold */ 2033338b8dc3SIngo Weinhold void 2034338b8dc3SIngo Weinhold BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags, 2035338b8dc3SIngo Weinhold int32 bytesPerRow, screen_id screenID) 2036338b8dc3SIngo Weinhold { 2037338b8dc3SIngo Weinhold //printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n", 2038338b8dc3SIngo Weinhold // bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow); 2039338b8dc3SIngo Weinhold 2040338b8dc3SIngo Weinhold // TODO: Hanlde setting up the offscreen window if we're such a bitmap! 2041338b8dc3SIngo Weinhold 2042338b8dc3SIngo Weinhold // TODO: Should we handle rounding of the "bounds" here? How does R5 behave? 2043338b8dc3SIngo Weinhold 2044338b8dc3SIngo Weinhold status_t error = B_OK; 2045338b8dc3SIngo Weinhold 2046338b8dc3SIngo Weinhold //#ifdef RUN_WITHOUT_APP_SERVER 2047338b8dc3SIngo Weinhold flags |= B_BITMAP_NO_SERVER_LINK; 2048338b8dc3SIngo Weinhold //#endif // RUN_WITHOUT_APP_SERVER 2049338b8dc3SIngo Weinhold flags &= ~B_BITMAP_ACCEPTS_VIEWS; 2050338b8dc3SIngo Weinhold 2051338b8dc3SIngo Weinhold CleanUp(); 2052338b8dc3SIngo Weinhold 2053338b8dc3SIngo Weinhold // check params 2054338b8dc3SIngo Weinhold if (!bounds.IsValid() || !bitmaps_support_space(colorSpace, NULL)) 2055338b8dc3SIngo Weinhold error = B_BAD_VALUE; 2056338b8dc3SIngo Weinhold if (error == B_OK) { 2057338b8dc3SIngo Weinhold int32 bpr = get_bytes_per_row(colorSpace, bounds.IntegerWidth() + 1); 2058338b8dc3SIngo Weinhold if (bytesPerRow < 0) 2059338b8dc3SIngo Weinhold bytesPerRow = bpr; 2060338b8dc3SIngo Weinhold else if (bytesPerRow < bpr) 2061338b8dc3SIngo Weinhold // NOTE: How does R5 behave? 2062338b8dc3SIngo Weinhold error = B_BAD_VALUE; 2063338b8dc3SIngo Weinhold } 2064338b8dc3SIngo Weinhold // allocate the bitmap buffer 2065338b8dc3SIngo Weinhold if (error == B_OK) { 2066338b8dc3SIngo Weinhold // NOTE: Maybe the code would look more robust if the 2067338b8dc3SIngo Weinhold // "size" was not calculated here when we ask the server 2068338b8dc3SIngo Weinhold // to allocate the bitmap. -Stephan 2069338b8dc3SIngo Weinhold int32 size = bytesPerRow * (bounds.IntegerHeight() + 1); 2070338b8dc3SIngo Weinhold 2071338b8dc3SIngo Weinhold if (flags & B_BITMAP_NO_SERVER_LINK) { 2072338b8dc3SIngo Weinhold fBasePtr = malloc(size); 2073338b8dc3SIngo Weinhold if (fBasePtr) { 2074338b8dc3SIngo Weinhold fSize = size; 2075338b8dc3SIngo Weinhold fColorSpace = colorSpace; 2076338b8dc3SIngo Weinhold fBounds = bounds; 2077338b8dc3SIngo Weinhold fBytesPerRow = bytesPerRow; 2078338b8dc3SIngo Weinhold fFlags = flags; 2079338b8dc3SIngo Weinhold } else 2080338b8dc3SIngo Weinhold error = B_NO_MEMORY; 2081338b8dc3SIngo Weinhold } else { 2082338b8dc3SIngo Weinhold // // Ask the server (via our owning application) to create a bitmap. 2083338b8dc3SIngo Weinhold // BPrivate::AppServerLink link; 2084338b8dc3SIngo Weinhold // 2085338b8dc3SIngo Weinhold // // Attach Data: 2086338b8dc3SIngo Weinhold // // 1) BRect bounds 2087338b8dc3SIngo Weinhold // // 2) color_space space 2088338b8dc3SIngo Weinhold // // 3) int32 bitmap_flags 2089338b8dc3SIngo Weinhold // // 4) int32 bytes_per_row 2090338b8dc3SIngo Weinhold // // 5) int32 screen_id::id 2091338b8dc3SIngo Weinhold // link.StartMessage(AS_CREATE_BITMAP); 2092338b8dc3SIngo Weinhold // link.Attach<BRect>(bounds); 2093338b8dc3SIngo Weinhold // link.Attach<color_space>(colorSpace); 2094338b8dc3SIngo Weinhold // link.Attach<int32>((int32)flags); 2095338b8dc3SIngo Weinhold // link.Attach<int32>(bytesPerRow); 2096338b8dc3SIngo Weinhold // link.Attach<int32>(screenID.id); 2097338b8dc3SIngo Weinhold // 2098338b8dc3SIngo Weinhold // // Reply Code: SERVER_TRUE 2099338b8dc3SIngo Weinhold // // Reply Data: 2100338b8dc3SIngo Weinhold // // 1) int32 server token 2101338b8dc3SIngo Weinhold // // 2) area_id id of the area in which the bitmap data resides 2102338b8dc3SIngo Weinhold // // 3) int32 area pointer offset used to calculate fBasePtr 2103338b8dc3SIngo Weinhold // 2104338b8dc3SIngo Weinhold // // alternatively, if something went wrong 2105338b8dc3SIngo Weinhold // // Reply Code: SERVER_FALSE 2106338b8dc3SIngo Weinhold // // Reply Data: 2107338b8dc3SIngo Weinhold // // None 2108338b8dc3SIngo Weinhold // int32 code = SERVER_FALSE; 2109338b8dc3SIngo Weinhold // error = link.FlushWithReply(code); 2110338b8dc3SIngo Weinhold // 2111338b8dc3SIngo Weinhold // if (error >= B_OK) { 2112338b8dc3SIngo Weinhold // // *communication* with server successful 2113338b8dc3SIngo Weinhold // if (code == SERVER_TRUE) { 2114338b8dc3SIngo Weinhold // // server side success 2115338b8dc3SIngo Weinhold // // Get token 2116338b8dc3SIngo Weinhold // area_id bmparea; 2117338b8dc3SIngo Weinhold // int32 areaoffset; 2118338b8dc3SIngo Weinhold // 2119338b8dc3SIngo Weinhold // link.Read<int32>(&fServerToken); 2120338b8dc3SIngo Weinhold // link.Read<area_id>(&bmparea); 2121338b8dc3SIngo Weinhold // link.Read<int32>(&areaoffset); 2122338b8dc3SIngo Weinhold // 2123338b8dc3SIngo Weinhold // // Get the area in which the data resides 2124338b8dc3SIngo Weinhold // fArea = clone_area("shared bitmap area", 2125338b8dc3SIngo Weinhold // (void**)&fBasePtr, 2126338b8dc3SIngo Weinhold // B_ANY_ADDRESS, 2127338b8dc3SIngo Weinhold // B_READ_AREA | B_WRITE_AREA, 2128338b8dc3SIngo Weinhold // bmparea); 2129338b8dc3SIngo Weinhold // 2130338b8dc3SIngo Weinhold // // Jump to the location in the area 2131338b8dc3SIngo Weinhold // fBasePtr = (int8*)fBasePtr + areaoffset; 2132338b8dc3SIngo Weinhold // 2133338b8dc3SIngo Weinhold // fSize = size; 2134338b8dc3SIngo Weinhold // fColorSpace = colorSpace; 2135338b8dc3SIngo Weinhold // fBounds = bounds; 2136338b8dc3SIngo Weinhold // fBytesPerRow = bytesPerRow; 2137338b8dc3SIngo Weinhold // fFlags = flags; 2138338b8dc3SIngo Weinhold // } else { 2139338b8dc3SIngo Weinhold // // server side error, we assume: 2140338b8dc3SIngo Weinhold // error = B_NO_MEMORY; 2141338b8dc3SIngo Weinhold // } 2142338b8dc3SIngo Weinhold // } 2143338b8dc3SIngo Weinhold // // NOTE: not "else" to handle B_NO_MEMORY on server side! 2144338b8dc3SIngo Weinhold // if (error < B_OK) { 2145338b8dc3SIngo Weinhold // fBasePtr = NULL; 2146338b8dc3SIngo Weinhold // fServerToken = -1; 2147338b8dc3SIngo Weinhold // fArea = -1; 2148338b8dc3SIngo Weinhold // // NOTE: why not "0" in case of error? 2149338b8dc3SIngo Weinhold // fFlags = flags; 2150338b8dc3SIngo Weinhold // } 2151338b8dc3SIngo Weinhold } 2152338b8dc3SIngo Weinhold // fWindow = NULL; 2153338b8dc3SIngo Weinhold fToken = -1; 2154338b8dc3SIngo Weinhold fOrigArea = -1; 2155338b8dc3SIngo Weinhold } 2156338b8dc3SIngo Weinhold 2157338b8dc3SIngo Weinhold fInitError = error; 2158338b8dc3SIngo Weinhold // TODO: on success, handle clearing to white if the flags say so. Needs to be 2159338b8dc3SIngo Weinhold // dependent on color space. 2160338b8dc3SIngo Weinhold 2161338b8dc3SIngo Weinhold if (fInitError == B_OK) { 2162338b8dc3SIngo Weinhold if (flags & B_BITMAP_ACCEPTS_VIEWS) { 2163338b8dc3SIngo Weinhold // fWindow = new BWindow(Bounds(), fServerToken); 2164338b8dc3SIngo Weinhold // // A BWindow starts life locked and is unlocked 2165338b8dc3SIngo Weinhold // // in Show(), but this window is never shown and 2166338b8dc3SIngo Weinhold // // it's message loop is never started. 2167338b8dc3SIngo Weinhold // fWindow->Unlock(); 2168338b8dc3SIngo Weinhold } 2169338b8dc3SIngo Weinhold } 2170338b8dc3SIngo Weinhold } 2171338b8dc3SIngo Weinhold 217264b2d169SAxel Dörfler 2173338b8dc3SIngo Weinhold /*! \brief Cleans up any memory allocated by the bitmap or 2174338b8dc3SIngo Weinhold informs the server to do so. 2175338b8dc3SIngo Weinhold */ 2176338b8dc3SIngo Weinhold void 2177338b8dc3SIngo Weinhold BBitmap::CleanUp() 2178338b8dc3SIngo Weinhold { 2179338b8dc3SIngo Weinhold if (fBasePtr) { 2180338b8dc3SIngo Weinhold if (fFlags & B_BITMAP_NO_SERVER_LINK) { 2181338b8dc3SIngo Weinhold free(fBasePtr); 2182338b8dc3SIngo Weinhold } else { 2183338b8dc3SIngo Weinhold // BPrivate::AppServerLink link; 2184338b8dc3SIngo Weinhold // // AS_DELETE_BITMAP: 2185338b8dc3SIngo Weinhold // // Attached Data: 2186338b8dc3SIngo Weinhold // // 1) int32 server token 2187338b8dc3SIngo Weinhold // 2188338b8dc3SIngo Weinhold // // Reply Code: SERVER_TRUE if successful, 2189338b8dc3SIngo Weinhold // // SERVER_FALSE if the buffer was already deleted 2190338b8dc3SIngo Weinhold // // Reply Data: none 2191338b8dc3SIngo Weinhold // // status_t freestat; 2192338b8dc3SIngo Weinhold // int32 code = SERVER_FALSE; 2193338b8dc3SIngo Weinhold // link.StartMessage(AS_DELETE_BITMAP); 2194338b8dc3SIngo Weinhold // link.Attach<int32>(fServerToken); 2195338b8dc3SIngo Weinhold // link.FlushWithReply(code); 2196338b8dc3SIngo Weinhold // if (code == SERVER_FALSE) { 2197338b8dc3SIngo Weinhold // // TODO: Find out if "SERVER_FALSE if the buffer 2198338b8dc3SIngo Weinhold // // was already deleted" is true. If not, maybe we 2199338b8dc3SIngo Weinhold // // need to take additional action. 2200338b8dc3SIngo Weinhold // } 2201338b8dc3SIngo Weinhold // fArea = -1; 2202338b8dc3SIngo Weinhold // fServerToken = -1; 2203338b8dc3SIngo Weinhold } 2204338b8dc3SIngo Weinhold fBasePtr = NULL; 2205338b8dc3SIngo Weinhold } 2206338b8dc3SIngo Weinhold } 2207338b8dc3SIngo Weinhold 220864b2d169SAxel Dörfler 2209338b8dc3SIngo Weinhold void 2210338b8dc3SIngo Weinhold BBitmap::AssertPtr() 2211338b8dc3SIngo Weinhold { 2212338b8dc3SIngo Weinhold } 2213338b8dc3SIngo Weinhold 2214