5 #define DBG(x) printf x
10 /* these functions currently assume RGB images - there seems to be some
11 support for other color spaces, but I can't tell how you find what
12 space an image is using.
14 HSV conversions from pages 401-403 "Procedural Elements for Computer
15 Graphics", 1985, ISBN 0-07-053534-5. The algorithm presents to produce
16 an HSV color calculates all components at once - I don't, so I've
17 simiplified the algorithm to avoid unnecessary calculation (any errors
18 (of which I had a few ;) are mine).
21 /* returns the value (brightness) of color from 0 to 1 */
22 static double hsv_value(i_color color) {
23 return i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b) / 255.0;
26 /* returns the hue (color) of color from 0 to 360 */
27 static double hsv_hue(i_color color) {
30 temp = i_min(i_min(color.rgb.r, color.rgb.g), color.rgb.b);
31 val = i_max(color.rgb.r, i_max(color.rgb.g, color.rgb.b));
32 if (val == 0 || val==temp) {
36 double cr = (val - color.rgb.r) / (double)(val - temp);
37 double cg = (val - color.rgb.g) / (double)(val - temp);
38 double cb = (val - color.rgb.b) / (double)(val - temp);
40 if (color.rgb.r == val) {
43 else if (color.rgb.g == val) {
46 else { /* if (blue == val) */
49 hue *= 60.0; /* to degrees */
57 /* return the saturation of color from 0 to 1 */
58 static double hsv_sat(i_color color) {
59 int value = i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b);
64 int temp = i_min(i_max(color.rgb.r, color.rgb.g), color.rgb.b);
65 return (value - temp) / (double)value;
69 static i_color make_hsv(double hue, double sat, double val, int alpha) {
72 for( i=0; i< MAXCHANNELS; i++) c.channel[i]=0;
73 DBG(("hsv=%f %f %f\n", hue, sat, val));
74 if (sat <= 0) { /* handle -ve in case someone supplies a bad value */
75 /* should this be * 256? */
76 c.rgb.r = c.rgb.g = c.rgb.b = 255 * val;
86 /* I want to handle -360 <= hue < 720 so that the caller can
97 m = val * (1.0 - sat);
98 n = val * (1.0 - sat * f);
99 k = val * (1.0 - sat * (1 - f));
103 c.rgb.r = v; c.rgb.g = k; c.rgb.b = m;
106 c.rgb.r = n; c.rgb.g = v; c.rgb.b = m;
109 c.rgb.r = m; c.rgb.g = v; c.rgb.b = k;
112 c.rgb.r = m; c.rgb.g = n; c.rgb.b = v;
115 c.rgb.r = k; c.rgb.g = m; c.rgb.b = v;
118 c.rgb.r = v; c.rgb.g = m; c.rgb.b = n;
127 static i_color make_rgb(int r, int g, int b, int a) {
150 /* greatly simplifies the code */
151 #define nout n_regs[codes->rout]
152 #define na n_regs[codes->ra]
153 #define nb n_regs[codes->rb]
154 #define nc n_regs[codes->rc]
155 #define nd n_regs[codes->rd]
156 #define cout c_regs[codes->rout]
157 #define ca c_regs[codes->ra]
158 #define cb c_regs[codes->rb]
159 #define cc c_regs[codes->rc]
160 #define cd c_regs[codes->rd]
162 /* this is a pretty poor epsilon used for loosening up equality comparisons
163 It isn't currently used for inequalities
166 #define n_epsilon(x, y) (abs(x)+abs(y))*0.001
167 static i_color bcol = {{ 0 }};
169 i_color i_rm_run(struct rm_op codes[], size_t code_count,
170 double n_regs[], size_t n_regs_count,
171 i_color c_regs[], size_t c_regs_count,
172 i_img *images[], size_t image_count) {
174 struct rm_op *codes_base = codes;
175 size_t count_base = code_count;
176 DBG(("rm_run(%p, %d)\n", codes, code_count));
178 DBG((" rm_code %d\n", codes->code));
179 switch (codes->code) {
200 if (abs(nb) > 1e-10) {
204 nout = 0; /* close enough ;) */
216 cout = make_rgb(ca.rgb.r * nb, ca.rgb.g * nb, ca.rgb.b * nb, 255);
220 cout = make_rgb(ca.rgb.r + cb.rgb.r, ca.rgb.g + cb.rgb.g,
221 ca.rgb.b + cb.rgb.b, 255);
225 cout = make_rgb(ca.rgb.r - cb.rgb.r, ca.rgb.g - cb.rgb.g,
226 ca.rgb.b - cb.rgb.b, 255);
238 nout = atan2(na, nb);
248 nout = sqrt(dx*dx+dy*dy);
252 i_gpix(images[0], na, nb, c_regs+codes->rout);
256 i_gpix(images[1], na, nb, c_regs+codes->rout);
260 i_gpix(images[2], na, nb, c_regs+codes->rout);
264 nout = hsv_value(ca);
276 cout = make_hsv(na, nb, nc, 255);
280 cout = make_hsv(na, nb, nc, nd);
300 cout = make_rgb(na, nb, nc, 255);
304 cout = make_rgb(na, nb, nc, nd);
320 nout = na <= nb + n_epsilon(na,nb);
328 nout = na >= nb - n_epsilon(na,nb);
336 nout = abs(na-nb) <= n_epsilon(na,nb);
340 nout = abs(na-nb) > n_epsilon(na,nb);
364 /* yes, order is important here */
365 code_count = count_base - codes->ra;
366 codes = codes_base + codes->ra;
371 /* yes, order is important here */
372 code_count = count_base - codes->rb;
373 codes = codes_base + codes->rb;
380 /* yes, order is important here */
381 code_count = count_base - codes->rb;
382 codes = codes_base + codes->rb;
396 printf("r%d is %g\n", codes->ra, na);
400 /*croak("bad opcode"); */
401 printf("bad op %d\n", codes->code);
408 /* croak("no return opcode"); */