Patch reduced memory leaks, caught by valgrind.

--- ./fb-gui.h  2006-08-12 22:17:14.000000000 +0100
+++ /home/user/fbi-2.07/./fb-gui.h      2012-01-16 13:48:03.000000000 +0000
@@ -27,6 +27,7 @@
                          wchar_t *lines[], unsigned int count);
 
 void font_init(void);
+void font_done(void);
 FT_Face font_open(char *fcname);
 
 void fb_clear_mem(void);
--- ./fbiconfig.h       2006-08-13 19:47:34.000000000 +0100
+++ /home/user/fbi-2.07/./fbiconfig.h   2012-01-16 15:29:24.000000000 +0000
@@ -70,4 +70,4 @@
 extern struct cfg_cmdline fbi_cfg[];
 void fbi_read_config(void);
 void fbi_write_config(void);
-
+void fbi_config_free(void);


--- ./fbiconfig.c       2006-08-13 19:28:49.000000000 +0100
+++ /home/user/fbi-2.07/./fbiconfig.c   2012-01-16 15:28:35.000000000 +0000
@@ -191,6 +191,12 @@
     sprintf(fbi_config,"%s/.fbirc", home);
 }
 
+void fbi_config_free(void)
+{
+       if (fbi_config)
+               free(fbi_config);
+}
+
 void fbi_read_config(void)
 {
     init_config();
--- ./fb-gui.c  2006-08-14 20:38:05.000000000 +0100
+++ /home/user/fbi-2.07/./fb-gui.c      2012-01-16 14:45:02.000000000 +0000
@@ -10,6 +10,8 @@
 #include <fontconfig/fontconfig.h>
 #include <fontconfig/fcfreetype.h>
 
+#include <freetype/freetype.h>
+
 #include "fbtools.h"
 #include "dither.h"
 #include "fb-gui.h"
@@ -622,15 +624,25 @@
     }
 }
 
+void font_done(void)
+{
+    if (FT_Done_FreeType(freetype)) {
+       fprintf(stderr,"FT_Done_FreeType() failed\n");
+       exit(1);
+    }
+    FcFini();
+}
+
 FT_Face font_open(char *fcname)
 {
     FcResult    result = 0;
     FT_Face     face = NULL;
     FcPattern   *pattern,*match;
-    char        *fontname,*h;
+    char        *fontname = NULL, *h = NULL;
     FcChar8     *filename;
     double      pixelsize;
     int         rc;
+    int         err = 1;
 
     /* parse + match font name */
     pattern = FcNameParse(fcname);
@@ -639,7 +651,7 @@
     match = FcFontMatch (0, pattern, &result);
     FcPatternDestroy(pattern);
     if (FcResultMatch != result)
-       return NULL;
+       goto out;
     fontname = FcNameUnparse(match);
     h = strchr(fontname, ':');
     if (h)
@@ -649,24 +661,33 @@
     result = FcPatternGetFTFace(match, FC_FT_FACE, 0, &face);
     if (FcResultMatch == result) {
        fprintf(stderr,"using \"%s\", face=%p\n",fontname,face);
-       return face;
+       err = 0;
+       goto out;
     }
 
     /* failing that use the filename */
     result = FcPatternGetString (match, FC_FILE, 0, &filename);
     if (FcResultMatch == result) {
-       result = FcPatternGetDouble(match, FC_PIXEL_SIZE, 0, &pixelsize);
+        result = FcPatternGetDouble(match, FC_PIXEL_SIZE, 0, &pixelsize);
        if (FcResultMatch != result)
            pixelsize = 16;
-       fprintf(stderr,"using \"%s\", pixelsize=%.2lf file=%s\n",
-               fontname,pixelsize,filename);
+       fprintf(stderr,"using \"%s\", pixelsize=%.2lf 
file=%s\n",fontname,pixelsize,filename);
        rc = FT_New_Face (freetype, filename, 0, &face);
        if (rc)
-           return NULL;
+           goto out;
+       else
+           err = 0;
        FT_Set_Pixel_Sizes(face, 0, (int)pixelsize);
-       return face;
     }
 
+out:
+    free(fontname);
+    FcPatternDestroy(match);
+
+    if (err == 0)
+        return face;
+
+    FT_Done_FreeType(freetype);
     /* oops, didn't work */
     return NULL;
 }
--- ./fbi.c     2008-06-09 15:53:33.000000000 +0100
+++ /home/user/fbi-2.07/./fbi.c 2012-01-17 12:21:36.000000000 +0000
@@ -113,6 +113,15 @@
 };
 static LIST_HEAD(flist);
 static LIST_HEAD(flru);
