]> Pileus Git - ~andy/gtk/blobdiff - gdk-pixbuf/gdk-pixbuf-io.c
Interpret patterns where the first byte of the mask is '*' as unanchored.
[~andy/gtk] / gdk-pixbuf / gdk-pixbuf-io.c
index 9ad408748e5c55c650317ccac99571cbad8d9f17..a8faa782f9bface00e013ff96a22fefe77cd6f32 100644 (file)
 #include <unistd.h>
 #endif
 
-#include "gdk-pixbuf-alias.h"
 #include "gdk-pixbuf-private.h"
 #include "gdk-pixbuf-io.h"
+#include "gdk-pixbuf-alias.h"
+
+#include <glib/gstdio.h>
 
 #ifdef G_OS_WIN32
 #define STRICT
 static gint 
 format_check (GdkPixbufModule *module, guchar *buffer, int size)
 {
-       int j;
+       int i, j;
        gchar m;
        GdkPixbufModulePattern *pattern;
+       gboolean unanchored;
+       guchar *prefix, *mask;
 
        for (pattern = module->info->signature; pattern->prefix; pattern++) {
-               for (j = 0; j < size && pattern->prefix[j] != 0; j++) {
-                       m = pattern->mask ? pattern->mask[j] : ' ';
-                       if (m == ' ') {
-                               if (buffer[j] != pattern->prefix[j])
-                                       break;
-                       }
-                       else if (m == '!') {
-                               if (buffer[j] == pattern->prefix[j])
-                                       break;
-                       }
-                       else if (m == 'z') {
-                               if (buffer[j] != 0)
-                                       break;
-                       }
-                       else if (m == 'n') {
-                               if (buffer[j] == 0)
-                                       break;
-                       }
-               } 
-               if (pattern->prefix[j] == 0) 
-                       return pattern->relevance;
+               if (pattern->mask && pattern->mask[0] == '*') {
+                       prefix = pattern->prefix + 1;
+                       mask = pattern->mask + 1;
+                       unanchored = TRUE;
+               }
+               else {
+                       prefix = pattern->prefix;
+                       mask = pattern->mask;
+                       unanchored = FALSE;
+               }
+               for (i = 0; unanchored && i < size; i++) {
+                       for (j = 0; i + j < size && prefix[j] != 0; j++) {
+                               m = mask ? mask[j] : ' ';
+                               if (m == ' ') {
+                                       if (buffer[i + j] != prefix[j])
+                                               break;
+                               }
+                               else if (m == '!') {
+                                       if (buffer[i + j] == prefix[j])
+                                               break;
+                               }
+                               else if (m == 'z') {
+                                       if (buffer[i + j] != 0)
+                                               break;
+                               }
+                               else if (m == 'n') {
+                                       if (buffer[i + j] == 0)
+                                               break;
+                               }
+                       } 
+                       if (prefix[j] == 0) 
+                               return pattern->relevance;
+               }
        }
        return 0;
 }
@@ -79,12 +95,17 @@ format_check (GdkPixbufModule *module, guchar *buffer, int size)
 G_LOCK_DEFINE_STATIC (init_lock);
 G_LOCK_DEFINE_STATIC (threadunsafe_loader_lock);
 
-void
+gboolean
 _gdk_pixbuf_lock (GdkPixbufModule *image_module)
 {
-       if (!(image_module->info->flags & GDK_PIXBUF_FORMAT_THREADSAFE)) {
+       if (g_threads_got_initialized &&
+           !(image_module->info->flags & GDK_PIXBUF_FORMAT_THREADSAFE)) {
                G_LOCK (threadunsafe_loader_lock);
+
+               return TRUE;
        }
+
+       return FALSE;
 }
  
 void
@@ -243,7 +264,7 @@ correct_prefix (gchar **path)
     }
 }
 
-#endif
+#endif  /* G_OS_WIN32 */
 
 static gchar *
 gdk_pixbuf_get_module_file (void)
