File 0006-tiff-WIP-Use-a-memory-pool-for-surface.patch of Package mingw32-evince

From 8b203e98a45ac6d8543d28ee421fef76209584d1 Mon Sep 17 00:00:00 2001
From: Hib Eris <hib@hiberis.nl>
Date: Fri, 15 Jul 2011 14:02:54 +0200
Subject: [PATCH 06/12] tiff: WIP Use a memory pool for surface

By reserving memory for rendering, we avoid out-of-memory failures
when rendering a second time.
This is a buggy work-around.
---
 backend/tiff/tiff-document.c |   69 ++++++++++++++++++++++++++++++++++++++---
 1 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/backend/tiff/tiff-document.c b/backend/tiff/tiff-document.c
index 8fda725..7e3cfe7 100644
--- a/backend/tiff/tiff-document.c
+++ b/backend/tiff/tiff-document.c
@@ -35,6 +35,65 @@
 #include "ev-document-print.h"
 #include "ev-file-helpers.h"
 
+static gpointer pool = NULL;
+static gsize poolsize = 0;
+static gboolean poolfree = TRUE;
+
+static gpointer
+try_malloc_from_pool (gsize n_bytes)
+{
+	if (!poolfree)
+		return NULL;
+
+	if (poolsize > n_bytes) {
+		poolfree = FALSE;
+		return pool;
+	}
+	
+	gpointer newpool = g_try_realloc (pool, n_bytes);
+	if (newpool != NULL) {
+		pool = newpool;
+		poolsize = n_bytes;
+		poolfree = FALSE;
+	}
+	return newpool;
+}
+
+static void
+free_from_pool (gpointer mem)
+{
+	poolfree = TRUE;
+}
+
+static int
+in_pool (gpointer mem)
+{
+	return (mem == pool);
+}
+
+static gpointer
+tiff_document_data_malloc (gsize n_bytes) {
+
+	gpointer mem;
+	mem = try_malloc_from_pool (n_bytes);
+
+	if (!mem)
+		mem = g_try_malloc (n_bytes);
+
+	return mem;
+}
+
+static void
+tiff_document_data_free (gpointer mem)
+{
+	if (in_pool (mem))
+		free_from_pool (mem);
+	else
+		g_free (mem);
+	
+	return;
+}
+
 struct _TiffDocumentClass
 {
   EvDocumentClass parent_class;
@@ -292,7 +351,7 @@ tiff_document_read_data (EvDocument *document,
 		return NULL;
 	}
 	
-	pixels = g_try_malloc (bytes);
+	pixels = tiff_document_data_malloc (bytes);
 	if (!pixels) {
 		g_warning("Failed to allocate memory for rendering.");
 		return NULL;
@@ -351,12 +410,12 @@ tiff_document_render (EvDocument      *document,
 						       width, height,
 						       rowstride);
 	if (!surface) {
-		g_free (pixels);
+		tiff_document_data_free (pixels);
 		g_warning("Failed to create surface for rendering.");
 		return NULL;
 	}
 	cairo_surface_set_user_data (surface, &key,
-				     pixels, (cairo_destroy_func_t)*g_free);
+				     pixels, (cairo_destroy_func_t)tiff_document_data_free);
 
 	rotated_surface = ev_document_misc_surface_rotate_and_scale (surface,
 								     (width * rc->scale) + 0.5,
@@ -560,12 +619,12 @@ tiff_document_print_print_page (EvDocumentPrint *document,
 						       width, height,
 						       rowstride);
 	if (!surface) {
-		g_free (pixels);
+		tiff_document_data_free (pixels);
 		g_warning("Failed to create image surface for printing.");
 		return;
 	}
 	cairo_surface_set_user_data (surface, &key,
-				     pixels, (cairo_destroy_func_t)*g_free);
+				     pixels, (cairo_destroy_func_t)tiff_document_data_free);
 
 	cairo_save (cr);
 	cairo_set_source_surface (cr, surface, 0, 0);
-- 
1.7.5.4

openSUSE Build Service is sponsored by