move around - flatter.
[profile/ivi/evas.git] / src / lib / engines / common / evas_convert_color.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include "evas_common.h"
6 #include "evas_convert_color.h"
7
8
9 EAPI void
10 evas_common_convert_argb_premul(DATA32 *data, unsigned int len)
11 {
12    DATA32  *de = data + len;
13
14    while (data < de)
15      {
16         DATA32  a = 1 + (*data >> 24);
17
18         *data = (*data & 0xff000000) +
19           (((((*data) >> 8) & 0xff) * a) & 0xff00) +
20           (((((*data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
21         data++;
22      }
23 }
24
25 EAPI void
26 evas_common_convert_argb_unpremul(DATA32 *data, unsigned int len)
27 {
28    DATA32  *de = data + len;
29
30    while (data < de)
31      {
32         DATA32  a = (*data >> 24);
33
34         if ((a > 0) && (a < 255))
35            *data = ARGB_JOIN(a,
36                              (R_VAL(data) * 255) / a,
37                              (G_VAL(data) * 255) / a,
38                              (B_VAL(data) * 255) / a);
39         data++;
40      }
41
42 }
43
44 EAPI void
45 evas_common_convert_color_argb_premul(int a, int *r, int *g, int *b)
46 {
47    a++;
48    if (r) { *r = (a * *r) >> 8; }
49    if (g) { *g = (a * *g) >> 8; }
50    if (b) { *b = (a * *b) >> 8; }
51 }
52
53 EAPI void
54 evas_common_convert_color_argb_unpremul(int a, int *r, int *g, int *b)
55 {
56    if (!a) return;
57    if (r) { *r = (255 * *r) / a; }
58    if (g) { *g = (255 * *g) / a; }
59    if (b) { *b = (255 * *b) / a; }
60 }
61
62 EAPI void
63 evas_common_convert_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b)
64 {
65    int i;
66    float f;
67
68    v *= 255;
69    if (s == 0)
70      {
71        if (r) *r = v;
72        if (g) *g = v;
73        if (b) *b = v;
74        return;
75      }
76
77    h /= 60;
78    i = h;
79    f = h - i;
80
81    s *= v;
82    f *= s;
83    s = v - s;
84
85    switch (i)
86      {
87        case 1:
88          if (r) *r = v - f;  if (g) *g = v;  if (b) *b = s;
89          return;
90        case 2:
91          if (r) *r = s;  if (g) *g = v;  if (b) *b = s + f;
92          return;
93        case 3:
94          if (r) *r = s;  if (g) *g = v - f;  if (b) *b = v;
95          return;
96        case 4:
97          if (r) *r = s + f;  if (g) *g = s;  if (b) *b = v;
98          return;
99        case 5:
100          if (r) *r = v;  if (g) *g = s;  if (b) *b = v - f;
101          return;
102        default:
103          if (r) *r = v;  if (g) *g = s + f;  if (b) *b = s;
104          break;
105      }
106 }
107
108 EAPI void
109 evas_common_convert_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
110 {
111    int max, min, d = r - g;
112
113    //set min to MIN(g,r)
114    d = (d & (~(d >> 8)));
115    min = r - d;
116    //set max to MAX(g,r)
117    max = g + d;
118
119    //set min to MIN(b,min)
120    d = min - b;
121    min -= (d & (~(d >> 8)));
122
123    //set max to MAX(max,b)
124    d = b - max;
125    max += (d & (~(d >> 8)));
126
127    d = max - min;
128
129    if (v) *v = (max / 255.0);
130    if (!max)
131      {
132         if (s) *s = 0;
133         if (h) *h = 0;
134         return;
135      }
136
137    if (s) *s = (d / (float)max);
138    if (r == max)
139      {
140        if (h)
141          {
142            *h = 60 * ((g - b) / (float)d);
143            if (*h < 0) *h += 360;
144          }
145        return;
146      }
147    if (g == max)
148      {
149        if (h)
150          {
151            *h = 120 + (60 * ((b - r) / (float)d));
152            if (*h < 0) *h += 360;
153          }
154        return;
155      }
156    if (h)
157      {
158        *h = 240 + (60 * ((r - g) / (float)d));
159        if (*h < 0) *h += 360;
160      }
161 }
162
163 EAPI void
164 evas_common_convert_color_hsv_to_rgb_int(int h, int s, int v, int *r, int *g, int *b)
165 {
166    int   i, f;
167
168    if (!s)
169      {
170         *r = *g = *b = v;
171         return;
172      }
173
174    i = h / 255;
175    f = h - (i * 255);
176    s = (v * s) / 255;
177    f = (s * f) / 255;
178    s = v - s;
179
180    switch (i)
181      {
182         case 1:
183           *r = v - f; *g = v; *b = s;
184           return;
185         case 2:
186           *r = s; *g = v; *b = s + f;
187           return;
188         case 3:
189           *r = s; *g = v - f; *b = v;
190           return;
191         case 4:
192           *r = s + f; *g = s; *b = v;
193           return;
194         case 5:
195           *r = v; *g = s; *b = v - f;
196           return;
197         default:
198           *r = v; *g = s + f; *b = s;
199          break;
200      }
201 }
202
203 EAPI void
204 evas_common_convert_color_rgb_to_hsv_int(int r, int g, int b, int *h, int *s, int *v)
205 {
206    int  min, max, d = r - g;
207
208    d = (d & (~(d >> 8)));
209    min = r - d;
210    max = g + d;
211
212    d = min - b;
213    min -= (d & (~(d >> 8)));
214
215    d = b - max;
216    max += (d & (~(d >> 8)));
217
218    d = max - min;
219
220    *v = max;
221    if (!max)
222      {
223         *s = *h = 0;
224         return;
225      }
226
227    *s = ((d * 255) / max);
228
229    if (r == max)
230      {
231         *h = (((g - b) * 255) / d);
232         if (*h < 0) *h += 1530;
233         return;
234      }
235    if (g == max)
236      {
237         *h = 510 + (((b - r) * 255) / d);
238         if (*h < 0) *h += 1530;
239         return;
240      }
241    *h = 1020 + (((r - g) * 255) / d);
242    if (*h < 0) *h += 1530;
243
244 }