- more memory allocation integer overflow auditing
authorTony Cook <tony@develop=help.com>
Fri, 17 Feb 2006 12:01:20 +0000 (12:01 +0000)
committerTony Cook <tony@develop=help.com>
Fri, 17 Feb 2006 12:01:20 +0000 (12:01 +0000)
- IM_DEBUG_MALLOC wasn't interacting well with the API

16 files changed:
Changes
Imager.pm
Imager.xs
datatypes.c
draw.c
filters.c
gif.c
imager.h
imdatatypes.h
imext.c
imext.h
imexttypes.h
imio.h
io.c
iolayer.c
lib/Imager/APIRef.pm

diff --git a/Changes b/Changes
index b0b7b3b..58c45ee 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1356,6 +1356,8 @@ Revision history for Perl extension Imager.
   - add AUTHOR, SEE ALSO, REVISION
 - eliminate sign warning from image.c
 - make TIFF detection stricter
+- more memory allocation integer overflow auditing
+- IM_DEBUG_MALLOC wasn't interacting well with the API
 
 =================================================================
 
index b4d15e4..d5812f9 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -241,11 +241,26 @@ BEGIN {
      }
     };
 
-  $filters{nearest_color} ={
-                           callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
-                           defaults => { },
-                           callsub => sub { my %hsh=@_; i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
-                          };
+  $filters{nearest_color} =
+    {
+     callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
+     defaults => { },
+     callsub => 
+     sub { 
+       my %hsh=@_; 
+       # make sure the segments are specified with colors
+       my @colors;
+       for my $color (@{$hsh{colors}}) {
+         my $new_color = _color($color) 
+           or die $Imager::ERRSTR."\n";
+         push @colors, $new_color;
+       }
+
+       i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, \@colors, 
+                       $hsh{dist})
+         or die Imager->_error_as_msg() . "\n";
+     },
+    };
   $filters{gaussian} = {
                         callseq => [ 'image', 'stddev' ],
                         defaults => { },
@@ -372,7 +387,8 @@ BEGIN {
 
        i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
                   $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
-                  $hsh{ssample_param}, \@segments);
+                  $hsh{ssample_param}, \@segments)
+         or die Imager->_error_as_msg() . "\n";
      },
     };
   $filters{unsharpmask} =
index 546bfb6..6c9dafe 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -3124,7 +3124,7 @@ i_diff_image(im, im2, mindist=0)
     Imager::ImgRaw     im2
                int     mindist
 
-void
+undef_int
 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
     Imager::ImgRaw     im
             double     xa
@@ -3146,9 +3146,11 @@ i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_para
         
        asegs = (AV *)SvRV(ST(10));
         segs = load_fount_segs(asegs, &count);
-        i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, 
-                   ssample_param, count, segs);
+        RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine, 
+                            super_sample, ssample_param, count, segs);
         myfree(segs);
+      OUTPUT:
+        RETVAL
 
 Imager::FillHandle
 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
@@ -3201,7 +3203,7 @@ i_errors()
          ++i;
        }
 
-void
+undef_int
 i_nearest_color(im, ...)
     Imager::ImgRaw     im
       PREINIT:
@@ -3246,10 +3248,9 @@ i_nearest_color(im, ...)
          }
          ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
        }
-        i_nearest_color(im, num, xo, yo, ival, dmeasure);
-
-
-
+        RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
+      OUTPUT:
+        RETVAL
 
 void
 malloc_state()
index 5a623ab..e8ecab1 100644 (file)
@@ -1,9 +1,7 @@
-#include "imio.h"
-#include "imdatatypes.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-
+#include "imager.h"
 
 /*
   2d bitmask with test and set operations
diff --git a/draw.c b/draw.c
index 4b6ba04..b9ab166 100644 (file)
--- a/draw.c
+++ b/draw.c
@@ -301,8 +301,9 @@ arc_poly(int *count, double **xvals, double **yvals,
   angle_inc = 2 * PI / steps;
 
   point_count = steps + 5; /* rough */
