2010-09-13 15:27:48 +00:00
|
|
|
/*--
|
2010-03-30 17:16:26 +00:00
|
|
|
Colors.c
|
2010-03-30 13:33:21 +00:00
|
|
|
Authors: Tyron
|
|
|
|
|
|
|
|
All sorts of operations on colors.
|
|
|
|
--*/
|
2009-12-29 13:44:16 +00:00
|
|
|
|
|
|
|
static const RGBA_ALPHA = 0;
|
|
|
|
static const RGBA_RED = 1;
|
|
|
|
static const RGBA_GREEN = 2;
|
|
|
|
static const RGBA_BLUE = 3;
|
|
|
|
|
2010-03-30 13:33:21 +00:00
|
|
|
global func HSL(int h, int s, int l) { return HSL2RGB(RGB(h, s, l)); }
|
|
|
|
global func HSLa(int h, int s, int l, int a) { return HSL2RGB(RGB(h, s, l)) | (a & 255) << 24; }
|
2009-12-29 13:44:16 +00:00
|
|
|
|
2010-03-30 13:33:21 +00:00
|
|
|
global func RGB(int r, int g, int b) { return (255 << 24) | (r & 255) << 16 | (g & 255) << 8 | (b & 255); }
|
|
|
|
global func RGBa (int r, int g, int b, int a) { return (a & 255) << 24 | (r & 255) << 16 | (g & 255) << 8 | (b & 255); }
|
2009-12-29 13:44:16 +00:00
|
|
|
|
2010-03-30 13:33:21 +00:00
|
|
|
global func GetRGBaValue(int val, int sel) { return val >> ((3 - sel) * 8) & 255; }
|
|
|
|
global func DoRGBaValue(int val, int chng, int sel) { return val + (chng << ((3 - sel) * 8)); }
|
|
|
|
|
2010-09-13 15:27:48 +00:00
|
|
|
global func SetRGBaValue(int val, int newval, int sel)
|
2010-03-30 13:33:21 +00:00
|
|
|
{
|
2010-03-30 16:48:38 +00:00
|
|
|
// 'delete' old color
|
|
|
|
val = val & ~(255 << ((3 - sel) * 8));
|
|
|
|
// add new
|
|
|
|
return val | newval << ((3 - sel) * 8);
|
2009-12-29 13:44:16 +00:00
|
|
|
}
|
2010-03-30 13:33:21 +00:00
|
|
|
|
2010-04-08 00:48:40 +00:00
|
|
|
global func SplitRGBaValue(int rgb) {
|
|
|
|
return [GetRGBaValue(rgb, 1), GetRGBaValue(rgb, 2), GetRGBaValue(rgb, 3), GetRGBaValue(rgb, 0)];
|
2009-12-29 13:44:16 +00:00
|
|
|
}
|
|
|
|
|
2010-03-30 13:33:21 +00:00
|
|
|
global func HSL2RGB(int hsl)
|
|
|
|
{
|
2010-03-30 16:48:38 +00:00
|
|
|
var hue = GetRGBaValue(hsl, 1), sat = GetRGBaValue(hsl, 2), lightness = GetRGBaValue(hsl, 3);
|
|
|
|
var red, green, blue;
|
|
|
|
var var1, var2;
|
|
|
|
|
|
|
|
if (sat == 0)
|
2010-03-30 13:33:21 +00:00
|
|
|
{
|
2010-03-30 16:48:38 +00:00
|
|
|
red = green = blue = lightness;
|
2010-09-13 15:27:48 +00:00
|
|
|
}
|
2010-03-30 13:33:21 +00:00
|
|
|
else
|
|
|
|
{
|
2010-09-13 15:27:48 +00:00
|
|
|
if (lightness < 128)
|
2010-03-30 13:33:21 +00:00
|
|
|
var2 = lightness * (255 + sat) / 255;
|
2010-03-30 16:48:38 +00:00
|
|
|
else
|
2010-03-30 13:33:21 +00:00
|
|
|
var2 = lightness + sat - lightness * sat / 255;
|
2010-03-30 16:48:38 +00:00
|
|
|
|
|
|
|
var1 = 2 * lightness - var2;
|
|
|
|
|
|
|
|
red = Hue_2_RGB(var1, var2, hue + 85);
|
|
|
|
green = Hue_2_RGB(var1, var2, hue);
|
|
|
|
blue = Hue_2_RGB(var1, var2, hue - 85);
|
|
|
|
}
|
|
|
|
|
|
|
|
return RGB(red, green, blue);
|
2009-12-29 13:44:16 +00:00
|
|
|
}
|
|
|
|
|
2010-03-30 13:33:21 +00:00
|
|
|
global func Hue_2_RGB(int var1, int var2, int hue)
|
|
|
|
{
|
|
|
|
if (hue < 0)
|
|
|
|
hue += 255;
|
|
|
|
if (hue > 255)
|
|
|
|
hue -= 255;
|
2010-09-13 15:27:48 +00:00
|
|
|
if (6 * hue < 255)
|
2010-03-30 13:33:21 +00:00
|
|
|
return var1 + (var2 - var1) * 6 * hue / 255;
|
2010-09-13 15:27:48 +00:00
|
|
|
if (2 * hue < 255)
|
2010-03-30 13:33:21 +00:00
|
|
|
return var2;
|
|
|
|
if (3 * hue < 510)
|
|
|
|
return var1 + (var2 - var1) * ( 510 / 3 - hue ) * 6 / 255;
|
|
|
|
return var1;
|
2009-12-29 13:44:16 +00:00
|
|
|
}
|
|
|
|
|
2010-03-30 13:33:21 +00:00
|
|
|
global func RGB2HSL(int rgb)
|
|
|
|
{
|
2010-03-30 16:48:38 +00:00
|
|
|
var red = GetRGBaValue(rgb, 1), green = GetRGBaValue(rgb, 2), blue = GetRGBaValue(rgb, 3);
|
|
|
|
var min_val = Min(red, Min(green, blue)), max_val = Max(red, Max(green, blue));
|
|
|
|
var diff_val = max_val - min_val;
|
|
|
|
var lightness = (max_val + min_val) / 2;
|
|
|
|
var hue, sat, diff_red, diff_green, diff_blue;
|
|
|
|
|
|
|
|
if (diff_val==0)
|
2010-03-30 13:33:21 +00:00
|
|
|
{
|
2010-03-30 16:48:38 +00:00
|
|
|
hue = 0;
|
2010-03-30 13:33:21 +00:00
|
|
|
sat = 0;
|
2010-09-13 15:27:48 +00:00
|
|
|
}
|
2010-03-30 13:33:21 +00:00
|
|
|
else
|
|
|
|
{
|
2010-09-13 15:27:48 +00:00
|
|
|
if (lightness < 128)
|
2010-03-30 13:33:21 +00:00
|
|
|
sat = 255 * diff_val / (max_val + min_val);
|
2010-09-13 15:27:48 +00:00
|
|
|
else
|
2010-03-30 13:33:21 +00:00
|
|
|
sat = 255 * diff_val / (510 - (max_val + min_val));
|
2009-12-29 13:44:16 +00:00
|
|
|
|
2010-03-30 16:48:38 +00:00
|
|
|
diff_red = ((255 * (max_val - red)) / 6 + (255 * diff_val) / 2) / diff_val;
|
|
|
|
diff_green = ((255 * (max_val - green)) / 6 + (255 * diff_val) / 2) / diff_val;
|
|
|
|
diff_blue = ((255 * (max_val - blue )) / 6 + (255 * diff_val) / 2) / diff_val;
|
|
|
|
|
2010-09-13 15:27:48 +00:00
|
|
|
if (red == max_val)
|
2010-03-30 13:33:21 +00:00
|
|
|
hue = diff_blue -diff_green;
|
2010-09-13 15:27:48 +00:00
|
|
|
else if (green == max_val)
|
2010-03-30 13:33:21 +00:00
|
|
|
hue = 255 / 3 + diff_red - diff_blue;
|
2010-03-30 16:48:38 +00:00
|
|
|
else if (blue == max_val)
|
2010-03-30 13:33:21 +00:00
|
|
|
hue = 510 / 3 + diff_green - diff_red;
|
2010-03-30 16:48:38 +00:00
|
|
|
|
2010-09-13 15:27:48 +00:00
|
|
|
if (hue < 0)
|
2010-03-30 13:33:21 +00:00
|
|
|
hue += 255;
|
2010-09-13 15:27:48 +00:00
|
|
|
if (hue > 255)
|
2010-03-30 13:33:21 +00:00
|
|
|
hue -= 255;
|
2010-03-30 16:48:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return RGB(hue,sat,lightness);
|
2009-12-29 13:44:16 +00:00
|
|
|
}
|