Skip to content
Browse files

Fixed most outstanding memory leaks that are revealed in the test cases.

gif.c, bmp.c, font.c and tga.c still need to be checked.
  • Loading branch information...
1 parent 7f882a0 commit a73aeb5fb8bf417b91c9f8e13905acf6a8692a37 Arnar Mar Hrafnkelsson committed Nov 1, 2001
Showing with 127 additions and 87 deletions.
  1. +11 −3 Imager.xs
  2. +2 −1 conv.c
  3. +3 −2 convert.c
  4. +30 −21 datatypes.c
  5. +22 −20 draw.c
  6. +2 −0 filters.c
  7. +12 −1 freetyp2.c
  8. +2 −1 gaussian.c
  9. +10 −2 gif.c
  10. +3 −1 io.c
  11. +6 −6 jpeg.c
  12. +5 −5 quant.c
  13. +16 −23 raw.c
  14. +1 −1 t/t38ft2font.t
  15. +2 −0 t/t58trans2.t
View
14 Imager.xs
@@ -1506,9 +1506,11 @@ i_writegif_gen(fd, ...)
copy_colors_back(hv, &quant);
}
}
- ST(0) = sv_newmortal();
- if (RETVAL == 0) ST(0)=&PL_sv_undef;
- else sv_setiv(ST(0), (IV)RETVAL);
+ ST(0) = sv_newmortal();
+ if (RETVAL == 0) ST(0)=&PL_sv_undef;
+ else sv_setiv(ST(0), (IV)RETVAL);
+ myfree(quant.mc_colors);
+
undef_int
i_writegif_callback(cb, maxbuffer,...)
@@ -2144,6 +2146,10 @@ i_gradgen(im, ...)
ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
}
i_gradgen(im, num, xo, yo, ival, dmeasure);
+ myfree(xo);
+ myfree(yo);
+ myfree(ival);
+
void
i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
@@ -2631,6 +2637,7 @@ i_gsamp(im, l, r, y, ...)
EXTEND(SP, 1);
PUSHs(sv_2mortal(newSVpv(data, count * sizeof(i_sample_t))));
}
+ myfree(data);
}
else {
if (GIMME_V != G_ARRAY) {
@@ -2639,6 +2646,7 @@ i_gsamp(im, l, r, y, ...)
}
}
+
Imager::ImgRaw
i_img_masked_new(targ, mask, x, y, w, h)
Imager::ImgRaw targ
View
3 conv.c
@@ -19,7 +19,7 @@ i_conv(i_img *im,float *coeff,int len) {
float res[11];
i_img timg;
- mm_log((1,"i_conv(im* 0x%x,coeff 0x%x,len %d)\n",im,coeff,len));
+ mm_log((1,"i_conv(im %p, coeff %p, len %d)\n",im,coeff,len));
i_img_empty_ch(&timg,im->xsize,im->ysize,im->channels);
@@ -66,6 +66,7 @@ i_conv(i_img *im,float *coeff,int len) {
i_ppix(im,l,i,&rcolor);
}
}
+ i_img_exorcise(&timg);
}
View
5 convert.c
@@ -41,8 +41,7 @@ Now handles images with more than 8-bits/sample.
*/
int
-i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan)
-{
+i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
int x, y;
int i, j;
int ilimit;
@@ -177,6 +176,8 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan)
i_gpal(src, 0, im->xsize, y, vals);
i_ppal(im, 0, im->xsize, y, vals);
}
+ myfree(vals);
+ myfree(colors);
}
return 1;
View
51 datatypes.c
@@ -49,17 +49,17 @@ btm_set(struct i_bitmap *btm,int x,int y) {
/*
- Linked list - stack type
+ Bucketed linked list - stack type
*/
struct llink *
llink_new(struct llink* p,int size) {
struct llink *l;
- l=(struct llink*)mymalloc(sizeof(struct llink));
- l->n=NULL;
- l->p=p;
- l->fill=0;
- l->data=(void*)mymalloc(size);
+ l = mymalloc(sizeof(struct llink));
+ l->n = NULL;
+ l->p = p;
+ l->fill = 0;
+ l->data = mymalloc(size);
return l;
}
@@ -79,7 +79,7 @@ llink_destroy(struct llink* l) {
int
llist_llink_push(struct llist *lst, struct llink *lnk,void *data) {
int multip;
- multip=lst->multip;
+ multip = lst->multip;
/* fprintf(stderr,"llist_llink_push: data=0x%08X -> 0x%08X\n",data,*(int*)data);
fprintf(stderr,"ssize = %d, multip = %d, fill = %d\n",lst->ssize,lst->multip,lnk->fill); */
@@ -96,32 +96,39 @@ llist_llink_push(struct llist *lst, struct llink *lnk,void *data) {
struct llist *
llist_new(int multip, int ssize) {
struct llist *l;
- l=(struct llist*)mymalloc(sizeof(struct llist));
- l->h=l->t=NULL;
- l->multip=multip;
- l->ssize=ssize;
- l->count=0;
+ l = mymalloc(sizeof(struct llist));
+ l->h = NULL;
+ l->t = NULL;
+ l->multip = multip;
+ l->ssize = ssize;
+ l->count = 0;
return l;
}
void
llist_push(struct llist *l,void *data) {
- int ssize=l->ssize;
- int multip=l->multip;
+ int ssize = l->ssize;
+ int multip = l->multip;
- /* fprintf(stderr,"llist_push: data=0x%08X\n",data); */
-
- if (l->t == NULL) l->t=l->h=llink_new(NULL,ssize*multip); /* Tail is empty - list is empty */
+ /* fprintf(stderr,"llist_push: data=0x%08X\n",data);
+ fprintf(stderr,"Chain size: %d\n", l->count); */
+
+ if (l->t == NULL) {
+ l->t = l->h = llink_new(NULL,ssize*multip); /* Tail is empty - list is empty */
+ /* fprintf(stderr,"Chain empty - extended\n"); */
+ }
else { /* Check for overflow in current tail */
if (l->t->fill >= l->multip) {
- struct llink* nt=llink_new(l->t,ssize*multip);
+ struct llink* nt = llink_new(l->t, ssize*multip);
l->t->n=nt;
l->t=nt;
/* fprintf(stderr,"Chain extended\n"); */
}
}
/* fprintf(stderr,"0x%08X\n",l->t); */
- if (llist_llink_push(l,l->t,data)) { fprintf(stderr,"DARN!\n"); }
+ if (llist_llink_push(l,l->t,data)) {
+ m_fatal(3, "out of memory\n");
+ }
}
/* returns 0 if the list is empty */
@@ -133,11 +140,13 @@ llist_pop(struct llist *l,void *data) {
if (l->t == NULL) return 0;
l->t->fill--;
l->count--;
- /* memcpy(data,(char*)(l->t->data)+l->ssize*l->t->fill,l->ssize); */
memcpy(data,(char*)(l->t->data)+l->ssize*l->t->fill,l->ssize);
if (!l->t->fill) { /* This link empty */
- if (l->t->p == NULL) l->h=l->t=NULL; /* and it's the only link */
+ if (l->t->p == NULL) { /* and it's the only link */
+ llink_destroy(l->t);
+ l->h = l->t = NULL;
+ }
else {
l->t=l->t->p;
llink_destroy(l->t->n);
View
42 draw.c
@@ -193,6 +193,7 @@ i_arc_cfill(i_img *im,int x,int y,float rad,float d1,float d2,i_fill_t *fill) {
/* dot.info(); */
i_mmarray_render_fill(im,&dot,fill);
+ i_mmarray_dst(&dot);
}
@@ -924,13 +925,13 @@ static
struct stack_element*
crdata(int left,int right,int dadl,int dadr,int y, int dir) {
struct stack_element *ste;
- ste=(struct stack_element*)mymalloc(sizeof(struct stack_element));
- ste->myLx=left;
- ste->myRx=right;
- ste->dadLx=dadl;
- ste->dadRx=dadr;
- ste->myY=y;
- ste->myDirection=dir;
+ ste = mymalloc(sizeof(struct stack_element));
+ ste->myLx = left;
+ ste->myRx = right;
+ ste->dadLx = dadl;
+ ste->dadRx = dadr;
+ ste->myY = y;
+ ste->myDirection = dir;
return ste;
}
@@ -970,14 +971,14 @@ i_rspan(i_img *im,int seedx,int seedy,i_color *val) {
/* Macro to create a link and push on to the list */
-#define ST_PUSH(left,right,dadl,dadr,y,dir) { struct stack_element *s=crdata(left,right,dadl,dadr,y,dir); llist_push(st,&s);}
+#define ST_PUSH(left,right,dadl,dadr,y,dir) { struct stack_element *s = crdata(left,right,dadl,dadr,y,dir); llist_push(st,&s); }
/* pops the shadow on TOS into local variables lx,rx,y,direction,dadLx and dadRx */
/* No overflow check! */
-#define ST_POP() { struct stack_element *s; llist_pop(st,&s); lx=s->myLx; rx=s->myRx; dadLx=s->dadLx; dadRx=s->dadRx; y=s->myY; direction=s->myDirection; myfree(s); }
+#define ST_POP() { struct stack_element *s; llist_pop(st,&s); lx = s->myLx; rx = s->myRx; dadLx = s->dadLx; dadRx = s->dadRx; y = s->myY; direction= s->myDirection; myfree(s); }
-#define ST_STACK(dir,dadLx,dadRx,lx,rx,y) { int pushrx=rx+1; int pushlx=lx-1; ST_PUSH(lx,rx,pushlx,pushrx,y+dir,dir); if (rx > dadRx) ST_PUSH(dadRx+1,rx,pushlx,pushrx,y-dir,-dir); if (lx < dadLx) ST_PUSH(lx,dadLx-1,pushlx,pushrx,y-dir,-dir); }
+#define ST_STACK(dir,dadLx,dadRx,lx,rx,y) { int pushrx = rx+1; int pushlx = lx-1; ST_PUSH(lx,rx,pushlx,pushrx,y+dir,dir); if (rx > dadRx) ST_PUSH(dadRx+1,rx,pushlx,pushrx,y-dir,-dir); if (lx < dadLx) ST_PUSH(lx,dadLx-1,pushlx,pushrx,y-dir,-dir); }
#define SET(x,y) btm_set(btm,x,y);
@@ -1004,26 +1005,26 @@ i_flood_fill(i_img *im,int seedx,int seedy,i_color *dcol) {
int channels,xsize,ysize;
i_color cval,val;
- channels=im->channels;
- xsize=im->xsize;
- ysize=im->ysize;
+ channels = im->channels;
+ xsize = im->xsize;
+ ysize = im->ysize;
- btm=btm_new(xsize,ysize);
- st=llist_new(100,sizeof(struct stack_element*));
+ btm = btm_new(xsize,ysize);
+ st = llist_new(100,sizeof(struct stack_element*));
/* Get the reference color */
i_gpix(im,seedx,seedy,&val);
/* Find the starting span and fill it */
- lx=i_lspan(im,seedx,seedy,&val);
- rx=i_rspan(im,seedx,seedy,&val);
+ lx = i_lspan(im,seedx,seedy,&val);
+ rx = i_rspan(im,seedx,seedy,&val);
/* printf("span: %d %d \n",lx,rx); */
- for(x=lx;x<=rx;x++) SET(x,seedy);
+ for(x=lx; x<=rx; x++) SET(x,seedy);
- ST_PUSH(lx,rx,lx,rx,seedy+1,1);
- ST_PUSH(lx,rx,lx,rx,seedy-1,-1);
+ ST_PUSH(lx, rx, lx, rx, seedy+1, 1);
+ ST_PUSH(lx, rx, lx, rx, seedy-1,-1);
while(st->count) {
ST_POP();
@@ -1107,6 +1108,7 @@ i_flood_fill(i_img *im,int seedx,int seedy,i_color *dcol) {
for(y=bymin;y<=bymax;y++) for(x=bxmin;x<=bxmax;x++) if (btm_test(btm,x,y)) i_ppix(im,x,y,dcol);
btm_destroy(btm);
+ mm_log((1, "DESTROY\n"));
llist_destroy(st);
}
View
2 filters.c
@@ -979,6 +979,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);
}
@@ -1456,6 +1457,7 @@ 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);
}
View
13 freetyp2.c
@@ -96,6 +96,8 @@ i_ft2_new(char *name, int index) {
double matrix[6] = { 1, 0, 0,
0, 1, 0 };
+ mm_log((1, "i_ft2_new(name %p, index %d)\n", name, index));
+
i_clear_error();
error = FT_New_Face(library, name, index, &face);
if (error) {
@@ -250,6 +252,9 @@ i_ft2_bbox(FT2_Fonthandle *handle, double cheight, double cwidth,
FT_Glyph_Metrics *gm;
int start = 0;
+ mm_log((1, "i_ft2_bbox(handle %p, cheight %f, cwidth %f, text %p, len %d, bbox %p)\n",
+ handle, cheight, cwidth, text, len, bbox));
+
error = FT_Set_Char_Size(handle->face, cwidth*64, cheight*64,
handle->xdpi, handle->ydpi);
if (error) {
@@ -548,6 +553,9 @@ i_ft2_text(FT2_Fonthandle *handle, i_img *im, int tx, int ty, i_color *cl,
i_color pel;
int loadFlags = FT_LOAD_DEFAULT;
+ mm_log((1, "i_ft2_text(handle %p, im %p, tx %d, ty %d, cl %p, cheight %f, cwidth %f, text %p, len %d, align %d, aa %d)\n",
+ handle, im, tx, ty, cl, cheight, cwidth, text, align, aa));
+
if (vlayout) {
if (!FT_HAS_VERTICAL(handle->face)) {
i_push_error(0, "face has no vertical metrics");
@@ -677,6 +685,9 @@ i_ft2_cp(FT2_Fonthandle *handle, i_img *im, int tx, int ty, int channel,
i_color cl, cl2;
int x, y;
+ mm_log((1, "i_ft2_cp(handle %p, im %p, tx %d, ty %d, channel %d, cheight %f, cwidth %f, text %p, len %d, ...)\n",
+ handle, im, tx, ty, channel, cheight, cwidth, text, len));
+
if (vlayout && !FT_HAS_VERTICAL(handle->face)) {
i_push_error(0, "face has no vertical metrics");
return 0;
@@ -706,7 +717,7 @@ i_ft2_cp(FT2_Fonthandle *handle, i_img *im, int tx, int ty, int channel,
i_ppix(im, tx + x + bbox[0], ty + y + bbox[1], &cl2);
}
}
-
+ i_img_destroy(work);
return 1;
}
View
3 gaussian.c
@@ -24,7 +24,7 @@ i_gaussian(i_img *im,float stdev) {
float res[11];
i_img timg;
- mm_log((1,"i_gaussian(im* 0x%x,stdev %.2f)\n",im,stdev));
+ mm_log((1,"i_gaussian(im %p, stdev %.2f)\n",im,stdev));
i_img_empty_ch(&timg,im->xsize,im->ysize,im->channels);
@@ -61,6 +61,7 @@ i_gaussian(i_img *im,float stdev) {
i_ppix(im,l,i,&rcolor);
}
}
+ i_img_exorcise(&timg);
}
View
12 gif.c
@@ -177,7 +177,7 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
Size = GifFile->SWidth * sizeof(GifPixelType);
- GifRow = (GifRowType) mymalloc(Size);
+ GifRow = mymalloc(Size);
for (i = 0; i < GifFile->SWidth; i++) GifRow[i] = GifFile->SBackGroundColor;
@@ -190,6 +190,7 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
@@ -204,6 +205,7 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
@@ -221,6 +223,7 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
mm_log((1, "Going in with no colormap\n"));
i_push_error(0, "Image does not have a local or a global color map");
/* we can't have allocated a colour table here */
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
@@ -240,9 +243,10 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
- return(0);
+ return NULL;
}
if (GifFile->Image.Interlace) {
@@ -255,6 +259,7 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
@@ -279,6 +284,7 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
@@ -304,6 +310,7 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
@@ -316,6 +323,7 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
View
4 io.c
@@ -205,9 +205,11 @@ myfree_file_line(void *p, char *file, int line) {
if (match != 1) {
mm_log((1, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line));
+ printf(stderr, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line);
+ exit(255);
}
- mm_log((1, "myfree_file_line: freeing address %p\n", pp-UNDRRNVAL));
+ mm_log((1, "myfree_file_line: freeing address %p (real %p)\n", pp, pp-UNDRRNVAL));
free(pp-UNDRRNVAL);
}
View
12 jpeg.c
@@ -215,10 +215,11 @@ wiol_empty_output_buffer(j_compress_ptr cinfo) {
mm_log((1,"wiol_empty_output_buffer(cinfo 0x%p)\n"));
rc = dest->data->writecb(dest->data, dest->buffer, JPGS);
-
+
if (rc != JPGS) { /* XXX: Should raise some jpeg error */
+ myfree(dest->buffer);
mm_log((1, "wiol_empty_output_buffer: Error: nbytes = %d != rc = %d\n", JPGS, rc));
- ERREXIT(cinfo, JERR_FILE_WRITE);
+ ERREXIT(cinfo, JERR_FILE_WRITE);
}
dest->pub.free_in_buffer = JPGS;
dest->pub.next_output_byte = dest->buffer;
@@ -231,13 +232,12 @@ wiol_term_destination (j_compress_ptr cinfo) {
size_t nbytes = JPGS - dest->pub.free_in_buffer;
/* yes, this needs to flush the buffer */
/* needs error handling */
+
if (dest->data->writecb(dest->data, dest->buffer, nbytes) != nbytes) {
+ myfree(dest->buffer);
ERREXIT(cinfo, JERR_FILE_WRITE);
}
-
-
- mm_log((1, "wiol_term_destination(cinfo %p)\n", cinfo));
- mm_log((1, "wiol_term_destination: dest %p\n", cinfo->dest));
+
if (dest != NULL) myfree(dest->buffer);
}
View
10 quant.c
@@ -68,9 +68,9 @@ static void translate_addi(i_quantize *, i_img *, i_palidx *);
*/
i_palidx *quant_translate(i_quantize *quant, i_img *img) {
i_palidx *result;
- mm_log((1, "quant_translate(quant %p, img %p)\n", quant, img));
+ mm_log((1, "quant_translate(quant %p, img %p)\n", quant, img));
- result = mymalloc(img->xsize * img->ysize);
+ result = mymalloc(img->xsize * img->ysize);
switch (quant->translate) {
#ifdef HAVE_LIBGIF
@@ -82,17 +82,17 @@ i_palidx *quant_translate(i_quantize *quant, i_img *img) {
case pt_closest:
translate_closest(quant, img, result);
break;
-
+
case pt_errdiff:
translate_errdiff(quant, img, result);
break;
-
+
case pt_perturb:
default:
translate_addi(quant, img, result);
break;
}
-
+
return result;
}
View
39 raw.c
@@ -121,41 +121,34 @@ i_writeraw_wiol(i_img* im, io_glue *ig) {
raw images later */
int line_size = im->xsize * im->channels;
unsigned char *data = mymalloc(line_size);
- if (data) {
- int y = 0;
- rc = line_size;
- while (rc == line_size && y < im->ysize) {
- i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels);
- rc = ig->writecb(ig, data, line_size);
- ++y;
- }
- } else {
- i_push_error(0, "Out of memory");
- return 0;
+
+ int y = 0;
+ rc = line_size;
+ while (rc == line_size && y < im->ysize) {
+ i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels);
+ rc = ig->writecb(ig, data, line_size);
+ ++y;
}
if (rc != line_size) {
i_push_error(errno, "write error");
return 0;
}
+ myfree(data);
} else {
/* paletted image - assumes the caller puts the palette somewhere
else
*/
int line_size = sizeof(i_palidx) * im->xsize;
i_palidx *data = mymalloc(sizeof(i_palidx) * im->xsize);
- if (data) {
- int y = 0;
- rc = line_size;
- while (rc == line_size && y < im->ysize) {
- i_gpal(im, 0, im->xsize, y, data);
- rc = ig->writecb(ig, data, line_size);
- ++y;
- }
- myfree(data);
- } else {
- i_push_error(0, "Out of memory");
- return 0;
+
+ int y = 0;
+ rc = line_size;
+ while (rc == line_size && y < im->ysize) {
+ i_gpal(im, 0, im->xsize, y, data);
+ rc = ig->writecb(ig, data, line_size);
+ ++y;
}
+ myfree(data);
if (rc != line_size) {
i_push_error(errno, "write error");
return 0;
View
2 t/t38ft2font.t
@@ -23,7 +23,7 @@ sub skip {
exit(0);
}
-if (!(i_has_format("ft2")) ) { skip(); }
+if (!(i_has_format("ft2")) ) { skip(); }
print "# has ft2\n";
$fontname=$ENV{'TTFONTTEST'}||'./fontfiles/dodge.ttf';
View
2 t/t58trans2.t
@@ -79,6 +79,8 @@ ok(11, !$im7, "expected failure on accessing invalid image");
print "# ", Imager->errstr, "\n";
ok(12, Imager->errstr =~ /not enough images/, "didn't get expected error");
+
+
sub ok ($$$) {
my ($num, $test, $desc) = @_;

0 comments on commit a73aeb5

Please sign in to comment.
Something went wrong with that request. Please try again.