From 9634d5ace164612ca1aad3ca9b13464985bd678b Mon Sep 17 00:00:00 2001
From: David Maciejak <david.maciejak@gmail.com>
Date: Mon, 31 Mar 2014 23:34:34 +0800
Subject: [PATCH] Added clean functions to wrlib

Some memory is never freed when leaving the lib.
---
 wrlib/context.c      | 11 +++++++++++
 wrlib/convert.c      | 27 ++++++++++++++++++++++++++-
 wrlib/libwraster.map |  1 +
 wrlib/load.c         | 17 +++++++++++++++++
 wrlib/wraster.h      |  7 +++++++
 5 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/wrlib/context.c b/wrlib/context.c
index b6794d0..04228ed 100644
--- a/wrlib/context.c
+++ b/wrlib/context.c
@@ -688,6 +688,17 @@ RContext *RCreateContext(Display * dpy, int screen_number, const RContextAttribu
 	return context;
 }
 
+void RDestroyContext(RContext * context)
+{
+	if (context) {
+		if (context && context->attribs)
+			free(context->attribs);
+		if (context && context->copy_gc)
+			XFreeGC(context->dpy, context->copy_gc);
+		free(context);
+	}
+}
+
 static Bool bestContext(Display * dpy, int screen_number, RContext * context)
 {
 	XVisualInfo *vinfo = NULL, rvinfo;
diff --git a/wrlib/convert.c b/wrlib/convert.c
index f3c9a49..867a3d8 100644
--- a/wrlib/convert.c
+++ b/wrlib/convert.c
@@ -62,6 +62,32 @@ typedef struct RStdConversionTable {
 static RConversionTable *conversionTable = NULL;
 static RStdConversionTable *stdConversionTable = NULL;
 
+static void release_conversion_table()
+{
+	RConversionTable *tmp = conversionTable;
+	while (tmp) {
+		RConversionTable *tmp_to_delete = tmp;
+		tmp = tmp->next;
+		free(tmp_to_delete);
+	}
+}
+
+static void release_std_conversion_table()
+{
+	RStdConversionTable *tmp = stdConversionTable;
+	while (tmp) {
+		RStdConversionTable *tmp_to_delete = tmp;
+		tmp = tmp->next;
+		free(tmp_to_delete);
+	}
+}
+
+void RDestroyConvertTables()
+{
+	release_conversion_table();
+	release_std_conversion_table();
+}
+
 static unsigned short *computeTable(unsigned short mask)
 {
 	RConversionTable *tmp = conversionTable;
@@ -356,7 +382,6 @@ static RXImage *image2TrueColor(RContext * ctx, RImage * image)
 		}
 
 	}
-
 	return ximg;
 }
 
diff --git a/wrlib/libwraster.map b/wrlib/libwraster.map
index 6e165ef..422af75 100644
--- a/wrlib/libwraster.map
+++ b/wrlib/libwraster.map
@@ -33,6 +33,7 @@ LIBWRASTER3
     RConvertImageMask;
     RCopyArea;
     RCreateContext;
+    RDestroyContext;
     RCreateImage;
     RCreateImageFromDrawable;
     RCreateImageFromXImage;
diff --git a/wrlib/load.c b/wrlib/load.c
index 8e0d34d..5e0e8cb 100644
--- a/wrlib/load.c
+++ b/wrlib/load.c
@@ -105,11 +105,28 @@ char **RSupportedFileFormats(void)
 	return tmp;
 }
 
+static void destroy_cache(void)
+{
+	if (RImageCacheSize > 0) {
+		for (int i = 0; i < RImageCacheSize; i++) {
+			if (RImageCache[i].file) {
+				free(RImageCache[i].file);
+				RImageCache[i].file = NULL;
+				RReleaseImage(RImageCache[i].image);
+			}
+
+		}
+		free(RImageCache);
+	}
+}
+
 /* cleaning third-party libs at shutdown */
 void RShutdown() {
 #ifdef USE_MAGICK
 	MagickWandTerminus();
 #endif
+	destroy_cache();
+	RDestroyConvertTables();
 }
 
 static void init_cache(void)
diff --git a/wrlib/wraster.h b/wrlib/wraster.h
index c4ed231..a87eb1c 100644
--- a/wrlib/wraster.h
+++ b/wrlib/wraster.h
@@ -461,11 +461,18 @@ void RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage,
                 int src_x, int src_y, int dest_x, int dest_y,
                 unsigned width, unsigned height);
 
+void RDestroyConvertTables();
+
 /* do not free the returned string! */
 const char *RMessageForError(int errorCode);
 
 int RBlurImage(RImage *image);
 
+
+#ifdef USE_MAGICK
+	extern void MagickWandTerminus();
+#endif
+
 /****** Global Variables *******/
 
 extern int RErrorCode;
-- 
1.8.3.2

