efl/src/lib/evas/common/evas_convert_color.c

279 lines
4.9 KiB
C

#include "evas_common_private.h"
#include "evas_convert_color.h"
#include "draw.h"
EAPI DATA32
evas_common_convert_ag_premul(DATA16 *data, unsigned int len)
{
DATA16 *de = data + len;
DATA32 nas = 0;
while (data < de)
{
DATA16 a = 1 + ((*data >> 8) & 0xff);
*data = (*data & 0xff00) |
((((*data & 0xff) * a) >> 8) & 0xff);
data++;
if ((a == 1) || (a == 256))
nas++;
}
return nas;
}
EAPI void
evas_common_convert_ag_unpremul(DATA16 *data, unsigned int len)
{
DATA16 *de = data + len;
DATA16 p_val = 0x0000, p_res = 0x0000;
while (data < de)
{
if (p_val == *data) *data = p_res;
else
{
DATA16 a = (*data >> 8);
p_val = *data;
if ((a > 0) && (a < 255))
{
*data = ((a << 8) | (((*data & 0xff) * 0xff) / a));
}
else if (a == 0)
{
*data = 0x0000;
}
p_res = *data;
}
data++;
}
}
EAPI DATA32
evas_common_convert_argb_premul(DATA32 *data, unsigned int len)
{
return (DATA32) efl_draw_argb_premul(data, len);
}
EAPI void
evas_common_convert_argb_unpremul(DATA32 *data, unsigned int len)
{
return efl_draw_argb_unpremul(data, len);
}
EAPI void
evas_common_convert_color_argb_premul(int a, int *r, int *g, int *b)
{
a++;
if (r) { *r = (a * *r) >> 8; }
if (g) { *g = (a * *g) >> 8; }
if (b) { *b = (a * *b) >> 8; }
}
EAPI void
evas_common_convert_color_argb_unpremul(int a, int *r, int *g, int *b)
{
if (!a) return;
if (r) { *r = (255 * *r) / a; }
if (g) { *g = (255 * *g) / a; }
if (b) { *b = (255 * *b) / a; }
}
EAPI void
evas_common_convert_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b)
{
int i;
float f;
v *= 255;
if (EINA_FLT_EQ(s, 0.0))
{
if (r) *r = v;
if (g) *g = v;
if (b) *b = v;
return;
}
h /= 60;
i = h;
f = h - i;
s *= v;
f *= s;
s = v - s;
switch (i)
{
case 1:
if (r) *r = v - f;
if (g) *g = v;
if (b) *b = s;
return;
case 2:
if (r) *r = s;
if (g) *g = v;
if (b) *b = s + f;
return;
case 3:
if (r) *r = s;
if (g) *g = v - f;
if (b) *b = v;
return;
case 4:
if (r) *r = s + f;
if (g) *g = s;
if (b) *b = v;
return;
case 5:
if (r) *r = v;
if (g) *g = s;
if (b) *b = v - f;
return;
default:
if (r) *r = v;
if (g) *g = s + f;
if (b) *b = s;
break;
}
}
EAPI void
evas_common_convert_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
{
int max, min, d = r - g;
//set min to MIN(g,r)
d = (d & (~(d >> 8)));
min = r - d;
//set max to MAX(g,r)
max = g + d;
//set min to MIN(b,min)
d = min - b;
min -= (d & (~(d >> 8)));
//set max to MAX(max,b)
d = b - max;
max += (d & (~(d >> 8)));
d = max - min;
if (v) *v = (max / 255.0);
if (!max || !d)
{
if (s) *s = 0;
if (h) *h = 0;
return;
}
if (s) *s = (d / (float)max);
if (r == max)
{
if (h)
{
*h = 60 * ((g - b) / (float)d);
if (*h < 0) *h += 360;
}
return;
}
if (g == max)
{
if (h)
{
*h = 120 + (60 * ((b - r) / (float)d));
if (*h < 0) *h += 360;
}
return;
}
if (h)
{
*h = 240 + (60 * ((r - g) / (float)d));
if (*h < 0) *h += 360;
}
}
EAPI void
evas_common_convert_color_hsv_to_rgb_int(int h, int s, int v, int *r, int *g, int *b)
{
int i, f;
if (!s)
{
*r = *g = *b = v;
return;
}
i = h / 255;
f = h - (i * 255);
s = (v * s) / 255;
f = (s * f) / 255;
s = v - s;
switch (i)
{
case 1:
*r = v - f; *g = v; *b = s;
return;
case 2:
*r = s; *g = v; *b = s + f;
return;
case 3:
*r = s; *g = v - f; *b = v;
return;
case 4:
*r = s + f; *g = s; *b = v;
return;
case 5:
*r = v; *g = s; *b = v - f;
return;
default:
*r = v; *g = s + f; *b = s;
break;
}
}
EAPI void
evas_common_convert_color_rgb_to_hsv_int(int r, int g, int b, int *h, int *s, int *v)
{
int min, max, d = r - g;
d = (d & (~(d >> 8)));
min = r - d;
max = g + d;
d = min - b;
min -= (d & (~(d >> 8)));
d = b - max;
max += (d & (~(d >> 8)));
d = max - min;
*v = max;
if (!max)
{
*s = *h = 0;
return;
}
*s = ((d * 255) / max);
if (r == max)
{
*h = (((g - b) * 255) / d);
if (*h < 0) *h += 1530;
return;
}
if (g == max)
{
*h = 510 + (((b - r) * 255) / d);
if (*h < 0) *h += 1530;
return;
}
*h = 1020 + (((r - g) * 255) / d);
if (*h < 0) *h += 1530;
}