]> git.imager.perl.org - imager.git/blobdiff - regmach.c
avoid a possible sign-extension for offsets/sizes in SGI
[imager.git] / regmach.c
index d088713225031e6f69ab81aefd4600a941412492..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.
 */
 
 /* 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);