]> git.imager.perl.org - imager.git/blobdiff - filters.c
point dyn loader users at external filters docs
[imager.git] / filters.c
index 05caae8f23dc550a4e09bf1ee78b504aef7972a9..0efa89a379c19db5175a6f440dbcc93e5e3242d7 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -1,5 +1,5 @@
-#include "image.h"
-#include "imagei.h"
+#include "imager.h"
+#include "imageri.h"
 #include <stdlib.h>
 #include <math.h>
 
@@ -109,21 +109,24 @@ 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));
+
+  row = mymalloc(sizeof(i_color) * im->xsize);
 
   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);
 }
 
 
@@ -140,7 +143,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
@@ -649,7 +652,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);
@@ -934,6 +940,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;
 
@@ -944,7 +951,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;
@@ -1044,6 +1064,72 @@ i_nearest_color_foo(i_img *im, int num, int *xo, int *yo, i_color *ival, int dme
   }
 }
 
+/*
+=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
+ */
 void
 i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasure) {
   i_color *ival;
@@ -1055,7 +1141,7 @@ i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasur
   int ysize    = im->ysize;
   int *cmatch;
 
-  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 );
@@ -1117,12 +1203,13 @@ 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);
 }
@@ -1136,7 +1223,7 @@ image from double the original.
 =cut
 */
 void i_unsharp_mask(i_img *im, double stddev, double scale) {
-  i_img copy;
+  i_img *copy;
   int x, y, ch;
 
   if (scale < 0)
@@ -1145,14 +1232,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;
 
     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) {
@@ -1176,7 +1263,7 @@ void i_unsharp_mask(i_img *im, double stddev, double scale) {
     i_fcolor *out = blur + im->xsize;
 
     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) {
@@ -1194,7 +1281,7 @@ void i_unsharp_mask(i_img *im, double stddev, double scale) {
 
     myfree(blur);
   }
-  i_img_exorcise(&copy);
+  i_img_destroy(copy);
 }
 
 /*
@@ -1213,7 +1300,6 @@ i_diff_image(i_img *im1, i_img *im2, int mindiff) {
   i_img *out;
   int outchans, diffchans;
   int xsize, ysize;
-  i_img temp;
 
   i_clear_error();
   if (im1->channels != im2->channels) {
@@ -1577,7 +1663,12 @@ 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.