<html>
<head><title>
Imlib Programmers Guide
</title></head>
<body
background=bg.gif
bgcolor=#c0c0b0
text=#000000
link=#0000aa
vlink=#000088
alink=#ffff00
>
<font face=helvetica size=3>
<center><img src=imlib.gif alt="Imlib"></center>
<center><b><font color=#ffffff size=6>The Imlib Programmers Guide</font></b></center>
<p>
<b>What is Imlib?</b><br>
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.
<p>
<b>Why use Imlib?</b><br>
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.
<p>
<b>So what are its features?</b><br>
<ul>
<li>
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.
<li>
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.
<li>
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.
<li>
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. 
<li>
Imlib can do basic Image modifications (flip and rotate by  90 degrees),
which may be desired.
<li>
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.
<li>
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.
<li>
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.
<il>
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.
<li>
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.
</ul>
<p>
<b>How do I start programming using Imlib?</b><br>
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).
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#cccccc><font face=helvetica size=3>
<b>This program is written for Xlib.</b><br>
To compile:<br>
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
</font></td></tr><tr><td bgcolor=#ffffff>
<pre>
#include &lt;X11/Xlib.h&gt;
#include &lt;X11/Xutil.h&gt;
#include &lt;X11/extensions/shape.h&gt;
#include &lt;Imlib.h&gt;

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&lt;=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);
         }
     }
}
</pre>
</td></tr></table></center>
<p>
<center><table width=100% border=1><tr><td bgcolor=#cccccc><font face=helvetica size=3>
<b>This program is written for GDK.</b><br>
To compile:<br>
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
</font></td></tr><tr><td bgcolor=#ffffff>
<pre>
#include &lt;gdk_imlib.h&gt;
#include &lt;gdk/gdk.h&gt;

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&lt;=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();
	  }
      }
  }
</pre>
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#cccccc><font face=helvetica size=3>
<b>This program is written for Xlib.</b><br>
To compile:<br>
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
</font></td></tr><tr><td bgcolor=#ffffff>
<pre>
#include &lt;X11/Xlib.h&gt;
#include &lt;X11/Xutil.h&gt;
#include &lt;X11/extensions/shape.h&gt;
#include &lt;Imlib.h&gt;

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&lt;=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);
         }
     }
}
</pre>
</td></tr></table></center>
<p>
<center><table width=100% border=1><tr><td bgcolor=#cccccc><font face=helvetica size=3>
<b>This program is written for GDK.</b><br>
To compile:<br>
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
</font></td></tr><tr><td bgcolor=#ffffff>
<pre>
#include &lt;gdk_imlib.h&gt;
#include &lt;gdk/gdk.h&gt;

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&lt;=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();
	  }
      }
  }
