- 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
=================================================================
}
};
- $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 => { },
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} =
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
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)
++i;
}
-void
+undef_int
i_nearest_color(im, ...)
Imager::ImgRaw im
PREINIT:
}
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()
-#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
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;
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);
=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;
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;
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:
ival[p].channel[ch] = tval[p*im->channels + ch];
i_nearest_color_foo(im, num, xo, yo, ival, dmeasure);
+
+ return 1;
}
/*
=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;
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);
}
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);
}
myfree(blur);
+ myfree(out);
}
i_img_destroy(copy);
}
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;
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;
i_plinf(out, 0, xsize, y, line2);
}
myfree(line1);
+ myfree(line2);
}
return out;
*/
-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) {
fount_finish_state(&state);
if (work) myfree(work);
myfree(line);
+
+ return 1;
}
typedef struct {
*/
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);
+ }
}
/*
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,
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
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
myfree,
myrealloc,
+ mymalloc_file_line,
+ myfree_file_line,
+ myrealloc_file_line,
+
i_img_8_new,
i_img_16_new,
i_img_double_new,
/* 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)))
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);
#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;
-#include "imio.h"
+#include "imager.h"
#include <stdlib.h>
#ifndef _MSC_VER
#include <unistd.h>
return buf;
}
-
-
-
void
malloc_state(void) {
int i, total = 0;
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;
return buf;
}
+void *
+(myrealloc)(void *ptr, size_t newsize) {
+ return myrealloc_file_line(ptr, newsize, "unknown", 0);
+}
+
static
void
bndcheck(int idx) {
bndcheck(idx);
}
-
-
-
-
void
myfree_file_line(void *p, char *file, int line) {
char *pp = p;
free(pp-UNDRRNVAL);
}
+void
+(myfree)(void *block) {
+ myfree_file_line(block, "unknown", 0);
+}
+
#else
#define malloc_comm(a,b) (mymalloc(a))
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;
return result;
}
+void *
+myrealloc_file_line(void *block, size_t newsize, char *file, int size) {
+ return myrealloc(block, newsize);
+}
+
#endif /* IMAGER_MALLOC_DEBUG */
-#include "imio.h"
+#include "imager.h"
#include "iolayer.h"
#include "imerror.h"
#include "log.h"
=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)
=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)
=for comment
-From: Line 515 in draw.c
+From: Line 516 in draw.c
=item i_box_cfill(im, x1, y1, x2, y2, 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)
=for comment
-From: Line 540 in draw.c
+From: Line 541 in draw.c
=item i_circle_aa(im, x, y, rad, color)
=for comment
-From: Line 461 in draw.c
+From: Line 462 in draw.c
=item i_flood_cfill(im, seedx, seedy, fill)
=for comment
-From: Line 1316 in draw.c
+From: Line 1317 in draw.c
=item i_flood_fill(im, seedx, seedy, color)
=for comment
-From: Line 1279 in draw.c
+From: Line 1280 in draw.c
=item i_glin(im, l, r, y, colors)
=for comment
-From: Line 195 in imext.c
+From: Line 199 in imext.c
=item i_glinf(im, l, r, y, colors)
=for comment
-From: Line 230 in imext.c
+From: Line 234 in imext.c
=item i_gpal(im, x, r, y, indexes)
=for comment
-From: Line 294 in imext.c
+From: Line 298 in imext.c
=item i_gpix(im, x, y, color)
=for comment
-From: Line 123 in imext.c
+From: Line 127 in imext.c
=item i_gpixf(im, x, y, fcolor)
=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)
=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)
=for comment
-From: Line 271 in imext.c
+From: Line 275 in imext.c
=item i_line(im, x1, y1, x2, y2, val, endp)
=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)
=for comment
-From: Line 833 in draw.c
+From: Line 834 in draw.c
=item i_plin(im, l, r, y, colors)
=for comment
-From: Line 177 in imext.c
+From: Line 181 in imext.c
=item i_plinf(im, l, r, fcolors)
=for comment
-From: Line 212 in imext.c
+From: Line 216 in imext.c
=item i_ppal(im, x, r, y, indexes)
=for comment
-From: Line 313 in imext.c
+From: Line 317 in imext.c
=item i_ppix(im, x, y, color)
=for comment
-From: Line 103 in imext.c
+From: Line 107 in imext.c
=item i_ppixf(im, x, y, fcolor)
=for comment
-From: Line 140 in imext.c
+From: Line 144 in imext.c
=back
=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)
=for comment
-From: Line 332 in imext.c
+From: Line 336 in imext.c
=item i_colorcount(im)
=for comment
-From: Line 378 in imext.c
+From: Line 382 in imext.c
=item i_findcolor(im, color, &entry)
=for comment
-From: Line 413 in imext.c
+From: Line 417 in imext.c
=item i_getcolors(im, index, colors, count)
=for comment
-From: Line 353 in imext.c
+From: Line 357 in imext.c
=item i_maxcolors(im)
=for comment
-From: Line 395 in imext.c
+From: Line 399 in imext.c
=item i_setcolors(im, index, colors, count)
=for comment
-From: Line 433 in imext.c
+From: Line 437 in imext.c
=back