Imlib Programmers Guide

The Imlib Programmers Guide

What is Imlib?
Imlib is a general Image loading and rendering library designed to make the task of loading images, and obtaining X-Windows drawables a simple task, as well as a quick one. It also aims to provide simple manipulation routines that might be desired for common operations.

Why use Imlib?
Imlib is display depth independent. It will load images and work in 24 bit internally, dithering, re-mapping or whatever is needed to generate X drawables ready for use on the display by programs. It can also handle rescaling images to different sizes very quickly, is configurable to be "kind" to the colormap on 8-bit displays, generate transparencies, load more than one image format (in fact Imlib will load any image format), and handle intelligent caching for naive programs.

So what are its features?

- If compiled fully, Imlib can, without the help of any other applications, load PPM, PGM, TIFF, PNG, XPM, JPEG and EIM format images and preserve their transparency characteristics. If Imlib does not natively (native and foreign formats will be discussed later), Imlib can call upon a set of tools on the system to convert the image into a format Imlib can understand - thus widening its range of formats to any format that another utility supports. Currently Imlib supports both Imagemagick and the PBMPLUS utilities to do this. This loading is slower, but it means that Imlib does not refuse to load an image just because it does not know its format.
- Imlib has image caches that allow the programmer to write naive code. Images are loaded and cached. If an image is in the cache, it will not be loaded again, but merely referenced from the cache. This can make naive programs work surprisingly fast.
- Imlib can rescale an image to any size (limit 32767 x 32767 pixels). This means small icons can be expanded in size via Imlib, or large images reduced to small thumbnails with a single function call.
- Imlib has the ability to do gamma, brightness, contrast or arbitrary curve mapping of images to improve their visibility, or to modify their appearance. This allows for gamma correction, white-point correction and other advanced features all in software, without any need for this in hardware. It also allows the use of greyscale image templates to have their R, G and B channels modified via mapping tables to be colorized. This can allow for interfaces to use greyscale templates and let the user modify the color mapping for a color scheme.
- Imlib can do basic Image modifications (flip and rotate by 90 degrees), which may be desired.
- Imlib is highly optimized to give best results wherever possible at high speeds. It has many options to hike up its rendering speed depending on what your X Server and hardware setup can handle.
- Imlib handles many display depths. It will work on monochrome, 2, 3, 4 ,5 ,6 7, and 8 bit pseudocolor and static color displays. It also works in 15 bit, 16 bit (555 and 565) displays, and 24 bit displays. If the display is pseudocolor, Imlib will remap the image to a palette. Imlib has a config file - a system and a user one - the user one taking preference over the system config. In this The user, or system administrator defines a palette file for Imlib to use. This file is a list of red , green and blue values to be used as a color set for Imlib to map to in pseudocolor. This list can be as large, or as small as desired (from 2 to 256 entries). By default Imlib comes with a table of about 40 entries, specifically chosen to contain colors commonly used in images and displays, rather than the more simplistic colorcube approach. This file can be edited, with entries taken out or added as desired. Imlib by default will dither using this colorset, if in 8 bit or less. It does not allocate a private colormap, but merely takes what colors it can get and compensates for this. Dithering can be turned off if it is not desired, or if extra speed is needed. Imlib will also seamlessly handle 15, 16 and 24 bits (with an optional High Quality mode for 15 and 16 bpp where Imlib will even dither in these modes to make smooth gradients look perfectly smooth). The end result is that images look as best they can, and also preserve colormaps, in all bit depths.
- When re-rendering an image at different sizes, Imlib has an advanced pixmap cache that will re-use cached pixmaps if already rendered at that size, speeding up rendering for native programs by saving the extra rendering into a pixmap. Imlib has support for the MIT-SHM extension via shared images to speed up rendering. It also has support for the MIT-SHM shared pixmap extension, but is unable to practically use this due to some major design flaws in the shared pixmap extension. The support is there waiting for the day when this is fixed.
- Imlib has both Xlib and GDK versions that can be installed simultaneously, share the same config file, and so can be used in both the Xlib low level environment and the GDK level environment.

How do I start programming using Imlib?
I suppose the best way to help you start using Imlib, is a small sample program. Here are two - one using GDK, another using Xlib. (I will point out that Xlib is more powerful than GDK - unlike GDK, an Xlib program can run on multiple displays, and Imlib supports this - you just have to initialize Imlib per display you connect to).

The following program is a very simple image viewer. It accepts an image file as an option, then displays this image in a window. Control-C will quit the program. You can resize the window and the image will be resized with it. There are two versions - one for Xlib + Imlib, the other for GDK + GDK Imlib.

This program is written for Xlib. To compile: cc test.c -o test -I/usr/X11R6/include -I/usr/local/include -L/usr/X11R6/lib -L/usr/local/lib -lX11 -lXext -ljpeg -lpng -ltiff -lz -lgif -lm -lImlib
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
    #include <X11/extensions/shape.h>
    #include <Imlib.h>

    int main(int argc, char **argv)
      {
        Display *disp;
        ImlibData *id;
        XSetWindowAttributes attr;
        Window win;
        ImlibImage *im;
        Pixmap p,m;
        int w,h;

    /* Be nice and tell the user if they don't, to provide a file as an arg */
        if (argc<=1)
          {
            printf("Usage:\n %s image_file\n",argv[0]);
            exit(1);
          }
    /* Connect to the default Xserver */
       disp=XOpenDisplay(NULL);
    /* Immediately afterwards Intitialise Imlib */
       id=Imlib_init(disp);

    /* Load the image specified as the first argument */
       im=Imlib_load_image(id,argv[1]);
    /* Suck the image's original width and height out of the Image structure */
       w=im->rgb_width;h=im->rgb_height;
    /* Create a Window to display in */
       win=XCreateWindow(disp,DefaultRootWindow(disp),0,0,w,h,0,id->x.depth,
                         InputOutput,id->x.visual,0,&attr);
       XSelectInput(disp,win,StructureNotifyMask);
    /* Render the original 24-bit Image data into a pixmap of size w * h */
       Imlib_render(id,im,w,h);
    /* Extract the Image and mask pixmaps from the Image */
       p=Imlib_move_image(id,im);
    /* The mask will be 0 if the image has no transparency */
       m=Imlib_move_mask(id,im);
    /* Put the Image pixmap in the background of the window */
       XSetWindowBackgroundPixmap(disp,win,p);
    /* If there was a mask to the image, set the Image's mask to it */
       if (m) XShapeCombineMask(disp,win,ShapeBounding,0,0,m,ShapeSet);
    /* Actually display the window */
       XMapWindow(disp,win);
    /* Synchronise with the Xserver */
       XSync(disp,False);
    /* Event loop to handle resizes */
       for(;;)
         {
           XEvent ev;

    /* Sit and wait for an event to happen */
           XNextEvent(disp,&ev);
           if (ev.type==ConfigureNotify)
             {
               w=ev.xconfigure.width;h=ev.xconfigure.height;
    /* Re-render the Image to the new size */
               Imlib_render(id,im,w,h);
    /* Free the previous pixmap used for the window - note ONLY the pixmap is */
    /* freed - the mask is marked automatically to be freed along with the */
    /* pixmap. There is no need to free it as well - in fact it is advised you do */
    /* not. You must use the Imlib free function because of Imlib's caching. Do */
    /* not use any other free functions. You can use this function for Pixmaps */
    /* not created by Imlib - and it will just go free them as expected. */
               Imlib_free_pixmap(id,p);
               p=Imlib_move_image(id,im);
    /* The mask will be 0 if the image has no transparency */
               m=Imlib_move_mask(id,im);
    /* Put the Image pixmap in the background of the window */
               XSetWindowBackgroundPixmap(disp,win,p);
    /* If there was a mask to the image, set the Image's mask to it */
               if (m) XShapeCombineMask(disp,win,ShapeBounding,0,0,m,ShapeSet);
    /* Clear the window to update the background change */
               XClearWindow(disp,win);
    /* Synchronise with the Xserver */
               XSync(disp,False);
             }
         }
    }