@@ -424,7 +445,7 @@ _gdk_pixbuf_load_module_unlocked (GdkPixbufModule *image_module,
        char *path;
        GModule *module;
        gpointer sym;
-       
+               
         g_return_val_if_fail (image_module->module == NULL, FALSE);
 
        path = image_module->module_path;
@@ -460,14 +481,23 @@ _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
                         GError         **error)
 {
        gboolean ret;
+       gboolean locked = FALSE;
 
-       G_LOCK (init_lock);
+       /* be extra careful, maybe the module initializes
+        * the thread system
+        */
+       if (g_threads_got_initialized)
+       {
+               G_LOCK (init_lock);
+               locked = TRUE;
+       }
        ret = _gdk_pixbuf_load_module_unlocked (image_module, error);
-       G_UNLOCK (init_lock);
-
+       if (locked)
+               G_UNLOCK (init_lock);
        return ret;
 }
-#else
+
+#else  /* !USE_GMODULE */
 
 #define module(type) \
   extern void MODULE_ENTRY (type, fill_info)   (GdkPixbufFormat *info);   \
@@ -631,14 +661,14 @@ gdk_pixbuf_io_init ()
        for (name = included_formats; *name; name++) {
                module = g_new0 (GdkPixbufModule, 1);
                module->module_name = *name;
-               if (_gdk_pixbuf_load_module_unlocked (module, NULL))
+               if (_gdk_pixbuf_load_module (module, NULL))
                        file_formats = g_slist_prepend (file_formats, module);
                else
                        g_free (module);
        }
 }
 
-#endif
+#endif  /* !USE_GMODULE */
 
 \f
 
@@ -736,8 +766,9 @@ _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
        GdkPixbuf *pixbuf = NULL;
        GdkPixbufAnimation *animation = NULL;
        gpointer context;
+       gboolean locked;
 
-       _gdk_pixbuf_lock (module);
+       locked = _gdk_pixbuf_lock (module);
 
        if (module->load != NULL) {
                pixbuf = (* module->load) (f, error);
@@ -773,19 +804,19 @@ _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
                        pixbuf = gdk_pixbuf_animation_get_static_image (animation);
 
                        g_object_ref (pixbuf);
-
                        g_object_unref (animation);
                }
        }
 
  out:
