1 #include "common.h"
2 
3 #include <math.h>
4 
5 #include "blend.h"
6 #include "colormod.h"
7 #include "image.h"
8 
9 static DATABIG      mod_count = 0;
10 
11 ImlibColorModifier *
__imlib_CreateCmod(void)12 __imlib_CreateCmod(void)
13 {
14    ImlibColorModifier *cm;
15    int                 i;
16 
17    cm = malloc(sizeof(ImlibColorModifier));
18    cm->modification_count = mod_count;
19    for (i = 0; i < 256; i++)
20      {
21         cm->red_mapping[i] = (DATA8) i;
22         cm->green_mapping[i] = (DATA8) i;
23         cm->blue_mapping[i] = (DATA8) i;
24         cm->alpha_mapping[i] = (DATA8) i;
25      }
26    return cm;
27 }
28 
29 void
__imlib_FreeCmod(ImlibColorModifier * cm)30 __imlib_FreeCmod(ImlibColorModifier * cm)
31 {
32    free(cm);
33 }
34 
35 void
__imlib_CmodChanged(ImlibColorModifier * cm)36 __imlib_CmodChanged(ImlibColorModifier * cm)
37 {
38    mod_count++;
39    cm->modification_count = mod_count;
40 }
41 
42 void
__imlib_CmodSetTables(ImlibColorModifier * cm,DATA8 * r,DATA8 * g,DATA8 * b,DATA8 * a)43 __imlib_CmodSetTables(ImlibColorModifier * cm,
44                       DATA8 * r, DATA8 * g, DATA8 * b, DATA8 * a)
45 {
46    int                 i;
47 
48    for (i = 0; i < 256; i++)
49      {
50         if (r)
51            cm->red_mapping[i] = r[i];
52         if (g)
53            cm->green_mapping[i] = g[i];
54         if (b)
55            cm->blue_mapping[i] = b[i];
56         if (a)
57            cm->alpha_mapping[i] = a[i];
58      }
59    __imlib_CmodChanged(cm);
60 }
61 
62 void
__imlib_CmodReset(ImlibColorModifier * cm)63 __imlib_CmodReset(ImlibColorModifier * cm)
64 {
65    int                 i;
66 
67    for (i = 0; i < 256; i++)
68      {
69         cm->red_mapping[i] = (DATA8) i;
70         cm->green_mapping[i] = (DATA8) i;
71         cm->blue_mapping[i] = (DATA8) i;
72         cm->alpha_mapping[i] = (DATA8) i;
73      }
74    __imlib_CmodChanged(cm);
75 }
76 
77 void
__imlib_DataCmodApply(DATA32 * data,int w,int h,int jump,ImlibImageFlags * fl,ImlibColorModifier * cm)78 __imlib_DataCmodApply(DATA32 * data, int w, int h, int jump,
79                       ImlibImageFlags * fl, ImlibColorModifier * cm)
80 {
81    int                 x, y;
82    DATA32             *p;
83 
84    /* We might be adding alpha */
85    if (fl && !(*fl & F_HAS_ALPHA))
86      {
87         p = data;
88         for (y = 0; y < h; y++)
89           {
90              for (x = 0; x < w; x++)
91                {
92                   R_VAL(p) = R_CMOD(cm, R_VAL(p));
93                   G_VAL(p) = G_CMOD(cm, G_VAL(p));
94                   B_VAL(p) = B_CMOD(cm, B_VAL(p));
95                   p++;
96                }
97              p += jump;
98           }
99         return;
100      }
101 
102    p = data;
103    for (y = 0; y < h; y++)
104      {
105         for (x = 0; x < w; x++)
106           {
107              R_VAL(p) = R_CMOD(cm, R_VAL(p));
108              G_VAL(p) = G_CMOD(cm, G_VAL(p));
109              B_VAL(p) = B_CMOD(cm, B_VAL(p));
110              A_VAL(p) = A_CMOD(cm, A_VAL(p));
111              p++;
112           }
113         p += jump;
114      }
115 }
116 
117 void
__imlib_CmodGetTables(ImlibColorModifier * cm,DATA8 * r,DATA8 * g,DATA8 * b,DATA8 * a)118 __imlib_CmodGetTables(ImlibColorModifier * cm, DATA8 * r, DATA8 * g,
119                       DATA8 * b, DATA8 * a)
120 {
121    if (r)
122       memcpy(r, cm->red_mapping, (256 * sizeof(DATA8)));
123    if (g)
124       memcpy(g, cm->green_mapping, (256 * sizeof(DATA8)));
125    if (b)
126       memcpy(b, cm->blue_mapping, (256 * sizeof(DATA8)));
127    if (a)
128       memcpy(a, cm->alpha_mapping, (256 * sizeof(DATA8)));
129 }
130 
131 void
__imlib_CmodModBrightness(ImlibColorModifier * cm,double v)132 __imlib_CmodModBrightness(ImlibColorModifier * cm, double v)
133 {
134    int                 i, val, val2;
135 
136    val = (int)(v * 255);
137    for (i = 0; i < 256; i++)
138      {
139         val2 = (int)cm->red_mapping[i] + val;
140         if (val2 < 0)
141            val2 = 0;
142         if (val2 > 255)
143            val2 = 255;
144         cm->red_mapping[i] = (DATA8) val2;
145 
146         val2 = (int)cm->green_mapping[i] + val;
147         if (val2 < 0)
148            val2 = 0;
149         if (val2 > 255)
150            val2 = 255;
151         cm->green_mapping[i] = (DATA8) val2;
152 
153         val2 = (int)cm->blue_mapping[i] + val;
154         if (val2 < 0)
155            val2 = 0;
156         if (val2 > 255)
157            val2 = 255;
158         cm->blue_mapping[i] = (DATA8) val2;
159 
160         val2 = (int)cm->alpha_mapping[i] + val;
161         if (val2 < 0)
162            val2 = 0;
163         if (val2 > 255)
164            val2 = 255;
165         cm->alpha_mapping[i] = (DATA8) val2;
166      }
167 }
168 
169 void
__imlib_CmodModContrast(ImlibColorModifier * cm,double v)170 __imlib_CmodModContrast(ImlibColorModifier * cm, double v)
171 {
172    int                 i, val2;
173 
174    for (i = 0; i < 256; i++)
175      {
176         val2 = (int)(((double)cm->red_mapping[i] - 127) * v) + 127;
177         if (val2 < 0)
178            val2 = 0;
179         if (val2 > 255)
180            val2 = 255;
181         cm->red_mapping[i] = (DATA8) val2;
182 
183         val2 = (int)(((double)cm->green_mapping[i] - 127) * v) + 127;
184         if (val2 < 0)
185            val2 = 0;
186         if (val2 > 255)
187            val2 = 255;
188         cm->green_mapping[i] = (DATA8) val2;
189 
190         val2 = (int)(((double)cm->blue_mapping[i] - 127) * v) + 127;
191         if (val2 < 0)
192            val2 = 0;
193         if (val2 > 255)
194            val2 = 255;
195         cm->blue_mapping[i] = (DATA8) val2;
196 
197         val2 = (int)(((double)cm->alpha_mapping[i] - 127) * v) + 127;
198         if (val2 < 0)
199            val2 = 0;
200         if (val2 > 255)
201            val2 = 255;
202         cm->alpha_mapping[i] = (DATA8) val2;
203      }
204 }
205 
206 void
__imlib_CmodModGamma(ImlibColorModifier * cm,double v)207 __imlib_CmodModGamma(ImlibColorModifier * cm, double v)
208 {
209    int                 i, val2;
210 
211    if (v < 0.01)
212       v = 0.01;
213    for (i = 0; i < 256; i++)
214      {
215         val2 = (int)(pow(((double)cm->red_mapping[i] / 255), (1 / v)) * 255);
216         if (val2 < 0)
217            val2 = 0;
218         if (val2 > 255)
219            val2 = 255;
220         cm->red_mapping[i] = (DATA8) val2;
221 
222         val2 = (int)(pow(((double)cm->green_mapping[i] / 255), (1 / v)) * 255);
223         if (val2 < 0)
224            val2 = 0;
225         if (val2 > 255)
226            val2 = 255;
227         cm->green_mapping[i] = (DATA8) val2;
228 
229         val2 = (int)(pow(((double)cm->blue_mapping[i] / 255), (1 / v)) * 255);
230         if (val2 < 0)
231            val2 = 0;
232         if (val2 > 255)
233            val2 = 255;
234         cm->blue_mapping[i] = (DATA8) val2;
235 
236         val2 = (int)(pow(((double)cm->alpha_mapping[i] / 255), (1 / v)) * 255);
237         if (val2 < 0)
238            val2 = 0;
239         if (val2 > 255)
240            val2 = 255;
241         cm->alpha_mapping[i] = (DATA8) val2;
242      }
243 }
244 
245 #if 0
246 void
247 __imlib_ImageCmodApply(ImlibImage * im, ImlibColorModifier * cm)
248 {
249    __imlib_DataCmodApply(im->data, im->w, im->h, 0, cm);
250 }
251 #endif
252