This program is written for GDK. To compile: cc test.c -o test -I/usr/X11R6/include -I/usr/local/include -L/usr/X11R6/lib -L/usr/local/lib -lX11 -lXext -ljpeg -lpng -ltiff -lz -lgif -lglib -lgdk -lm -lgdk_imlib
    #include <gdk_imlib.h>
    #include <gdk/gdk.h>

    int main(int argc, char **argv)
      {
        GdkWindowAttr         attr;
        GdkWindow             *win;
        GdkPixmap             *p,*m;
        GdkImlibImage         *im;
        gint w,h;

    /* Be nice and tell the user if they don't, to provide a file as an arg */
        if (argc<=1)
          {
            printf("Usage:\n %s image_file\n",argv[0]);
            exit(1);
          }
    /* Inititalise GDK */
        gdk_init(&argc,&argv);
    /* Immediately after initialising GDK, Initialise Imlib */
        gdk_imlib_init();

    /* Get gdk to use imlib's visual and colormap */
       gtk_widget_push_visual(gdk_imlib_get_visual());
       gtk_widget_push_colormap(gdk_imlib_get_colormap());

    /* Load the image specified as the first argument */
        im=gdk_imlib_load_image(argv[1]);
    /* Suck[B the image's original width and height out of the Image structure */
        w=im->rgb_width;h=im->rgb_height;
    /* Set up attributes for GDK to create a Window */
        attr.window_type=GDK_WINDOW_TOPLEVEL;
        attr.wclass=GDK_INPUT_OUTPUT;
        attr.event_mask=GDK_STRUCTURE_MASK;
        attr.width=w;
        attr.height=h;
    /* Create a Window to display in */
        win=gdk_window_new(NULL,&attr,0);

    /* Render the original 24-bit Image data into a pixmap of size w * h */
        gdk_imlib_render(im,w,h);
    /* Extract the Image and mask pixmaps from the Image */
        p=gdk_imlib_move_image(im);
    /* The mask will be NULL if the image has no transparency */
        m=gdk_imlib_move_mask(im);
    /* Put the Image pixmap in the background of the window */
        gdk_window_set_back_pixmap(win,p,0);
    /* If there was a mask to the image, set the Image's mask to it */
        if (m) gdk_window_shape_combine_mask(win,m,0,0);
    /* Actually display the window */
        gdk_window_show(win);
    /* Flush the GDK buffer */
        gdk_flush();
    /* Event loop to handle resizes */
        for(;;)
          {
            GdkEvent *ev;

    /* Sit and wait for an event to happen */
            gdk_events_pending();
    /* Drag the event out of the Event queue */
            ev=gdk_event_get();
    /* If the event is a resize event */
    	if ((ev)&&(ev->type==GDK_CONFIGURE))
    	  {
     	    w=ev->configure.width;h=ev->configure.height;
                gdk_event_free(ev);
    /* Re-render the Image to the new size */
    	    gdk_imlib_render(im,w,h);
    /* Free the previous pixmap used for the window - note ONLY the pixmap is */
    /* freed - the mask is marked automatically to be freed along with the */
    /* pixmap. There is no need to free it as well - in fact it is advised you do */
    /* not. You must use the Imlib free function because of Imlib's caching. Do */
    /* not use any other free functions. You can use this function for Pixmaps */
    /* not created by Imlib - and it will just go free them as expected. */
    	    gdk_imlib_free_pixmap(p);
    /* Extract the pixmap out of the Image */
    	    p=gdk_imlib_move_image(im);
    /* The mask will be NULL if the image has no transparency */
                m=gdk_imlib_move_mask(im);
    /* Set the new pixmap background */
    	    gdk_window_set_back_pixmap(win,p,0);
    /* If there was a mask to the image, set the Image's mask to it */
                if (m) gdk_window_shape_combine_mask(win,m,0,0);
    /* Clear the window to update the background change */
    	    gdk_window_clear(win);
    /* Flush GDK's buffer */
    	    gdk_flush();
    	  }
          }
      }

We could now optimize these programs (which are longer than they need to be just as an exercise) to use Imlib a bit more. Note the Differences.

This program is written for Xlib. To compile: cc test.c -o test -I/usr/X11R6/include -I/usr/local/include -L/usr/X11R6/lib -L/usr/local/lib -lX11 -lXext -ljpeg -lpng -ltiff -lz -lgif -lm -lImlib
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
    #include <X11/extensions/shape.h>
    #include <Imlib.h>

    int main(int argc, char **argv)
      {
        Display *disp;
        ImlibData *id;
        XSetWindowAttributes attr;
        Window win;
        ImlibImage *im;
        Pixmap p,m;
        int w,h;

    /* Be nice and tell the user if they don't, to provide a file as an arg */
        if (argc<=1)
          {
            printf("Usage:\n %s image_file\n",argv[0]);
            exit(1);
          }
    /* Connect to the default Xserver */
       disp=XOpenDisplay(NULL);
    /* Immediately afterwards Intitialise Imlib */
       id=Imlib_init(disp);

    /* Load the image specified as the first argument */
       im=Imlib_load_image(id,argv[1]);
    /* Suck the image's original width and height out of the Image structure */
       w=im->rgb_width;h=im->rgb_height;
    /* Create a Window to display in */
       win=XCreateWindow(disp,DefaultRootWindow(disp),0,0,w,h,0,id->x.depth,
                         InputOutput,id->x.visual,0,&attr);
       XSelectInput(disp,win,StructureNotifyMask);
    /* Put the Image in the window, at the window's size and apply a shape mask */
    /* if applicable, or remove one if not */
       Imlib_apply_image(id,im,win);
    /* Actually display the window */
       XMapWindow(disp,win);
    /* Synchronise with the Xserver */
       XSync(disp,False);
    /* Event loop to handle resizes */
       for(;;)
         {
           XEvent ev;

    /* Sit and wait for an event to happen */
           XNextEvent(disp,&ev);
           if (ev.type==ConfigureNotify)
             {
    /* Put the Image in the window, at the window's size and apply a shape mask */
    /* if applicable, or remove one if not */
               Imlib_apply_image(id,im,win);
    /* Synchronise with the Xserver */
               XSync(disp,False);
             }
         }
    }

