1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2005, Haiku, Inc. 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: SystemPalette.cpp 23 // Authors: DarkWyrm <bpmagic@columbus.rr.com> 24 // Stefano Ceccherini <burton666@libero.it> 25 // Description: Methods to initialize and get the system color_map. 26 // 27 //------------------------------------------------------------------------------ 28 #include <stdio.h> 29 30 #include <SystemPalette.h> 31 32 const static rgb_color kSystemPalette[] = { 33 { 0, 0, 0, 255 }, { 8, 8, 8, 255 }, { 16, 16, 16, 255 }, 34 { 24, 24, 24, 255 }, { 32, 32, 32, 255 }, { 40, 40, 40, 255 }, 35 { 48, 48, 48, 255 }, { 56, 56, 56, 255 }, { 64, 64, 64, 255 }, 36 { 72, 72, 72, 255 }, { 80, 80, 80, 255 }, { 88, 88, 88, 255 }, 37 { 96, 96, 96, 255 }, { 104, 104, 104, 255 }, { 112, 112, 112, 255 }, 38 { 120, 120, 120, 255 }, { 128, 128, 128, 255 }, { 136, 136, 136, 255 }, 39 { 144, 144, 144, 255 }, { 152, 152, 152, 255 }, { 160, 160, 160, 255 }, 40 { 168, 168, 168, 255 }, { 176, 176, 176, 255 }, { 184, 184, 184, 255 }, 41 { 192, 192, 192, 255 }, { 200, 200, 200, 255 }, { 208, 208, 208, 255 }, 42 { 216, 216, 216, 255 }, { 224, 224, 224, 255 }, { 232, 232, 232, 255 }, 43 { 240, 240, 240, 255 }, { 248, 248, 248, 255 }, { 0, 0, 255, 255 }, 44 { 0, 0, 229, 255 }, { 0, 0, 204, 255 }, { 0, 0, 179, 255 }, 45 { 0, 0, 154, 255 }, { 0, 0, 129, 255 }, { 0, 0, 105, 255 }, 46 { 0, 0, 80, 255 }, { 0, 0, 55, 255 }, { 0, 0, 30, 255 }, 47 { 255, 0, 0, 255 }, { 228, 0, 0, 255 }, { 203, 0, 0, 255 }, 48 { 178, 0, 0, 255 }, { 153, 0, 0, 255 }, { 128, 0, 0, 255 }, 49 { 105, 0, 0, 255 }, { 80, 0, 0, 255 }, { 55, 0, 0, 255 }, 50 { 30, 0, 0, 255 }, { 0, 255, 0, 255 }, { 0, 228, 0, 255 }, 51 { 0, 203, 0, 255 }, { 0, 178, 0, 255 }, { 0, 153, 0, 255 }, 52 { 0, 128, 0, 255 }, { 0, 105, 0, 255 }, { 0, 80, 0, 255 }, 53 { 0, 55, 0, 255 }, { 0, 30, 0, 255 }, { 0, 152, 51, 255 }, 54 { 255, 255, 255, 255 }, { 203, 255, 255, 255 }, { 203, 255, 203, 255 }, 55 { 203, 255, 152, 255 }, { 203, 255, 102, 255 }, { 203, 255, 51, 255 }, 56 { 203, 255, 0, 255 }, { 152, 255, 255, 255 }, { 152, 255, 203, 255 }, 57 { 152, 255, 152, 255 }, { 152, 255, 102, 255 }, { 152, 255, 51, 255 }, 58 { 152, 255, 0, 255 }, { 102, 255, 255, 255 }, { 102, 255, 203, 255 }, 59 { 102, 255, 152, 255 }, { 102, 255, 102, 255 }, { 102, 255, 51, 255 }, 60 { 102, 255, 0, 255 }, { 51, 255, 255, 255 }, { 51, 255, 203, 255 }, 61 { 51, 255, 152, 255 }, { 51, 255, 102, 255 }, { 51, 255, 51, 255 }, 62 { 51, 255, 0, 255 }, { 255, 152, 255, 255 }, { 255, 152, 203, 255 }, 63 { 255, 152, 152, 255 }, { 255, 152, 102, 255 }, { 255, 152, 51, 255 }, 64 { 255, 152, 0, 255 }, { 0, 102, 255, 255 }, { 0, 102, 203, 255 }, 65 { 203, 203, 255, 255 }, { 203, 203, 203, 255 }, { 203, 203, 152, 255 }, 66 { 203, 203, 102, 255 }, { 203, 203, 51, 255 }, { 203, 203, 0, 255 }, 67 { 152, 203, 255, 255 }, { 152, 203, 203, 255 }, { 152, 203, 152, 255 }, 68 { 152, 203, 102, 255 }, { 152, 203, 51, 255 }, { 152, 203, 0, 255 }, 69 { 102, 203, 255, 255 }, { 102, 203, 203, 255 }, { 102, 203, 152, 255 }, 70 { 102, 203, 102, 255 }, { 102, 203, 51, 255 }, { 102, 203, 0, 255 }, 71 { 51, 203, 255, 255 }, { 51, 203, 203, 255 }, { 51, 203, 152, 255 }, 72 { 51, 203, 102, 255 }, { 51, 203, 51, 255 }, { 51, 203, 0, 255 }, 73 { 255, 102, 255, 255 }, { 255, 102, 203, 255 }, { 255, 102, 152, 255 }, 74 { 255, 102, 102, 255 }, { 255, 102, 51, 255 }, { 255, 102, 0, 255 }, 75 { 0, 102, 152, 255 }, { 0, 102, 102, 255 }, { 203, 152, 255, 255 }, 76 { 203, 152, 203, 255 }, { 203, 152, 152, 255 }, { 203, 152, 102, 255 }, 77 { 203, 152, 51, 255 }, { 203, 152, 0, 255 }, { 152, 152, 255, 255 }, 78 { 152, 152, 203, 255 }, { 152, 152, 152, 255 }, { 152, 152, 102, 255 }, 79 { 152, 152, 51, 255 }, { 152, 152, 0, 255 }, { 102, 152, 255, 255 }, 80 { 102, 152, 203, 255 }, { 102, 152, 152, 255 }, { 102, 152, 102, 255 }, 81 { 102, 152, 51, 255 }, { 102, 152, 0, 255 }, { 51, 152, 255, 255 }, 82 { 51, 152, 203, 255 }, { 51, 152, 152, 255 }, { 51, 152, 102, 255 }, 83 { 51, 152, 51, 255 }, { 51, 152, 0, 255 }, { 230, 134, 0, 255 }, 84 { 255, 51, 203, 255 }, { 255, 51, 152, 255 }, { 255, 51, 102, 255 }, 85 { 255, 51, 51, 255 }, { 255, 51, 0, 255 }, { 0, 102, 51, 255 }, 86 { 0, 102, 0, 255 }, { 203, 102, 255, 255 }, { 203, 102, 203, 255 }, 87 { 203, 102, 152, 255 }, { 203, 102, 102, 255 }, { 203, 102, 51, 255 }, 88 { 203, 102, 0, 255 }, { 152, 102, 255, 255 }, { 152, 102, 203, 255 }, 89 { 152, 102, 152, 255 }, { 152, 102, 102, 255 }, { 152, 102, 51, 255 }, 90 { 152, 102, 0, 255 }, { 102, 102, 255, 255 }, { 102, 102, 203, 255 }, 91 { 102, 102, 152, 255 }, { 102, 102, 102, 255 }, { 102, 102, 51, 255 }, 92 { 102, 102, 0, 255 }, { 51, 102, 255, 255 }, { 51, 102, 203, 255 }, 93 { 51, 102, 152, 255 }, { 51, 102, 102, 255 }, { 51, 102, 51, 255 }, 94 { 51, 102, 0, 255 }, { 255, 0, 255, 255 }, { 255, 0, 203, 255 }, 95 { 255, 0, 152, 255 }, { 255, 0, 102, 255 }, { 255, 0, 51, 255 }, 96 { 255, 175, 19, 255 }, { 0, 51, 255, 255 }, { 0, 51, 203, 255 }, 97 { 203, 51, 255, 255 }, { 203, 51, 203, 255 }, { 203, 51, 152, 255 }, 98 { 203, 51, 102, 255 }, { 203, 51, 51, 255 }, { 203, 51, 0, 255 }, 99 { 152, 51, 255, 255 }, { 152, 51, 203, 255 }, { 152, 51, 152, 255 }, 100 { 152, 51, 102, 255 }, { 152, 51, 51, 255 }, { 152, 51, 0, 255 }, 101 { 102, 51, 255, 255 }, { 102, 51, 203, 255 }, { 102, 51, 152, 255 }, 102 { 102, 51, 102, 255 }, { 102, 51, 51, 255 }, { 102, 51, 0, 255 }, 103 { 51, 51, 255, 255 }, { 51, 51, 203, 255 }, { 51, 51, 152, 255 }, 104 { 51, 51, 102, 255 }, { 51, 51, 51, 255 }, { 51, 51, 0, 255 }, 105 { 255, 203, 102, 255 }, { 255, 203, 152, 255 }, { 255, 203, 203, 255 }, 106 { 255, 203, 255, 255 }, { 0, 51, 152, 255 }, { 0, 51, 102, 255 }, 107 { 0, 51, 51, 255 }, { 0, 51, 0, 255 }, { 203, 0, 255, 255 }, 108 { 203, 0, 203, 255 }, { 203, 0, 152, 255 }, { 203, 0, 102, 255 }, 109 { 203, 0, 51, 255 }, { 255, 227, 70, 255 }, { 152, 0, 255, 255 }, 110 { 152, 0, 203, 255 }, { 152, 0, 152, 255 }, { 152, 0, 102, 255 }, 111 { 152, 0, 51, 255 }, { 152, 0, 0, 255 }, { 102, 0, 255, 255 }, 112 { 102, 0, 203, 255 }, { 102, 0, 152, 255 }, { 102, 0, 102, 255 }, 113 { 102, 0, 51, 255 }, { 102, 0, 0, 255 }, { 51, 0, 255, 255 }, 114 { 51, 0, 203, 255 }, { 51, 0, 152, 255 }, { 51, 0, 102, 255 }, 115 { 51, 0, 51, 255 }, { 51, 0, 0, 255 }, { 255, 203, 51, 255 }, 116 { 255, 203, 0, 255 }, { 255, 255, 0, 255 }, { 255, 255, 51, 255 }, 117 { 255, 255, 102, 255 }, { 255, 255, 152, 255 }, { 255, 255, 203, 255 }, 118 { 255, 255, 255, 0 } // B_TRANSPARENT_MAGIC_CMAP8 119 }; 120 121 122 // TODO: BWindowScreen has a method to set the palette. 123 // maybe we should have a lock to protect this variable. 124 static color_map sColorMap; 125 126 127 // color_distance 128 /*! \brief Returns the "distance" between two RGB colors. 129 130 This functions defines an metric on the RGB color space. The distance 131 between two colors is 0, if and only if the colors are equal. 132 133 \param red1 Red component of the first color. 134 \param green1 Green component of the first color. 135 \param blue1 Blue component of the first color. 136 \param red2 Red component of the second color. 137 \param green2 Green component of the second color. 138 \param blue2 Blue component of the second color. 139 \return The distance between the given colors. 140 */ 141 static inline 142 unsigned 143 color_distance(uint8 red1, uint8 green1, uint8 blue1, 144 uint8 red2, uint8 green2, uint8 blue2) 145 { 146 int rd = (int)red1 - (int)red2; 147 int gd = (int)green1 - (int)green2; 148 int bd = (int)blue1 - (int)blue2; 149 150 // distance according to psycho-visual tests 151 // algorithm taken from here: 152 // http://www.stud.uni-hannover.de/~michaelt/juggle/Algorithms.pdf 153 int rmean = ((int)red1 + (int)red2) / 2; 154 return (((512 + rmean) * rd * rd) >> 8) 155 + 4 * gd * gd 156 + (((767 - rmean) * bd * bd) >> 8); 157 } 158 159 160 static inline uint8 161 FindClosestColor(const rgb_color &color, const rgb_color *palette) 162 { 163 uint8 closestIndex = 0; 164 unsigned closestDistance = UINT_MAX; 165 for (int32 i = 0; i < 256; i++) { 166 const rgb_color &c = palette[i]; 167 unsigned distance = color_distance(color.red, color.green, color.blue, 168 c.red, c.green, c.blue); 169 if (distance < closestDistance) { 170 closestIndex = (uint8)i; 171 closestDistance = distance; 172 } 173 } 174 return closestIndex; 175 } 176 177 178 static inline rgb_color 179 InvertColor(const rgb_color &color) 180 { 181 // For some reason, Inverting (255, 255, 255) on beos 182 // results in the same color. 183 if (color.red == 255 && color.green == 255 184 && color.blue == 255) 185 return color; 186 187 rgb_color inverted; 188 inverted.red = 255 - color.red; 189 inverted.green = 255 - color.green; 190 inverted.blue = 255 - color.blue; 191 inverted.alpha = 255; 192 193 return inverted; 194 } 195 196 197 static void 198 FillColorMap(const rgb_color *palette, color_map *map) 199 { 200 memcpy(map->color_list, palette, sizeof(map->color_list)); 201 202 // init index map 203 for (int32 color = 0; color < 32768; color++) { 204 // get components 205 rgb_color rgbColor; 206 rgbColor.red = (color & 0x7c00) >> 7; 207 rgbColor.green = (color & 0x3e0) >> 2; 208 rgbColor.blue = (color & 0x1f) << 3; 209 210 map->index_map[color] = FindClosestColor(rgbColor, palette); 211 } 212 213 // init inversion map 214 for (int32 index = 0; index < 256; index++) { 215 rgb_color inverted = InvertColor(map->color_list[index]); 216 map->inversion_map[index] = FindClosestColor(inverted, palette); 217 } 218 } 219 220 221 /*! \brief Initializes the system color_map. 222 */ 223 void 224 InitializeColorMap() 225 { 226 FillColorMap(kSystemPalette, &sColorMap); 227 } 228 229 230 /*! \brief Returns a pointer to the system palette. 231 \return A pointer to the system palette. 232 */ 233 const rgb_color * 234 SystemPalette() 235 { 236 return sColorMap.color_list; 237 } 238 239 240 /*! \brief Returns a pointer to the system color_map structure. 241 \return A pointer to the system color_map. 242 */ 243 const color_map * 244 SystemColorMap() 245 { 246 return &sColorMap; 247 } 248