* Copyright 2001-2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Stefano Ceccherini (burton666@libero.it)
*/
#include "SystemPalette.h"
#include <stdio.h>
#include <string.h>
#include <Palette.h>
static color_map sColorMap;
This functions defines an metric on the RGB color space. The distance
between two colors is 0, if and only if the colors are equal.
\param red1 Red component of the first color.
\param green1 Green component of the first color.
\param blue1 Blue component of the first color.
\param red2 Red component of the second color.
\param green2 Green component of the second color.
\param blue2 Blue component of the second color.
\return The distance between the given colors.
*/
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((void*)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);
}
}
*/
void
InitializeColorMap()
{
FillColorMap(kSystemPalette, &sColorMap);
}
\return A pointer to the system palette.
*/
const rgb_color *
SystemPalette()
{
return sColorMap.color_list;
}
\return A pointer to the system color_map.
*/
const color_map *
SystemColorMap()
{
return &sColorMap;
}