Fixed most outstanding memory leaks that are revealed in the test cases.
authorArnar Mar Hrafnkelsson <addi@cpan.org>
Thu, 1 Nov 2001 05:36:14 +0000 (05:36 +0000)
committerArnar Mar Hrafnkelsson <addi@cpan.org>
Thu, 1 Nov 2001 05:36:14 +0000 (05:36 +0000)
gif.c, bmp.c, font.c and tga.c still need to be checked.

15 files changed:
Imager.xs
conv.c
convert.c
datatypes.c
draw.c
filters.c
freetyp2.c
gaussian.c
gif.c
io.c
jpeg.c
quant.c
raw.c
t/t38ft2font.t
t/t58trans2.t

index f55390a..0a90145 100644 (file)
--- a/Imager.xs
+++ b/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
diff --git a/conv.c b/conv.c
index dd79af1..3277b6e 100644 (file)
--- a/conv.c
+++ b/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);
 }
 
 
index 61017e8..c3bf132 100644 (file)
--- a/convert.c
+++ b/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;
index fd13e20..33d27a5 100644 (file)
@@ -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);
diff --git a/draw.c b/draw.c
index b86ac59..1656105 100644 (file)
--- a/draw.c
+++ b/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);
 }
 
index 2110a34..ef5f63a 100644 (file)
--- a/filters.c
+++ b/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);
 }
 
index 5070784..b5dec0e 100644 (file)
@@ -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;
 }
 
index 13cfd31..c3025b7 100644 (file)
@@ -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);
 }
 
 
diff --git a/gif.c b/gif.c
index 5d7d889..3b29d14 100644 (file)
--- a/gif.c
+++ b/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;
diff --git a/io.c b/io.c
index 1a56e14..66829bd 100644 (file)
--- a/io.c
+++ b/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);
 }
diff --git a/jpeg.c b/jpeg.c
index 86fc7cf..d6f9f27 100644 (file)
--- a/jpeg.c
+++ b/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);
 }
 
diff --git a/quant.c b/quant.c
index f745f6f..290d0c2 100644 (file)
--- a/quant.c
+++ b/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;
 }
 
diff --git a/raw.c b/raw.c
index e87bf98..928b33a 100644 (file)
--- a/raw.c
+++ b/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;
index 415323e..391c914 100644 (file)
@@ -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';
index 8baefdf..bf92dba 100644 (file)
@@ -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) = @_;