#include <GraphicsDefs.h>
#include <InterfaceDefs.h>
#include <Palette.h>
static color_map sColorMap;
static inline uint32
color_distance(uint8 red1, uint8 green1, uint8 blue1,
uint8 red2, uint8 green2, uint8 blue2)
{
int rd = (int)red1 - (int)red2;
int gd = (int)green1 - (int)green2;
int bd = (int)blue1 - (int)blue2;
int rmean = ((int)red1 + (int)red2) / 2;
return (((512 + rmean) * rd * rd) >> 8)
+ 4 * gd * gd
+ (((767 - rmean) * bd * bd) >> 8);
}
static inline uint8
FindClosestColor(const rgb_color &color, const rgb_color *palette)
{
uint8 closestIndex = 0;
unsigned closestDistance = UINT_MAX;
for (int32 i = 0; i < 256; i++) {
const rgb_color &c = palette[i];
unsigned distance = color_distance(color.red, color.green, color.blue,
c.red, c.green, c.blue);
if (distance < closestDistance) {
closestIndex = (uint8)i;
closestDistance = distance;
}
}
return closestIndex;
}
static inline rgb_color
InvertColor(const rgb_color &color)
{
if (color.red == 255 && color.green == 255
&& color.blue == 255)
return color;
rgb_color inverted;
inverted.red = 255 - color.red;
inverted.green = 255 - color.green;
inverted.blue = 255 - color.blue;
inverted.alpha = 255;
return inverted;
}
static void
FillColorMap(const rgb_color *palette, color_map *map)
{
memcpy(map->color_list, palette, sizeof(map->color_list));
for (int32 color = 0; color < 32768; color++) {
rgb_color rgbColor;
rgbColor.red = (color & 0x7c00) >> 7;
rgbColor.green = (color & 0x3e0) >> 2;
rgbColor.blue = (color & 0x1f) << 3;
map->index_map[color] = FindClosestColor(rgbColor, palette);
}
for (int32 index = 0; index < 256; index++) {
rgb_color inverted = InvertColor(map->color_list[index]);
map->inversion_map[index] = FindClosestColor(inverted, palette);
}
}
const color_map *
system_colors()
{
static bool sInitialized = false;
if (!sInitialized) {
FillColorMap(kSystemPalette, &sColorMap);
sInitialized = true;
}
return &sColorMap;
}