7 #define DBG(x) printf x
12 static float MAX_EXP_ARG; /* = log(DBL_MAX); */
15 /* these functions currently assume RGB images - there seems to be some
16 support for other color spaces, but I can't tell how you find what
17 space an image is using.
19 HSV conversions from pages 401-403 "Procedural Elements for Computer
20 Graphics", 1985, ISBN 0-07-053534-5. The algorithm presents to produce
21 an HSV color calculates all components at once - I don't, so I've
22 simiplified the algorithm to avoid unnecessary calculation (any errors
23 (of which I had a few ;) are mine).
26 /* returns the value (brightness) of color from 0 to 1 */
27 static double hsv_value(i_color color) {
28 return i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b) / 255.0;
31 /* returns the hue (color) of color from 0 to 360 */
32 static double hsv_hue(i_color color) {
35 temp = i_min(i_min(color.rgb.r, color.rgb.g), color.rgb.b);
36 val = i_max(color.rgb.r, i_max(color.rgb.g, color.rgb.b));
37 if (val == 0 || val==temp) {
41 double cr = (val - color.rgb.r) / (double)(val - temp);
42 double cg = (val - color.rgb.g) / (double)(val - temp);
43 double cb = (val - color.rgb.b) / (double)(val - temp);
45 if (color.rgb.r == val) {
48 else if (color.rgb.g == val) {
51 else { /* if (blue == val) */
54 hue *= 60.0; /* to degrees */
62 /* return the saturation of color from 0 to 1 */
63 static double hsv_sat(i_color color) {
64 int value = i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b);
69 int temp = i_min(i_max(color.rgb.r, color.rgb.g), color.rgb.b);
70 return (value - temp) / (double)value;
74 static i_color make_hsv(double hue, double sat, double val, int alpha) {
77 for( i=0; i< MAXCHANNELS; i++) c.channel[i]=0;
78 DBG(("hsv=%f %f %f\n", hue, sat, val));
79 if (sat <= 0) { /* handle -ve in case someone supplies a bad value */
80 /* should this be * 256? */
81 c.rgb.r = c.rgb.g = c.rgb.b = 255 * val;
91 /* I want to handle -360 <= hue < 720 so that the caller can
102 m = val * (1.0 - sat);
103 n = val * (1.0 - sat * f);
104 k = val * (1.0 - sat * (1 - f));
108 c.rgb.r = v; c.rgb.g = k; c.rgb.b = m;
111 c.rgb.r = n; c.rgb.g = v; c.rgb.b = m;
114 c.rgb.r = m; c.rgb.g = v; c.rgb.b = k;
117 c.rgb.r = m; c.rgb.g = n; c.rgb.b = v;
120 c.rgb.r = k; c.rgb.g = m; c.rgb.b = v;
123 c.rgb.r = v; c.rgb.g = m; c.rgb.b = n;
132 static i_color make_rgb(int r, int g, int b, int a) {
155 /* greatly simplifies the code */
156 #define nout n_regs[codes->rout]
157 #define na n_regs[codes->ra]
158 #define nb n_regs[codes->rb]
159 #define nc n_regs[codes->rc]
160 #define nd n_regs[codes->rd]
161 #define cout c_regs[codes->rout]
162 #define ca c_regs[codes->ra]
163 #define cb c_regs[codes->rb]
164 #define cc c_regs[codes->rc]
165 #define cd c_regs[codes->rd]
167 /* this is a pretty poor epsilon used for loosening up equality comparisons
168 It isn't currently used for inequalities
171 #define n_epsilon(x, y) (abs(x)+abs(y))*0.001
172 static i_color bcol = {{ 0 }};
174 i_color i_rm_run(struct rm_op codes[], size_t code_count,
175 double n_regs[], size_t n_regs_count,
176 i_color c_regs[], size_t c_regs_count,
177 i_img *images[], size_t image_count) {
179 struct rm_op *codes_base = codes;
180 size_t count_base = code_count;
182 DBG(("rm_run(%p, %d)\n", codes, code_count));
184 DBG((" rm_code %d\n", codes->code));
185 switch (codes->code) {
206 if (abs(nb) > 1e-10) {
210 nout = 0; /* close enough ;) */
223 cout = make_rgb(ca.rgb.r * nb, ca.rgb.g * nb, ca.rgb.b * nb, 255);
227 cout = make_rgb(ca.rgb.r + cb.rgb.r, ca.rgb.g + cb.rgb.g,
228 ca.rgb.b + cb.rgb.b, 255);
232 cout = make_rgb(ca.rgb.r - cb.rgb.r, ca.rgb.g - cb.rgb.g,
233 ca.rgb.b - cb.rgb.b, 255);
245 nout = atan2(na, nb);
255 nout = sqrt(dx*dx+dy*dy);
259 i_gpix(images[0], na, nb, c_regs+codes->rout);
260 if (images[0]->channels < 4) cout.rgba.a = 255;
264 i_gpix(images[1], na, nb, c_regs+codes->rout);
265 if (images[1]->channels < 4) cout.rgba.a = 255;
269 i_gpix(images[2], na, nb, c_regs+codes->rout);
270 if (images[2]->channels < 4) cout.rgba.a = 255;
274 nout = hsv_value(ca);
286 cout = make_hsv(na, nb, nc, 255);
290 cout = make_hsv(na, nb, nc, nd);
310 cout = make_rgb(na, nb, nc, 255);
314 cout = make_rgb(na, nb, nc, nd);
330 nout = na <= nb + n_epsilon(na,nb);
338 nout = na >= nb - n_epsilon(na,nb);
346 nout = abs(na-nb) <= n_epsilon(na,nb);
350 nout = abs(na-nb) > n_epsilon(na,nb);
374 /* yes, order is important here */
375 code_count = count_base - codes->ra;
376 codes = codes_base + codes->ra;
381 /* yes, order is important here */
382 code_count = count_base - codes->rb;
383 codes = codes_base + codes->rb;
390 /* yes, order is important here */
391 code_count = count_base - codes->rb;
392 codes = codes_base + codes->rb;
415 if (!MAX_EXP_ARG) MAX_EXP_ARG = log(DBL_MAX);
416 if (na <= MAX_EXP_ARG) {
426 printf("r%d is %g\n", codes->ra, na);
434 /*croak("bad opcode"); */
435 printf("bad op %d\n", codes->code);
442 /* croak("no return opcode"); */