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