]> git.imager.perl.org - imager.git/blobdiff - filters.c
Imager 0.58 release
[imager.git] / filters.c
index 2c870163c818c55327091903e5ac266625230802..704ea2d83424a6dfdc26cb24afee81db0250e5a5 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -1,4 +1,5 @@
-#include "image.h"
+#include "imager.h"
+#include "imageri.h"
 #include <stdlib.h>
 #include <math.h>
 
@@ -26,7 +27,7 @@ the pod for Imager.
 
 Some of these functions are internal.
 
-=over 4
+=over
 
 =cut
 */
@@ -108,21 +109,25 @@ i_hardinvert(i_img *im) {
   int x, y;
   unsigned char ch;
   
-  i_color rcolor;
+  i_color *row, *entry;
   
-    mm_log((1,"i_hardinvert(im %p)\n", im));
+  mm_log((1,"i_hardinvert(im %p)\n", im));
+
+  /* always rooms to allocate a single line of i_color */
+  row = mymalloc(sizeof(i_color) * im->xsize); /* checked 17feb2005 tonyc */
 
   for(y = 0; y < im->ysize; y++) {
+    i_glin(im, 0, im->xsize, y, row);
+    entry = row;
     for(x = 0; x < im->xsize; x++) {
-      i_gpix(im, x, y, &rcolor);
-      
       for(ch = 0; ch < im->channels; ch++) {
-       rcolor.channel[ch] = 255 - rcolor.channel[ch];
+       entry->channel[ch] = 255 - entry->channel[ch];
       }
-      
-      i_ppix(im, x, y, &rcolor);
+      ++entry;
     }
+    i_plin(im, 0, im->xsize, y, row);
   }  
+  myfree(row);
 }
 
 
@@ -139,7 +144,7 @@ Inverts the pixel values by the amount specified.
 =cut
 */
 
-#ifdef _MSC_VER
+#ifdef WIN32
 /* random() is non-ASCII, even if it is better than rand() */
 #define random() rand()
 #endif
@@ -648,7 +653,10 @@ i_watermark(i_img *im, i_img *wmark, int tx, int ty, int pixdiff) {
   int vx, vy, ch;
   i_color val, wval;
 
-  for(vx=0;vx<128;vx++) for(vy=0;vy<110;vy++) {
+       int mx = wmark->xsize;
+       int my = wmark->ysize;
+
+  for(vx=0;vx<mx;vx++) for(vy=0;vy<my;vy++) {
     
     i_gpix(im,    tx+vx, ty+vy,&val );
     i_gpix(wmark, vx,    vy,   &wval);
@@ -933,6 +941,7 @@ i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure) {
   int channels = im->channels;
   int xsize    = im->xsize;
   int ysize    = im->ysize;
+  int bytes;
 
   float *fdist;
 
@@ -943,7 +952,20 @@ i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure) {
     ICL_info(&ival[p]);
   }
 
-  fdist = mymalloc( sizeof(float) * num );
+  /* on the systems I have sizeof(float) == sizeof(int) and thus
+     this would be same size as the arrays xo and yo point at, but this
+     may not be true for other systems
+
+     since the arrays here are caller controlled, I assume that on
+     overflow is a programming error rather than an end-user error, so
+     calling exit() is justified.
+  */
+  bytes = sizeof(float) * num;
+  if (bytes / num != sizeof(float)) {
+    fprintf(stderr, "integer overflow calculating memory allocation");
+    exit(1);
+  }
+  fdist = mymalloc( bytes ); /* checked 14jul05 tonyc */
   
   for(y = 0; y<ysize; y++) for(x = 0; x<xsize; x++) {
     float cs = 0;
@@ -959,10 +981,10 @@ i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure) {
        fdist[p]  = xd*xd + yd*yd; /* euclidean distance */
        break;
       case 2: /* euclidean squared */
-       fdist[p]  = max(xd*xd, yd*yd); /* manhattan distance */
+       fdist[p]  = i_max(xd*xd, yd*yd); /* manhattan distance */
        break;
       default:
-       m_fatal(3,"i_gradgen: Unknown distance measure\n");
+       i_fatal(3,"i_gradgen: Unknown distance measure\n");
       }
       cs += fdist[p];
     }
@@ -978,6 +1000,7 @@ i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure) {
     }
     i_ppix(im, x, y, &val); 
   }