This program is written for GDK. To compile: cc test.c -o test -I/usr/X11R6/include -I/usr/local/include -L/usr/X11R6/lib -L/usr/local/lib -lX11 -lXext -ljpeg -lpng -ltiff -lz -lgif -lglib -lgdk -lm -lgdk_imlib
    #include <gdk_imlib.h>
    #include <gdk/gdk.h>

    int main(int argc, char **argv)
      {
        GdkWindowAttr         attr;
        GdkWindow             *win;
        GdkPixmap             *p,*m;
        GdkImlibImage         *im;
        gint w,h;

    /* Be nice and tell the user if they don't, to provide a file as an arg */
        if (argc<=1)
          {
            printf("Usage:\n %s image_file\n",argv[0]);
            exit(1);
          }
    /* Inititalise GDK */
        gdk_init(&argc,&argv);
    /* Immediately after initialising GDK, Initialise Imlib */
        gdk_imlib_init();

    /* Get gdk to use imlib's visual and colormap */
       gtk_widget_push_visual(gdk_imlib_get_visual());
       gtk_widget_push_colormap(gdk_imlib_get_colormap());

    /* Load the image specified as the first argument */
        im=gdk_imlib_load_image(argv[1]);
    /* Suck the image's original width and height out of the Image structure */
        w=im->rgb_width;h=im->rgb_height;
    /* Set up attributes for GDK to create a Window */
        attr.window_type=GDK_WINDOW_TOPLEVEL;
        attr.wclass=GDK_INPUT_OUTPUT;
        attr.event_mask=GDK_STRUCTURE_MASK;
        attr.width=w;
        attr.height=h;
    /* Create a Window to display in */
        win=gdk_window_new(NULL,&attr,0);

    /* Put the Image in the window, at the window's size and apply a shape mask */
    /* if applicable, or remove one if not */
       gdk_imlib_apply_image(im,win);
    /* Actually display the window */
        gdk_window_show(win);
    /* Flush the GDK buffer */
        gdk_flush();
    /* Event loop to handle resizes */
        for(;;)
          {
            GdkEvent *ev;

    /* Sit and wait for an event to happen */
            gdk_events_pending();
    /* Drag the event out of the Event queue */
            ev=gdk_event_get();
    /* If the event is a resize event */
    	if ((ev)&&(ev->type==GDK_CONFIGURE))
    	  {
    	    gdk_event_free(ev);
    /* Put the Image in the window, at the window's size and apply a shape mask */
    /* if applicable, or remove one if not */
                gdk_imlib_apply_image(im,win);
    /* Flush GDK's buffer */
    	    gdk_flush();
    	  }
          }
      }

> As a note for future code snippets:
> All data types beginning with Imlib are Xlib Imlib data types, those beginning with Gdk are GDK Imlib data types. All functions beginning with Imlib_ are Xlib Imlib functions and all functions beginning with gdk_ are GDK Imlib function calls. All calls perform the same functions and accept similar parameters - the differences are GDK and Xlib primitives, and the Xlib Imlib has an extra ImlibData parameter at the start of each function call. Examples of sibling data types and functions calls will be given together. Chose the appropriate one for your situation.

You will notice we saved a fair few commands - that I have found my code littered with all over the place, by using a function in Imlib that does this for you. It shows that you can have full control over your programs, if you desire, or let Imlib do it for you.

Imlib's concept of an image
Imlib has a certain concept of what an image is. It is designed to be fast, fairly general and powerful. For Imlib an image is:

- An image is a large chunk of 24-bit pixel data in RGBRGBRGB format.
- There is a second chunk of alpha channel data that matches the RGB chunk pixel for pixel, but currently is unused, provided for future expansion.
- An image contains an optional RGB value that tags all pixels with that value as being transparent. This is specifically designed around X's on or off transparency and clip mask operations.
- Images have a set of border pixels - if not set, the borders are all set to 0 pixels. The borders are a special set of pixels that are scaled slightly differently from the rest of the image when rendered to a pixmap.
- Images have attached map-tables that can either be explicitly set, or are generated from the image's Gamma, Brightness and Contrast settings (and the same settings per Red, Green and Blue channel). These settings and map-tables are inherited upon loading from the system settings (currently all normalized - will be added to the configuration file and init soon).

The data in the 24-bit representation of an image is a large block of unsigned char bytes. The image has a pointer to this data which is in the order from top-left pixel to bottom right, scanline by scanline. Each pixel is an RGB triplet, with the bytes in the order Red Green Blue, so the array looks something like RGBRGBRGBRGBRGBRGB...

If our image is:

    ImlibImage *im;
    GdkImlibImage *im;

The pointer to the RGB data and the alpha data would be:

    im->rgb_data;   /* pointer to unsigned char RGB data */
    im->alpha_data; /* pointer to unsigned char Alpha data */

The alpha data is currently unused and should be ignored - the pointer to it should be kept NULL.

The shape color is an RGB value for the pixel color that is to be considered transparent. This defines how Imlib renders the image and if it generates a mask pixmap on rendering. Certain image formats (GIF, TIFF, PNG, EIM and XPM) contain transparency information. This is inherited by Imlib, so there is no need to set the shape color. If it is not set, a program can set a shape color, or if it is not desired, it can be removed by setting the RGB values for the Shape Color to R,G,B -1,-1,-1.

The way to retrieve the shape color, examine it and set it is as follows. It is assumes images have been loaded, Imlib initialised etc. already:

    ImlibData *id;
    ImlibImage *im;
    ImlibColor color;
    int r,g,b;

    Imlib_get_image_shape(id,im,&color);
    r=color.r;
    g=color.g;
    b=color.b;
    color.r=100;
    color.g=50;
    color.b=255;
    Imlib_set_image_shape(id,im,&color);

    GdkImlibImage *im;
    GdkImlibColor color;
    int r,g,b;

    gdk_imlib_get_image_shape(im,&color);
    r=color.r;
    g=color.g;
    b=color.b;
    color.r=100;
    color.g=50;
    color.b=255;
    gdk_imlib_set_image_shape(im,&color);

The Border attribute is where the programmer or user gets to choose border scaling attributes. The border values define margins around the image that are not to be scaled in that direction (ie the top and bottom borders do not get scaled vertically but retain their pixel sizes). The best way to explain is with an example.