-       _gdk_pixbuf_unlock (module);
+       if (locked)
+               _gdk_pixbuf_unlock (module);
        return pixbuf;
 }
 
 /**
  * gdk_pixbuf_new_from_file:
- * @filename: Name of file to load.
+ * @filename: Name of file to load, in the GLib file name encoding
  * @error: Return location for an error
  *
  * Creates a new pixbuf by loading an image from a file.  The file format is
@@ -804,7 +835,7 @@ gdk_pixbuf_new_from_file (const char *filename,
        GdkPixbuf *pixbuf;
        int size;
        FILE *f;
-       guchar buffer [128];
+       guchar buffer[256];
        GdkPixbufModule *image_module;
        gchar *display_name;
 
@@ -813,7 +844,7 @@ gdk_pixbuf_new_from_file (const char *filename,
        
        display_name = g_filename_display_name (filename);      
 
-       f = fopen (filename, "rb");
+       f = g_fopen (filename, "rb");
        if (!f) {
                 g_set_error (error,
                              G_FILE_ERROR,
@@ -886,6 +917,28 @@ gdk_pixbuf_new_from_file (const char *filename,
        return pixbuf;
 }
 
+#ifdef G_OS_WIN32
+
+#undef gdk_pixbuf_new_from_file
+GdkPixbuf *
+gdk_pixbuf_new_from_file (const char *filename,
+                          GError    **error)
+{
+       gchar *utf8_filename =
+               g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+       GdkPixbuf *retval;
+
+       if (utf8_filename == NULL)
+               return NULL;
+
+       retval = gdk_pixbuf_new_from_file_utf8 (utf8_filename, error);
+
+       g_free (utf8_filename);
+
+       return retval;
+}
+#endif
+
 static void
 size_prepared_cb (GdkPixbufLoader *loader, 
                  int              width,
@@ -900,9 +953,20 @@ size_prepared_cb (GdkPixbufLoader *loader,
 
        g_return_if_fail (width > 0 && height > 0);
 
-       if(info->preserve_aspect_ratio) {
-               if ((double)height * (double)info->width >
-                   (double)width * (double)info->height) {
+       if (info->preserve_aspect_ratio && 
+           (info->width > 0 || info->height > 0)) {
+               if (info->width < 0)
+               {
+                       width = width * (double)info->height/(double)height;
+                       height = info->height;
+               }
+               else if (info->height < 0)
+               {
+                       height = height * (double)info->width/(double)width;
+                       width = info->width;
+               }
+               else if ((double)height * (double)info->width >
+                        (double)width * (double)info->height) {
                        width = 0.5 + (double)width * (double)info->height / (double)height;
                        height = info->height;
                } else {
@@ -910,18 +974,79 @@ size_prepared_cb (GdkPixbufLoader *loader,
                        width = info->width;
                }
        } else {
-               width = info->width;
-               height = info->height;
+               if (info->width > 0)
+                       width = info->width;
+               if (info->height > 0)
+                       height = info->height;
        }
        
        gdk_pixbuf_loader_set_size (loader, width, height);
 }
 
+/**
+ * gdk_pixbuf_new_from_file_at_size:
+ * @filename: Name of file to load, in the GLib file name encoding
+ * @width: The width the image should have or -1 to not constrain the width
+ * @height: The height the image should have or -1 to not constrain the height
+ * @error: Return location for an error
+ *
+ * Creates a new pixbuf by loading an image from a file.  The file format is
+ * detected automatically. If %NULL is returned, then @error will be set.
+ * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
+ * The image will be scaled to fit in the requested size, preserving
+ * the image's aspect ratio.
+ *
+ * Return value: A newly-created pixbuf with a reference count of 1, or 
+ * %NULL if any of several error conditions occurred:  the file could not 
+ * be opened, there was no loader for the file's format, there was not 
+ * enough memory to allocate the image buffer, or the image file contained 
+ * invalid data.
+ *
+ * Since: 2.4
+ **/
+GdkPixbuf *
+gdk_pixbuf_new_from_file_at_size (const char *filename,
+                                 int         width, 
+                                 int         height,
+                                 GError    **error)
+{
+       return gdk_pixbuf_new_from_file_at_scale (filename, 
+                                                 width, height, 
+                                                 TRUE, error);
+}
+
+#ifdef G_OS_WIN32
+
+#undef gdk_pixbuf_new_from_file_at_size
+
+GdkPixbuf *
+gdk_pixbuf_new_from_file_at_size (const char *filename,
+                                 int         width, 
+                                 int         height,
+                                 GError    **error)
+{
+       gchar *utf8_filename =
+               g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+       GdkPixbuf *retval;
+
+       if (utf8_filename == NULL)
+               return NULL;
+
+       retval = gdk_pixbuf_new_from_file_at_size_utf8 (utf8_filename,
+                                                       width, height,
+                                                       error);
+
+       g_free (utf8_filename);
+
+       return retval;
+}
+#endif
+
 /**
  * gdk_pixbuf_new_from_file_at_scale:
- * @filename: Name of file to load.
- * @width: The width the image should have
- * @height: The height the image should have
+ * @filename: Name of file to load, in the GLib file name encoding
+ * @width: The width the image should have or -1 to not constrain the width
+ * @height: The height the image should have or -1 to not constrain the height
  * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio
  * @error: Return location for an error
  *
@@ -929,7 +1054,14 @@ size_prepared_cb (GdkPixbufLoader *loader,
  * detected automatically. If %NULL is returned, then @error will be set.
  * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
  * The image will be scaled to fit in the requested size, optionally preserving
- * the image's aspect ratio.
+ * the image's aspect ratio. 
+ *
+ * When preserving the aspect ratio, a @width of -1 will cause the image
+ * to be scaled to the exact given height, and a @height of -1 will cause
+ * the image to be scaled to the exact given width. When not preserving
+ * aspect ratio, a @width or @height of -1 means to not scale the image 
+ * at all in that dimension. Negative values for @width and @height are 
+ * allowed since 2.8.
  *
  * Return value: A newly-created pixbuf with a reference count of 1, or %NULL 
  * if any of several error conditions occurred:  the file could not be opened,
@@ -959,9 +1091,10 @@ gdk_pixbuf_new_from_file_at_scale (const char *filename,
        } info;
 
        g_return_val_if_fail (filename != NULL, NULL);
-        g_return_val_if_fail (width > 0 && height > 0, NULL);
+        g_return_val_if_fail (width > 0 || width == -1, NULL);
+        g_return_val_if_fail (height > 0 || height == -1, NULL);
 
-       f = fopen (filename, "rb");
+       f = g_fopen (filename, "rb");
        if (!f) {
                 gchar *display_name = g_filename_display_name (filename);
                 g_set_error (error,
@@ -1021,37 +1154,35 @@ gdk_pixbuf_new_from_file_at_scale (const char *filename,
        return pixbuf;
 }
 
-/**
- * gdk_pixbuf_new_from_file_at_size:
- * @filename: Name of file to load.
- * @width: The width the image should have
- * @height: The height the image should have
- * @error: Return location for an error
- *
- * Creates a new pixbuf by loading an image from a file.  The file format is
- * detected automatically. If %NULL is returned, then @error will be set.
- * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
- * The image will be scaled to fit in the requested size, preserving
- * the image's aspect ratio.
- *
- * Return value: A newly-created pixbuf with a reference count of 1, or 
- * %NULL if any of several error conditions occurred:  the file could not 
- * be opened, there was no loader for the file's format, there was not 
- * enough memory to allocate the image buffer, or the image file contained 
- * invalid data.
- *
- * Since: 2.4
- **/
+#ifdef G_OS_WIN32
+
+#undef gdk_pixbuf_new_from_file_at_scale
+
 GdkPixbuf *