+  myfree(fdist);
   
 }
 
@@ -1011,10 +1034,10 @@ i_nearest_color_foo(i_img *im, int num, int *xo, int *yo, i_color *ival, int dme
       mindist = xd*xd + yd*yd; /* euclidean distance */
       break;
     case 2: /* euclidean squared */
-      mindist = max(xd*xd, yd*yd); /* manhattan distance */
+      mindist = i_max(xd*xd, yd*yd); /* manhattan distance */
       break;
     default:
-      m_fatal(3,"i_nearest_color: Unknown distance measure\n");
+      i_fatal(3,"i_nearest_color: Unknown distance measure\n");
     }
 
     for(p = 1; p<num; p++) {
@@ -1028,10 +1051,10 @@ i_nearest_color_foo(i_img *im, int num, int *xo, int *yo, i_color *ival, int dme
        curdist = xd*xd + yd*yd; /* euclidean distance */
        break;
       case 2: /* euclidean squared */
-       curdist = max(xd*xd, yd*yd); /* manhattan distance */
+       curdist = i_max(xd*xd, yd*yd); /* manhattan distance */
        break;
       default:
-       m_fatal(3,"i_nearest_color: Unknown distance measure\n");
+       i_fatal(3,"i_nearest_color: Unknown distance measure\n");
       }
       if (curdist < mindist) {
        mindist = curdist;
@@ -1042,7 +1065,74 @@ i_nearest_color_foo(i_img *im, int num, int *xo, int *yo, i_color *ival, int dme
   }
 }
 
-void
+/*
+=item i_nearest_color(im, num, xo, yo, oval, dmeasure)
+
+This wasn't document - quoth Addi:
+
+  An arty type of filter
+
+FIXME: check IRC logs for actual text.
+
+Inputs:
+
+=over
+
+=item *
+
+i_img *im - image to render on.
+
+=item *
+
+int num - number of points/colors in xo, yo, oval
+
+=item *
+
+int *xo - array of I<num> x positions
+
+=item *
+
+int *yo - array of I<num> y positions
+
+=item *
+
+i_color *oval - array of I<num> colors
+
+xo, yo, oval correspond to each other, the point xo[i], yo[i] has a
+color something like oval[i], at least closer to that color than other
+points.
+
+=item *
+
+int dmeasure - how we measure the distance from some point P(x,y) to
+any (xo[i], yo[i]).
+
+Valid values are:
+
+=over
+
+=item 0
+
+euclidean distance: sqrt((x2-x1)**2 + (y2-y1)**2)
+
+=item 1
+
+square of euclidean distance: ((x2-x1)**2 + (y2-y1)**2)
+
+=item 2
+
+manhattan distance: max((y2-y1)**2, (x2-x1)**2)
+
+=back
+
+An invalid value causes an error exit (the program is aborted).
+
+=back
+
+=cut
+ */
+
+int
 i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasure) {
   i_color *ival;
   float *tval;
@@ -1052,12 +1142,35 @@ i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasur
   int xsize    = im->xsize;
   int ysize    = im->ysize;
   int *cmatch;
+  int ival_bytes, tval_bytes;
 
-  mm_log((1,"i_nearest_color(im %p, num %d, xo %p, yo %p, ival %p, dmeasure %d)\n", im, num, xo, yo, oval, dmeasure));
+  mm_log((1,"i_nearest_color(im %p, num %d, xo %p, yo %p, oval %p, dmeasure %d)\n", im, num, xo, yo, oval, dmeasure));
 
-  tval   = mymalloc( sizeof(float)*num*im->channels );
-  ival   = mymalloc( sizeof(i_color)*num );
-  cmatch = mymalloc( sizeof(int)*num     );
+  i_clear_error();
+
+  if (num <= 0) {
+    i_push_error(0, "no points supplied to nearest_color filter");
+    return 0;
+  }
+
+  if (dmeasure < 0 || dmeasure > i_dmeasure_limit) {
+    i_push_error(0, "distance measure invalid");
+    return 0;
+  }
+
+  tval_bytes = sizeof(float)*num*im->channels;
+  if (tval_bytes / num != sizeof(float) * im->channels) {
+    i_push_error(0, "integer overflow calculating memory allocation");
+    return 0;
+  }
+  ival_bytes  = sizeof(i_color) * num;
+  if (ival_bytes / sizeof(i_color) != num) {
+    i_push_error(0, "integer overflow calculating memory allocation");
+    return 0;
+  }
+  tval   = mymalloc( tval_bytes ); /* checked 17feb2005 tonyc */
+  ival   = mymalloc( ival_bytes ); /* checked 17feb2005 tonyc */
+  cmatch = mymalloc( sizeof(int)*num     ); /* checked 17feb2005 tonyc */
 
   for(p = 0; p<num; p++) {
     for(ch = 0; ch<im->channels; ch++) tval[ p * im->channels + ch] = 0;
@@ -1080,11 +1193,11 @@ i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasur
     case 1: /* euclidean squared */
       mindist = xd*xd + yd*yd; /* euclidean distance */
       break;
-    case 2: /* euclidean squared */
-      mindist = max(xd*xd, yd*yd); /* manhattan distance */
+    case 2: /* manhatten distance */
+      mindist = i_max(xd*xd, yd*yd); /* manhattan distance */
       break;
     default:
-      m_fatal(3,"i_nearest_color: Unknown distance measure\n");
+      i_fatal(3,"i_nearest_color: Unknown distance measure\n");
     }
     
     for(p = 1; p<num; p++) {
@@ -1098,10 +1211,10 @@ i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasur
        curdist = xd*xd + yd*yd; /* euclidean distance */
        break;
       case 2: /* euclidean squared */
-       curdist = max(xd*xd, yd*yd); /* manhattan distance */
+       curdist = i_max(xd*xd, yd*yd); /* manhattan distance */
        break;
       default:
-       m_fatal(3,"i_nearest_color: Unknown distance measure\n");
+       i_fatal(3,"i_nearest_color: Unknown distance measure\n");
       }
       if (curdist < mindist) {
        mindist = curdist;
@@ -1115,14 +1228,17 @@ i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasur
     c1 = 1.0-c2;
     
     for(ch = 0; ch<im->channels; ch++) 
-      tval[midx*im->channels + ch] = c1*tval[midx*im->channels + ch] + c2 * (float) val.channel[ch];
+      tval[midx*im->channels + ch] = 
+        c1*tval[midx*im->channels + ch] + c2 * (float) val.channel[ch];
   
-    
   }
 
-  for(p = 0; p<num; p++) for(ch = 0; ch<im->channels; ch++) ival[p].channel[ch] = tval[p*im->channels + ch];
+  for(p = 0; p<num; p++) for(ch = 0; ch<im->channels; ch++)
+    ival[p].channel[ch] = tval[p*im->channels + ch];
 
   i_nearest_color_foo(im, num, xo, yo, ival, dmeasure);
+
+  return 1;
 }
 
 /*
@@ -1133,8 +1249,10 @@ image from double the original.
 
 =cut
 */
