X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/02d1d62827cef86398edc2013f7d2ff04bf21c63..e1c0692925:/regmach.c diff --git a/regmach.c b/regmach.c index d0887132..64783432 100644 --- a/regmach.c +++ b/regmach.c @@ -1,4 +1,6 @@ #include "regmach.h" +#include +#include "imageri.h" /*#define DEBUG*/ #ifdef DEBUG @@ -7,6 +9,9 @@ #define DBG(x) #endif +static float MAX_EXP_ARG; /* = log(DBL_MAX); */ + + /* these functions currently assume RGB images - there seems to be some support for other color spaces, but I can't tell how you find what space an image is using. @@ -19,16 +24,16 @@ */ /* returns the value (brightness) of color from 0 to 1 */ -double hsv_value(i_color color) { - return max(max(color.rgb.r, color.rgb.g), color.rgb.b) / 255.0; +static double hsv_value(i_color color) { + return i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b) / 255.0; } /* returns the hue (color) of color from 0 to 360 */ -double hsv_hue(i_color color) { +static double hsv_hue(i_color color) { int val; int temp; - temp = min(min(color.rgb.r, color.rgb.g), color.rgb.b); - val = max(color.rgb.r, max(color.rgb.g, color.rgb.b)); + temp = i_min(i_min(color.rgb.r, color.rgb.g), color.rgb.b); + val = i_max(color.rgb.r, i_max(color.rgb.g, color.rgb.b)); if (val == 0 || val==temp) { return 0; } @@ -55,18 +60,18 @@ double hsv_hue(i_color color) { } /* return the saturation of color from 0 to 1 */ -double hsv_sat(i_color color) { - int value = max(max(color.rgb.r, color.rgb.g), color.rgb.b); +static double hsv_sat(i_color color) { + int value = i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b); if (value == 0) { return 0; } else { - int temp = min(max(color.rgb.r, color.rgb.g), color.rgb.b); + int temp = i_min(i_min(color.rgb.r, color.rgb.g), color.rgb.b); return (value - temp) / (double)value; } } -i_color make_hsv(double hue, double sat, double val) { +static i_color make_hsv(double hue, double sat, double val, int alpha) { int i; i_color c; for( i=0; i< MAXCHANNELS; i++) c.channel[i]=0; @@ -119,11 +124,12 @@ i_color make_hsv(double hue, double sat, double val) { break; } } + c.rgba.a = alpha; return c; } -i_color make_rgb(int r, int g, int b) { +static i_color make_rgb(int r, int g, int b, int a) { i_color c; if (r < 0) r = 0; @@ -141,6 +147,8 @@ i_color make_rgb(int r, int g, int b) { b = 255; c.rgb.b = b; + c.rgba.a = a; + return c; } @@ -160,16 +168,17 @@ i_color make_rgb(int r, int g, int b) { It isn't currently used for inequalities */ -#define n_epsilon(x, y) (abs(x)+abs(y))*0.001 +#define n_epsilon(x, y) (fabs(x)+fabs(y))*0.001 static i_color bcol = {{ 0 }}; -i_color rm_run(struct rm_op codes[], size_t code_count, +i_color i_rm_run(struct rm_op codes[], size_t code_count, double n_regs[], size_t n_regs_count, i_color c_regs[], size_t c_regs_count, i_img *images[], size_t image_count) { double dx, dy; struct rm_op *codes_base = codes; size_t count_base = code_count; + DBG(("rm_run(%p, %d)\n", codes, code_count)); while (code_count) { DBG((" rm_code %d\n", codes->code)); @@ -187,14 +196,14 @@ i_color rm_run(struct rm_op codes[], size_t code_count, break; case rbc_div: - if (abs(nb) < 1e-10) + if (fabs(nb) < 1e-10) nout = 1e10; else nout = na / nb; break; case rbc_mod: - if (abs(nb) > 1e-10) { + if (fabs(nb) > 1e-10) { nout = fmod(na, nb); } else { @@ -208,19 +217,20 @@ i_color rm_run(struct rm_op codes[], size_t code_count, case rbc_uminus: nout = -na; + break; case rbc_multp: - cout = make_rgb(ca.rgb.r * nb, ca.rgb.g * nb, ca.rgb.b * nb); + cout = make_rgb(ca.rgb.r * nb, ca.rgb.g * nb, ca.rgb.b * nb, 255); break; case rbc_addp: cout = make_rgb(ca.rgb.r + cb.rgb.r, ca.rgb.g + cb.rgb.g, - ca.rgb.b + cb.rgb.b); + ca.rgb.b + cb.rgb.b, 255); break; case rbc_subtractp: cout = make_rgb(ca.rgb.r - cb.rgb.r, ca.rgb.g - cb.rgb.g, - ca.rgb.b - cb.rgb.b); + ca.rgb.b - cb.rgb.b, 255); break; case rbc_sin: @@ -247,14 +257,17 @@ i_color rm_run(struct rm_op codes[], size_t code_count, case rbc_getp1: i_gpix(images[0], na, nb, c_regs+codes->rout); + if (images[0]->channels < 4) cout.rgba.a = 255; break; case rbc_getp2: i_gpix(images[1], na, nb, c_regs+codes->rout); + if (images[1]->channels < 4) cout.rgba.a = 255; break; case rbc_getp3: i_gpix(images[2], na, nb, c_regs+codes->rout); + if (images[2]->channels < 4) cout.rgba.a = 255; break; case rbc_value: @@ -270,7 +283,11 @@ i_color rm_run(struct rm_op codes[], size_t code_count, break; case rbc_hsv: - cout = make_hsv(na, nb, nc); + cout = make_hsv(na, nb, nc, 255); + break; + + case rbc_hsva: + cout = make_hsv(na, nb, nc, nd); break; case rbc_red: @@ -285,8 +302,16 @@ i_color rm_run(struct rm_op codes[], size_t code_count, nout = ca.rgb.b; break; + case rbc_alpha: + nout = ca.rgba.a; + break; + case rbc_rgb: - cout = make_rgb(na, nb, nc); + cout = make_rgb(na, nb, nc, 255); + break; + + case rbc_rgba: + cout = make_rgb(na, nb, nc, nd); break; case rbc_int: @@ -318,11 +343,11 @@ i_color rm_run(struct rm_op codes[], size_t code_count, break; case rbc_eq: - nout = abs(na-nb) <= n_epsilon(na,nb); + nout = fabs(na-nb) <= n_epsilon(na,nb); break; case rbc_ne: - nout = abs(na-nb) > n_epsilon(na,nb); + nout = fabs(na-nb) > n_epsilon(na,nb); break; case rbc_and: @@ -338,7 +363,7 @@ i_color rm_run(struct rm_op codes[], size_t code_count, break; case rbc_abs: - nout = abs(na); + nout = fabs(na); break; case rbc_ret: @@ -377,10 +402,34 @@ i_color rm_run(struct rm_op codes[], size_t code_count, cout = ca; break; + case rbc_log: + if (na > 0) { + nout = log(na); + } + else { + nout = DBL_MAX; + } + break; + + case rbc_exp: + if (!MAX_EXP_ARG) MAX_EXP_ARG = log(DBL_MAX); + if (na <= MAX_EXP_ARG) { + nout = exp(na); + } + else { + nout = DBL_MAX; + } + break; + case rbc_print: + nout = na; printf("r%d is %g\n", codes->ra, na); break; + case rbc_det: + nout = na*nd-nb*nc; + break; + default: /*croak("bad opcode"); */ printf("bad op %d\n", codes->code);