| Notice how this is the original image, with a hilighted bevel of 3 pixels on each side. This is the original and so, we want these borders to to remain 3 pixels wide when the image is scaled to a larger size. The original is 32x32 pixels.
| Here is an example of the image scaled to 80x40 pixels, when the borders are set to 0 pixels - notice how the bevels get scaled too, giving quite an un-aesthetic look? This is how a vanilla scaling algorithm would work.
| Now take a look at this third example scaled to the same size, but it has the border attributes set to 3 pixels for top, bottom, left and right borders. This time the image looks correct.
| Note with this diagram that the borders map out an inner and outer boxes with corner pieces, effectively dividing the Image into 9 segments. The borders need not be of the same width - as shown here, they can each be of a different size, allowing for shadows, and other effects that may exist in the image.

The image map-tables are a set of 3, 256 value lookup tables of unsigned char values. These are calculated form the image's brightness, gamma, and contrast settings for the image as a whole and each red, green and blue channel. You can set and get these values as follows:

    ImlibData *id;
    ImlibImage *im;
    ImlibColorModifier mod;
    double gamma,brightness,contrast;

    Imlib_get_image_modifier(id,im,&mod);
    gamma=(double)mod.gamma/256;
    brightness=(double)mod.brightness/256;
    contrast=(dobule)mod.contrast/256;
    Imlib_set_image_modifier(id,im,&mod);

    GdkImlibImage *im;
    GdkImlibColorModifier mod;
    double gamma,brightness,contrast;

    gdk_imlib_get_image_modifier(im,&mod);
    gamma=(double)mod.gamma/256;
    brightness=(double)mod.brightness/256;
    contrast=(double)mod.contrast/256;
    gdk_imlib_set_image_modifier(im,&mod);

Note that the contrast, brightness and gamma values are in fact int's. A value of 1.0 (unmodified verbatim data) is in fact 256, so to use a value of 0.5 for any of these, you would have to use a value of 128 etc.

When you set the modifiers, the map-tables (the curves) are re-calculated for that image. You have to re-render the image to gain a pixmap with these settings in effect.

There are also identical modifier settings for the red, green and blue channels, so these can be used for white point adjustment and other functions.

It is also possible to gain direct access to these map-table curves and set the values in them manually for finer control. There are 3 tables - one for red, one for green and one for blue. The functions Imlib_set_image_red_curve, Imlib_set_image_green_curve, Imlib_set_image_blue_curve, Imlib_get_image_red_curve, Imlib_get_image_green_curve, Imlib_get_image_blue_curve, gdk_imlib_set_image_red_curve, gdk_imlib_set_image_green_curve, gdk_imlib_set_image_blue_curve, gdk_imlib_get_image_red_curve, gdk_imlib_get_image_green_curve, and gdk_imlib_get_image_blue_curve will set and get these. You pass the pointer to an array of 256 unsigned char's as the last parameter in each of these functions to have Imlib fill that table's contents or use that table's contents.

By default the map-table is linear if the global gamma, brightness and contrast settings are all normal (ie at 256). This would produce a mapping table such as the one here on the left. There is a table per channel describing this mapping. If you want you could set the table per red, green and blue channel to perhaps something like the graph below, that would then give a more interesting mapping. The tables for each channel can be different, and so could be used for re-coloring images in interesting ways.

It is also possible to then use these mappings to in fact modify the original 24-bit data for the image - making the changes permanent, and thus not needing and of the modifiers. To do this you would call the Imlib_apply_modifiers_to_rgb or gdk_imlib_apply_modifiers_to_rgb functions.

If you need advanced manipulation of the 24-bit data (eg blurring, other convolutions etc.) you may do this to your heart's content. Just remember - before you render any pixmaps to call Imlib_changed_image or gdk_imlib_changed_image which will prevent Imlib's caching form not updating the pixmaps. This marks all pixmaps rendered off that image as being "dirty" and so they will never be referenced again by Imlib's caching. Once they are all freed and their reference counts are zero, they will be freed from memory.

Below is a list of All Imlib functions - the Xlib version fist, then the GDK version listed second. GDK Imlib functions do not use the ImlibData pointer at the start, and so this parameter, being common to ALL Xlib Imlib functions will not be mentioned, but it will be assumed you realise that it is required.

    ImlibData *Imlib_init(Display *disp);
    void gdk_imlib_init();

This function inititalised Imlib. It must be called early in the program BEFORE any other Imlib functions are called. You must call it AFTER you call XOpenDisplay or gdk_init. The Xlib version needs to have the display variable passed to it. The Xlib version is capable of running on multiple displays - you just init Imlib per display variable.

This function causes Imlib to investigate properties of your XServer - ie, is the shared memory extension available? - if so, use it. The depth(s) of the visual(s) and choosing the best visual, initializing the caches to be empty, load a default palette (if in 8bpp) and set up a dither matrix etc. the default palette file is defined in the system or users imrc file as PaletteFile which is simply a flat file of line delimited colors, each color being space separated hexadecimal values for red, green and blue. See the sample palette file provided with Imlib. You can also force Imlib's shared memory use off in the system or user's imrc files with the Mit-Shm option - shared pixmaps are available if this is turned on, but it is currently advised to turn shared pixmaps off due to Xserver design flaws. Some operating systems define maximum chunk sizes for shared memory blocks, and so Imlib can be told not to create images of greater than a certain size in bytes with the Shm_Max_Size option in the imrc file. Image and pixmap caches can be turned on or off and set to their sizes here as well.

    ImlibData *Imlib_init_with_params(Display *disp, ImlibInitParams *p);
    void gdk_imlib_init_params(GdkImlibInitParams *p);

This function inititalised Imlib, BUT allows the programmer to specify startup parameters that override the users or system imrc file. Use these options with cauthion, as it is assumed you know what you are doing.

The structure containing the parameters to giv Imlib is:

    typedef struct _ImlibInitParams
    {
       int   flags;
       int   visualid;
       char *palettefile;
       char  sharedmem;
       char  sharedpixmaps;
       char  paletteoverride;
       char  remap;
       char  fastrender;
       char  hiquality;
       char  dither;
       int   imagecachesize;
       int   pixmapcachesize;
    } ImlibInitParams;

    #define PARAMS_VISUALID        1<<0
    #define PARAMS_PALETTEFILE     1<<1
    #define PARAMS_SHAREDMEM       1<<2
    #define PARAMS_SHAREDPIXMAPS   1<<3
    #define PARAMS_PALETTEOVERRIDE 1<<4
    #define PARAMS_REMAP           1<<5
    #define PARAMS_FASTRENDER      1<<6
    #define PARAMS_HIQUALITY       1<<7
    #define PARAMS_DITHER          1<<8
    #define PARAMS_IMAGECACHESIZE  1<<9
    #define PARAMS_PIXMAPCACHESIZE 1<<10

with a simliar one for gdk (same members), and same defines for the flags.

You set the bits in the flags member with the appropriate defines (PARAMS_VISUALID | PARAMS_PALETTEFILE | PARAMS_SHAREDMEM etc.) which flag whihc members of the structure are actually relevant and should be used by Imlib in overriding the user/system defaults. If the flag bit is set, then that structure member is used. the members are as follows:

visualid: contains an int with the visualid to be used by Imlib.
palettefile: string containing the file for the palette file.
sharedmem: is 1 if you want shared memory used, otherwise 0.
sharedpixmaps: is 1 if you want shared pixmaps, otherwise 0.
paletteoverride: 1 if palette remapping is to be forced on, otherwise 0.
remap: 1 for fast remapping 0 for slower more accurate remapping.
fastrender: 1 for fast rendering, 0 for slightly slower rendering.
hiquality: 1 to turn dithering on in 15/16bpp, 0 otherwise.
dither: 1 to turn dithering on in 8bpp or less, otherwise 0.
imagecachesize: the size of the image cache to be used in bytes.
pixmapcachesize: the size of the pixmap cache to be used in bits.

Remember the member is ignored if the flags does not contain the bit set for that member - if the bit is set, then that member is used.

    int Imlib_get_render_type(ImlibData *id);
    gint gdk_imlib_get_render_type();

This function returns Imlib's current rendering mode. It will return one of:

RT_PLAIN_PALETTE
RT_PLAIN_PALETTE_FAST
RT_DITHER_PALETTE
RT_DITHER_PALETTE_FAST
RT_PLAIN_TRUECOL
RT_DITHER_TRUECOL

These modes determine how images will appear when rendered as pixmaps. The first 4 modes are for 8-bit displays only (though they can be used for higher bit displays after the loading of a palette - Imlib won't load a palette in higher display depths to save time). If you wish to use these lower modes in higher bit depths, you will need to call Imlib_load_colors or gdk_imlib_load_colors on a palette file. You can replace the default palette any time by first calling Imlib_free_colors or gdk_imlib_free_colors. The first 2 modes do not dither the images, and thus are faster. The fast versions used a quick 32x32x32 colorcube lookup to obtain a best color match - the other versions use a slightly more accurate color matching function, but are slower. Dithering gives much better results, but is slower. Dithering and Fast remapping are turned on or of in the users or system imrc file. See this file and its comments for details. You can ALSO override Imlib using truecolor renderers, and force it to use paletted dithered images in higher bit depths by turning these render types on, or turning PaletteOverride on in the system or user's imrc file.

RT_PLAIN_TRUECOL is used for all higher bit depths (Imlib won't allow this mode to be set if the depth is less than or equal to 8 bit). This s a fast renderer that provides high quality. RT_DITHER_TRUECOL is an even higher quality renderer that only has effect in 15 and 16 bit depths. It dithers in these modes to provide the highest quality images. This option is turned on by the HighQuality option in the user's or system imrc file.

    void Imlib_set_render_type(ImlibData *id, int rend_type);
    void gdk_imlib_set_render_type(gint rend_type);

This function sets the render type to rend_type which should be one of the above listed render types. This is optional and Imlib will default to settings provided by the user, system and Xserver. This is primarily here, in conjunction with Imlib_get_render_type or gdk_imlib_get_render_type to allow fine tweaking by applications of Imlib's rendering performance.

    int Imlib_load_colors(ImlibData *id, char *file);
    gint gdk_imlib_load_colors(char *file);

This function loads the named palette file (described in Imlib_init). It is advised to call Imlib_free_colors or gdk_imlib_free_colors first before calling this. There may be strange effects when changing palettes "on the fly" in 8-bit color. All pixmaps should be re-rendered to inherit this new palette.

    ImlibImage *Imlib_load_image(ImlibData *id, char *file);
    GdkImlibImage *gdk_imlib_load_image(char *file);

This function loads the named file and returns a pointer to an image structure. Imlib will first check to see if the file has magic numbers defining it as a file Imlib can natively read - and then attempt to read it. If Imlib doesn't recognise the magic numbers, or certain native loaders have not been compiled in, it will fall back to asking Imagemagick's convert utility to convert the image into a PPM format image for Imlib to read in. If this doesn't work, Imlib will call on the NETPBM utilities to convert the image to a PPM for Imlib to read. If this fails, Imlib gives up and returns NULL. Imlib does not create any temporary files in this process.

Imlib can, if all native loaders are compiled in, read JPEG, GIF, PPM, PGM, XPM, PNG, TIFF and EIM image formats. GIF, PNG, XPM, TIFF and EIM images all retain their transparency information when being loaded.

    int Imlib_best_color_match(ImlibData *id, int *r, int *g, int *b);
    gint gdk_imlib_best_color_match(gint *r, gint *g, gint *b);

If the render type is a truecolor one, Imlib returns a pixel value that is the closest match to the requested RGB value (RGB each being in the range of 0-255). This will normally be very close. If using a palette render type, Imlib returns the closest match to the allocated palette and the rgb members are set to the actual RGB value of the color returned, The function always returns the pixel value of this color.

    int Imlib_render(ImlibData *id, ImlibImage *image, int width, int height);
    gint gdk_imlib_render(GdkImlibImage *image, gint width, gint height);

This will render the image pointed to by image into a pixmap of the defined width and height. If the image contains transparency, a mask will also be rendered. These can be extracted form the image using the functions below. If any pixmaps were already existant in the image, these are destroyed upon re-rendering the image. If Imlib was unable for some reason to render the Image to that pixmap, it will return 0, otherwise it will return 1.

    Pixmap Imlib_copy_image(ImlibData *id, ImlibImage *image);
    GdkPixmap *gdk_imlib_copy_image(GdkImlibImage *image);

This routine returns a copy of the image pixmap. You should use this routine if you wish to modify the pixmap itself afterwards by doing any drawing on it. Do NOT use the move functions for pixmap that will be modified later. You can make multiple copies of the pixmap by calling this function repeatedly. If no pixmap was rendered it will return 0 or NULL.

    Pixmap Imlib_copy_mask(ImlibData *id, ImlibImage *image);
    GdkBitmap *gdk_imlib_copy_mask(GdkImlibImage *image);

This is the Imlib_copy_image or gdk_imlib_copy_image functions, but it returns the mask for the image. If there is no transparency, or no mask was rendered, it returns 0, or NULL.

    Pixmap Imlib_move_image(ImlibData *id, ImlibImage *image);
    GdkPixmap *gdk_imlib_move_image(GdkImlibImage *image);

This returns the rendered pixmap from the image structure, and removes the image pixmap (setting it to 0 or NULL) inside the image structure. If you do not need to modify the pixmap - ie just use it, this is the function you should call. It is faster than Imlib_copy_image or gdk_imlib_copy_image.

    Pixmap Imlib_move_mask(ImlibData *id, ImlibImage *image);
    GdkBitmap *gdk_imlib_move_mask(GdkImlibImage *image);

This is the same as Imlib_move_image or gdk_imlib_move_image but returns the mask for the rendered Image.

    void Imlib_destroy_image(ImlibData *id, ImlibImage *image);
    void gdk_imlib_destroy_image(GdkImlibImage *image);

This destroys the Image structure, making it invalid. It reduces the reference count on that image and if at zero, it enters the cache. Once the cache fills and this image gets to the oldest part of the cache, it will be freed when the cache exceeds its boundaries.

    void Imlib_kill_image(ImlibData *id, ImlibImage *image);
    void gdk_imlib_kill_image(GdkImlibImage *image);

This does the same as Imlib_destroy_image or gdk_imlib_destroy_image but forces it to be freed immediately once its reference count hits zero - ie it does not hang around in the cache.

    void Imlib_free_colors(ImlibData *id);
    void gdk_imlib_free_colors();

This frees the current colormap used by Imlib and all the colors in it, setting the color count to zero. It is not a good idea to go rendering anything in an 8-bit display if the colors are freed.

    void Imlib_free_pixmap(ImlibData *id, Pixmap pixmap);
    void gdk_imlib_free_pixmap(GdkPixmap *pixmap);

This frees the pixmap pointed to - reducing its reference count by 1. If the count is zero it enters the cache and once the cache is filled and the pixmap is too old, it is freed. You must use this function for ALL pixmaps generated by Imlib. You may use it on Pixmaps not generated by Imlib and it will free them as normal. This function ALSO frees (or reduces the reference count) on the associated mask pixmap for that image pixmap, if there is a mask, so you do not need to free the mask separately.

    void Imlib_get_image_border(ImlibData *id, ImlibImage *image, ImlibBorder *border);
    void gdk_imlib_get_image_border(GdkImlibImage *image, GdkImlibBorder *border);

This function returns the image's border attributes in the border structure.

    void Imlib_set_image_border(ImlibData *id, ImlibImage *image, ImlibBorder *border);
    void gdk_imlib_set_image_border(GdkImlibImage *image, GdkImlibBorder *border);

This function sets the image's border attributes to those in the border structure.

    void Imlib_get_image_shape(ImlibData *id, ImlibImage *image, ImlibColor *color);
    void gdk_imlib_get_image_shape(GdkImlibImage *image, GdkImlibColor *color);

This function returns the color of the transparent color in an image - if there is no transparent color the RGB members are all set to -1, otherwise they are set to the RGB value of this color.

    void Imlib_set_image_shape(ImlibData *id, ImlibImage *image, ImlibColor *color);
    void gdk_imlib_set_image_shape(GdkImlibImage *image, GdkImlibColor *color);

This function sets the transparent color to the RGB values in the color structure. If any of these are -1, transparency for that image is turned off.

    int Imlib_save_image_to_eim(ImlibData *id, ImlibImage *image, char *file);
    gint gdk_imlib_save_image_to_eim(GdkImlibImage *image, char *file);

This Function saves the image into an EIM format image. EIM image format is currently under construction. Please come back later.

    int Imlib_add_image_to_eim(ImlibData *id, ImlibImage *image, char *file);
    gint gdk_imlib_add_image_to_eim(GdkImlibImage *image, char *file);

This Function adds the image into an EIM file that currently exists. EIM image format is currently under construction. Please come back later.

    int Imlib_save_image_to_ppm(ImlibData *id, ImlibImage *image, char *file);
    gint gdk_imlib_save_image_to_ppm(GdkImlibImage *image, char *file);

This function saves the current image as a binary format PPM file. If it is successful, it returns 1, otherwise it returns 0.

    int Imlib_load_file_to_pixmap(ImlibData *id, char *filename, Pixmap *pmap, Pixmap *mask);
    gint gdk_imlib_load_file_to_pixmap(char *filename, GdkPixmap **pmap, GdkBitmap **mask);

This is a macro function that does the following. It loads the named image file, and sets the pmap and mask variables to the image pixmap and mask pixmaps that are rendered at the image's original size. It returns 1 if successful and 0 if the load and render do not succeed. It frees the image after loading. The pixmaps should be freed by Imlib_free_pixmap or gdk_imlib_free_pixmap. This is a nigh identical replacement for XpmReadFileToPixmap or gdk_pixmap_create_from_xpm.

    void Imlib_set_image_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
    void gdk_imlib_set_image_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);

This function sets the image's brightness, contrast and gamma settings to those defined in the mod structure. You need to re-render the image to make this have any effect.

    void Imlib_set_image_red_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
    void gdk_imlib_set_image_red_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);