-gdk_pixbuf_new_from_file_at_size (const char *filename,
-                                 int         width, 
-                                 int         height,
-                                 GError    **error)
+gdk_pixbuf_new_from_file_at_scale (const char *filename,
+                                  int         width, 
+                                  int         height,
+                                  gboolean    preserve_aspect_ratio,
+                                  GError    **error)
 {
-       return gdk_pixbuf_new_from_file_at_scale (filename, 
-                                                 width, height, 
-                                                 TRUE, error);
+       gchar *utf8_filename =
+               g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+       GdkPixbuf *retval;
+
+       if (utf8_filename == NULL)
+               return NULL;
+
+       retval = gdk_pixbuf_new_from_file_at_scale_utf8 (utf8_filename,
+                                                        width, height,
+                                                        preserve_aspect_ratio,
+                                                        error);
+
+       g_free (utf8_filename);
+
+       return retval;
 }
+#endif
+
 
 static void
 info_cb (GdkPixbufLoader *loader, 
@@ -1105,7 +1236,7 @@ gdk_pixbuf_get_file_info (const gchar  *filename,
 
        g_return_val_if_fail (filename != NULL, NULL);
 
-       f = fopen (filename, "rb");
+       f = g_fopen (filename, "rb");
        if (!f)
                return NULL;
 
@@ -1154,7 +1285,10 @@ gdk_pixbuf_new_from_xpm_data (const char **data)
        GdkPixbuf *(* load_xpm_data) (const char **data);
        GdkPixbuf *pixbuf;
         GError *error = NULL;
-       GdkPixbufModule *xpm_module = _gdk_pixbuf_get_named_module ("xpm", &error);
+       GdkPixbufModule *xpm_module;
+       gboolean locked;
+
+       xpm_module = _gdk_pixbuf_get_named_module ("xpm", &error);
        if (xpm_module == NULL) {
                g_warning ("Error loading XPM image loader: %s", error->message);
                g_error_free (error);
@@ -1169,7 +1303,7 @@ gdk_pixbuf_new_from_xpm_data (const char **data)
                 }
         }
 
-       _gdk_pixbuf_lock (xpm_module);
+       locked = _gdk_pixbuf_lock (xpm_module);
 
        if (xpm_module->load_xpm_data == NULL) {
                g_warning ("gdk-pixbuf XPM module lacks XPM data capability");
@@ -1178,8 +1312,9 @@ gdk_pixbuf_new_from_xpm_data (const char **data)
                load_xpm_data = xpm_module->load_xpm_data;
                pixbuf = (* load_xpm_data) (data);
        }
-
-       _gdk_pixbuf_unlock (xpm_module);
+       
+       if (locked)
+               _gdk_pixbuf_unlock (xpm_module);
        return pixbuf;
 }
 