+
+/*FIXME A dirty hack, to avoid memleak */
+
+#define fbucket_max 1000
+struct {
+       void *ptr;
+} fbucket[fbucket_max];
+int fbucket_elem = 0;
+
 static int           fcount;
 static struct flist  *fcurrent;
 static struct ida_image *img;
@@ -154,6 +163,8 @@
 static struct ida_image *flist_img_get(struct flist *f);
 static void *flist_malloc(size_t size);
 static void flist_img_load(struct flist *f, int prefetch);
+static void free_image(struct ida_image *img);
+static void flist_img_free(struct flist *f);
 
 /* ---------------------------------------------------------------------- */
 
@@ -203,6 +214,13 @@
     struct flist *f;
 
     f = malloc(sizeof(*f));
+    if (fbucket_elem == fbucket_max) {
+       fprintf(stderr, "too many files?\n");
+       //TODO what?
+    }
+
+    fbucket[fbucket_elem++].ptr = f;
+
     memset(f,0,sizeof(*f));
     f->name = strdup(filename);
     list_add_tail(&f->list,&flist);
@@ -333,6 +351,43 @@
     }
 }
 
+static void flist_free_names(void)
+{
+       struct list_head *item;
+       struct flist *f;
+       list_for_each(item, &flist) {
+               f = list_entry(item, struct flist, list);
+               if (f->name) {
+                   free(f->name);
+               }
+               if (f->fimg) {
+                       if (f->fimg->i.extra) {
+                           if (f->fimg->i.extra->data) {
+                               fprintf(stderr, "extra was not freed, cleaned 
up now\n");
+                               free(f->fimg->i.extra->data); 
+                           }
+                           free(f->fimg->i.extra);
+                       }
+                   fprintf(stderr, "fimg was not freed, cleaned up now\n");
+                   free_image(f->fimg);
+               }
+               if (f->simg) {
+                   fprintf(stderr, "simg was not freed, cleaned up now\n");
+                   free_image(f->simg);
+               }
+       }
+}
+
+static void free_fbucket(void)
+{
+       while (fbucket_elem > 0) {
+           void *ptr = fbucket[--fbucket_elem].ptr;
+           if (ptr != NULL)
+               free(ptr);
+       }
+}
+
+
 /* ---------------------------------------------------------------------- */
 
 static void
@@ -689,11 +744,12 @@
            loader = &ppm_loader;
        }
     }
-
+  
     /* load image */
     img = malloc(sizeof(*img));
     memset(img,0,sizeof(*img));
     data = loader->init(fp,filename,0,&img->i,0);
+    
     if (NULL == data) {
        fprintf(stderr,"loading %s [%s] FAILED\n",filename,loader->name);
        free_image(img);
@@ -707,6 +763,7 @@
        loader->read(img->data + img->i.width * 3 * y, y, data);
     }
     loader->done(data);
+
     return img;
 }
 
@@ -1383,6 +1440,11 @@
     tty_restore();
     fb_cleanup();
     flist_print_tagged(stdout);
+    font_done();
+    flist_img_release_memory();
+    flist_free_names();
+    free_fbucket();
+    fbi_config_free();
     exit(code);
 }
 
@@ -1596,6 +1658,7 @@
            timeout = arg;
            break;
        case KEY_VERBOSE:
+
 #if 0 /* fbdev testing/debugging hack */
            {
                ioctl(fd,FBIOBLANK,1);
 

        Jalil
--- ./fb-gui.h	2006-08-12 22:17:14.000000000 +0100
+++ /home/user/fbi-2.07/./fb-gui.h	2012-01-16 13:48:03.000000000 +0000
@@ -27,6 +27,7 @@
 			  wchar_t *lines[], unsigned int count);
 
 void font_init(void);