This function sets the image's red channel brightness, contrast and gamma settings to those defined in the mod structure. You need to re-render the image to make this have any effect.

    void Imlib_set_image_green_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
    void gdk_imlib_set_image_green_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);

This function sets the image's green channel brightness, contrast and gamma settings to those defined in the mod structure. You need to re-render the image to make this have any effect.

    void Imlib_set_image_blue_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
    void gdk_imlib_set_image_blue_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);

This function sets the image's blue channel brightness, contrast and gamma settings to those defined in the mod structure. You need to re-render the image to make this have any effect.

    void Imlib_get_image_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
    void gdk_imlib_get_image_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);

This function returns the image's current modifier settings in the mod structure.

    void Imlib_get_image_red_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
    void gdk_imlib_get_image_red_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);

This function returns the image's red channel modifier settings in the mod structure.

    void Imlib_get_image_green_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
    void gdk_imlib_get_image_green_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);

This function returns the image's green channel modifier settings in the mod structure.

    void Imlib_get_image_blue_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
    void gdk_imlib_get_image_blue_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);

This function returns the image's blue channel modifier settings in the mod structure.

    void Imlib_set_image_red_curve(ImlibData *id, ImlibImage *im, unsigned char *mod);
    void gdk_imlib_set_image_red_curve(GdkImlibImage *im, unsigned char *mod);

This function sets the mapping table curve for the red channel to the contents of the array pointer to by mod, which is a 256 element array of unsigned char values that map newvalue=mod[value]. This overrides the current modifier table generated by any gamma, brightness or contrast settings.

    void Imlib_set_image_green_curve(ImlibData *id, ImlibImage *im, unsigned char *mod);
    void gdk_imlib_set_image_green_curve(GdkImlibImage *im, unsigned char *mod);

This function sets the mapping table curve for the green channel to the contents of the array pointer to by mod, which is a 256 element array of unsigned char values that map newvalue=mod[value]. This overrides the current modifier table generated by any gamma, brightness or contrast settings.

    void Imlib_set_image_blue_curve(ImlibData *id, ImlibImage *im, unsigned char *mod);
    void gdk_imlib_set_image_blue_curve(GdkImlibImage *im, unsigned char *mod);

This function sets the mapping table curve for the blue channel to the contents of the array pointer to by mod, which is a 256 element array of unsigned char values that map newvalue=mod[value]. This overrides the current modifier table generated by any gamma, brightness or contrast settings.

    void Imlib_get_image_red_curve(ImlibData *id, ImlibImage *im, unsigned char *mod);
    void gdk_imlib_set_image_red_curve(GdkImlibImage *im, unsigned char *mod);

This function returns the current red channel mapping table curve by copying its contents into the 256 element array of unsigned char's pointed to by mod.

    void Imlib_get_image_green_curve(ImlibData *id, ImlibImage *im, unsigned char *mod);
    void gdk_imlib_get_image_green_curve(GdkImlibImage *im, unsigned char *mod);

