Re: pixbuf leakage

Espen S Johnsen <[email protected]> 30 Apr 2008 21:38:14 +0200
Newsgroups gmane.lisp.clg.devel
Message-ID <[email protected]>
"Walter C. Pelissero" <[email protected]> writes:

> The following code will leak memory but I couldn't quite find the hole.
> The larger the loaded pixbuf/image the faster.

I suspect this to be a memory leak in the library code for Pixbuf or
Gtk+, as the included C translation of your test code give the exact
same result. Someone with time to spare should definitely look more
closely into this...
 
> (gffi:defbinding (pixbuf-loader-write "gdk_pixbuf_loader_write") () boolean
>   (loader gdk:pixbuf-loader)
>   (buffer (vector (unsigned-byte 8)))
>   ((length buffer) integer)
>   (nil glib:gerror-signal :out))

Bindings to the Pixbuf loader are now in CVS. I just want point out that
using the vector type in bindings as above, is not very efficient. The
reason for this is that the vector has to be copied to foreign memory
before calling the foreign function and the destroyed afterwards. In
SBCL and CMUCL this could be avoided if the vector is unboxed, by just
passing a pointer to the vector data to the foreign function. This has
previously not been possible in clg, but I have now added a type called
UNBOXED-VECTOR which will do this.



#include <gtk/gtk.h>

GtkImage *image;

void size_prepared (GdkPixbufLoader *loader,
                     gint             width,
                     gint             height,
                     gpointer         user_data)
{
  gdk_pixbuf_loader_set_size (loader, 128, 64);
}

void area_prepared (GdkPixbufLoader *loader,
                    gpointer         user_data)
{
  gtk_image_set_from_pixbuf (image, gdk_pixbuf_loader_get_pixbuf (loader));
}

int main (int argc, char **argv)
{
  g_mem_set_vtable (glib_mem_profiler_table);
  g_type_init ();

  image = (GtkImage*)gtk_image_new ();
  g_object_set (G_OBJECT (image), "width-request", 128, "height-request", 64, NULL);

  g_mem_profile ();
  int i;
  for (i = 0; i < 100; i++) {  
    GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
    g_signal_connect (G_OBJECT (loader), "size-prepared", (GCallback)size_prepared, NULL);
    g_signal_connect (G_OBJECT (loader), "area-prepared", (GCallback)area_prepared, NULL);
    
    FILE *stream = fopen ("/home/espen/picture.jpg", "r");
    char buffer[4096];
    int n;

    do {
      n = fread (buffer, 1, 4096, stream);
      gdk_pixbuf_loader_write (loader, buffer, n, NULL);
    } while (n > 0);

    fclose (stream);
    gdk_pixbuf_loader_close (loader, NULL);
  }
  g_mem_profile ();
  return 0;  
}

-- 
Espen

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone