Fix compilation error of Cycles after recent py node removal
[blender-staging.git] / release / plugins / sequence / color-correction-hsv.c
1 /*
2  * Color Correction Plugin (YUV Version) 0.01
3  *
4  * Copyright (c) 2005 Peter Schlaile
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <math.h>
19 #include "plugin.h"
20 #include <stdio.h>
21
22 char name[] = "Color Correction";
23
24 VarStruct varstr[] = {
25         { NUMSLI | FLO, "St Y:", 0.0, -1.0,   1.0, "Setup Y"},
26         { NUMSLI | FLO, "Gn Y:",  1.0,    0.0,    10.0, "Gain Y"},
27         { NUMSLI | FLO, "Ga Y:", 1.0, 0.0,    10.0, "Gamma Y"},
28
29         { NUMSLI | FLO, "Lo S:",  1.0,    0.0,    10.0, "Saturation Shadows"},
30         { NUMSLI | FLO, "Md S:",  1.0,    0.0,    10.0, "Saturation Midtones"},
31         { NUMSLI | FLO, "Hi S:",  1.0,    0.0,    10.0, "Saturation Highlights"},
32
33         { NUMSLI | FLO, "MA S:",  1.0,    0.0,    10.0, "Master Saturation"},
34
35         { NUMSLI | FLO, "Lo T:",  0.25, 0.0, 1.0,
36           "Saturation Shadow Thres"}, 
37         { NUMSLI | FLO, "Hi T:",  0.75, 0.0, 1.0,
38           "Saturation Highlights Thres"}, 
39         { TOG | INT,  "Debug", 0.0,   0.0,    1.0,
40           "Show curves as overlay"}, 
41 };
42
43 typedef struct Cast {
44         float setup_y;
45         float gain_y;
46         float gamma_y;
47         float sat_shadows;
48         float sat_midtones;
49         float sat_highlights;
50
51         float master_sat;
52         float lo_thres;
53         float hi_thres;
54         int debug;
55 } Cast;
56
57 float cfra;
58
59 void plugin_seq_doit(Cast *, float, float, int, int, ImBuf *, ImBuf *, ImBuf *, ImBuf *);
60
61 int plugin_seq_getversion(void)
62 {
63         return B_PLUGIN_VERSION;
64 }
65 void plugin_but_changed(int but) {}
66 void plugin_init() {}
67
68 void plugin_getinfo(PluginInfo *info)
69 {
70         info->name = name;
71         info->nvars = sizeof(varstr) / sizeof(VarStruct);
72         info->cfra = &cfra;
73
74         info->varstr = varstr;
75
76         info->init = plugin_init;
77         info->seq_doit = (SeqDoit) plugin_seq_doit;
78         info->callback = plugin_but_changed;
79 }
80
81 static void hsv_to_rgb(double h, double s, double v,
82                        double *r, double *g, double *b)
83 {
84         int i;
85         double f, w, q, t;
86
87         if (s == 0.0)
88                 s = 0.000001;
89         
90         if (h == -1.0)
91         {
92                 *r = v;
93                 *g = v;
94                 *b = v;
95         }
96         else {
97                 if (h == 360.0)
98                         h = 0.0;
99                 h = h / 60.0;
100                 i = (int) h;
101                 f = h - i;
102                 w = v * (1.0 - s);
103                 q = v * (1.0 - (s * f));
104                 t = v * (1.0 - (s * (1.0 - f)));
105                 
106                 switch (i)
107                 {
108                         case 0:
109                                 *r = v;
110                                 *g = t;
111                                 *b = w;
112                                 break;
113                         case 1:
114                                 *r = q;
115                                 *g = v;
116                                 *b = w;
117                                 break;
118                         case 2:
119                                 *r = w;
120                                 *g = v;
121                                 *b = t;
122                                 break;
123                         case 3:
124                                 *r = w;
125                                 *g = q;
126                                 *b = v;
127                                 break;
128                         case 4:
129                                 *r = t;
130                                 *g = w;
131                                 *b = v;
132                                 break;
133                         case 5:
134                                 *r = v;
135                                 *g = w;
136                                 *b = q;
137                                 break;
138                 }
139         }
140 }
141
142 static void rgb_to_hsv(double r, double g, double b,
143                        double *h, double *s, double *v)
144 {
145         double max, min, delta;
146
147         max = r;
148         if (g > max)
149                 max = g;
150         if (b > max)
151                 max = b;
152         
153         min = r;
154         if (g < min)
155                 min = g;
156         if (b < min)
157                 min = b;
158         
159         *v = max;
160         
161         if (max != 0.0)
162                 *s = (max - min) / max;
163         else
164                 *s = 0.0;
165         
166         if (*s == 0.0)
167                 *h = -1.0;
168         else {
169                 delta = max - min;
170                 
171                 if (r == max)
172                         *h = (g - b) / delta;
173                 else if (g == max)
174                         *h = 2.0 + (b - r) / delta;
175                 else if (b == max)
176                         *h = 4.0 + (r - g) / delta;
177                 
178                 *h = *h * 60.0;
179                 
180                 if (*h < 0.0)
181                         *h = *h + 360;
182         }
183 }
184
185 void plugin_seq_doit(Cast *cast, float facf0, float facf1, int width, 
186                      int height, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *out, ImBuf *use)
187 {
188         char *dest, *src1;
189         int x, y, c;
190         double gamma_table[256];
191         double uv_table[256];
192         float *destf = out->rect_float;
193         float *src1f;
194         
195         if (!ibuf1) return;
196
197         dest = (char *) out->rect;
198         src1 = (char *) ibuf1->rect;
199         src1f = ibuf1->rect_float;
200
201         for (y = 0; y < 256; y++) {
202                 float v = 1.0 * y / 255;
203                 v += cast->setup_y;
204                 v *= cast->gain_y;
205                 v = pow(v, cast->gamma_y);
206                 if (v > 1.0) {
207                         v = 1.0;
208                 }
209                 else if (v < 0.0) {
210                         v = 0.0;
211                 }
212                 gamma_table[y] = v * 255;
213         }
214
215         for (y = 0; y < 256; y++) {
216                 float v = 1.0;
217                 v *= cast->master_sat;
218                 if (y < cast->lo_thres * 255) {
219                         v *= cast->sat_shadows;
220                 }
221                 else if (y > cast->hi_thres * 255) {
222                         v *= cast->sat_highlights;
223                 }
224                 else {
225                         v *= cast->sat_midtones;
226                 }
227                 uv_table[y] = v;
228         }
229
230
231         for (y = 0; y < height; y++) {
232                 for (x = 0; x < width; x++) {
233                         double h, s, v, r, g, b;
234                         double fac;
235
236                         if (ibuf1->rect_float) rgb_to_hsv(src1f[0], src1f[1],
237                                                               src1f[2], &h, &s, &v);
238                         else rgb_to_hsv((double) src1[0] / 255.0,
239                                             (double) src1[1] / 255.0,
240                                             (double) src1[2] / 255.0,
241                                             &h, &s, &v);
242                         v = gamma_table[(int) (v * 255.0)] / 255.0;
243
244                         fac = uv_table[(int) (255.0 * v)];
245
246                         s *= fac;
247                         if (s >= 1.0) {
248                                 s = 1.0;
249                         }
250                         hsv_to_rgb(h, s, v, &r, &g, &b);
251                         
252                         if (out->rect_float) {
253                                 destf[0] = r;
254                                 destf[1] = g;
255                                 destf[2] = b;
256                                 destf = destf + 4;
257                                 src1f += 4;
258                         }
259                         else {
260                                 dest[0] = r * 255.0;
261                                 dest[1] = g * 255.0;
262                                 dest[2] = b * 255.0;
263                                 dest += 4;
264                         }
265
266                         src1 += 4;
267                 }
268         }
269
270         if (cast->debug) {
271                 dest = (char *) out->rect;
272                 for (c = 0; c < 10; c++) {
273                         x = 0;
274                         for (y = 0; y < 256; y++) {
275                                 char val = gamma_table[y];
276                                 while (x < y * width / 255) {
277                                         *dest++ = val;
278                                         *dest++ = val;
279                                         *dest++ = val;
280                                         dest++;
281                                         x++;
282                                 }
283                         }
284                 }
285                 for (c = 0; c < 10; c++) {
286                         x = 0;
287                         for (y = 0; y < 256; y++) {
288                                 char val = uv_table[y] * 255.0 / 10.0;
289                                 while (x < y * width / 255) {
290                                         *dest++ = val;
291                                         *dest++ = val;
292                                         *dest++ = val;
293                                         dest++;
294                                         x++;
295                                 }
296                         }
297                 }
298         }
299 }