This function returns the current green channel mapping table curve by copying its contents into the 256 element array of unsigned char's pointed to by mod.

    void Imlib_get_image_blue_curve(ImlibData *id, ImlibImage *im, unsigned char *mod);
    void gdk_imlib_get_image_blue_curve(GdkImlibImage *im, unsigned char *mod);

This function returns the current blue channel mapping table curve by copying its contents into the 256 element array of unsigned char's pointed to by mod.

    void Imlib_apply_modifiers_to_rgb(ImlibData *id, ImlibImage *im);
    void gdk_imlib_apply_modifiers_to_rgb(GdkImlibImage *im);

This function takes all the current RGB mapping tables and modifies the original 24-bit RGB data to match. This dirties all cached pixmaps of that image, and you will need to re-render the image for it to take any effect.

    void Imlib_changed_image(ImlibData *id, ImlibImage *im);
    void gdk_imlib_changed_image(GdkImlibImage *im);

If you go and modify the image's RGB data yourself via your own routines, once finished and before rendering any more pixmaps, you should call this function to inform Imlib that the contents of the image have changed.

    void Imlib_apply_image(ImlibData *id, ImlibImage *im, Window p);
    void gdk_imlib_apply_image(GdkImlibImage *im, GdkWindow *p);

This function takes an image, renders it at the size of the window specified as p, sets the window's background pixmap to be this rendered pixmap, and sets the window's shape mask to the the mask for the image if it has any transparency. It frees both pixmaps after use.

    void Imlib_paste_image(ImlibData *id, ImlibImage *im, Window p, int x, int y, int w, int h);
    void gdk_imlib_paste_image(GdkImlibImage *im, GdkWindow *p, gint x, gint y, gint w, gint h);

This pastes a pixmap of the image at the x,y co-ordinates in the drawable p (which can be either a window or a pixmap), and uses the shape mask to determine which pixels are actually drawn. It is effectively like pasting the image at that size at that location. Both the pixmap and the mask are freed afterwards.

    void Imlib_paste_image_border(ImlibData *id, ImlibImage *im, Window p, int x, int y, int w, int h);
    void gdk_imlib_paste_image_border(GdkImlibImage *im, GdkWindow *p, gint x, gint y, gint w, gint h);

This function works just like Imlib_paste_image or gdk_imlib_paste_image, but only pastes the borders of the image. This is handy if the image is being used to define bevel borders on a button for maximum efficiency.

    void Imlib_flip_image_horizontal(ImlibData *id, ImlibImage *im);
    void gdk_imlib_flip_image_horizontal(GdkImlibImage *im);

This flips the RGB data in an image horizontally. You need to re-render the image for it to take effect.

    void Imlib_flip_image_vertical(ImlibData *id, ImlibImage *im);
    void gdk_imlib_flip_image_vertical(GdkImlibImage *im);

This flips the RGB data in an image vertically. You need to re-render the image for it to take effect.

    void Imlib_rotate_image(ImlibData *id, ImlibImage *im, int d);
    void gdk_imlib_rotate_image(GdkImlibImage *im, gint d);

This function currently is a bit of a misnomer. It does not use the d parameter - it merely mirrors the image about a diagonal line going from the top-left to the bottom right at 45 degrees. It effectively rotates the image, combined with flips horizontally and vertically this can be used to give the image any orientation in steps of 90 degrees. This function needs some work (it must use the d parameter to work out which way to rotate and how much - 1 rotates clockwise, -1 counter-clockwise by 90 degrees, 2 or -2 180 degrees etc.)

    ImlibImage *Imlib_create_image_from_data(ImlibData *id, unsigned char *data, unsigned char *alpha, int w, int h);
    GdkImlibImage *gdk_imlib_create_image_from_data(unsigned char *data, unsigned char *alpha, gint w, gint h);

This function take a pointer to 24-bit RGB data (in the format RGBRGBRGB) and creates an image of size w x h out of it that can then be used by Imlib's routines for rendering. The pointer to the alpha data is currently unused and is there for future use. If successful it returns a pointer to the image, or NULL of unsuccessful. The data pointed to is copied into the image. This means you may free or destroy this original data or do with it as you see fit without affecting Imlib's image.

    ImlibImage *Imlib_clone_image(ImlibData *id, ImlibImage *im);
    GdkImlibImage *gdk_imlib_clone_image(GdkImlibImage *im);

This function makes a duplicate copy of the image pointed to. If unsuccessful it returns NULL, otherwise it returns a pointer to the new image.

    ImlibImage *Imlib_clone_scaled_image(ImlibData *id, ImlibImage *im, int w, int h);
    GdkImlibImage *gdk_imlib_clone_scaled_image(GdkImlibImage *im, int w, int h);

This Function creates a duplicate image scaled to the size w x h of the image pointed to - the 24-bit data is what is scaled. If successful it returns a pointer to the new image or NULL if not.

    int Imlib_get_fallback(ImlibData *id);
    gint gdk_imlib_get_fallback();

This function gets the status of ImageMagick and NETPBM fallback mechanisms. 1 means they are active, 0 means they are not.

    void Imlib_set_fallback(ImlibData *id, int fallback);
    void gdk_imlib_set_fallback(gint fallback);

This function sets the state of the ImageMagick and NETPBM fallback mechanisms. 1 makes them active, 0 deactivates them.

    Visual *Imlib_get_visual(ImlibData *id);
    GdkVisual *gdk_imlib_get_visual();

This function returns the Visual that Imlib has decided to use (accoridng to imrc and XServer capabilities).

    Colormap Imlib_get_colormap(ImlibData *id);
    GdkColormap *gdk_imlib_get_colormap();

This function returns the Colormap that Imlib has chosen to use for its visual.

    char *Imlib_get_sysconfig(ImlibData *id);
    gchar *gdk_imlib_get_sysconfig();

This function returns a pointer to a copy of the path to the system imrc file. When finished you should free this string.

    ImlibImage *Imlib_create_image_from_xpm_data(ImlibData *id, char **data);
    GdkImlibImage *gdk_imlib_create_image_from_xpm_data(char **data);

