1 /* 2 * Copyright 2001-2006, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * DarkWyrm <bpmagic@columbus.rr.com> 7 * Stefano Ceccherini (burton666@libero.it) 8 */ 9 10 //! Methods to initialize and get the system color_map. 11 12 13 #include "SystemPalette.h" 14 15 #include <stdio.h> 16 #include <string.h> 17 18 19 const static rgb_color kSystemPalette[] = { 20 { 0, 0, 0, 255 }, { 8, 8, 8, 255 }, { 16, 16, 16, 255 }, 21 { 24, 24, 24, 255 }, { 32, 32, 32, 255 }, { 40, 40, 40, 255 }, 22 { 48, 48, 48, 255 }, { 56, 56, 56, 255 }, { 64, 64, 64, 255 }, 23 { 72, 72, 72, 255 }, { 80, 80, 80, 255 }, { 88, 88, 88, 255 }, 24 { 96, 96, 96, 255 }, { 104, 104, 104, 255 }, { 112, 112, 112, 255 }, 25 { 120, 120, 120, 255 }, { 128, 128, 128, 255 }, { 136, 136, 136, 255 }, 26 { 144, 144, 144, 255 }, { 152, 152, 152, 255 }, { 160, 160, 160, 255 }, 27 { 168, 168, 168, 255 }, { 176, 176, 176, 255 }, { 184, 184, 184, 255 }, 28 { 192, 192, 192, 255 }, { 200, 200, 200, 255 }, { 208, 208, 208, 255 }, 29 { 216, 216, 216, 255 }, { 224, 224, 224, 255 }, { 232, 232, 232, 255 }, 30 { 240, 240, 240, 255 }, { 248, 248, 248, 255 }, { 0, 0, 255, 255 }, 31 { 0, 0, 229, 255 }, { 0, 0, 204, 255 }, { 0, 0, 179, 255 }, 32 { 0, 0, 154, 255 }, { 0, 0, 129, 255 }, { 0, 0, 105, 255 }, 33 { 0, 0, 80, 255 }, { 0, 0, 55, 255 }, { 0, 0, 30, 255 }, 34 { 255, 0, 0, 255 }, { 228, 0, 0, 255 }, { 203, 0, 0, 255 }, 35 { 178, 0, 0, 255 }, { 153, 0, 0, 255 }, { 128, 0, 0, 255 }, 36 { 105, 0, 0, 255 }, { 80, 0, 0, 255 }, { 55, 0, 0, 255 }, 37 { 30, 0, 0, 255 }, { 0, 255, 0, 255 }, { 0, 228, 0, 255 }, 38 { 0, 203, 0, 255 }, { 0, 178, 0, 255 }, { 0, 153, 0, 255 }, 39 { 0, 128, 0, 255 }, { 0, 105, 0, 255 }, { 0, 80, 0, 255 }, 40 { 0, 55, 0, 255 }, { 0, 30, 0, 255 }, { 0, 152, 51, 255 }, 41 { 255, 255, 255, 255 }, { 203, 255, 255, 255 }, { 203, 255, 203, 255 }, 42 { 203, 255, 152, 255 }, { 203, 255, 102, 255 }, { 203, 255, 51, 255 }, 43 { 203, 255, 0, 255 }, { 152, 255, 255, 255 }, { 152, 255, 203, 255 }, 44 { 152, 255, 152, 255 }, { 152, 255, 102, 255 }, { 152, 255, 51, 255 }, 45 { 152, 255, 0, 255 }, { 102, 255, 255, 255 }, { 102, 255, 203, 255 }, 46 { 102, 255, 152, 255 }, { 102, 255, 102, 255 }, { 102, 255, 51, 255 }, 47 { 102, 255, 0, 255 }, { 51, 255, 255, 255 }, { 51, 255, 203, 255 }, 48 { 51, 255, 152, 255 }, { 51, 255, 102, 255 }, { 51, 255, 51, 255 }, 49 { 51, 255, 0, 255 }, { 255, 152, 255, 255 }, { 255, 152, 203, 255 }, 50 { 255, 152, 152, 255 }, { 255, 152, 102, 255 }, { 255, 152, 51, 255 }, 51 { 255, 152, 0, 255 }, { 0, 102, 255, 255 }, { 0, 102, 203, 255 }, 52 { 203, 203, 255, 255 }, { 203, 203, 203, 255 }, { 203, 203, 152, 255 }, 53 { 203, 203, 102, 255 }, { 203, 203, 51, 255 }, { 203, 203, 0, 255 }, 54 { 152, 203, 255, 255 }, { 152, 203, 203, 255 }, { 152, 203, 152, 255 }, 55 { 152, 203, 102, 255 }, { 152, 203, 51, 255 }, { 152, 203, 0, 255 }, 56 { 102, 203, 255, 255 }, { 102, 203, 203, 255 }, { 102, 203, 152, 255 }, 57 { 102, 203, 102, 255 }, { 102, 203, 51, 255 }, { 102, 203, 0, 255 }, 58 { 51, 203, 255, 255 }, { 51, 203, 203, 255 }, { 51, 203, 152, 255 }, 59 { 51, 203, 102, 255 }, { 51, 203, 51, 255 }, { 51, 203, 0, 255 }, 60 { 255, 102, 255, 255 }, { 255, 102, 203, 255 }, { 255, 102, 152, 255 }, 61 { 255, 102, 102, 255 }, { 255, 102, 51, 255 }, { 255, 102, 0, 255 }, 62 { 0, 102, 152, 255 }, { 0, 102, 102, 255 }, { 203, 152, 255, 255 }, 63 { 203, 152, 203, 255 }, { 203, 152, 152, 255 }, { 203, 152, 102, 255 }, 64 { 203, 152, 51, 255 }, { 203, 152, 0, 255 }, { 152, 152, 255, 255 }, 65 { 152, 152, 203, 255 }, { 152, 152, 152, 255 }, { 152, 152, 102, 255 }, 66 { 152, 152, 51, 255 }, { 152, 152, 0, 255 }, { 102, 152, 255, 255 }, 67 { 102, 152, 203, 255 }, { 102, 152, 152, 255 }, { 102, 152, 102, 255 }, 68 { 102, 152, 51, 255 }, { 102, 152, 0, 255 }, { 51, 152, 255, 255 }, 69 { 51, 152, 203, 255 }, { 51, 152, 152, 255 }, { 51, 152, 102, 255 }, 70 { 51, 152, 51, 255 }, { 51, 152, 0, 255 }, { 230, 134, 0, 255 }, 71 { 255, 51, 203, 255 }, { 255, 51, 152, 255 }, { 255, 51, 102, 255 }, 72 { 255, 51, 51, 255 }, { 255, 51, 0, 255 }, { 0, 102, 51, 255 }, 73 { 0, 102, 0, 255 }, { 203, 102, 255, 255 }, { 203, 102, 203, 255 }, 74 { 203, 102, 152, 255 }, { 203, 102, 102, 255 }, { 203, 102, 51, 255 }, 75 { 203, 102, 0, 255 }, { 152, 102, 255, 255 }, { 152, 102, 203, 255 }, 76 { 152, 102, 152, 255 }, { 152, 102, 102, 255 }, { 152, 102, 51, 255 }, 77 { 152, 102, 0, 255 }, { 102, 102, 255, 255 }, { 102, 102, 203, 255 }, 78 { 102, 102, 152, 255 }, { 102, 102, 102, 255 }, { 102, 102, 51, 255 }, 79 { 102, 102, 0, 255 }, { 51, 102, 255, 255 }, { 51, 102, 203, 255 }, 80 { 51, 102, 152, 255 }, { 51, 102, 102, 255 }, { 51, 102, 51, 255 }, 81 { 51, 102, 0, 255 }, { 255, 0, 255, 255 }, { 255, 0, 203, 255 }, 82 { 255, 0, 152, 255 }, { 255, 0, 102, 255 }, { 255, 0, 51, 255 }, 83 { 255, 175, 19, 255 }, { 0, 51, 255, 255 }, { 0, 51, 203, 255 }, 84 { 203, 51, 255, 255 }, { 203, 51, 203, 255 }, { 203, 51, 152, 255 }, 85 { 203, 51, 102, 255 }, { 203, 51, 51, 255 }, { 203, 51, 0, 255 }, 86 { 152, 51, 255, 255 }, { 152, 51, 203, 255 }, { 152, 51, 152, 255 }, 87 { 152, 51, 102, 255 }, { 152, 51, 51, 255 }, { 152, 51, 0, 255 }, 88 { 102, 51, 255, 255 }, { 102, 51, 203, 255 }, { 102, 51, 152, 255 }, 89 { 102, 51, 102, 255 }, { 102, 51, 51, 255 }, { 102, 51, 0, 255 }, 90 { 51, 51, 255, 255 }, { 51, 51, 203, 255 }, { 51, 51, 152, 255 }, 91 { 51, 51, 102, 255 }, { 51, 51, 51, 255 }, { 51, 51, 0, 255 }, 92 { 255, 203, 102, 255 }, { 255, 203, 152, 255 }, { 255, 203, 203, 255 }, 93 { 255, 203, 255, 255 }, { 0, 51, 152, 255 }, { 0, 51, 102, 255 }, 94 { 0, 51, 51, 255 }, { 0, 51, 0, 255 }, { 203, 0, 255, 255 }, 95 { 203, 0, 203, 255 }, { 203, 0, 152, 255 }, { 203, 0, 102, 255 }, 96 { 203, 0, 51, 255 }, { 255, 227, 70, 255 }, { 152, 0, 255, 255 }, 97 { 152, 0, 203, 255 }, { 152, 0, 152, 255 }, { 152, 0, 102, 255 }, 98 { 152, 0, 51, 255 }, { 152, 0, 0, 255 }, { 102, 0, 255, 255 }, 99 { 102, 0, 203, 255 }, { 102, 0, 152, 255 }, { 102, 0, 102, 255 }, 100 { 102, 0, 51, 255 }, { 102, 0, 0, 255 }, { 51, 0, 255, 255 }, 101 { 51, 0, 203, 255 }, { 51, 0, 152, 255 }, { 51, 0, 102, 255 }, 102 { 51, 0, 51, 255 }, { 51, 0, 0, 255 }, { 255, 203, 51, 255 }, 103 { 255, 203, 0, 255 }, { 255, 255, 0, 255 }, { 255, 255, 51, 255 }, 104 { 255, 255, 102, 255 }, { 255, 255, 152, 255 }, { 255, 255, 203, 255 }, 105 { 255, 255, 255, 0 } // B_TRANSPARENT_MAGIC_CMAP8 106 }; 107 108 109 // TODO: BWindowScreen has a method to set the palette. 110 // maybe we should have a lock to protect this variable. 111 static color_map sColorMap; 112 113 114 // color_distance 115 /*! \brief Returns the "distance" between two RGB colors. 116 117 This functions defines an metric on the RGB color space. The distance 118 between two colors is 0, if and only if the colors are equal. 119 120 \param red1 Red component of the first color. 121 \param green1 Green component of the first color. 122 \param blue1 Blue component of the first color. 123 \param red2 Red component of the second color. 124 \param green2 Green component of the second color. 125 \param blue2 Blue component of the second color. 126 \return The distance between the given colors. 127 */ 128 static inline uint32 129 color_distance(uint8 red1, uint8 green1, uint8 blue1, 130 uint8 red2, uint8 green2, uint8 blue2) 131 { 132 int rd = (int)red1 - (int)red2; 133 int gd = (int)green1 - (int)green2; 134 int bd = (int)blue1 - (int)blue2; 135 136 // distance according to psycho-visual tests 137 // algorithm taken from here: 138 // http://www.stud.uni-hannover.de/~michaelt/juggle/Algorithms.pdf 139 int rmean = ((int)red1 + (int)red2) / 2; 140 return (((512 + rmean) * rd * rd) >> 8) 141 + 4 * gd * gd 142 + (((767 - rmean) * bd * bd) >> 8); 143 } 144 145 146 static inline uint8 147 FindClosestColor(const rgb_color &color, const rgb_color *palette) 148 { 149 uint8 closestIndex = 0; 150 unsigned closestDistance = UINT_MAX; 151 for (int32 i = 0; i < 256; i++) { 152 const rgb_color &c = palette[i]; 153 unsigned distance = color_distance(color.red, color.green, color.blue, 154 c.red, c.green, c.blue); 155 if (distance < closestDistance) { 156 closestIndex = (uint8)i; 157 closestDistance = distance; 158 } 159 } 160 return closestIndex; 161 } 162 163 164 static inline rgb_color 165 InvertColor(const rgb_color &color) 166 { 167 // For some reason, Inverting (255, 255, 255) on beos 168 // results in the same color. 169 if (color.red == 255 && color.green == 255 170 && color.blue == 255) 171 return color; 172 173 rgb_color inverted; 174 inverted.red = 255 - color.red; 175 inverted.green = 255 - color.green; 176 inverted.blue = 255 - color.blue; 177 inverted.alpha = 255; 178 179 return inverted; 180 } 181 182 183 static void 184 FillColorMap(const rgb_color *palette, color_map *map) 185 { 186 memcpy(map->color_list, palette, sizeof(map->color_list)); 187 188 // init index map 189 for (int32 color = 0; color < 32768; color++) { 190 // get components 191 rgb_color rgbColor; 192 rgbColor.red = (color & 0x7c00) >> 7; 193 rgbColor.green = (color & 0x3e0) >> 2; 194 rgbColor.blue = (color & 0x1f) << 3; 195 196 map->index_map[color] = FindClosestColor(rgbColor, palette); 197 } 198 199 // init inversion map 200 for (int32 index = 0; index < 256; index++) { 201 rgb_color inverted = InvertColor(map->color_list[index]); 202 map->inversion_map[index] = FindClosestColor(inverted, palette); 203 } 204 } 205 206 207 /*! \brief Initializes the system color_map. 208 */ 209 void 210 InitializeColorMap() 211 { 212 FillColorMap(kSystemPalette, &sColorMap); 213 } 214 215 216 /*! \brief Returns a pointer to the system palette. 217 \return A pointer to the system palette. 218 */ 219 const rgb_color * 220 SystemPalette() 221 { 222 return sColorMap.color_list; 223 } 224 225 226 /*! \brief Returns a pointer to the system color_map structure. 227 \return A pointer to the system color_map. 228 */ 229 const color_map * 230 SystemColorMap() 231 { 232 return &sColorMap; 233 } 234