6 #define DBG(x) printf x
11 static float MAX_EXP_ARG; /* = log(DBL_MAX); */
14 /* these functions currently assume RGB images - there seems to be some
15 support for other color spaces, but I can't tell how you find what
16 space an image is using.
18 HSV conversions from pages 401-403 "Procedural Elements for Computer
19 Graphics", 1985, ISBN 0-07-053534-5. The algorithm presents to produce
20 an HSV color calculates all components at once - I don't, so I've
21 simiplified the algorithm to avoid unnecessary calculation (any errors
22 (of which I had a few ;) are mine).
25 /* returns the value (brightness) of color from 0 to 1 */
26 static double hsv_value(i_color color) {
27 return i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b) / 255.0;
30 /* returns the hue (color) of color from 0 to 360 */
31 static double hsv_hue(i_color color) {
34 temp = i_min(i_min(color.rgb.r, color.rgb.g), color.rgb.b);
35 val = i_max(color.rgb.r, i_max(color.rgb.g, color.rgb.b));
36 if (val == 0 || val==temp) {
40 double cr = (val - color.rgb.r) / (double)(val - temp);
41 double cg = (val - color.rgb.g) / (double)(val - temp);
42 double cb = (val - color.rgb.b) / (double)(val - temp);
44 if (color.rgb.r == val) {
47 else if (color.rgb.g == val) {
50 else { /* if (blue == val) */
53 hue *= 60.0; /* to degrees */
61 /* return the saturation of color from 0 to 1 */
62 static double hsv_sat(i_color color) {
63 int value = i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b);
68 int temp = i_min(i_max(color.rgb.r, color.rgb.g), color.rgb.b);
69 return (value - temp) / (double)value;
73 static i_color make_hsv(double hue, double sat, double val, int alpha) {
76 for( i=0; i< MAXCHANNELS; i++) c.channel[i]=0;
77 DBG(("hsv=%f %f %f\n", hue, sat, val));
78 if (sat <= 0) { /* handle -ve in case someone supplies a bad value */
79 /* should this be * 256? */
80 c.rgb.r = c.rgb.g = c.rgb.b = 255 * val;
90 /* I want to handle -360 <= hue < 720 so that the caller can
101 m = val * (1.0 - sat);
102 n = val * (1.0 - sat * f);
103 k = val * (1.0 - sat * (1 - f));
107 c.rgb.r = v; c.rgb.g = k; c.rgb.b = m;
110 c.rgb.r = n; c.rgb.g = v; c.rgb.b = m;
113 c.rgb.r = m; c.rgb.g = v; c.rgb.b = k;
116 c.rgb.r = m; c.rgb.g = n; c.rgb.b = v;
119 c.rgb.r = k; c.rgb.g = m; c.rgb.b = v;
122 c.rgb.r = v; c.rgb.g = m; c.rgb.b = n;
131 static i_color make_rgb(int r, int g, int b, int a) {
154 /* greatly simplifies the code */
155 #define nout n_regs[codes->rout]
156 #define na n_regs[codes->ra]
157 #define nb n_regs[codes->rb]
158 #define nc n_regs[codes->rc]
159 #define nd n_regs[codes->rd]
160 #define cout c_regs[codes->rout]
161 #define ca c_regs[codes->ra]
162 #define cb c_regs[codes->rb]
163 #define cc c_regs[codes->rc]
164 #define cd c_regs[codes->rd]
166 /* this is a pretty poor epsilon used for loosening up equality comparisons
167 It isn't currently used for inequalities
170 #define n_epsilon(x, y) (abs(x)+abs(y))*0.001
171 static i_color bcol = {{ 0 }};
173 i_color i_rm_run(struct rm_op codes[], size_t code_count,
174 double n_regs[], size_t n_regs_count,
175 i_color c_regs[], size_t c_regs_count,
176 i_img *images[], size_t image_count) {
178 struct rm_op *codes_base = codes;
179 size_t count_base = code_count;
181 DBG(("rm_run(%p, %d)\n", codes, code_count));
183 DBG((" rm_code %d\n", codes->code));
184 switch (codes->code) {
205 if (abs(nb) > 1e-10) {
209 nout = 0; /* close enough ;) */
222 cout = make_rgb(ca.rgb.r * nb, ca.rgb.g * nb, ca.rgb.b * nb, 255);
226 cout = make_rgb(ca.rgb.r + cb.rgb.r, ca.rgb.g + cb.rgb.g,
227 ca.rgb.b + cb.rgb.b, 255);
231 cout = make_rgb(ca.rgb.r - cb.rgb.r, ca.rgb.g - cb.rgb.g,
232 ca.rgb.b - cb.rgb.b, 255);
244 nout = atan2(na, nb);
254 nout = sqrt(dx*dx+dy*dy);
258 i_gpix(images[0], na, nb, c_regs+codes->rout);
259 if (images[0]->channels < 4) cout.rgba.a = 255;
263 i_gpix(images[1], na, nb, c_regs+codes->rout);
264 if (images[1]->channels < 4) cout.rgba.a = 255;
268 i_gpix(images[2], na, nb, c_regs+codes->rout);
269 if (images[2]->channels < 4) cout.rgba.a = 255;
273 nout = hsv_value(ca);
285 cout = make_hsv(na, nb, nc, 255);
289 cout = make_hsv(na, nb, nc, nd);
309 cout = make_rgb(na, nb, nc, 255);
313 cout = make_rgb(na, nb, nc, nd);
329 nout = na <= nb + n_epsilon(na,nb);
337 nout = na >= nb - n_epsilon(na,nb);
345 nout = abs(na-nb) <= n_epsilon(na,nb);
349 nout = abs(na-nb) > n_epsilon(na,nb);
373 /* yes, order is important here */
374 code_count = count_base - codes->ra;
375 codes = codes_base + codes->ra;
380 /* yes, order is important here */
381 code_count = count_base - codes->rb;
382 codes = codes_base + codes->rb;
389 /* yes, order is important here */
390 code_count = count_base - codes->rb;
391 codes = codes_base + codes->rb;
414 if (!MAX_EXP_ARG) MAX_EXP_ARG = log(DBL_MAX);
415 if (na <= MAX_EXP_ARG) {
424 printf("r%d is %g\n", codes->ra, na);
428 /*croak("bad opcode"); */
429 printf("bad op %d\n", codes->code);
436 /* croak("no return opcode"); */