]> git.imager.perl.org - imager.git/blobdiff - regmach.c
most numeric parameters to the XS implementation now throw an exception if supplied...
[imager.git] / regmach.c
index cea9a791fdaebf683e472d839c45c19c0410e9f1..64783432d3192cc37b31a702603e9b784070963d 100644 (file)
--- a/regmach.c
+++ b/regmach.c
@@ -1,4 +1,6 @@
 #include "regmach.h"
+#include <float.h>
+#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.
@@ -61,7 +66,7 @@ static double hsv_sat(i_color color) {
     return 0;
   }
   else {
-    int temp = i_min(i_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;
   }
 }
@@ -163,7 +168,7 @@ static i_color make_rgb(int r, int g, int b, int a) {
    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 i_rm_run(struct rm_op codes[], size_t code_count, 
@@ -173,6 +178,7 @@ i_color i_rm_run(struct rm_op codes[], size_t code_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));
@@ -190,14 +196,14 @@ i_color i_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 {
@@ -211,6 +217,7 @@ i_color i_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, 255);
@@ -250,14 +257,17 @@ i_color i_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:
@@ -333,11 +343,11 @@ i_color i_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:
@@ -353,7 +363,7 @@ i_color i_rm_run(struct rm_op codes[], size_t code_count,
       break;
 
     case rbc_abs:
-      nout = abs(na);
+      nout = fabs(na);
       break;
 
     case rbc_ret:
@@ -392,10 +402,34 @@ i_color i_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);