-  *xvals = mymalloc(point_count * sizeof(double));
-  *yvals = mymalloc(point_count * sizeof(double));
+  /* point_count is always relatively small, so allocation won't overflow */
+  *xvals = mymalloc(point_count * sizeof(double)); /* checked 17feb2005 tonyc */
+  *yvals = mymalloc(point_count * sizeof(double)); /* checked 17feb2005 tonyc */
 
   /* from centre to edge at d1 */
   (*xvals)[0] = x;
index 0efa89a..a13cb55 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -113,7 +113,8 @@ i_hardinvert(i_img *im) {
   
   mm_log((1,"i_hardinvert(im %p)\n", im));
 
-  row = mymalloc(sizeof(i_color) * im->xsize);
+  /* 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);
@@ -1130,7 +1131,8 @@ An invalid value causes an error exit (the program is aborted).
 
 =cut
  */
-void
+
+int
 i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasure) {
   i_color *ival;
   float *tval;
@@ -1140,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, 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;
@@ -1168,7 +1193,7 @@ 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 */
+    case 2: /* manhatten distance */
       mindist = i_max(xd*xd, yd*yd); /* manhattan distance */
       break;
     default:
@@ -1212,6 +1237,8 @@ i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasur
     ival[p].channel[ch] = tval[p*im->channels + ch];
 
   i_nearest_color_foo(im, num, xo, yo, ival, dmeasure);
+
+  return 1;
 }
 
 /*
@@ -1222,7 +1249,9 @@ image from double the original.
 
 =cut
 */
-void i_unsharp_mask(i_img *im, double stddev, double scale) {
+
+void
+i_unsharp_mask(i_img *im, double stddev, double scale) {
   i_img *copy;
   int x, y, ch;
 
@@ -1235,8 +1264,8 @@ void i_unsharp_mask(i_img *im, double stddev, double scale) {
   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);
@@ -1257,10 +1286,11 @@ 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);
@@ -1280,6 +1310,7 @@ void i_unsharp_mask(i_img *im, double stddev, double scale) {
     }
 
     myfree(blur);
+    myfree(out);
   }
   i_img_destroy(copy);
 }