This function creates an Imlib image out of an inlined XPM image (ie. #include "file.xpm"). data is the pointer to the XPM data.

    gint gdk_imlib_data_to_pixmap(char **data, GdkPixmap **pmap, GdkBitmap **mask);
    int Imlib_data_to_pixmap(ImlibData *id, char **data, Pixmap *pmap, Pixmap *mask);

This function creates a pixmap (and optionally a mask) out of the data pointed to by data. This data is in the form of an XPM file that has been included into the source (eg #include "file.xpm"). If the XPM data has no transparency the mask is set to 0 or NULL. The pmap is set to the pixmap created. If the operation fails 0 is returned, otherwise 1 is returned.

    void gdk_imlib_crop_image(GdkImlibImage *im, gint x, gint y, gint w, gint h);
    void Imlib_crop_image(ImlibData *id, ImlibImage *im, int x, int y, int w, int h);

When called, this function will crop out the section of the 24-bit original image specified by the rectangle with its top-left corner at (x,y) and with width w and height h in pixels. These pixels are pixels in the original 24-bit data held in the image structure, not a scaled down or up rendered version.

    GdkImlibImage *gdk_imlib_crop_and_clone_image(GdkImlibImage *im, gint x, gint y, gint w, gint h);
    ImlibImage *Imlib_crop_and_clone_image(ImlibData *id, ImlibImage *im, int x, int y, int w, int h);

When called, this function will crop out the section of the 24-bit original image specified by the rectangle with its top-left corner at (x,y) and with width w and height h in pixels. These pixels are pixels in the original 24-bit data held in the image structure, not a scaled down or up rendered version. Instead of modifying the original, it makes a copy of the Image and returns that. NULL is returned if the crop fails.

    void gdk_imlib_best_color_get(GdkColor *c);

This is a gdk_imlib only API call, as much of GTK and GDK pass GdkColor structs around, and so Imlbi will fill the pixel value of the GdkColro and set the red, green and blue members to a member form Imlib's palette (unless it is in 15bpp or higher and palette remapping sin't forced), thus conserving colors wherever possible. In truecolor and higher it will give exact matches.

    gint gdk_imlib_save_image(GdkImlibImage *im, char *file, GdkImlibSaveInfo *info);
    int Imlib_save_image(ImlibData *id, ImlibImage *im, char *file, ImlibSaveInfo *info);

This function is for those who want brain-dead saving in a single function. It will save the image pointed to as the file passed. The extension is used to determine filetype to save as, so saving as image.jpg will save as a jpeg, or saving as file.png will save as a png file etc. The info pointer can be NULL, in which case the image will be saved with certain settings if the format supports it. for example a jpeg image will always be saved at 80% quality unless you provide a pointer to this structre and set the quality member to a value from 0 to 256, 256 being 100% quality, 0 being 0% quality. Only jpeg images use this member. The other members of the info structure are used for postscript saving, so if you plan to output as a postscript, file set the members in the structure. The scaling member is a value, with 1024 meaning "scale the image to maximum size on paper", 512 meaning "half the paper size" and 0 meaning zero size. you can use larger values, but the image will be clipped to the border of your paper. The color member is either 0 or 1 - 1 meaning save as color, 0 meaning save as grayscale. the x and yjustification members specify a justification in the x and y directions (on paper relative to the bottom-left of the page) - 1024 meaning right or top justify, 0 meaning left or bottom justify. Using values inbetween (like 512,512) will give center justification or many variations inbetween.

The page_size member can be one of PAGE_SIZE_EXECUTIVE, PAGE_SIZE_LETTER, PAGE_SIZE_LEGAL, PAGE_SIZE_A4, PAGE_SIZE_A3, PAGE_SIZE_A5, or PAGE_SIZE_FOLIO. This specifies the page size for the postscript output.

    GdkImlibImage *gdk_imlib_create_image_from_drawable(GdkWindow *gwin, GdkBitmap *gmask, int x, int y, int width, int height);
    ImlibImage *Imlib_create_image_from_drawable(ImlibData *id, Drawable win, Pixmap mask, int x, int y, int width, int height);

These functions create an Imlib Image out of an X drawable. The Drawable (win or gwin) is either a pixmap or a window. The mask is a mask pixmap (optional for creating the mask for the image - currently unused - reserved for future use). X, y, width and height describe a rectangle inside the drawable (x, and y being relative to the drawable's top-left corner). This function, if successful will return a pointer to an image (NOTE to advanced programmers - this function internally performs server grabs - it means if you had a grab before this function you will no longer have it afterwards. This is necessary to avoid race conditions that could kill your client).

Here are some data types that you may be interested in (note I have only listed the structure members that you should view or play with. It is not advisable to play with any structure members, but inspecting them is fine).

    typedef struct _ImlibBorder
    {
       int left,right;
       int top,bottom;
    } ImlibBorder;

    typedef struct _GdkImlibBorder
    {
       gint left,right;
       gint top,bottom;
    } GdkImlibBorder;

This is the structure containing the border pixel settings in pixels from their respective sides. Normally all images have borders of 0,0,0,0.

    typedef struct _ImlibColor
    {
       int r,g,b;
    } ImlibColor;

    typedef struct _GdkImlibColor
    {
       gint r,g,b;
    } GdkImlibColor;

The r,g and b members are ints in the range 0 - 255. If any value is -1, and this is used to set or get that shape color, the shape color is either off, or will be turned off.

    typedef struct _ImlibColorModifier
    {
       int gamma;
       int brightness;
       int contrast;
    } ImlibColorModifier;

    typedef struct _GdkImlibColorModifier
    {
       gint gamma;
       gint brightness;
       gint contrast;
    } GdkImlibColorModifier;

The members of this structure are fairly self-evident. They are integers, with 256 being taken as a value of 1.0. Multiply your gamma, brightness and contrast values by 256 to get a value to put in these structures.

    typedef struct _ImlibImage
    {
       int                   rgb_width,rgb_height;
       unsigned char         *rgb_data;
       unsigned char         *alpha_data;
       char                  *filename;
    } ImlibImage;

    typedef struct _GdkImlibImage
    {
       gint                  rgb_width,rgb_height;
       unsigned char         *rgb_data;
       unsigned char         *alpha_data;
       gchar                 *filename;
    } GdkImlibImage;

These are the image data structures. You may read all these data members, and you may edit the data that rgb_data and alpha_data point to. Remember that if you modify this data to call Imlib_apply_modifiers_to_rgb or gdk_imlib_apply_modifiers_to_rgb to dirty the pixmaps in the cache. You may not free this data or change the pointer. Currently the alpha_data member is unused and will remain NULL. Setting it to anything else may produce unexpected results.

    typedef struct _ImlibSaveInfo
    {
       int quality;
       int scaling;
       int xjustification;
       int yjustification;
       int page_size;
       char color;
    } ImlibSaveInfo;

    typedef struct _GdkImlibSaveInfo
    {
       int quality;
       int scaling;
       int xjustification;
       int yjustification;
       int page_size;
       char color;
    } GdkImlibSaveInfo;

These are the ImlibSaveInfo data structs - they may be expanded in future. Their use is described above in the imlib_save_image function.

    typedef struct _ImlibData
    {
       struct _xdata
       {
          Display         *disp;
          int             screen;
          Window          root;
          Visual          *visual;
          int             depth;
       } x;
    } ImlibData;

This data structure is not visible in the GDK version of Imlib. It is expected for the Xlib version, that all applications that will place pixmaps in their windows, create those windows with the depth and visual in Imlib's ImlibData - Imlib hunts and chooses the best quality visual on the Xserver for its rendering. If you do not use this visual and depth the results are implementation dependent - ie, may vary between Xservers.