]> git.imager.perl.org - imager.git/blobdiff - regmach.c
- minor cleanup of Imager::Fill
[imager.git] / regmach.c
index d088713225031e6f69ab81aefd4600a941412492..1659a530ef0bbaac0eacee5b4ac84e563d25c592 100644 (file)
--- a/regmach.c
+++ b/regmach.c
@@ -1,4 +1,5 @@
 #include "regmach.h"
+#include <float.h>
 
 /*#define DEBUG*/
 #ifdef DEBUG
@@ -7,6 +8,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 +59,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_max(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 +123,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 +146,8 @@ i_color make_rgb(int r, int g, int b) {
     b = 255;
   c.rgb.b = b;
 
+  c.rgba.a = a;
+
   return c;
 }
 
@@ -163,13 +170,14 @@ i_color make_rgb(int r, int g, int b) {
 #define n_epsilon(x, y) (abs(x)+abs(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));
@@ -210,17 +218,17 @@ i_color rm_run(struct rm_op codes[], size_t code_count,
       nout = -na;
 
     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 +255,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 +281,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 +300,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:
@@ -377,6 +400,25 @@ 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:
       printf("r%d is %g\n", codes->ra, na);
       break;