@@ -1317,8 +1348,8 @@ i_diff_image(i_img *im1, i_img *im2, int mindiff) {
   out = i_sametype_chans(im1, xsize, ysize, outchans);
   
   if (im1->bits == i_8_bits && im2->bits == i_8_bits) {
-    i_color *line1 = mymalloc(2 * xsize * sizeof(*line1));
-    i_color *line2 = line1 + xsize;
+    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;
 
@@ -1348,10 +1379,11 @@ i_diff_image(i_img *im1, i_img *im2, int mindiff) {
       i_plin(out, 0, xsize, y, line2);
     }
     myfree(line1);
+    myfree(line2);
   }
   else {
-    i_fcolor *line1 = mymalloc(2 * xsize * sizeof(*line1));
-    i_fcolor *line2 = line1 + xsize;
+    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 = mindiff / 255;
@@ -1382,6 +1414,7 @@ i_diff_image(i_img *im1, i_img *im2, int mindiff) {
       i_plinf(out, 0, xsize, y, line2);
     }
     myfree(line1);
+    myfree(line2);
   }
 
   return out;
@@ -1604,26 +1637,38 @@ 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 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);
+                   super_sample, ssample_param, count, segs)) {
   my_segs = state.segs;
 
   for (y = 0; y < im->ysize; ++y) {
@@ -1649,6 +1694,8 @@ i_fountain(i_img *im, double xa, double ya, double xb, double yb,
   fount_finish_state(&state);
   if (work) myfree(work);
   myfree(line);
+
+  return 1;
 }
 
 typedef struct {
diff --git a/gif.c b/gif.c
index e300831..3aa46d4 100644 (file)
--- a/gif.c
+++ b/gif.c
@@ -416,9 +416,12 @@ Internal function called by i_readgif_multi_low() in error handling
 */
 static void free_images(i_img **imgs, int count) {
   int i;
-  for (i = 0; i < count; ++i)
-    i_img_destroy(imgs[i]);
-  myfree(imgs);
+  
+  if (count) {
+    for (i = 0; i < count; ++i)
+      i_img_destroy(imgs[i]);
+    myfree(imgs);
+  }
 }
 
 /*
index deefa45..1b32b34 100644 (file)
--- a/imager.h
+++ b/imager.h
@@ -442,12 +442,13 @@ void i_autolevels(i_img *im,float lsat,float usat,float skew);
 void i_radnoise(i_img *im,int xo,int yo,float rscale,float ascale);
 void i_turbnoise(i_img *im,float xo,float yo,float scale);
 void i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
-void i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
+int i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
 i_img *i_diff_image(i_img *im, i_img *im2, int mindist);
-void 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);
+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);
 extern i_fill_t *
 i_new_fill_fount(double xa, double ya, double xb, double yb, 
                  i_fountain_type type, i_fountain_repeat repeat, 
@@ -529,4 +530,29 @@ i_set_image_file_limits(int width, int height, int bytes);
 extern int
 i_get_image_file_limits(int *width, int *height, int *bytes);
 
+/* memory allocation */
+void* mymalloc(int size);
+void  myfree(void *p);
+void* myrealloc(void *p, size_t newsize);
+void* mymalloc_file_line (size_t size, char* file, int line);
+void  myfree_file_line   (void *p, char*file, int line);
+void* myrealloc_file_line(void *p, size_t newsize, char* file,int line);
+
+#ifdef IMAGER_DEBUG_MALLOC
+
+#define mymalloc(x) (mymalloc_file_line((x), __FILE__, __LINE__))
+#define myrealloc(x,y) (myrealloc_file_line((x),(y), __FILE__, __LINE__))
+#define myfree(x) (myfree_file_line((x), __FILE__, __LINE__))
+
+void  malloc_state       (void);
+void* mymalloc_comm      (int size, char *comm);
+void  bndcheck_all       (void);
+
+#else
+
+#define malloc_comm(a,b) (mymalloc(a))
+void  malloc_state(void);
+
+#endif /* IMAGER_MALLOC_DEBUG */
+
 #endif
index 7dd5839..af264b0 100644 (file)
@@ -508,6 +508,13 @@ typedef struct i_gif_opts {
   int eliminate_unused;
 } i_gif_opts;
 
+/* distance measures used by some filters */
+enum {
+  i_dmeasure_euclidean = 0,
+  i_dmeasure_euclidean_squared = 1,
+  i_dmeasure_manhatten = 2,
+  i_dmeasure_limit = 2,
+};
 
 
 #endif
diff --git a/imext.c b/imext.c
index ef34d7a..670e771 100644 (file)
--- a/imext.c
+++ b/imext.c
@@ -10,6 +10,10 @@ im_ext_funcs imager_function_table =
     myfree,
     myrealloc,
 
+    mymalloc_file_line,
+    myfree_file_line,
+    myrealloc_file_line,
+
     i_img_8_new,
     i_img_16_new,
     i_img_double_new,
diff --git a/imext.h b/imext.h
index e5b7d98..85a6e24 100644 (file)
--- a/imext.h
+++ b/imext.h
@@ -13,10 +13,20 @@ extern im_ext_funcs *imager_function_ext_table;
 /* just for use here */
 #define im_extt imager_function_ext_table
 
+#ifdef IMAGER_DEBUG_MALLOC
+
+#define mymalloc(size) ((im_extt->f_mymalloc_file_line)((size), __FILE__, __LINE__))
+#define myrealloc(ptr, size) ((im_extt->f_myrealloc_file_line)((ptr), (size), __FILE__, __LINE__))
+#define myfree(ptr) ((im_extt->f_myfree_file_line)((ptr), __FILE__, __LINE__))
+
+#else
+
 #define mymalloc(size) ((im_extt->f_mymalloc)(size))
 #define myfree(size) ((im_extt->f_myfree)(size))
 #define myrealloc(block, newsize) ((im_extt->f_myrealloc)((block), (newsize)))
 
+#endif
+
 #define i_img_8_new(xsize, ysize, channels) ((im_extt->f_i_img_8_new)((xsize), (ysize), (channels)))
 #define i_img_16_new(xsize, ysize, channels) ((im_extt->f_i_img_16_new)((xsize), (ysize), (channels)))
 #define i_img_double_new(xsize, ysize, channels) ((im_extt->f_i_img_double_new)((xsize), (ysize), (channels)))
index b55f378..892985d 100644 (file)
@@ -9,6 +9,9 @@ typedef struct {
   void * (*f_mymalloc)(int size);
   void (*f_myfree)(void *block);
   void * (*f_myrealloc)(void *block, size_t newsize);
+  void* (*f_mymalloc_file_line)(size_t size, char* file, int line);
+  void  (*f_myfree_file_line)(void *p, char*file, int line);
+  void* (*f_myrealloc_file_line)(void *p, size_t newsize, char* file,int line);
 
   i_img *(*f_i_img_8_new)(int xsize, int ysize, int channels);
   i_img *(*f_i_img_16_new)(int xsize, int ysize, int channels);
diff --git a/imio.h b/imio.h
index 48a55d5..6827501 100644 (file)
--- a/imio.h
+++ b/imio.h
@@ -5,34 +5,6 @@
 
 #include "log.h"
 
-
-/* #define MALLOC_DEBUG */
-
-#ifdef IMAGER_DEBUG_MALLOC
-
-#define mymalloc(x) (mymalloc_file_line((x), __FILE__, __LINE__))
-#define myrealloc(x,y) (myrealloc_file_line((x),(y), __FILE__, __LINE__))
-#define myfree(x) (myfree_file_line((x), __FILE__, __LINE__))
-
-void  malloc_state       (void);
-void* mymalloc_file_line (size_t size, char* file, int line);
-void  myfree_file_line   (void *p, char*file, int line);
-void* myrealloc_file_line(void *p, size_t newsize, char* file,int line);
-void* mymalloc_comm      (int size, char *comm);
-void  bndcheck_all       (void);
-
-#else
-
-#define malloc_comm(a,b) (mymalloc(a))
-void  malloc_state(void);
-void* mymalloc(int size);
-void  myfree(void *p);
-void* myrealloc(void *p, size_t newsize);
-
-#endif /* IMAGER_MALLOC_DEBUG */
-
-
-
 typedef struct i_mempool {
   void **p;
   unsigned int alloc;
diff --git a/io.c b/io.c
index 5624361..16bad64 100644 (file)
--- a/io.c
+++ b/io.c
@@ -1,4 +1,4 @@
-#include "imio.h"
+#include "imager.h"
 #include <stdlib.h>
 #ifndef _MSC_VER
 #include <unistd.h>
@@ -72,9 +72,6 @@ set_entry(int i, char *buf, size_t size, char *file, int line) {
   return buf;
 }
 
-
-
-
 void
 malloc_state(void) {
   int i, total = 0;
@@ -115,6 +112,11 @@ mymalloc_file_line(size_t size, char* file, int line) {
   return buf;
 }
 
+void *
+(mymalloc)(int size) {
+  return mymalloc_file_line(size, "unknown", 0);
+}
+
 void*
 myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) {
   char *buf;
@@ -149,6 +151,11 @@ myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) {
   return buf;
 }
 
+void *
+(myrealloc)(void *ptr, size_t newsize) {
+  return myrealloc_file_line(ptr, newsize, "unknown", 0);
+}
+
 static
 void
 bndcheck(int idx) {
@@ -178,10 +185,6 @@ bndcheck_all() {
       bndcheck(idx);
 }
 
-
-
-
-
 void
 myfree_file_line(void *p, char *file, int line) {
   char  *pp = p;
@@ -207,6 +210,11 @@ myfree_file_line(void *p, char *file, int line) {
   free(pp-UNDRRNVAL);
 }
 
+void
+(myfree)(void *block) {
+  myfree_file_line(block, "unknown", 0);
+}
+
 #else 
 
 #define malloc_comm(a,b) (mymalloc(a))
@@ -233,12 +241,22 @@ mymalloc(int size) {
   return buf;
 }
 
+void *
+mymalloc_file_line(size_t size, char *file, int line) {
+  return mymalloc(size);
+}
+
 void
 myfree(void *p) {
   mm_log((1, "myfree(p %p)\n", p));
   free(p);
 }
 
+void
+myfree_file_line(void *p, char *file, int line) {
+  myfree(p);
+}
+
 void *
 myrealloc(void *block, size_t size) {
   void *result;
@@ -252,6 +270,11 @@ myrealloc(void *block, size_t size) {
   return result;
 }
 
+void *
+myrealloc_file_line(void *block, size_t newsize, char *file, int size) {
+  return myrealloc(block, newsize);
+}
+
 #endif /* IMAGER_MALLOC_DEBUG */
 
 
index 7dce1d3..d4eb55c 100644 (file)
--- a/iolayer.c
+++ b/iolayer.c
@@ -1,4 +1,4 @@
-#include "imio.h"
+#include "imager.h"
 #include "iolayer.h"
 #include "imerror.h"
 #include "log.h"
index fe47047..c4ae78a 100644 (file)
@@ -69,7 +69,7 @@ the range of angles in degrees from d1 to d2, with the color.
 
 
 =for comment
-From: Line 329 in draw.c
+From: Line 330 in draw.c
 
 =item i_arc_aa_cfill(im, x, y, rad, d1, d2, fill)
 
@@ -79,7 +79,7 @@ the range of angles in degrees from d1 to d2, with the fill object.
 
 
 =for comment
-From: Line 355 in draw.c
+From: Line 356 in draw.c
 
 =item i_arc_cfill(im, x, y, rad, d1, d2, fill)
 
@@ -98,7 +98,7 @@ Outlines the box from (x1,y1) to (x2,y2) inclusive with I<color>.
 
 
 =for comment
-From: Line 515 in draw.c
+From: Line 516 in draw.c
 
 =item i_box_cfill(im, x1, y1, x2, y2, fill)
 
@@ -107,7 +107,7 @@ Fills the box from (x1,y1) to (x2,y2) inclusive with fill.
 
 
 =for comment
-From: Line 558 in draw.c
+From: Line 559 in draw.c
 
 =item i_box_filled(im, x1, y1, x2, y2, color)
 
@@ -116,7 +116,7 @@ Fills the box from (x1,y1) to (x2,y2) inclusive with color.
 
 
 =for comment
-From: Line 540 in draw.c
+From: Line 541 in draw.c
 
 =item i_circle_aa(im, x, y, rad, color)
 
@@ -126,7 +126,7 @@ color.
 
 
 =for comment
-From: Line 461 in draw.c
+From: Line 462 in draw.c
 
 =item i_flood_cfill(im, seedx, seedy, fill)
 
@@ -138,7 +138,7 @@ Returns false if (seedx, seedy) are outside the image.
 
 
 =for comment
-From: Line 1316 in draw.c
+From: Line 1317 in draw.c
 
 =item i_flood_fill(im, seedx, seedy, color)
 
@@ -150,7 +150,7 @@ Returns false if (seedx, seedy) are outside the image.
 
 
 =for comment
-From: Line 1279 in draw.c
+From: Line 1280 in draw.c
 
 =item i_glin(im, l, r, y, colors)
 
@@ -161,7 +161,7 @@ Returns the number of pixels retrieved.
 
 
 =for comment
-From: Line 195 in imext.c
+From: Line 199 in imext.c
 
 =item i_glinf(im, l, r, y, colors)
 
@@ -173,7 +173,7 @@ Returns the number of pixels retrieved.
 
 
 =for comment
-From: Line 230 in imext.c
+From: Line 234 in imext.c
 
 =item i_gpal(im, x, r, y, indexes)
 
@@ -187,7 +187,7 @@ Always returns 0 for direct color images.
 
 
 =for comment
-From: Line 294 in imext.c
+From: Line 298 in imext.c
 
 =item i_gpix(im, x, y, color)
 
@@ -198,7 +198,7 @@ Returns 0 if the pixel was retrieved, or -1 if not.
 
 
 =for comment
-From: Line 123 in imext.c
+From: Line 127 in imext.c
 
 =item i_gpixf(im, x, y, fcolor)
 
@@ -210,7 +210,7 @@ Returns 0 if the pixel was retrieved, or -1 if not.
 
 
 =for comment
-From: Line 159 in imext.c
+From: Line 163 in imext.c
 
 =item i_gsamp(im, l, r, y, samp, chans, chan_count)
 
@@ -227,7 +227,7 @@ chan_count)
 
 
 =for comment
-From: Line 248 in imext.c
+From: Line 252 in imext.c
 
 =item i_gsampf(im, l, r, y, samp, chans, chan_count)
 
@@ -244,7 +244,7 @@ chan_count)
 
 
 =for comment
-From: Line 271 in imext.c
+From: Line 275 in imext.c
 
 =item i_line(im, x1, y1, x2, y2, val, endp)
 
@@ -261,7 +261,7 @@ Draw a line to image using bresenhams linedrawing algorithm
 
 
 =for comment
-From: Line 629 in draw.c
+From: Line 630 in draw.c
 
 =item i_line_aa(im, x1, x2, y1, y2, color, endp)
 
@@ -272,7 +272,7 @@ The point (x2, y2) is drawn only if endp is set.
 
 
 =for comment
-From: Line 833 in draw.c
+From: Line 834 in draw.c
 
 =item i_plin(im, l, r, y, colors)
 
@@ -284,7 +284,7 @@ Returns the number of pixels set.
 
 
 =for comment
-From: Line 177 in imext.c
+From: Line 181 in imext.c
 
 =item i_plinf(im, l, r, fcolors)
 
@@ -296,7 +296,7 @@ Returns the number of pixels set.
 
 
 =for comment
-From: Line 212 in imext.c
+From: Line 216 in imext.c
 
 =item i_ppal(im, x, r, y, indexes)
 
@@ -310,7 +310,7 @@ Always returns 0 for direct color images.
 
 
 =for comment
-From: Line 313 in imext.c
+From: Line 317 in imext.c
 
 =item i_ppix(im, x, y, color)
 
@@ -324,7 +324,7 @@ color to the image.
 
 
 =for comment
-From: Line 103 in imext.c
+From: Line 107 in imext.c
 
 =item i_ppixf(im, x, y, fcolor)
 
@@ -338,7 +338,7 @@ color to the image.
 
 
 =for comment
-From: Line 140 in imext.c
+From: Line 144 in imext.c
 
 
 =back
@@ -414,7 +414,7 @@ Creates a new general fill which fills with a fountain fill.
 
 
 =for comment
-From: Line 1666 in filters.c
+From: Line 1718 in filters.c
 
 =item i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
 
@@ -715,7 +715,7 @@ Always fails for direct color images.
 
 
 =for comment
-From: Line 332 in imext.c
+From: Line 336 in imext.c
 
 =item i_colorcount(im)
 
@@ -726,7 +726,7 @@ Returns -1 for direct images.
 
 
 =for comment
-From: Line 378 in imext.c
+From: Line 382 in imext.c
 
 =item i_findcolor(im, color, &entry)
 
@@ -741,7 +741,7 @@ Always fails on direct color images.
 
 
 =for comment
-From: Line 413 in imext.c
+From: Line 417 in imext.c
 
 =item i_getcolors(im, index, colors, count)
 
@@ -760,7 +760,7 @@ palette.
 
 
 =for comment
-From: Line 353 in imext.c
+From: Line 357 in imext.c
 
 =item i_maxcolors(im)
 
@@ -772,7 +772,7 @@ Returns -1 for direct color images.
 
 
 =for comment
-From: Line 395 in imext.c
+From: Line 399 in imext.c
 
 =item i_setcolors(im, index, colors, count)
 
@@ -790,7 +790,7 @@ Always fails on direct color images.
 
 
 =for comment
-From: Line 433 in imext.c
+From: Line 437 in imext.c
 
 
 =back