+void font_done(void);
 FT_Face font_open(char *fcname);
 
 void fb_clear_mem(void);
--- ./fbiconfig.h	2006-08-13 19:47:34.000000000 +0100
+++ /home/user/fbi-2.07/./fbiconfig.h	2012-01-16 15:29:24.000000000 +0000
@@ -70,4 +70,4 @@
 extern struct cfg_cmdline fbi_cfg[];
 void fbi_read_config(void);
 void fbi_write_config(void);
-
+void fbi_config_free(void);
--- ./fbiconfig.c	2006-08-13 19:28:49.000000000 +0100
+++ /home/user/fbi-2.07/./fbiconfig.c	2012-01-16 15:28:35.000000000 +0000
@@ -191,6 +191,12 @@
     sprintf(fbi_config,"%s/.fbirc", home);
 }
 
+void fbi_config_free(void)
+{
+	if (fbi_config)
+		free(fbi_config);
+}
+
 void fbi_read_config(void)
 {
     init_config();
--- ./fb-gui.c	2006-08-14 20:38:05.000000000 +0100
+++ /home/user/fbi-2.07/./fb-gui.c	2012-01-16 14:45:02.000000000 +0000
@@ -10,6 +10,8 @@
 #include <fontconfig/fontconfig.h>
 #include <fontconfig/fcfreetype.h>
 
+#include <freetype/freetype.h>
+
 #include "fbtools.h"
 #include "dither.h"
 #include "fb-gui.h"
@@ -622,15 +624,25 @@
     }
 }
 
+void font_done(void)
+{
+    if (FT_Done_FreeType(freetype)) {
+	fprintf(stderr,"FT_Done_FreeType() failed\n");
+	exit(1);
+    }
+    FcFini();
+}
+
 FT_Face font_open(char *fcname)
 {
     FcResult    result = 0;
     FT_Face     face = NULL;
     FcPattern   *pattern,*match;
-    char        *fontname,*h;
+    char        *fontname = NULL, *h = NULL;
     FcChar8     *filename;
     double      pixelsize;
     int         rc;
+    int         err = 1;
 
     /* parse + match font name */
     pattern = FcNameParse(fcname);
@@ -639,7 +651,7 @@
     match = FcFontMatch (0, pattern, &result);
     FcPatternDestroy(pattern);
     if (FcResultMatch != result)
-	return NULL;
+	goto out;
     fontname = FcNameUnparse(match);
     h = strchr(fontname, ':');
     if (h)
@@ -649,24 +661,33 @@
     result = FcPatternGetFTFace(match, FC_FT_FACE, 0, &face);
     if (FcResultMatch == result) {
 	fprintf(stderr,"using \"%s\", face=%p\n",fontname,face);
-	return face;
+	err = 0;
+	goto out;
     }
 
     /* failing that use the filename */
     result = FcPatternGetString (match, FC_FILE, 0, &filename);
     if (FcResultMatch == result) {
-	result = FcPatternGetDouble(match, FC_PIXEL_SIZE, 0, &pixelsize);
+        result = FcPatternGetDouble(match, FC_PIXEL_SIZE, 0, &pixelsize);
 	if (FcResultMatch != result)
 	    pixelsize = 16;
-	fprintf(stderr,"using \"%s\", pixelsize=%.2lf file=%s\n",
-		fontname,pixelsize,filename);
+	fprintf(stderr,"using \"%s\", pixelsize=%.2lf file=%s\n",fontname,pixelsize,filename);
 	rc = FT_New_Face (freetype, filename, 0, &face);
 	if (rc)
-	    return NULL;
+	    goto out;
+	else
+	    err = 0;
 	FT_Set_Pixel_Sizes(face, 0, (int)pixelsize);
-	return face;
     }
 
+out:
+    free(fontname);
+    FcPatternDestroy(match);
+
+    if (err == 0)
+        return face;
+
+    FT_Done_FreeType(freetype);
     /* oops, didn't work */
     return NULL;
 }