@@ -1250,6 +1385,7 @@ gdk_pixbuf_real_save (GdkPixbuf     *pixbuf,
 {
        gboolean ret;
        GdkPixbufModule *image_module = NULL;       
+       gboolean locked;
 
        image_module = _gdk_pixbuf_get_named_module (type, error);
 
@@ -1260,7 +1396,7 @@ gdk_pixbuf_real_save (GdkPixbuf     *pixbuf,
                if (!_gdk_pixbuf_load_module (image_module, error))
                        return FALSE;
 
-       _gdk_pixbuf_lock (image_module);
+       locked = _gdk_pixbuf_lock (image_module);
 
        if (image_module->save) {
                /* save normally */
@@ -1283,7 +1419,8 @@ gdk_pixbuf_real_save (GdkPixbuf     *pixbuf,
                ret = FALSE;
        }
 
-       _gdk_pixbuf_unlock (image_module);
+       if (locked)
+               _gdk_pixbuf_unlock (image_module);
        return ret;
 }
 
@@ -1304,6 +1441,7 @@ save_to_callback_with_tmp_file (GdkPixbufModule   *image_module,
        gchar *buf = NULL;
        gsize n;
        gchar *filename = NULL;
+       gboolean locked;
 
        buf = g_try_malloc (TMP_FILE_BUF_SIZE);
        if (buf == NULL) {
@@ -1326,9 +1464,10 @@ save_to_callback_with_tmp_file (GdkPixbufModule   *image_module,
                goto end;
        }
 
-       _gdk_pixbuf_lock (image_module);
+       locked = _gdk_pixbuf_lock (image_module);
        retval = (image_module->save) (f, pixbuf, keys, values, error);
-       _gdk_pixbuf_unlock (image_module);
+       if (locked)
+               _gdk_pixbuf_unlock (image_module);
        if (!retval)
                goto end;
 
@@ -1356,7 +1495,7 @@ save_to_callback_with_tmp_file (GdkPixbufModule   *image_module,
        if (f)
                fclose (f);
        if (filename) {
-               unlink (filename);
+               g_unlink (filename);
                g_free (filename);
        }
        g_free (buf);
@@ -1375,6 +1514,7 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
 {
        gboolean ret;
        GdkPixbufModule *image_module = NULL;       
+       gboolean locked;
 
        image_module = _gdk_pixbuf_get_named_module (type, error);
 
@@ -1385,7 +1525,7 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
                if (!_gdk_pixbuf_load_module (image_module, error))
                        return FALSE;
 
-       _gdk_pixbuf_lock (image_module);
+       locked = _gdk_pixbuf_lock (image_module);
 
        if (image_module->save_to_callback) {
                /* save normally */
@@ -1408,7 +1548,8 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
                ret = FALSE;
        }
 
-       _gdk_pixbuf_unlock (image_module);
+       if (locked)
+               _gdk_pixbuf_unlock (image_module);
        return ret;
 }
 
@@ -1421,8 +1562,8 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
  * @error: return location for error, or %NULL
  * @Varargs: list of key-value save options
  *
- * Saves pixbuf to a file in format @type. By default, "jpeg", "png" and 
- * "ico" are possible file formats to save in, but more formats may be
+ * Saves pixbuf to a file in format @type. By default, "jpeg", "png", "ico" 
+ * and "bmp" are possible file formats to save in, but more formats may be
  * installed. The list of all writable formats can be determined in the 
  * following way:
  *
@@ -1450,11 +1591,15 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
  *                  "quality", "100", NULL);
  * </programlisting></informalexample>
  *
- * Currently only few parameters exist. JPEG images can be saved with a 
- * "quality" parameter; its value should be in the range [0,100]. 
+ * Currently only few parameters exist. JPEG images can be saved with a
+ * "quality" parameter; its value should be in the range [0,100].
+ *
  * Text chunks can be attached to PNG images by specifying parameters of
  * the form "tEXt::key", where key is an ASCII string of length 1-79.
- * The values are UTF-8 encoded strings. 
+ * The values are UTF-8 encoded strings. The PNG compression level can
+ * be specified using the "compression" parameter; it's value is in an
+ * integer in the range of [0,9].
+ *
  * ICO images can be saved in depth 16, 24, or 32, by using the "depth"
  * parameter. When the ICO saver is given "x_hot" and "y_hot" parameters,
  * it produces a CUR instead of an ICO.
@@ -1492,6 +1637,50 @@ gdk_pixbuf_save (GdkPixbuf  *pixbuf,
         return result;
 }
 
+#ifdef G_OS_WIN32
+
+#undef gdk_pixbuf_save
+
+gboolean
+gdk_pixbuf_save (GdkPixbuf  *pixbuf, 
+                 const char *filename, 
+                 const char *type, 
+                 GError    **error,
+                 ...)
+{
+       char *utf8_filename;
+        gchar **keys = NULL;
+        gchar **values = NULL;
+        va_list args;
+       gboolean result;
+
+        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+        
+       utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+
+       if (utf8_filename == NULL)
+               return FALSE;
+
+        va_start (args, error);
+        
+        collect_save_options (args, &keys, &values);
+        
+        va_end (args);
+
+        result = gdk_pixbuf_savev_utf8 (pixbuf, utf8_filename, type,
+                                       keys, values,
+                                       error);
+
+       g_free (utf8_filename);
+
+        g_strfreev (keys);
+        g_strfreev (values);
+
+        return result;
+}
+
+#endif
+
 /**
  * gdk_pixbuf_savev:
  * @pixbuf: a #GdkPixbuf.
@@ -1501,7 +1690,7 @@ gdk_pixbuf_save (GdkPixbuf  *pixbuf,
  * @option_values: values for named options
  * @error: return location for error, or %NULL
  *
- * Saves pixbuf to a file in @type, which is currently "jpeg", "png" or "ico".
+ * Saves pixbuf to a file in @type, which is currently "jpeg", "png", "ico" or "bmp".
  * If @error is set, %FALSE will be returned. 
  * See gdk_pixbuf_save () for more details.
  *
@@ -1518,13 +1707,12 @@ gdk_pixbuf_savev (GdkPixbuf  *pixbuf,
 {
         FILE *f = NULL;
         gboolean result;
-        
        
         g_return_val_if_fail (filename != NULL, FALSE);
         g_return_val_if_fail (type != NULL, FALSE);
         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
        
-        f = fopen (filename, "wb");
+        f = g_fopen (filename, "wb");
         
         if (f == NULL) {
                 gchar *display_name = g_filename_display_name (filename);
@@ -1565,6 +1753,38 @@ gdk_pixbuf_savev (GdkPixbuf  *pixbuf,
        return TRUE;
 }
 
+#ifdef G_OS_WIN32
+
+#undef gdk_pixbuf_savev
+
+gboolean
+gdk_pixbuf_savev (GdkPixbuf  *pixbuf, 
+                  const char *filename, 
+                  const char *type,
+                  char      **option_keys,
+                  char      **option_values,
+                  GError    **error)
+{
+       char *utf8_filename;
+       gboolean retval;
+
+        g_return_val_if_fail (filename != NULL, FALSE);
+       
+       utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+
+       if (utf8_filename == NULL)
+               return FALSE;
+
+       retval = gdk_pixbuf_savev_utf8 (pixbuf, utf8_filename, type,
+                                       option_keys, option_values, error);
+
+       g_free (utf8_filename);
+
+       return retval;
+}
+
+#endif
+
 /**
  * gdk_pixbuf_save_to_callback:
  * @pixbuf: a #GdkPixbuf.
@@ -1631,7 +1851,7 @@ gdk_pixbuf_save_to_callback    (GdkPixbuf  *pixbuf,
  * @error: return location for error, or %NULL
  *
  * Saves pixbuf to a callback in format @type, which is currently "jpeg",
- * "png" or "ico".  If @error is set, %FALSE will be returned. See
+ * "png", "ico" or "bmp".  If @error is set, %FALSE will be returned. See
  * gdk_pixbuf_save_to_callback () for more details.
  *
  * Return value: whether an error was set
@@ -1677,7 +1897,7 @@ gdk_pixbuf_save_to_callbackv   (GdkPixbuf  *pixbuf,
  * @Varargs: list of key-value save options
  *
  * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
- * "png" or "ico".  This is a convenience function that uses
+ * "png", "ico" or "bmp".  This is a convenience function that uses
  * gdk_pixbuf_save_to_callback() to do the real work. Note that the buffer 
  * is not nul-terminated and may contain embedded  nuls.
  * If @error is set, %FALSE will be returned and @string will be set to
@@ -1765,7 +1985,7 @@ save_to_buffer_callback (const gchar *data,
  * @error: return location for error, or %NULL
  *
  * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
- * "png" or "ico".  See gdk_pixbuf_save_to_buffer() for more details.
+ * "png", "ico" or "bmp".  See gdk_pixbuf_save_to_buffer() for more details.
  *
  * Return value: whether an error was set
  *
@@ -2030,6 +2250,9 @@ gdk_pixbuf_get_formats (void)
 }
 
 
+#define __GDK_PIXBUF_IO_C__
+#include "gdk-pixbuf-aliasdef.c"
+