[dia] Fix (inlined) image related leaks
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] Fix (inlined) image related leaks
- Date: Thu, 2 Jan 2014 12:30:39 +0000 (UTC)
commit c0a2ad1cb354f7c25d691d74882765e9b6671e9d
Author: Hans Breuer <hans breuer org>
Date: Thu Jan 2 13:28:19 2014 +0100
Fix (inlined) image related leaks
- DiaImage::scaled was leaked
- undo information of dia_object_set_pixbuf() was not freed completely
- Standard - Image (_Image::pixbuf) was not properly reference counted
app/commands.c | 4 +++-
lib/dia_image.c | 5 +++++
lib/prop_pixbuf.c | 2 ++
objects/standard/image.c | 23 ++++++++++++++++-------
plug-ins/pdf/pdf-import.cpp | 27 ++++++++++++++++++---------
5 files changed, 44 insertions(+), 17 deletions(-)
---
diff --git a/app/commands.c b/app/commands.c
index 811aa71..99f2994 100644
--- a/app/commands.c
+++ b/app/commands.c
@@ -283,8 +283,10 @@ received_clipboard_image_handler(GtkClipboard *clipboard,
&handle1, &handle2)) != NULL)) {
/* as above, transfer the data */
change = dia_object_set_pixbuf (obj, pixbuf);
- if (change) /* ... but drop undo info */
+ if (change) { /* ... but drop undo info */
change->free (change);
+ g_free (change);
+ }
/* allow undo of the whole thing */
undo_insert_objects(dia, g_list_prepend(NULL, obj), 1);
diff --git a/lib/dia_image.c b/lib/dia_image.c
index 6bbb9a4..88598be 100644
--- a/lib/dia_image.c
+++ b/lib/dia_image.c
@@ -119,6 +119,11 @@ static void
dia_image_finalize(GObject* object)
{
DiaImage *image = DIA_IMAGE(object);
+#ifdef SCALING_CACHE
+ if (image->scaled)
+ g_object_unref (image->scaled);
+ image->scaled = NULL;
+#endif
if (image->image)
g_object_unref (image->image);
image->image = NULL;
diff --git a/lib/prop_pixbuf.c b/lib/prop_pixbuf.c
index 2402365..5a5e588 100644
--- a/lib/prop_pixbuf.c
+++ b/lib/prop_pixbuf.c
@@ -249,6 +249,8 @@ pixbufprop_set_from_offset(PixbufProperty *prop,
void *base, guint offset, guint offset2)
{
GdkPixbuf *dest = struct_member(base,offset,GdkPixbuf *);
+ if (dest == prop->pixbuf)
+ return;
if (dest)
g_object_unref (dest);
if (prop->pixbuf)
diff --git a/objects/standard/image.c b/objects/standard/image.c
index 715e919..a2d1851 100644
--- a/objects/standard/image.c
+++ b/objects/standard/image.c
@@ -66,7 +66,7 @@ struct _Image {
gchar *file;
gboolean inline_data;
- /* may contain the images pixbuf pointer */
+ /* may contain the images pixbuf pointer - if so: reference counted! */
GdkPixbuf *pixbuf;
gboolean draw_border;
@@ -184,8 +184,10 @@ static PropOffset image_offsets[] = {
static void
image_get_props(Image *image, GPtrArray *props)
{
- if (image->inline_data)
- image->pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image);
+ if (image->inline_data) {
+ if (image->pixbuf != dia_image_pixbuf (image->image))
+ image->pixbuf = (GdkPixbuf *)g_object_ref (dia_image_pixbuf (image->image));
+ }
object_get_props_from_offsets(&image->element.object, image_offsets, props);
}
@@ -210,7 +212,9 @@ image_set_props(Image *image, GPtrArray *props)
if (image->image)
g_object_unref (image->image);
image->image = dia_image_new_from_pixbuf (image->pixbuf ? image->pixbuf : pixbuf);
- image->pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image);
+ if (image->pixbuf)
+ g_object_unref (image->pixbuf);
+ image->pixbuf = (GdkPixbuf *)g_object_ref (dia_image_pixbuf (image->image));
if (pixbuf)
g_object_unref (pixbuf);
} else {
@@ -241,6 +245,7 @@ image_set_props(Image *image, GPtrArray *props)
image->image = dia_image_get_broken();
elem->height = (elem->width*(float)dia_image_height(image->image))/
(float)dia_image_width(image->image);
+ /* release image->pixbuf? */
}
g_free(old_file);
/* remember it */
@@ -526,13 +531,17 @@ image_create(Point *startpoint,
}
static void
-image_destroy(Image *image) {
+image_destroy(Image *image)
+{
if (image->file != NULL)
g_free(image->file);
if (image->image != NULL)
dia_image_unref(image->image);
+ if (image->pixbuf != NULL)
+ g_object_unref(image->pixbuf);
+
element_destroy(&image->element);
}
@@ -574,9 +583,9 @@ image_copy(Image *image)
* for every single undoable step */
newimage->inline_data = image->inline_data;
if (image->pixbuf)
- newimage->pixbuf = g_object_ref(image->pixbuf);
+ newimage->pixbuf = g_object_ref (dia_image_pixbuf(newimage->image));
else
- newimage->pixbuf = image->pixbuf;
+ newimage->pixbuf = image->pixbuf; /* Just say NULL */
newimage->mtime = image->mtime;
newimage->draw_border = image->draw_border;
diff --git a/plug-ins/pdf/pdf-import.cpp b/plug-ins/pdf/pdf-import.cpp
index e13a361..d8ca7d2 100644
--- a/plug-ins/pdf/pdf-import.cpp
+++ b/plug-ins/pdf/pdf-import.cpp
@@ -569,6 +569,7 @@ DiaOutputDev::applyStyle (DiaObject *obj, bool fill)
{
GPtrArray *plist = g_ptr_array_new ();
+
if (!fill) {
prop_list_add_line_width (plist, this->line_width);
prop_list_add_line_style (plist, this->line_style, this->dash_length);
@@ -603,7 +604,7 @@ DiaOutputDev::stroke (GfxState *state)
GfxPath *path = state->getPath();
bool haveClose = false;
- if (doPath (points, state, path, haveClose)) {
+ if (doPath (points, state, path, haveClose) && points->len > 1) {
if (path->getNumSubpaths() == 1) {
if (!haveClose)
obj = create_standard_bezierline (points->len, &g_array_index (points, BezPoint, 0), NULL, NULL);
@@ -628,18 +629,24 @@ DiaOutputDev::_fill (GfxState *state, bool winding)
GfxPath *path = state->getPath();
bool haveClose = true;
- if (doPath (points, state, path, haveClose)) {
+ if (doPath (points, state, path, haveClose) && points->len > 2) {
if (path->getNumSubpaths() == 1 && haveClose)
obj = create_standard_beziergon (points->len, &g_array_index (points, BezPoint, 0));
else
obj = create_standard_path (points->len, &g_array_index (points, BezPoint, 0));
applyStyle (obj, true);
- if (this->pattern)
- dia_object_set_pattern (obj, this->pattern);
+ if (this->pattern) {
+ ObjectChange *change = dia_object_set_pattern (obj, this->pattern);
+ if (change) {
+ change->free (change);
+ g_free (change);
+ }
+ }
}
g_array_free (points, TRUE);
if (obj) {
- dia_object_set_meta (obj, "fill-rule", winding ? "winding" : "even-odd");
+ // Useful for debugging but high performance penalty
+ // dia_object_set_meta (obj, "fill-rule", winding ? "winding" : "even-odd");
addObject (obj);
}
}
@@ -788,10 +795,12 @@ DiaOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
obj = create_standard_image (pos.x, pos.y,
ctm[0] * scale,
ctm[3] * scale, NULL);
- if ((change = dia_object_set_pixbuf (obj, pixbuf)) != NULL)
- change->free (change); /* reference transfered */
- else
- g_object_unref (pixbuf);
+ if ((change = dia_object_set_pixbuf (obj, pixbuf)) != NULL) {
+ change->free (change);
+ g_free (change);
+ }
+
+ g_object_unref (pixbuf);
addObject (obj);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]