--- ./fbi.c	2008-06-09 15:53:33.000000000 +0100
+++ /home/user/fbi-2.07/./fbi.c	2012-01-17 12:21:36.000000000 +0000
@@ -113,6 +113,15 @@
 };
 static LIST_HEAD(flist);
 static LIST_HEAD(flru);
+
+/*FIXME A dirty hack, to avoid memleak */
+
+#define fbucket_max 1000
+struct {
+	void *ptr;
+} fbucket[fbucket_max];
+int fbucket_elem = 0;
+
 static int           fcount;
 static struct flist  *fcurrent;
 static struct ida_image *img;
@@ -154,6 +163,8 @@
 static struct ida_image *flist_img_get(struct flist *f);
 static void *flist_malloc(size_t size);
 static void flist_img_load(struct flist *f, int prefetch);
+static void free_image(struct ida_image *img);
+static void flist_img_free(struct flist *f);
 
 /* ---------------------------------------------------------------------- */
 
@@ -203,6 +214,13 @@
     struct flist *f;
 
     f = malloc(sizeof(*f));
+    if (fbucket_elem == fbucket_max) {
+	fprintf(stderr, "too many files?\n");
+	//TODO what?
+    }
+
+    fbucket[fbucket_elem++].ptr = f;
+
     memset(f,0,sizeof(*f));
     f->name = strdup(filename);
     list_add_tail(&f->list,&flist);
@@ -333,6 +351,43 @@
     }
 }
 
+static void flist_free_names(void)
+{
+	struct list_head *item;
+	struct flist *f;
+	list_for_each(item, &flist) {
+		f = list_entry(item, struct flist, list);
+		if (f->name) {
+		    free(f->name);
+		}
+		if (f->fimg) {
+			if (f->fimg->i.extra) {
+			    if (f->fimg->i.extra->data) {
+				fprintf(stderr, "extra was not freed, cleaned up now\n");
+				free(f->fimg->i.extra->data); 
+			    }
+			    free(f->fimg->i.extra);
+			}
+		    fprintf(stderr, "fimg was not freed, cleaned up now\n");
+		    free_image(f->fimg);
+		}
+		if (f->simg) {
+		    fprintf(stderr, "simg was not freed, cleaned up now\n");
+		    free_image(f->simg);
+		}
+	}
+}
+
+static void free_fbucket(void)
+{
+	while (fbucket_elem > 0) {
+	    void *ptr = fbucket[--fbucket_elem].ptr;
+	    if (ptr != NULL)
+		free(ptr);
+	}
+}
+
+
 /* ---------------------------------------------------------------------- */
 
 static void
@@ -689,11 +744,12 @@
 	    loader = &ppm_loader;
 	}
     }
-
+  
     /* load image */
     img = malloc(sizeof(*img));
     memset(img,0,sizeof(*img));
     data = loader->init(fp,filename,0,&img->i,0);
+    
     if (NULL == data) {
 	fprintf(stderr,"loading %s [%s] FAILED\n",filename,loader->name);
 	free_image(img);
@@ -707,6 +763,7 @@
 	loader->read(img->data + img->i.width * 3 * y, y, data);
     }
     loader->done(data);
+
     return img;
 }
 
@@ -1383,6 +1440,11 @@
     tty_restore();
     fb_cleanup();
     flist_print_tagged(stdout);
+    font_done();
+    flist_img_release_memory();
+    flist_free_names();
+    free_fbucket();
+    fbi_config_free();
     exit(code);
 }
 
@@ -1596,6 +1658,7 @@
 	    timeout = arg;
 	    break;
 	case KEY_VERBOSE:
+
 #if 0 /* fbdev testing/debugging hack */
 	    {
 		ioctl(fd,FBIOBLANK,1);
--- ./rd/read-jpeg.c	2006-06-13 14:35:48.000000000 +0100
+++ /home/user/fbi-2.07/./rd/read-jpeg.c	2012-01-16 21:47:40.000000000 +0000
@@ -185,6 +185,7 @@
 
     if (setjmp(h->errjump))
 	return;
+
     jpeg_destroy_decompress(&h->cinfo);
     if (h->infile)
 	fclose(h->infile);

Reply via email to