Differences between Imlib and gdk-pixbuf

Generally, applications that use Imlib do not have to be changed extensively to use gdk-pixbuf; its simple and flexible API makes things easy. This section describes the differences between Imlib and gdk-pixbuf; you should take these into account when modifying your applications to use gdk-pixbuf.

Initialization

The gdk-pixbuf library does not need to be initialized.

Note

In GNOME applications you normally don't need to initialize Imlib, as gnome_init() calls gdk_imlib_init() automatically.

Memory management

The gdk-pixbuf library provides a simple, well-defined memory management mechanism for images in the form of reference counting. This makes it very convenient to use for large-scale applications that need to share images between different parts of the program. In stark contrast, Imlib has a terribly complex mechanism of an image and pixmap cache which makes it very hard for applications to share image structures between different parts of the program. Unfortunately this mechanism makes things very prone to memory leaks and tricky bugs.

The basic principle in gdk-pixbuf is that when you obtain a new GdkPixbuf structure, it is created with an initial reference count of 1. When another part of the program wants to keep a reference to the pixbuf, it should call g_object_ref(); this will increase the reference count by 1. When some part of the program does not need to keep a reference to a pixbuf anymore and wants to release the pixbuf, it should call g_object_unref(); this will decrease the reference count by 1. When the reference count drops to zero, the pixbuf gets destroyed or finalized and its memory is freed.

For applications that need to implement a cache of loaded images, gdk-pixbuf provides a way to hook to the last unreference operation of a pixbuf; instead of finalizing the pixbuf, the user-installed hook can decide to keep it around in a cache instead.

Finally, gdk-pixbuf does not provide a cache of rendered pixmaps. This is unnecessary for most applications, since the scaling and rendering functions are quite fast and applications may need to use subtly different values each time they call these functions, for example, to take into account dithering and zooming offsets.

Most applications will simply need to call g_object_ref() when they want to keep an extra reference to a pixbuf, and then g_object_unref() when they are done with it.

The Rendering Process

The gdk-pixbuf library has the policy of always rendering pixbufs to GDK drawables you provide; it will not create them for you. This is in general more flexible than Imlib's policy of always creating a pixmap and making you use that instead.

The disadvantage of always having a pixmap created for you is that it wastes memory in the X server if you intend to copy that rendered data onto another drawable, for example, the final destination window or a temporary pixmap for drawing. This is the most common case, unfortunately, so the Imlib policy introduces unnecessary copying.

Also, Imlib can only render pixmaps that are the whole size of the source image; you cannot render just a subset region of the image. This is inconvenient for applications that need to render small portions at a time, such as applications that do scrolling. Since the whole image must be rendered at a time, this can lead to performance and memory usage problems.

The gdk-pixbuf library lets you render any rectangular region from an image onto any drawable that you provide. This lets the application have fine control the way images are rendered.