-void i_unsharp_mask(i_img *im, double stddev, double scale) {
-  i_img copy;
+
+void
+i_unsharp_mask(i_img *im, double stddev, double scale) {
+  i_img *copy;
   int x, y, ch;
 
   if (scale < 0)
@@ -1143,14 +1261,14 @@ void i_unsharp_mask(i_img *im, double stddev, double scale) {
   if (scale > 100)
     scale = 100;
 
-  i_copy(&copy, im);
-  i_gaussian(&copy, stddev);
+  copy = i_copy(im);
+  i_gaussian(copy, stddev);
   if (im->bits == i_8_bits) {
-    i_color *blur = mymalloc(im->xsize * sizeof(i_color) * 2);
-    i_color *out = blur + im->xsize;
+    i_color *blur = mymalloc(im->xsize * sizeof(i_color)); /* checked 17feb2005 tonyc */
+    i_color *out = mymalloc(im->xsize * sizeof(i_color)); /* checked 17feb2005 tonyc */
 
     for (y = 0; y < im->ysize; ++y) {
-      i_glin(&copy, 0, copy.xsize, y, blur);
+      i_glin(copy, 0, copy->xsize, y, blur);
       i_glin(im, 0, im->xsize, y, out);
       for (x = 0; x < im->xsize; ++x) {
         for (ch = 0; ch < im->channels; ++ch) {
@@ -1168,13 +1286,14 @@ void i_unsharp_mask(i_img *im, double stddev, double scale) {
     }
 
     myfree(blur);
+    myfree(out);
   }
   else {
-    i_fcolor *blur = mymalloc(im->xsize * sizeof(i_fcolor) * 2);
-    i_fcolor *out = blur + im->xsize;
+    i_fcolor *blur = mymalloc(im->xsize * sizeof(i_fcolor)); /* checked 17feb2005 tonyc */
+    i_fcolor *out = mymalloc(im->xsize * sizeof(i_fcolor)); /* checked 17feb2005 tonyc */
 
     for (y = 0; y < im->ysize; ++y) {
-      i_glinf(&copy, 0, copy.xsize, y, blur);
+      i_glinf(copy, 0, copy->xsize, y, blur);
       i_glinf(im, 0, im->xsize, y, out);
       for (x = 0; x < im->xsize; ++x) {
         for (ch = 0; ch < im->channels; ++ch) {
@@ -1191,8 +1310,115 @@ void i_unsharp_mask(i_img *im, double stddev, double scale) {
     }
 
     myfree(blur);
+    myfree(out);
   }
-  i_img_exorcise(&copy);
+  i_img_destroy(copy);
+}
+
+/*
+=item i_diff_image(im1, im2, mindist)
+
+Creates a new image that is transparent, except where the pixel in im2
+is different from im1, where it is the pixel from im2.
+
+The samples must differ by at least mindiff to be considered different.
+
+=cut
+*/
+
+i_img *
+i_diff_image(i_img *im1, i_img *im2, double mindist) {
+  i_img *out;
+  int outchans, diffchans;
+  int xsize, ysize;
+
+  i_clear_error();
+  if (im1->channels != im2->channels) {
+    i_push_error(0, "different number of channels");
+    return NULL;
+  }
+
+  outchans = diffchans = im1->channels;
+  if (outchans == 1 || outchans == 3)
+    ++outchans;
+
+  xsize = i_min(im1->xsize, im2->xsize);
+  ysize = i_min(im1->ysize, im2->ysize);
+
+  out = i_sametype_chans(im1, xsize, ysize, outchans);
+  
+  if (im1->bits == i_8_bits && im2->bits == i_8_bits) {
+    i_color *line1 = mymalloc(xsize * sizeof(*line1)); /* checked 17feb2005 tonyc */
+    i_color *line2 = mymalloc(xsize * sizeof(*line1)); /* checked 17feb2005 tonyc */
+    i_color empty;
+    int x, y, ch;
+    int imindist = (int)mindist;
+
+    for (ch = 0; ch < MAXCHANNELS; ++ch)
+      empty.channel[ch] = 0;
+
+    for (y = 0; y < ysize; ++y) {
+      i_glin(im1, 0, xsize, y, line1);
+      i_glin(im2, 0, xsize, y, line2);
+      if (outchans != diffchans) {
+        /* give the output an alpha channel since it doesn't have one */
+        for (x = 0; x < xsize; ++x)
+          line2[x].channel[diffchans] = 255;
+      }
+      for (x = 0; x < xsize; ++x) {
+        int diff = 0;
+        for (ch = 0; ch < diffchans; ++ch) {
+          if (line1[x].channel[ch] != line2[x].channel[ch]
+              && abs(line1[x].channel[ch] - line2[x].channel[ch]) > imindist) {
+            diff = 1;
+            break;
+          }
+        }
+        if (!diff)
+          line2[x] = empty;
+      }
+      i_plin(out, 0, xsize, y, line2);
+    }
+    myfree(line1);
+    myfree(line2);
+  }
+  else {
+    i_fcolor *line1 = mymalloc(xsize * sizeof(*line1)); /* checked 17feb2005 tonyc */
+    i_fcolor *line2 = mymalloc(xsize * sizeof(*line2)); /* checked 17feb2005 tonyc */
+    i_fcolor empty;
+    int x, y, ch;
+    double dist = mindist / 255.0;
+
+    for (ch = 0; ch < MAXCHANNELS; ++ch)
+      empty.channel[ch] = 0;
+
+    for (y = 0; y < ysize; ++y) {
+      i_glinf(im1, 0, xsize, y, line1);
+      i_glinf(im2, 0, xsize, y, line2);
+      if (outchans != diffchans) {
+        /* give the output an alpha channel since it doesn't have one */
+        for (x = 0; x < xsize; ++x)
+          line2[x].channel[diffchans] = 1.0;
+      }
+      for (x = 0; x < xsize; ++x) {
+        int diff = 0;
+        for (ch = 0; ch < diffchans; ++ch) {
+          if (line1[x].channel[ch] != line2[x].channel[ch]
+              && fabs(line1[x].channel[ch] - line2[x].channel[ch]) > dist) {
+            diff = 1;
+            break;
+          }
+        }
+        if (!diff)
+          line2[x] = empty;
+      }
+      i_plinf(out, 0, xsize, y, line2);
+    }
+    myfree(line1);
+    myfree(line2);
+  }
+
+  return out;
 }
 
 struct fount_state;
@@ -1412,23 +1638,35 @@ I<count> and I<segs> define the segments of the fill.
 
 */
 
-void
+int
 i_fountain(i_img *im, double xa, double ya, double xb, double yb, 
            i_fountain_type type, i_fountain_repeat repeat, 
            int combine, int super_sample, double ssample_param, 
            int count, i_fountain_seg *segs) {
   struct fount_state state;
   int x, y;
-  i_fcolor *line = mymalloc(sizeof(i_fcolor) * im->xsize);
+  i_fcolor *line = NULL;
   i_fcolor *work = NULL;
-  int ch;
+  int line_bytes;
   i_fountain_seg *my_segs;
   i_fill_combine_f combine_func = NULL;
   i_fill_combinef_f combinef_func = NULL;
 
+  i_clear_error();
+
+  /* i_fountain() allocates floating colors even for 8-bit images,
+     so we need to do this check */
+  line_bytes = sizeof(i_fcolor) * im->xsize;
+  if (line_bytes / sizeof(i_fcolor) != im->xsize) {
+    i_push_error(0, "integer overflow calculating memory allocation");
+    return 0;
+  }
+  
+  line = mymalloc(line_bytes); /* checked 17feb2005 tonyc */
+
   i_get_combine(combine, &combine_func, &combinef_func);
   if (combinef_func)
-    work = mymalloc(sizeof(i_fcolor) * im->xsize);
+    work = mymalloc(line_bytes); /* checked 17feb2005 tonyc */
 
   fount_init_state(&state, xa, ya, xb, yb, type, repeat, combine, 
                    super_sample, ssample_param, count, segs);
@@ -1439,7 +1677,6 @@ i_fountain(i_img *im, double xa, double ya, double xb, double yb,
     for (x = 0; x < im->xsize; ++x) {
       i_fcolor c;
       int got_one;
-      double v;
       if (super_sample == i_fts_none)
         got_one = fount_getat(&c, x, y, &state);
       else
@@ -1456,7 +1693,10 @@ i_fountain(i_img *im, double xa, double ya, double xb, double yb,
     i_plinf(im, 0, im->xsize, y, line);
   }
   fount_finish_state(&state);
+  if (work) myfree(work);
   myfree(line);
+
+  return 1;
 }
 
 typedef struct {
@@ -1466,12 +1706,17 @@ typedef struct {
 
 static void
 fill_fountf(i_fill_t *fill, int x, int y, int width, int channels, 
-            i_fcolor *data, i_fcolor *work);
+            i_fcolor *data);
 static void
 fount_fill_destroy(i_fill_t *fill);
 
 /*
-=item i_new_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, count, segs)
+=item i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, count, segs)
+
+=category Fills
+=synopsis fill = i_new_fill_fount(0, 0, 100, 100, i_ft_linear, i_ft_linear, 
+=synopsis                         i_fr_triangle, 0, i_fts_grid, 9, 1, segs);
+
 
 Creates a new general fill which fills with a fountain fill.
 
@@ -1520,9 +1765,9 @@ fount_init_state(struct fount_state *state, double xa, double ya,
                  i_fountain_repeat repeat, int combine, int super_sample, 
                  double ssample_param, int count, i_fountain_seg *segs) {
   int i, j;
-  i_fountain_seg *my_segs = mymalloc(sizeof(i_fountain_seg) * count);
+  int bytes;
+  i_fountain_seg *my_segs = mymalloc(sizeof(i_fountain_seg) * count); /* checked 2jul06 - duplicating original */
   /*int have_alpha = im->channels == 2 || im->channels == 4;*/
-  int ch;
   
   memset(state, 0, sizeof(*state));
   /* we keep a local copy that we can adjust for speed */
@@ -1530,8 +1775,8 @@ fount_init_state(struct fount_state *state, double xa, double ya,
     i_fountain_seg *seg = my_segs + i;
 
     *seg = segs[i];
-    if (seg->type < 0 || type >= i_ft_end)
-      seg->type = i_ft_linear;
+    if (seg->type < 0 || seg->type >= i_fst_end)
+      seg->type = i_fst_linear;
     if (seg->color < 0 || seg->color >= i_fc_end)
       seg->color = i_fc_direct;
     if (seg->color == i_fc_hue_up || seg->color == i_fc_hue_down) {
@@ -1596,20 +1841,32 @@ fount_init_state(struct fount_state *state, double xa, double ya,
   }
   state->ffunc = fount_funcs[type];
   if (super_sample < 0 
-      || super_sample >= (sizeof(fount_ssamples)/sizeof(*fount_ssamples))) {
+      || super_sample >= (int)(sizeof(fount_ssamples)/sizeof(*fount_ssamples))) {
     super_sample = 0;
   }
   state->ssample_data = NULL;
   switch (super_sample) {
   case i_fts_grid:
     ssample_param = floor(0.5 + sqrt(ssample_param));
-    state->ssample_data = mymalloc(sizeof(i_fcolor) * ssample_param * ssample_param);
+    bytes = ssample_param * ssample_param * sizeof(i_fcolor);
+    if (bytes / sizeof(i_fcolor) == ssample_param * ssample_param) {
+      state->ssample_data = mymalloc(sizeof(i_fcolor) * ssample_param * ssample_param); /* checked 1jul06 tonyc */
+    }
+    else {
+      super_sample = i_fts_none;
+    }
     break;
 
   case i_fts_random:
   case i_fts_circle:
     ssample_param = floor(0.5+ssample_param);
-    state->ssample_data = mymalloc(sizeof(i_fcolor) * ssample_param);
+    bytes = sizeof(i_fcolor) * ssample_param;
+    if (bytes / sizeof(i_fcolor) == ssample_param) {
+      state->ssample_data = mymalloc(sizeof(i_fcolor) * ssample_param);
+    }
+    else {
+      super_sample = i_fts_none;
+    }
     break;
   }
   state->parm = ssample_param;
@@ -2078,42 +2335,21 @@ The fill function for fountain fills.
 */
 static void
 fill_fountf(i_fill_t *fill, int x, int y, int width, int channels, 
-            i_fcolor *data, i_fcolor *work) {
+            i_fcolor *data) {
   i_fill_fountain_t *f = (i_fill_fountain_t *)fill;
   
-  if (fill->combinef) {
-    i_fcolor *wstart = work;
-    int count = width;
-
-    while (width--) {
-      i_fcolor c;
-      int got_one;
-      double v;
-      if (f->state.ssfunc)
-        got_one = f->state.ssfunc(&c, x, y, &f->state);
-      else
-        got_one = fount_getat(&c, x, y, &f->state);
-      
-      *work++ = c;
-      
-      ++x;
-    }
-    (fill->combinef)(data, wstart, channels, count);
-  }
-  else {
-    while (width--) {
-      i_fcolor c;
-      int got_one;
-      double v;
-      if (f->state.ssfunc)
-        got_one = f->state.ssfunc(&c, x, y, &f->state);
-      else
-        got_one = fount_getat(&c, x, y, &f->state);
-      
-      *data++ = c;
-      
-      ++x;
-    }
+  while (width--) {
+    i_fcolor c;
+    int got_one;
+    
+    if (f->state.ssfunc)
+      got_one = f->state.ssfunc(&c, x, y, &f->state);
+    else
+      got_one = fount_getat(&c, x, y, &f->state);
+    
+    *data++ = c;
+    
+    ++x;
   }
 }