</pre>
</td></tr></table></center>
<blockquote>
<b>As a note for future code snippets:</b><br>
All data types beginning with <b>Imlib</b> are Xlib Imlib data types, those
beginning with <b>Gdk</b> are GDK Imlib data types. All functions beginning 
with <b>Imlib_</b> are Xlib Imlib functions and all functions beginning with 
<b>gdk_</b> 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.
</blockquote>
<p>
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.
<p>
<b>Imlib's concept of an image</b><br>
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:
<ul>
<li>
An image is a large chunk of 24-bit pixel data in RGBRGBRGB format.
<li>
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.
<li>
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.
<li>
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.
<li>
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).
</ul>
<p>
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...
<p>
If our image is:
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
ImlibImage *im;
GdkImlibImage *im;
</pre></td></tr></table></center>
<p>
The pointer to the RGB data and the alpha data would be:
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
im->rgb_data;   /* pointer to unsigned char RGB data */
im->alpha_data; /* pointer to unsigned char Alpha data */
</pre></td></tr></table></center>
<p>
The alpha data is currently unused and should be ignored - the pointer to it
should be kept NULL.
<p>
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.
<p>
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:
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</pre></td></tr></table></center>
<p>
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.
<p>
<center><table border=1>
<tr>
<td align=center><img src=border_eg1.gif width=128 alt="Unscaled Image"></td>
<td><font face= helvetica size=3>
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.
</font></td>
</tr><tr>
<td align=center><img src=border_eg2.gif width=320 alt="Scaled Image"></td>
<td><font face= helvetica size=3>
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.
</font></td>
</tr><tr>
<td align=center><img src=border_eg3.gif width=320 alt="Scaled Image"></td>
<td><font face= helvetica size=3>
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.
</font></td>
</tr><tr>
<td align=center><img src=border_diag.gif alt="Diagram"></td>
<td><font face= helvetica size=3>
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.
</font></td></tr></table></center>
<p>
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:
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</pre></td></tr></table></center>
<p>
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.
<p>
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.
<p>
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.
<p>
<img src=curve1.gif alt="Curve" align=left>
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.
<p>
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.
<img src=curve2.gif alt="Curve" align=right>
<p>
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.
<p>
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.
<p>
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.
<hr>
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
ImlibData *Imlib_init(Display *disp);
void gdk_imlib_init();
</td></tr></table></center>
<p>
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. 
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
ImlibData *Imlib_init_with_params(Display *disp, ImlibInitParams *p);
void gdk_imlib_init_params(GdkImlibInitParams *p);
</td></tr></table></center>
<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.
<p>
The structure containing the parameters to giv Imlib is:
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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
</td></tr></table></center>
<p>
with a simliar one for gdk (same members), and same defines for the flags.
<p>
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:
<p>
<b>visualid</b>: contains an int with the visualid to be used by Imlib.<br>
<br>
<b>palettefile</b>: string containing the file  for the palette file.<br>
<br>
<b>sharedmem</b>: is 1 if you want shared memory used, otherwise 0.<br>
<br>
<b>sharedpixmaps</b>: is 1 if you want shared pixmaps, otherwise 0.<br>
<br>
<b>paletteoverride</b>: 1 if palette remapping is to be forced on, otherwise 0.<br>
<br>
<b>remap</b>: 1 for fast remapping 0 for slower more accurate remapping.<br>
<br>
<b>fastrender</b>: 1 for fast rendering, 0 for slightly slower rendering.<br>
<br>
<b>hiquality</b>: 1 to turn dithering on in 15/16bpp, 0 otherwise.<br>
<br>
<b>dither</b>: 1 to turn dithering on in 8bpp or less, otherwise 0.<br>
<br>
<b>imagecachesize</b>: the size of the image cache to be used in bytes.<br>
<br>
<b>pixmapcachesize</b>: the size of the pixmap cache to be used in bits.<br>
<br>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
int Imlib_get_render_type(ImlibData *id);
gint gdk_imlib_get_render_type();
</td></tr></table></center>
<p>
This function returns Imlib's current rendering mode. It will return one of:
<ul>
RT_PLAIN_PALETTE<br>
RT_PLAIN_PALETTE_FAST<br>
RT_DITHER_PALETTE<br>
RT_DITHER_PALETTE_FAST<br>
RT_PLAIN_TRUECOL<br>
RT_DITHER_TRUECOL<br>
</ul>
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.
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_set_render_type(ImlibData *id, int rend_type);
void gdk_imlib_set_render_type(gint rend_type);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
int Imlib_load_colors(ImlibData *id, char *file);
gint gdk_imlib_load_colors(char *file);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
ImlibImage *Imlib_load_image(ImlibData *id, char *file);
GdkImlibImage *gdk_imlib_load_image(char *file);
</td></tr></table></center>
<p>
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.
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
int Imlib_render(ImlibData *id, ImlibImage *image, int width, int height);
gint gdk_imlib_render(GdkImlibImage *image, gint width, gint height);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
Pixmap Imlib_copy_image(ImlibData *id, ImlibImage *image);
GdkPixmap *gdk_imlib_copy_image(GdkImlibImage *image);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
Pixmap Imlib_copy_mask(ImlibData *id, ImlibImage *image);
GdkBitmap *gdk_imlib_copy_mask(GdkImlibImage *image);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
Pixmap Imlib_move_image(ImlibData *id, ImlibImage *image);
GdkPixmap *gdk_imlib_move_image(GdkImlibImage *image);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
Pixmap Imlib_move_mask(ImlibData *id, ImlibImage *image);
GdkBitmap *gdk_imlib_move_mask(GdkImlibImage *image);
</td></tr></table></center>
<p>
This is the same as Imlib_move_image or gdk_imlib_move_image but returns the
mask for the rendered Image.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_destroy_image(ImlibData *id, ImlibImage *image);
void gdk_imlib_destroy_image(GdkImlibImage *image);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_kill_image(ImlibData *id, ImlibImage *image);
void gdk_imlib_kill_image(GdkImlibImage *image);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_free_colors(ImlibData *id);
void gdk_imlib_free_colors();
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_free_pixmap(ImlibData *id, Pixmap pixmap);
void gdk_imlib_free_pixmap(GdkPixmap *pixmap);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_get_image_border(ImlibData *id, ImlibImage *image, ImlibBorder *border);
void gdk_imlib_get_image_border(GdkImlibImage *image, GdkImlibBorder *border);
</td></tr></table></center>
<p>
This function returns the image's border attributes in the  border structure.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_set_image_border(ImlibData *id, ImlibImage *image, ImlibBorder *border);
void gdk_imlib_set_image_border(GdkImlibImage *image, GdkImlibBorder *border);
</td></tr></table></center>
<p>
This function sets the image's border attributes to those in the border
structure.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_get_image_shape(ImlibData *id, ImlibImage *image, ImlibColor *color);
void gdk_imlib_get_image_shape(GdkImlibImage *image, GdkImlibColor *color);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_set_image_shape(ImlibData *id, ImlibImage *image, ImlibColor *color);
void gdk_imlib_set_image_shape(GdkImlibImage *image, GdkImlibColor *color);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
int Imlib_save_image_to_eim(ImlibData *id, ImlibImage *image, char *file);
gint gdk_imlib_save_image_to_eim(GdkImlibImage *image, char *file);
</td></tr></table></center>
<p>
This Function saves the image into an EIM format image. EIM image format is
currently under construction. Please come back later.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
int Imlib_add_image_to_eim(ImlibData *id, ImlibImage *image, char *file);
gint gdk_imlib_add_image_to_eim(GdkImlibImage *image, char *file);
</td></tr></table></center>
<p>
This Function adds the image into an EIM file that currently exists. EIM 
image format is currently under construction. Please come back later.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
int Imlib_save_image_to_ppm(ImlibData *id, ImlibImage *image, char *file);
gint gdk_imlib_save_image_to_ppm(GdkImlibImage *image, char *file);
</td></tr></table></center>
<p>
This function saves the current image as a binary format PPM file. If it is
successful, it returns 1, otherwise it returns 0.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_set_image_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
void gdk_imlib_set_image_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_set_image_red_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
void gdk_imlib_set_image_red_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_set_image_green_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
void gdk_imlib_set_image_green_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_set_image_blue_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
void gdk_imlib_set_image_blue_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_get_image_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
void gdk_imlib_get_image_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);
</td></tr></table></center>
<p>
This function returns the image's current modifier settings in the mod
structure.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_get_image_red_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
void gdk_imlib_get_image_red_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);
</td></tr></table></center>
<p>
This function returns the image's red channel modifier settings in the mod
structure.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_get_image_green_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
void gdk_imlib_get_image_green_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);
</td></tr></table></center>
<p>
This function returns the image's green channel modifier settings in the mod
structure.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_get_image_blue_modifier(ImlibData *id, ImlibImage *im, ImlibColorModifier *mod);
void gdk_imlib_get_image_blue_modifier(GdkImlibImage *im, GdkImlibColorModifier *mod);
</td></tr></table></center>
<p>
This function returns the image's blue channel modifier settings in the mod
structure.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_apply_modifiers_to_rgb(ImlibData *id, ImlibImage *im);
void gdk_imlib_apply_modifiers_to_rgb(GdkImlibImage *im);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_changed_image(ImlibData *id, ImlibImage *im);
void gdk_imlib_changed_image(GdkImlibImage *im);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_apply_image(ImlibData *id, ImlibImage *im, Window p);
void gdk_imlib_apply_image(GdkImlibImage *im, GdkWindow *p);
</td></tr></table></center>
<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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_flip_image_horizontal(ImlibData *id, ImlibImage *im);
void gdk_imlib_flip_image_horizontal(GdkImlibImage *im);
</td></tr></table></center>
<p>
This flips the RGB data in an image horizontally. You need to re-render the 
image for it to take effect.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_flip_image_vertical(ImlibData *id, ImlibImage *im);
void gdk_imlib_flip_image_vertical(GdkImlibImage *im);
</td></tr></table></center>
<p>
This flips the RGB data in an image vertically. You need to re-render the 
image for it to take effect.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_rotate_image(ImlibData *id, ImlibImage *im, int d);
void gdk_imlib_rotate_image(GdkImlibImage *im, gint d);
</td></tr></table></center>
<p>
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.)
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
ImlibImage *Imlib_clone_image(ImlibData *id, ImlibImage *im);
GdkImlibImage *gdk_imlib_clone_image(GdkImlibImage *im);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
int Imlib_get_fallback(ImlibData *id);
gint gdk_imlib_get_fallback();
</td></tr></table></center>
<p>
This function gets the status of ImageMagick and NETPBM fallback mechanisms.
1 means they are active, 0 means they are not.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void Imlib_set_fallback(ImlibData *id, int fallback);
void gdk_imlib_set_fallback(gint fallback);
</td></tr></table></center>
<p>
This function sets the state of the ImageMagick and NETPBM fallback
mechanisms. 1 makes them active, 0 deactivates them.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
Visual *Imlib_get_visual(ImlibData *id);
GdkVisual *gdk_imlib_get_visual();
</td></tr></table></center>
<p>
This function returns the Visual that Imlib has decided to use (accoridng to
imrc and XServer capabilities).
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
Colormap Imlib_get_colormap(ImlibData *id);
GdkColormap *gdk_imlib_get_colormap();
</td></tr></table></center>
<p>
This function returns the Colormap that Imlib has chosen to use for its
visual.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
char *Imlib_get_sysconfig(ImlibData *id);
gchar *gdk_imlib_get_sysconfig();
</td></tr></table></center>
<p>
This function returns a pointer to a copy of the path to the system imrc
file. When finished you should free this string.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
ImlibImage *Imlib_create_image_from_xpm_data(ImlibData *id, char **data);
GdkImlibImage *gdk_imlib_create_image_from_xpm_data(char **data);
</td></tr></table></center>
<p>
This function creates an Imlib image out of an inlined XPM image 
(ie. #include "file.xpm"). data is the pointer to the XPM data.
<p>
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<hr>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<hr>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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.
<p>
<hr>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
void gdk_imlib_best_color_get(GdkColor *c);
</td></tr></table></center>
<p>
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.
<p>
<hr>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
gint gdk_imlib_save_image(GdkImlibImage *im, char *file, GdkImlibSaveInfo *info);
int Imlib_save_image(ImlibData *id, ImlibImage *im, char *file, ImlibSaveInfo *info);
</td></tr></table></center>
<p>
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.
<p>
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.
<p>
<hr>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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);
</td></tr></table></center>
<p>
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).
<p>
<hr>
<p>
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).
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
typedef struct _ImlibBorder
{
   int left,right;
   int top,bottom;
} ImlibBorder;

typedef struct _GdkImlibBorder
{
   gint left,right;
   gint top,bottom;
} GdkImlibBorder;
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
typedef struct _ImlibColor
{
   int r,g,b;
} ImlibColor;

typedef struct _GdkImlibColor
{
   gint r,g,b;
} GdkImlibColor;
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
typedef struct _ImlibColorModifier
{
   int gamma;
   int brightness;
   int contrast;
} ImlibColorModifier;

typedef struct _GdkImlibColorModifier
{
   gint gamma;
   gint brightness;
   gint contrast;
} GdkImlibColorModifier;
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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;
</td></tr></table></center>
<p>
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.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
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;
</td></tr></table></center>
<p>
These are the ImlibSaveInfo data structs - they may be expanded in future.
Their use is described above in the imlib_save_image function.
<p>
<center><table width=100% border=1><tr><td bgcolor=#ffffff><pre>
typedef struct _ImlibData
{
   struct _xdata
   {
      Display         *disp;
      int             screen;
      Window          root;
      Visual          *visual;
      int             depth;
   } x;
} ImlibData;
</td></tr></table></center>
<p>
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.
</font>
</body>
</html>
