]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/gdk-pixbuf-io.c
Use explicit G_MODULE_EXPORT decoration when building the loader in
[~andy/gtk] / gdk-pixbuf / gdk-pixbuf-io.c
1 /* -*- mode: C; c-file-style: "linux" -*- */
2 /* GdkPixbuf library - Main loading interface.
3  *
4  * Copyright (C) 1999 The Free Software Foundation
5  *
6  * Authors: Miguel de Icaza <miguel@gnu.org>
7  *          Federico Mena-Quintero <federico@gimp.org>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include <config.h>
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <errno.h>
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #include <glib.h>
36 #include <gio/gio.h>
37
38 #include "gdk-pixbuf-private.h"
39 #include "gdk-pixbuf-io.h"
40 #include "gdk-pixbuf-loader.h"
41 #include "gdk-pixbuf-alias.h"
42
43 #include <glib/gstdio.h>
44
45 #ifdef G_OS_WIN32
46 #define STRICT
47 #include <windows.h>
48 #undef STRICT
49 #endif
50
51 #define SNIFF_BUFFER_SIZE 4096
52 #define LOAD_BUFFER_SIZE 65536
53
54 static gint 
55 format_check (GdkPixbufModule *module, guchar *buffer, int size)
56 {
57         int i, j;
58         gchar m;
59         GdkPixbufModulePattern *pattern;
60         gboolean anchored;
61         guchar *prefix;
62         gchar *mask;
63
64         for (pattern = module->info->signature; pattern->prefix; pattern++) {
65                 if (pattern->mask && pattern->mask[0] == '*') {
66                         prefix = (guchar *)pattern->prefix + 1;
67                         mask = pattern->mask + 1;
68                         anchored = FALSE;
69                 }
70                 else {
71                         prefix = (guchar *)pattern->prefix;
72                         mask = pattern->mask;
73                         anchored = TRUE;
74                 }
75                 for (i = 0; i < size; i++) {
76                         for (j = 0; i + j < size && prefix[j] != 0; j++) {
77                                 m = mask ? mask[j] : ' ';
78                                 if (m == ' ') {
79                                         if (buffer[i + j] != prefix[j])
80                                                 break;
81                                 }
82                                 else if (m == '!') {
83                                         if (buffer[i + j] == prefix[j])
84                                                 break;
85                                 }
86                                 else if (m == 'z') {
87                                         if (buffer[i + j] != 0)
88                                                 break;
89                                 }
90                                 else if (m == 'n') {
91                                         if (buffer[i + j] == 0)
92                                                 break;
93                                 }
94                         } 
95
96                         if (prefix[j] == 0) 
97                                 return pattern->relevance;
98
99                         if (anchored)
100                                 break;
101                 }
102         }
103         return 0;
104 }
105
106 G_LOCK_DEFINE_STATIC (init_lock);
107 G_LOCK_DEFINE_STATIC (threadunsafe_loader_lock);
108
109 gboolean
110 _gdk_pixbuf_lock (GdkPixbufModule *image_module)
111 {
112         if (g_threads_got_initialized &&
113             !(image_module->info->flags & GDK_PIXBUF_FORMAT_THREADSAFE)) {
114                 G_LOCK (threadunsafe_loader_lock);
115
116                 return TRUE;
117         }
118
119         return FALSE;
120 }
121  
122 void
123 _gdk_pixbuf_unlock (GdkPixbufModule *image_module)
124 {
125         if (!(image_module->info->flags & GDK_PIXBUF_FORMAT_THREADSAFE)) {
126                 G_UNLOCK (threadunsafe_loader_lock);
127         }
128 }
129
130 static GSList *file_formats = NULL;
131
132 static void gdk_pixbuf_io_init (void);
133
134 static GSList *
135 get_file_formats (void)
136 {
137         G_LOCK (init_lock);
138         if (file_formats == NULL)
139                 gdk_pixbuf_io_init ();
140         G_UNLOCK (init_lock);
141         
142         return file_formats;
143 }
144
145
146 #ifdef USE_GMODULE 
147
148 static gboolean
149 scan_string (const char **pos, GString *out)
150 {
151         const char *p = *pos, *q = *pos;
152         char *tmp, *tmp2;
153         gboolean quoted;
154         
155         while (g_ascii_isspace (*p))
156                 p++;
157         
158         if (!*p)
159                 return FALSE;
160         else if (*p == '"') {
161                 p++;
162                 quoted = FALSE;
163                 for (q = p; (*q != '"') || quoted; q++) {
164                         if (!*q)
165                                 return FALSE;
166                         quoted = (*q == '\\') && !quoted;
167                 }
168                 
169                 tmp = g_strndup (p, q - p);
170                 tmp2 = g_strcompress (tmp);
171                 g_string_truncate (out, 0);
172                 g_string_append (out, tmp2);
173                 g_free (tmp);
174                 g_free (tmp2);
175         }
176         
177         q++;
178         *pos = q;
179         
180         return TRUE;
181 }
182
183 static gboolean
184 scan_int (const char **pos, int *out)
185 {
186         int i = 0;
187         char buf[32];
188         const char *p = *pos;
189         
190         while (g_ascii_isspace (*p))
191                 p++;
192         
193         if (*p < '0' || *p > '9')
194                 return FALSE;
195         
196         while ((*p >= '0') && (*p <= '9') && i < sizeof (buf)) {
197                 buf[i] = *p;
198                 i++;
199                 p++;
200         }
201         
202         if (i == sizeof (buf))
203                 return FALSE;
204         else
205                 buf[i] = '\0';
206         
207         *out = atoi (buf);
208         
209         *pos = p;
210
211         return TRUE;
212 }
213
214 static gboolean
215 skip_space (const char **pos)
216 {
217         const char *p = *pos;
218         
219         while (g_ascii_isspace (*p))
220                 p++;
221   
222         *pos = p;
223         
224         return !(*p == '\0');
225 }
226   
227 #ifdef G_OS_WIN32
228
229 /* DllMain function needed to tuck away the gdk-pixbuf DLL name */
230 G_WIN32_DLLMAIN_FOR_DLL_NAME (static, dll_name)
231
232 static char *
233 get_toplevel (void)
234 {
235   static char *toplevel = NULL;
236
237   if (toplevel == NULL)
238     toplevel = g_win32_get_package_installation_subdirectory
239       (GETTEXT_PACKAGE, dll_name, "");
240
241   return toplevel;
242 }
243
244 static char *
245 get_sysconfdir (void)
246 {
247   static char *sysconfdir = NULL;
248
249   if (sysconfdir == NULL)
250     sysconfdir = g_win32_get_package_installation_subdirectory
251       (GETTEXT_PACKAGE, dll_name, "etc");
252
253   return sysconfdir;
254 }
255
256 #undef GTK_SYSCONFDIR
257 #define GTK_SYSCONFDIR get_sysconfdir()
258
259 static void
260 correct_prefix (gchar **path)
261 {
262   if (strncmp (*path, GTK_PREFIX "/", strlen (GTK_PREFIX "/")) == 0 ||
263       strncmp (*path, GTK_PREFIX "\\", strlen (GTK_PREFIX "\\")) == 0)
264     {
265       /* This is an entry put there by gdk-pixbuf-query-loaders on the
266        * packager's system. On Windows a prebuilt GTK+ package can be
267        * installed in a random location. The gdk-pixbuf.loaders file
268        * distributed in such a package contains paths from the package
269        * builder's machine. Replace the build-time prefix with the
270        * installation prefix on this machine.
271        */
272       gchar *tem = *path;
273       *path = g_strconcat (get_toplevel (), tem + strlen (GTK_PREFIX), NULL);
274       g_free (tem);
275     }
276 }
277
278 #endif  /* G_OS_WIN32 */
279
280 static gchar *
281 gdk_pixbuf_get_module_file (void)
282 {
283   gchar *result = g_strdup (g_getenv ("GDK_PIXBUF_MODULE_FILE"));
284
285   if (!result)
286           result = g_build_filename (GTK_SYSCONFDIR, "gtk-2.0", "gdk-pixbuf.loaders", NULL);
287
288   return result;
289 }
290
291 #endif  /* USE_GMODULE */
292
293 static void 
294 gdk_pixbuf_io_init (void)
295 {
296 #ifdef USE_GMODULE
297         GIOChannel *channel;
298         gchar *line_buf;
299         gsize term;
300         GString *tmp_buf = g_string_new (NULL);
301         gboolean have_error = FALSE;
302         GdkPixbufModule *module = NULL;
303         gchar *filename = gdk_pixbuf_get_module_file ();
304         int flags;
305         int n_patterns = 0;
306         GdkPixbufModulePattern *pattern;
307         GError *error = NULL;
308 #endif
309         GdkPixbufModule *builtin_module ;
310
311         /*  initialize on separate line to avoid compiler warnings in the
312          *  common case of no compiled-in modules.
313          */
314         builtin_module = NULL;
315
316 #define load_one_builtin_module(format)                                 \
317         builtin_module = g_new0 (GdkPixbufModule, 1);                   \
318         builtin_module->module_name = #format;                          \
319         if (_gdk_pixbuf_load_module (builtin_module, NULL))             \
320                 file_formats = g_slist_prepend (file_formats, builtin_module);\
321         else                                                            \
322                 g_free (builtin_module)
323
324 #ifdef INCLUDE_ani
325         load_one_builtin_module (ani);
326 #endif
327 #ifdef INCLUDE_png
328         load_one_builtin_module (png);
329 #endif
330 #ifdef INCLUDE_bmp
331         load_one_builtin_module (bmp);
332 #endif
333 #ifdef INCLUDE_wbmp
334         load_one_builtin_module (wbmp);
335 #endif
336 #ifdef INCLUDE_gif
337         load_one_builtin_module (gif);
338 #endif
339 #ifdef INCLUDE_ico
340         load_one_builtin_module (ico);
341 #endif
342 #ifdef INCLUDE_jpeg
343         load_one_builtin_module (jpeg);
344 #endif
345 #ifdef INCLUDE_pnm
346         load_one_builtin_module (pnm);
347 #endif
348 #ifdef INCLUDE_ras
349         load_one_builtin_module (ras);
350 #endif
351 #ifdef INCLUDE_tiff
352         load_one_builtin_module (tiff);
353 #endif
354 #ifdef INCLUDE_xpm
355         load_one_builtin_module (xpm);
356 #endif
357 #ifdef INCLUDE_xbm
358         load_one_builtin_module (xbm);
359 #endif
360 #ifdef INCLUDE_tga
361         load_one_builtin_module (tga);
362 #endif
363 #ifdef INCLUDE_pcx
364         load_one_builtin_module (pcx);
365 #endif
366 #ifdef INCLUDE_icns
367         load_one_builtin_module (icns);
368 #endif
369 #ifdef INCLUDE_jasper
370         load_one_builtin_module (jasper);
371 #endif
372 #ifdef INCLUDE_gdiplus
373         /* We don't bother having the GDI+ loaders individually selectable
374          * for building in or not.
375          */
376         load_one_builtin_module (ico);
377         load_one_builtin_module (wmf);
378         load_one_builtin_module (emf);
379         load_one_builtin_module (bmp);
380         load_one_builtin_module (gif);
381         load_one_builtin_module (jpeg);
382         load_one_builtin_module (tiff);
383 #endif
384 #ifdef INCLUDE_gdip_png
385         /* Except the gdip-png loader which normally isn't built at all even */
386         load_one_builtin_module (png);
387 #endif
388
389 #undef load_one_builtin_module
390
391 #ifdef USE_GMODULE
392         channel = g_io_channel_new_file (filename, "r",  &error);
393         if (!channel) {
394                 /* Don't bother warning if we have some built-in loaders */
395                 if (file_formats == NULL)
396                         g_warning ("Cannot open pixbuf loader module file '%s': %s",
397                                    filename, error->message);
398                 return;
399         }
400         
401         while (!have_error && g_io_channel_read_line (channel, &line_buf, NULL, &term, NULL) == G_IO_STATUS_NORMAL) {
402                 const char *p;
403                 
404                 p = line_buf;
405
406                 line_buf[term] = 0;
407
408                 if (!skip_space (&p)) {
409                                 /* Blank line marking the end of a module
410                                  */
411                         if (module && *p != '#') {
412 #ifdef G_OS_WIN32
413                                 correct_prefix (&module->module_path);
414 #endif
415                                 file_formats = g_slist_prepend (file_formats, module);
416                                 module = NULL;
417                         }
418                         
419                         goto next_line;
420                 }
421
422                 if (*p == '#') 
423                         goto next_line;
424                 
425                 if (!module) {
426                                 /* Read a module location
427                                  */
428                         module = g_new0 (GdkPixbufModule, 1);
429                         n_patterns = 0;
430                         
431                         if (!scan_string (&p, tmp_buf)) {
432                                 g_warning ("Error parsing loader info in '%s'\n  %s", 
433                                            filename, line_buf);
434                                 have_error = TRUE;
435                         }
436                         module->module_path = g_strdup (tmp_buf->str);
437                 }
438                 else if (!module->module_name) {
439                         module->info = g_new0 (GdkPixbufFormat, 1);
440                         if (!scan_string (&p, tmp_buf)) {
441                                 g_warning ("Error parsing loader info in '%s'\n  %s", 
442                                            filename, line_buf);
443                                 have_error = TRUE;
444                         }
445                         module->info->name =  g_strdup (tmp_buf->str);
446                         module->module_name = module->info->name;
447
448                         if (!scan_int (&p, &flags)) {
449                                 g_warning ("Error parsing loader info in '%s'\n  %s", 
450                                            filename, line_buf);
451                                 have_error = TRUE;
452                         }
453                         module->info->flags = flags;
454                         
455                         if (!scan_string (&p, tmp_buf)) {
456                                 g_warning ("Error parsing loader info in '%s'\n  %s", 
457                                            filename, line_buf);
458                                 have_error = TRUE;
459                         }                       
460                         if (tmp_buf->str[0] != 0)
461                                 module->info->domain = g_strdup (tmp_buf->str);
462
463                         if (!scan_string (&p, tmp_buf)) {
464                                 g_warning ("Error parsing loader info in '%s'\n  %s", 
465                                            filename, line_buf);
466                                 have_error = TRUE;
467                         }                       
468                         module->info->description = g_strdup (tmp_buf->str);
469                 }
470                 else if (!module->info->mime_types) {
471                         int n = 1;
472                         module->info->mime_types = g_new0 (gchar*, 1);
473                         while (scan_string (&p, tmp_buf)) {
474                                 if (tmp_buf->str[0] != 0) {
475                                         module->info->mime_types =
476                                                 g_realloc (module->info->mime_types, (n + 1) * sizeof (gchar*));
477                                         module->info->mime_types[n - 1] = g_strdup (tmp_buf->str);
478                                         module->info->mime_types[n] = NULL;
479                                         n++;
480                                 }
481                         }
482                 }
483                 else if (!module->info->extensions) {
484                         int n = 1;
485                         module->info->extensions = g_new0 (gchar*, 1);
486                         while (scan_string (&p, tmp_buf)) {
487                                 if (tmp_buf->str[0] != 0) {
488                                         module->info->extensions =
489                                                 g_realloc (module->info->extensions, (n + 1) * sizeof (gchar*));
490                                         module->info->extensions[n - 1] = g_strdup (tmp_buf->str);
491                                         module->info->extensions[n] = NULL;
492                                         n++;
493                                 }
494                         }
495                 }
496                 else {
497                         n_patterns++;
498                         module->info->signature = (GdkPixbufModulePattern *)
499                                 g_realloc (module->info->signature, (n_patterns + 1) * sizeof (GdkPixbufModulePattern));
500                         pattern = module->info->signature + n_patterns;
501                         pattern->prefix = NULL;
502                         pattern->mask = NULL;
503                         pattern->relevance = 0;
504                         pattern--;
505                         if (!scan_string (&p, tmp_buf))
506                                 goto context_error;
507                         pattern->prefix = g_strdup (tmp_buf->str);
508                         
509                         if (!scan_string (&p, tmp_buf))
510                                 goto context_error;
511                         if (*tmp_buf->str)
512                                 pattern->mask = g_strdup (tmp_buf->str);
513                         else
514                                 pattern->mask = NULL;
515                         
516                         if (!scan_int (&p, &pattern->relevance))
517                                 goto context_error;
518                         
519                         goto next_line;
520
521                 context_error:
522                         g_free (pattern->prefix);
523                         g_free (pattern->mask);
524                         g_free (pattern);
525                         g_warning ("Error parsing loader info in '%s'\n  %s", 
526                                    filename, line_buf);
527                         have_error = TRUE;
528                 }
529         next_line:
530                 g_free (line_buf);
531         }
532         g_string_free (tmp_buf, TRUE);
533         g_io_channel_unref (channel);
534         g_free (filename);
535 #endif
536 }
537
538 #ifdef USE_GMODULE
539
540 /* actually load the image handler - gdk_pixbuf_get_module only get a */
541 /* reference to the module to load, it doesn't actually load it       */
542 /* perhaps these actions should be combined in one function           */
543 static gboolean
544 _gdk_pixbuf_load_module_unlocked (GdkPixbufModule *image_module,
545                                   GError         **error)
546 {
547         char *path;
548         GModule *module;
549         gpointer sym;
550                 
551         g_return_val_if_fail (image_module->module == NULL, FALSE);
552
553         path = image_module->module_path;
554         module = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
555
556         if (!module) {
557                 g_set_error (error,
558                              GDK_PIXBUF_ERROR,
559                              GDK_PIXBUF_ERROR_FAILED,
560                              _("Unable to load image-loading module: %s: %s"),
561                              path, g_module_error ());
562                 return FALSE;
563         }
564
565         image_module->module = module;        
566         
567         if (g_module_symbol (module, "fill_vtable", &sym)) {
568                 GdkPixbufModuleFillVtableFunc func = (GdkPixbufModuleFillVtableFunc) sym;
569                 (* func) (image_module);
570                 return TRUE;
571         } else {
572                 g_set_error (error,
573                              GDK_PIXBUF_ERROR,
574                              GDK_PIXBUF_ERROR_FAILED,
575                              _("Image-loading module %s does not export the proper interface; perhaps it's from a different GTK version?"),
576                              path);
577                 return FALSE;
578         }
579 }
580
581 #endif  /* !USE_GMODULE */
582
583 #define module(type) \
584   extern void _gdk_pixbuf__##type##_fill_info   (GdkPixbufFormat *info);   \
585   extern void _gdk_pixbuf__##type##_fill_vtable (GdkPixbufModule *module)
586
587 module (png);
588 module (jpeg);
589 module (gif);
590 module (ico);
591 module (ani);
592 module (ras);
593 module (xpm);
594 module (tiff);
595 module (pnm);
596 module (bmp);
597 module (wbmp);
598 module (xbm);
599 module (tga);
600 module (pcx);
601 module (icns);
602 module (jasper);
603 module (gdip_ico);
604 module (gdip_wmf);
605 module (gdip_emf);
606 module (gdip_bmp);
607 module (gdip_gif);
608 module (gdip_jpeg);
609 module (gdip_png);
610 module (gdip_tiff);
611
612 #undef module
613
614 gboolean
615 _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
616                          GError         **error)
617 {
618         gboolean ret;
619         gboolean locked = FALSE;
620         GdkPixbufModuleFillInfoFunc fill_info = NULL;
621         GdkPixbufModuleFillVtableFunc fill_vtable = NULL;
622
623 #define try_module(format,id)                                           \
624         if (fill_info == NULL &&                                        \
625             strcmp (image_module->module_name, #format) == 0) {         \
626                 fill_info = _gdk_pixbuf__##id##_fill_info;              \
627                 fill_vtable = _gdk_pixbuf__##id##_fill_vtable;  \
628         }
629 #ifdef INCLUDE_png      
630         try_module (png,png);
631 #endif
632 #ifdef INCLUDE_bmp
633         try_module (bmp,bmp);
634 #endif
635 #ifdef INCLUDE_wbmp
636         try_module (wbmp,wbmp);
637 #endif
638 #ifdef INCLUDE_gif
639         try_module (gif,gif);
640 #endif
641 #ifdef INCLUDE_ico
642         try_module (ico,ico);
643 #endif
644 #ifdef INCLUDE_ani
645         try_module (ani,ani);
646 #endif
647 #ifdef INCLUDE_jpeg
648         try_module (jpeg,jpeg);
649 #endif
650 #ifdef INCLUDE_pnm
651         try_module (pnm,pnm);
652 #endif
653 #ifdef INCLUDE_ras
654         try_module (ras,ras);
655 #endif
656 #ifdef INCLUDE_tiff
657         try_module (tiff,tiff);
658 #endif
659 #ifdef INCLUDE_xpm
660         try_module (xpm,xpm);
661 #endif
662 #ifdef INCLUDE_xbm
663         try_module (xbm,xbm);
664 #endif
665 #ifdef INCLUDE_tga
666         try_module (tga,tga);
667 #endif
668 #ifdef INCLUDE_pcx
669         try_module (pcx,pcx);
670 #endif
671 #ifdef INCLUDE_icns
672         try_module (icns,icns);
673 #endif
674 #ifdef INCLUDE_jasper
675         try_module (jasper,jasper);
676 #endif
677 #ifdef INCLUDE_gdiplus
678         try_module (ico,gdip_ico);
679         try_module (wmf,gdip_wmf);
680         try_module (emf,gdip_emf);
681         try_module (bmp,gdip_bmp);
682         try_module (gif,gdip_gif);
683         try_module (jpeg,gdip_jpeg);
684         try_module (tiff,gdip_tiff);
685 #endif
686 #ifdef INCLUDE_gdip_png
687         try_module (png,gdip_png);
688 #endif
689
690 #undef try_module
691         
692         if (fill_vtable) {
693                 image_module->module = (void *) 1;
694                 (* fill_vtable) (image_module);
695                 image_module->info = g_new0 (GdkPixbufFormat, 1);
696                 (* fill_info) (image_module->info);
697
698                 return TRUE;
699         }
700
701 #ifdef USE_GMODULE
702
703         /* be extra careful, maybe the module initializes
704          * the thread system
705          */
706         if (g_threads_got_initialized)
707         {
708                 G_LOCK (init_lock);
709                 locked = TRUE;
710         }
711         ret = _gdk_pixbuf_load_module_unlocked (image_module, error);
712         if (locked)
713                 G_UNLOCK (init_lock);
714         return ret;
715
716 #else
717         g_set_error (error,
718                      GDK_PIXBUF_ERROR,
719                      GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
720                      _("Image type '%s' is not supported"),
721                      image_module->module_name);
722
723         return FALSE;
724
725 #endif
726 }
727
728 \f
729
730 GdkPixbufModule *
731 _gdk_pixbuf_get_named_module (const char *name,
732                               GError **error)
733 {
734         GSList *modules;
735
736         for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
737                 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
738
739                 if (module->info->disabled)
740                         continue;
741
742                 if (!strcmp (name, module->module_name))
743                         return module;
744         }
745
746         g_set_error (error,
747                      GDK_PIXBUF_ERROR,
748                      GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
749                      _("Image type '%s' is not supported"),
750                      name);
751         
752         return NULL;
753 }
754
755 GdkPixbufModule *
756 _gdk_pixbuf_get_module (guchar *buffer, guint size,
757                         const gchar *filename,
758                         GError **error)
759 {
760         GSList *modules;
761
762         gint score, best = 0;
763         GdkPixbufModule *selected = NULL;
764         gchar *display_name = NULL;
765
766         for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
767                 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
768
769                 if (module->info->disabled)
770                         continue;
771
772                 score = format_check (module, buffer, size);
773                 if (score > best) {
774                         best = score; 
775                         selected = module;
776                 }
777                 if (score >= 100) 
778                         break;
779         }
780         if (selected != NULL)
781                 return selected;
782
783         if (filename)
784         {
785                 display_name = g_filename_display_name (filename);
786                 g_set_error (error,
787                              GDK_PIXBUF_ERROR,
788                              GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
789                              _("Couldn't recognize the image file format for file '%s'"),
790                              display_name);
791                 g_free (display_name);
792         }
793         else
794                 g_set_error (error,
795                              GDK_PIXBUF_ERROR,
796                              GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
797                              _("Unrecognized image file format"));
798
799
800         return NULL;
801 }
802
803
804 static void
805 prepared_notify (GdkPixbuf *pixbuf, 
806                  GdkPixbufAnimation *anim, 
807                  gpointer user_data)
808 {
809         if (pixbuf != NULL)
810                 g_object_ref (pixbuf);
811         *((GdkPixbuf **)user_data) = pixbuf;
812 }
813
814 GdkPixbuf *
815 _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
816                                 FILE *f,
817                                 GError **error)
818 {
819         guchar buffer[LOAD_BUFFER_SIZE];
820         size_t length;
821         GdkPixbuf *pixbuf = NULL;
822         GdkPixbufAnimation *animation = NULL;
823         gpointer context;
824         gboolean locked;
825
826         locked = _gdk_pixbuf_lock (module);
827
828         if (module->load != NULL) {
829                 pixbuf = (* module->load) (f, error);
830         } else if (module->begin_load != NULL) {
831                 
832                 context = module->begin_load (NULL, prepared_notify, NULL, &pixbuf, error);
833         
834                 if (!context)
835                         goto out;
836                 
837                 while (!feof (f) && !ferror (f)) {
838                         length = fread (buffer, 1, sizeof (buffer), f);
839                         if (length > 0)
840                                 if (!module->load_increment (context, buffer, length, error)) {
841                                         module->stop_load (context, NULL);
842                                         if (pixbuf != NULL) {
843                                                 g_object_unref (pixbuf);
844                                                 pixbuf = NULL;
845                                         }
846                                         goto out;
847                                 }
848                 }
849                 
850                 if (!module->stop_load (context, error)) {
851                         if (pixbuf != NULL) {
852                                 g_object_unref (pixbuf);
853                                 pixbuf = NULL;
854                         }
855                 }
856         } else if (module->load_animation != NULL) {
857                 animation = (* module->load_animation) (f, error);
858                 if (animation != NULL) {
859                         pixbuf = gdk_pixbuf_animation_get_static_image (animation);
860
861                         g_object_ref (pixbuf);
862                         g_object_unref (animation);
863                 }
864         }
865
866  out:
867         if (locked)
868                 _gdk_pixbuf_unlock (module);
869         return pixbuf;
870 }
871
872 /**
873  * gdk_pixbuf_new_from_file:
874  * @filename: Name of file to load, in the GLib file name encoding
875  * @error: Return location for an error
876  *
877  * Creates a new pixbuf by loading an image from a file.  The file format is
878  * detected automatically. If %NULL is returned, then @error will be set.
879  * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
880  *
881  * Return value: A newly-created pixbuf with a reference count of 1, or %NULL if
882  * any of several error conditions occurred:  the file could not be opened,
883  * there was no loader for the file's format, there was not enough memory to
884  * allocate the image buffer, or the image file contained invalid data.
885  **/
886 GdkPixbuf *
887 gdk_pixbuf_new_from_file (const char *filename,
888                           GError    **error)
889 {
890         GdkPixbuf *pixbuf;
891         int size;
892         FILE *f;
893         guchar buffer[SNIFF_BUFFER_SIZE];
894         GdkPixbufModule *image_module;
895         gchar *display_name;
896
897         g_return_val_if_fail (filename != NULL, NULL);
898         g_return_val_if_fail (error == NULL || *error == NULL, NULL);
899         
900         display_name = g_filename_display_name (filename);      
901
902         f = g_fopen (filename, "rb");
903         if (!f) {
904                 gint save_errno = errno;
905                 g_set_error (error,
906                              G_FILE_ERROR,
907                              g_file_error_from_errno (save_errno),
908                              _("Failed to open file '%s': %s"),
909                              display_name,
910                              g_strerror (save_errno));
911                 g_free (display_name);
912                 return NULL;
913         }
914
915         size = fread (&buffer, 1, sizeof (buffer), f);
916         if (size == 0) {
917                 g_set_error (error,
918                              GDK_PIXBUF_ERROR,
919                              GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
920                              _("Image file '%s' contains no data"),
921                              display_name);
922                 g_free (display_name);
923                 fclose (f);
924                 return NULL;
925         }
926
927         image_module = _gdk_pixbuf_get_module (buffer, size, filename, error);
928         if (image_module == NULL) {
929                 g_free (display_name);
930                 fclose (f);
931                 return NULL;
932         }
933
934         if (image_module->module == NULL)
935                 if (!_gdk_pixbuf_load_module (image_module, error)) {
936                         g_free (display_name);
937                         fclose (f);
938                         return NULL;
939                 }
940
941         fseek (f, 0, SEEK_SET);
942         pixbuf = _gdk_pixbuf_generic_image_load (image_module, f, error);
943         fclose (f);
944
945         if (pixbuf == NULL && error != NULL && *error == NULL) {
946
947                 /* I don't trust these crufty longjmp()'ing image libs
948                  * to maintain proper error invariants, and I don't
949                  * want user code to segfault as a result. We need to maintain
950                  * the invariant that error gets set if NULL is returned.
951                  */
952
953                 g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", image_module->module_name);
954                 g_set_error (error,
955                              GDK_PIXBUF_ERROR,
956                              GDK_PIXBUF_ERROR_FAILED,
957                              _("Failed to load image '%s': reason not known, probably a corrupt image file"),
958                              display_name);
959         } else if (error != NULL && *error != NULL) {
960
961           /* Add the filename to the error message */
962           GError *e = *error;
963           gchar  *old;
964
965           old = e->message;
966           e->message = g_strdup_printf (_("Failed to load image '%s': %s"),
967                                         display_name,
968                                         old);
969           g_free (old);
970         }
971
972         g_free (display_name);
973         return pixbuf;
974 }
975
976 #ifdef G_OS_WIN32
977
978 #undef gdk_pixbuf_new_from_file
979 GdkPixbuf *
980 gdk_pixbuf_new_from_file (const char *filename,
981                           GError    **error)
982 {
983         gchar *utf8_filename =
984                 g_locale_to_utf8 (filename, -1, NULL, NULL, error);
985         GdkPixbuf *retval;
986
987         if (utf8_filename == NULL)
988                 return NULL;
989
990         retval = gdk_pixbuf_new_from_file_utf8 (utf8_filename, error);
991
992         g_free (utf8_filename);
993
994         return retval;
995 }
996 #endif
997
998
999 /**
1000  * gdk_pixbuf_new_from_file_at_size:
1001  * @filename: Name of file to load, in the GLib file name encoding
1002  * @width: The width the image should have or -1 to not constrain the width
1003  * @height: The height the image should have or -1 to not constrain the height
1004  * @error: Return location for an error
1005  *
1006  * Creates a new pixbuf by loading an image from a file.  The file format is
1007  * detected automatically. If %NULL is returned, then @error will be set.
1008  * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
1009  * The image will be scaled to fit in the requested size, preserving
1010  * the image's aspect ratio.
1011  *
1012  * Return value: A newly-created pixbuf with a reference count of 1, or 
1013  * %NULL if any of several error conditions occurred:  the file could not 
1014  * be opened, there was no loader for the file's format, there was not 
1015  * enough memory to allocate the image buffer, or the image file contained 
1016  * invalid data.
1017  *
1018  * Since: 2.4
1019  **/
1020 GdkPixbuf *
1021 gdk_pixbuf_new_from_file_at_size (const char *filename,
1022                                   int         width, 
1023                                   int         height,
1024                                   GError    **error)
1025 {
1026         return gdk_pixbuf_new_from_file_at_scale (filename, 
1027                                                   width, height, 
1028                                                   TRUE, error);
1029 }
1030
1031 #ifdef G_OS_WIN32
1032
1033 #undef gdk_pixbuf_new_from_file_at_size
1034
1035 GdkPixbuf *
1036 gdk_pixbuf_new_from_file_at_size (const char *filename,
1037                                   int         width, 
1038                                   int         height,
1039                                   GError    **error)
1040 {
1041         gchar *utf8_filename =
1042                 g_locale_to_utf8 (filename, -1, NULL, NULL, error);
1043         GdkPixbuf *retval;
1044
1045         if (utf8_filename == NULL)
1046                 return NULL;
1047
1048         retval = gdk_pixbuf_new_from_file_at_size_utf8 (utf8_filename,
1049                                                         width, height,
1050                                                         error);
1051
1052         g_free (utf8_filename);
1053
1054         return retval;
1055 }
1056 #endif
1057
1058 typedef struct {
1059         gint width;
1060         gint height;
1061         gboolean preserve_aspect_ratio;
1062 } AtScaleData; 
1063
1064 static void
1065 at_scale_size_prepared_cb (GdkPixbufLoader *loader, 
1066                            int              width,
1067                            int              height,
1068                            gpointer         data)
1069 {
1070         AtScaleData *info = data;
1071
1072         g_return_if_fail (width > 0 && height > 0);
1073
1074         if (info->preserve_aspect_ratio && 
1075             (info->width > 0 || info->height > 0)) {
1076                 if (info->width < 0)
1077                 {
1078                         width = width * (double)info->height/(double)height;
1079                         height = info->height;
1080                 }
1081                 else if (info->height < 0)
1082                 {
1083                         height = height * (double)info->width/(double)width;
1084                         width = info->width;
1085                 }
1086                 else if ((double)height * (double)info->width >
1087                          (double)width * (double)info->height) {
1088                         width = 0.5 + (double)width * (double)info->height / (double)height;
1089                         height = info->height;
1090                 } else {
1091                         height = 0.5 + (double)height * (double)info->width / (double)width;
1092                         width = info->width;
1093                 }
1094         } else {
1095                 if (info->width > 0)
1096                         width = info->width;
1097                 if (info->height > 0)
1098                         height = info->height;
1099         }
1100         
1101         width = MAX (width, 1);
1102         height = MAX (height, 1);
1103
1104         gdk_pixbuf_loader_set_size (loader, width, height);
1105 }
1106
1107 /**
1108  * gdk_pixbuf_new_from_file_at_scale:
1109  * @filename: Name of file to load, in the GLib file name encoding
1110  * @width: The width the image should have or -1 to not constrain the width
1111  * @height: The height the image should have or -1 to not constrain the height
1112  * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio
1113  * @error: Return location for an error
1114  *
1115  * Creates a new pixbuf by loading an image from a file.  The file format is
1116  * detected automatically. If %NULL is returned, then @error will be set.
1117  * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
1118  * The image will be scaled to fit in the requested size, optionally preserving
1119  * the image's aspect ratio. 
1120  *
1121  * When preserving the aspect ratio, a @width of -1 will cause the image
1122  * to be scaled to the exact given height, and a @height of -1 will cause
1123  * the image to be scaled to the exact given width. When not preserving
1124  * aspect ratio, a @width or @height of -1 means to not scale the image 
1125  * at all in that dimension. Negative values for @width and @height are 
1126  * allowed since 2.8.
1127  *
1128  * Return value: A newly-created pixbuf with a reference count of 1, or %NULL 
1129  * if any of several error conditions occurred:  the file could not be opened,
1130  * there was no loader for the file's format, there was not enough memory to
1131  * allocate the image buffer, or the image file contained invalid data.
1132  *
1133  * Since: 2.6
1134  **/
1135 GdkPixbuf *
1136 gdk_pixbuf_new_from_file_at_scale (const char *filename,
1137                                    int         width, 
1138                                    int         height,
1139                                    gboolean    preserve_aspect_ratio,
1140                                    GError    **error)
1141 {
1142
1143         GdkPixbufLoader *loader;
1144         GdkPixbuf       *pixbuf;
1145         guchar buffer[LOAD_BUFFER_SIZE];
1146         int length;
1147         FILE *f;
1148         AtScaleData info;
1149         GdkPixbufAnimation *animation;
1150         GdkPixbufAnimationIter *iter;
1151         gboolean has_frame;
1152
1153         g_return_val_if_fail (filename != NULL, NULL);
1154         g_return_val_if_fail (width > 0 || width == -1, NULL);
1155         g_return_val_if_fail (height > 0 || height == -1, NULL);
1156
1157         f = g_fopen (filename, "rb");
1158         if (!f) {
1159                 gint save_errno = errno;
1160                 gchar *display_name = g_filename_display_name (filename);
1161                 g_set_error (error,
1162                              G_FILE_ERROR,
1163                              g_file_error_from_errno (save_errno),
1164                              _("Failed to open file '%s': %s"),
1165                              display_name,
1166                              g_strerror (save_errno));
1167                 g_free (display_name);
1168                 return NULL;
1169         }
1170
1171         loader = gdk_pixbuf_loader_new ();
1172
1173         info.width = width;
1174         info.height = height;
1175         info.preserve_aspect_ratio = preserve_aspect_ratio;
1176
1177         g_signal_connect (loader, "size-prepared", 
1178                           G_CALLBACK (at_scale_size_prepared_cb), &info);
1179
1180         has_frame = FALSE;
1181         while (!has_frame && !feof (f) && !ferror (f)) {
1182                 length = fread (buffer, 1, sizeof (buffer), f);
1183                 if (length > 0)
1184                         if (!gdk_pixbuf_loader_write (loader, buffer, length, error)) {
1185                                 gdk_pixbuf_loader_close (loader, NULL);
1186                                 fclose (f);
1187                                 g_object_unref (loader);
1188                                 return NULL;
1189                         }
1190                 
1191                 animation = gdk_pixbuf_loader_get_animation (loader);
1192                 if (animation) {
1193                         iter = gdk_pixbuf_animation_get_iter (animation, NULL);
1194                         if (!gdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) {
1195                                 has_frame = TRUE;
1196                         }
1197                         g_object_unref (iter);
1198                 }
1199         }
1200
1201         fclose (f);
1202
1203         if (!gdk_pixbuf_loader_close (loader, error) && !has_frame) {
1204                 g_object_unref (loader);
1205                 return NULL;
1206         }
1207
1208         pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1209
1210         if (!pixbuf) {
1211                 gchar *display_name = g_filename_display_name (filename);
1212                 g_object_unref (loader);
1213                 g_set_error (error,
1214                              GDK_PIXBUF_ERROR,
1215                              GDK_PIXBUF_ERROR_FAILED,
1216                              _("Failed to load image '%s': reason not known, probably a corrupt image file"),
1217                              display_name);
1218                 g_free (display_name);
1219                 return NULL;
1220         }
1221
1222         g_object_ref (pixbuf);
1223
1224         g_object_unref (loader);
1225
1226         return pixbuf;
1227 }
1228
1229 #ifdef G_OS_WIN32
1230
1231 #undef gdk_pixbuf_new_from_file_at_scale
1232
1233 GdkPixbuf *
1234 gdk_pixbuf_new_from_file_at_scale (const char *filename,
1235                                    int         width, 
1236                                    int         height,
1237                                    gboolean    preserve_aspect_ratio,
1238                                    GError    **error)
1239 {
1240         gchar *utf8_filename =
1241                 g_locale_to_utf8 (filename, -1, NULL, NULL, error);
1242         GdkPixbuf *retval;
1243
1244         if (utf8_filename == NULL)
1245                 return NULL;
1246
1247         retval = gdk_pixbuf_new_from_file_at_scale_utf8 (utf8_filename,
1248                                                          width, height,
1249                                                          preserve_aspect_ratio,
1250                                                          error);
1251
1252         g_free (utf8_filename);
1253
1254         return retval;
1255 }
1256 #endif
1257
1258
1259 static GdkPixbuf *
1260 load_from_stream (GdkPixbufLoader  *loader,
1261                   GInputStream     *stream,
1262                   GCancellable     *cancellable,
1263                   GError          **error)
1264 {
1265         GdkPixbuf *pixbuf;
1266         gssize n_read;
1267         guchar buffer[LOAD_BUFFER_SIZE];
1268         gboolean res;
1269
1270         res = TRUE;
1271         while (1) { 
1272                 n_read = g_input_stream_read (stream, 
1273                                               buffer, 
1274                                               sizeof (buffer), 
1275                                               cancellable, 
1276                                               error);
1277                 if (n_read < 0) {
1278                         res = FALSE;
1279                         error = NULL; /* Ignore further errors */
1280                         break;
1281                 }
1282
1283                 if (n_read == 0)
1284                         break;
1285
1286                 if (!gdk_pixbuf_loader_write (loader, 
1287                                               buffer, 
1288                                               n_read, 
1289                                               error)) {
1290                         res = FALSE;
1291                         error = NULL;
1292                         break;
1293                 }
1294         }
1295
1296         if (!gdk_pixbuf_loader_close (loader, error)) {
1297                 res = FALSE;
1298                 error = NULL;
1299         }
1300
1301         pixbuf = NULL;
1302         if (res) {
1303                 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1304                 if (pixbuf)
1305                         g_object_ref (pixbuf);
1306         }
1307
1308         return pixbuf;
1309 }
1310
1311
1312 /**
1313  * gdk_pixbuf_new_from_stream_at_scale:
1314  * @stream:  a #GInputStream to load the pixbuf from
1315  * @width: The width the image should have or -1 to not constrain the width
1316  * @height: The height the image should have or -1 to not constrain the height
1317  * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio
1318  * @cancellable: optional #GCancellable object, %NULL to ignore
1319  * @error: Return location for an error
1320  *
1321  * Creates a new pixbuf by loading an image from an input stream.  
1322  *
1323  * The file format is detected automatically. If %NULL is returned, then 
1324  * @error will be set. The @cancellable can be used to abort the operation
1325  * from another thread. If the operation was cancelled, the error 
1326  * %GIO_ERROR_CANCELLED will be returned. Other possible errors are in 
1327  * the #GDK_PIXBUF_ERROR and %G_IO_ERROR domains. 
1328  *
1329  * The image will be scaled to fit in the requested size, optionally 
1330  * preserving the image's aspect ratio. When preserving the aspect ratio, 
1331  * a @width of -1 will cause the image to be scaled to the exact given 
1332  * height, and a @height of -1 will cause the image to be scaled to the 
1333  * exact given width. When not preserving aspect ratio, a @width or 
1334  * @height of -1 means to not scale the image at all in that dimension.
1335  *
1336  * The stream is not closed.
1337  *
1338  * Return value: A newly-created pixbuf, or %NULL if any of several error 
1339  * conditions occurred: the file could not be opened, the image format is 
1340  * not supported, there was not enough memory to allocate the image buffer, 
1341  * the stream contained invalid data, or the operation was cancelled.
1342  *
1343  * Since: 2.14
1344  */
1345 GdkPixbuf *
1346 gdk_pixbuf_new_from_stream_at_scale (GInputStream  *stream,
1347                                      gint           width,
1348                                      gint           height,
1349                                      gboolean       preserve_aspect_ratio,
1350                                      GCancellable  *cancellable,
1351                                      GError       **error)
1352 {
1353         GdkPixbufLoader *loader;
1354         GdkPixbuf *pixbuf;
1355         AtScaleData info;
1356
1357         loader = gdk_pixbuf_loader_new ();
1358
1359         info.width = width;
1360         info.height = height;
1361         info.preserve_aspect_ratio = preserve_aspect_ratio;
1362
1363         g_signal_connect (loader, "size-prepared", 
1364                           G_CALLBACK (at_scale_size_prepared_cb), &info);
1365
1366         pixbuf = load_from_stream (loader, stream, cancellable, error);
1367         g_object_unref (loader);
1368
1369         return pixbuf;
1370 }
1371
1372 /**
1373  * gdk_pixbuf_new_from_stream:
1374  * @stream:  a #GInputStream to load the pixbuf from
1375  * @cancellable: optional #GCancellable object, %NULL to ignore
1376  * @error: Return location for an error
1377  *
1378  * Creates a new pixbuf by loading an image from an input stream.  
1379  *
1380  * The file format is detected automatically. If %NULL is returned, then 
1381  * @error will be set. The @cancellable can be used to abort the operation
1382  * from another thread. If the operation was cancelled, the error 
1383  * %GIO_ERROR_CANCELLED will be returned. Other possible errors are in 
1384  * the #GDK_PIXBUF_ERROR and %G_IO_ERROR domains. 
1385  *
1386  * The stream is not closed.
1387  *
1388  * Return value: A newly-created pixbuf, or %NULL if any of several error 
1389  * conditions occurred: the file could not be opened, the image format is 
1390  * not supported, there was not enough memory to allocate the image buffer, 
1391  * the stream contained invalid data, or the operation was cancelled.
1392  *
1393  * Since: 2.14
1394  **/
1395 GdkPixbuf *
1396 gdk_pixbuf_new_from_stream (GInputStream  *stream,
1397                             GCancellable  *cancellable,
1398                             GError       **error)
1399 {
1400         GdkPixbuf *pixbuf;
1401         GdkPixbufLoader *loader;
1402
1403         loader = gdk_pixbuf_loader_new ();
1404         pixbuf = load_from_stream (loader, stream, cancellable, error);
1405         g_object_unref (loader);
1406
1407         return pixbuf;
1408 }
1409
1410 static void
1411 info_cb (GdkPixbufLoader *loader, 
1412          int              width,
1413          int              height,
1414          gpointer         data)
1415 {
1416         struct {
1417                 GdkPixbufFormat *format;
1418                 int width;
1419                 int height;
1420         } *info = data;
1421
1422         g_return_if_fail (width > 0 && height > 0);
1423
1424         info->format = gdk_pixbuf_loader_get_format (loader);
1425         info->width = width;
1426         info->height = height;
1427
1428         gdk_pixbuf_loader_set_size (loader, 0, 0);
1429 }
1430
1431 /**
1432  * gdk_pixbuf_get_file_info:
1433  * @filename: The name of the file to identify.
1434  * @width: Return location for the width of the image, or %NULL
1435  * @height: Return location for the height of the image, or %NULL
1436  * 
1437  * Parses an image file far enough to determine its format and size.
1438  * 
1439  * Returns: A #GdkPixbufFormat describing the image format of the file 
1440  *    or %NULL if the image format wasn't recognized. The return value 
1441  *    is owned by GdkPixbuf and should not be freed.
1442  *
1443  * Since: 2.4
1444  **/
1445 GdkPixbufFormat *
1446 gdk_pixbuf_get_file_info (const gchar  *filename,
1447                           gint         *width, 
1448                           gint         *height)
1449 {
1450         GdkPixbufLoader *loader;
1451         guchar buffer[SNIFF_BUFFER_SIZE];
1452         int length;
1453         FILE *f;
1454         struct {
1455                 GdkPixbufFormat *format;
1456                 gint width;
1457                 gint height;
1458         } info;
1459
1460         g_return_val_if_fail (filename != NULL, NULL);
1461
1462         f = g_fopen (filename, "rb");
1463         if (!f)
1464                 return NULL;
1465
1466         loader = gdk_pixbuf_loader_new ();
1467
1468         info.format = NULL;
1469         info.width = -1;
1470         info.height = -1;
1471                 
1472         g_signal_connect (loader, "size-prepared", G_CALLBACK (info_cb), &info);
1473
1474         while (!feof (f) && !ferror (f)) {
1475                 length = fread (buffer, 1, sizeof (buffer), f);
1476                 if (length > 0) {
1477                         if (!gdk_pixbuf_loader_write (loader, buffer, length, NULL))
1478                                 break;
1479                 }
1480                 if (info.format != NULL)
1481                         break;
1482         }
1483
1484         fclose (f);
1485         gdk_pixbuf_loader_close (loader, NULL);
1486         g_object_unref (loader);
1487
1488         if (width) 
1489                 *width = info.width;
1490         if (height) 
1491                 *height = info.height;
1492
1493         return info.format;
1494 }
1495
1496 /**
1497  * gdk_pixbuf_new_from_xpm_data:
1498  * @data: Pointer to inline XPM data.
1499  *
1500  * Creates a new pixbuf by parsing XPM data in memory.  This data is commonly
1501  * the result of including an XPM file into a program's C source.
1502  *
1503  * Return value: A newly-created pixbuf with a reference count of 1.
1504  **/
1505 GdkPixbuf *
1506 gdk_pixbuf_new_from_xpm_data (const char **data)
1507 {
1508         GdkPixbuf *(* load_xpm_data) (const char **data);
1509         GdkPixbuf *pixbuf;
1510         GError *error = NULL;
1511         GdkPixbufModule *xpm_module;
1512         gboolean locked;
1513
1514         g_return_val_if_fail (data != NULL, NULL);
1515
1516         xpm_module = _gdk_pixbuf_get_named_module ("xpm", &error);
1517         if (xpm_module == NULL) {
1518                 g_warning ("Error loading XPM image loader: %s", error->message);
1519                 g_error_free (error);
1520                 return NULL;
1521         }
1522
1523         if (xpm_module->module == NULL) {
1524                 if (!_gdk_pixbuf_load_module (xpm_module, &error)) {
1525                         g_warning ("Error loading XPM image loader: %s", error->message);
1526                         g_error_free (error);
1527                         return NULL;
1528                 }
1529         }
1530
1531         locked = _gdk_pixbuf_lock (xpm_module);
1532
1533         if (xpm_module->load_xpm_data == NULL) {
1534                 g_warning ("gdk-pixbuf XPM module lacks XPM data capability");
1535                 pixbuf = NULL;
1536         } else {
1537                 load_xpm_data = xpm_module->load_xpm_data;
1538                 pixbuf = (* load_xpm_data) (data);
1539         }
1540         
1541         if (locked)
1542                 _gdk_pixbuf_unlock (xpm_module);
1543         return pixbuf;
1544 }
1545
1546 static void
1547 collect_save_options (va_list   opts,
1548                       gchar  ***keys,
1549                       gchar  ***vals)
1550 {
1551   gchar *key;
1552   gchar *val;
1553   gchar *next;
1554   gint count;
1555
1556   count = 0;
1557   *keys = NULL;
1558   *vals = NULL;
1559   
1560   next = va_arg (opts, gchar*);
1561   while (next)
1562     {
1563       key = next;
1564       val = va_arg (opts, gchar*);
1565
1566       ++count;
1567
1568       /* woo, slow */
1569       *keys = g_realloc (*keys, sizeof(gchar*) * (count + 1));
1570       *vals = g_realloc (*vals, sizeof(gchar*) * (count + 1));
1571       
1572       (*keys)[count-1] = g_strdup (key);
1573       (*vals)[count-1] = g_strdup (val);
1574
1575       (*keys)[count] = NULL;
1576       (*vals)[count] = NULL;
1577       
1578       next = va_arg (opts, gchar*);
1579     }
1580 }
1581
1582 static gboolean
1583 save_to_file_callback (const gchar *buf,
1584                        gsize        count,
1585                        GError     **error,
1586                        gpointer     data)
1587 {
1588         FILE *filehandle = data;
1589         gsize n;
1590
1591         n = fwrite (buf, 1, count, filehandle);
1592         if (n != count) {
1593                 gint save_errno = errno;
1594                 g_set_error (error,
1595                              G_FILE_ERROR,
1596                              g_file_error_from_errno (save_errno),
1597                              _("Error writing to image file: %s"),
1598                              g_strerror (save_errno));
1599                 return FALSE;
1600         }
1601         return TRUE;
1602 }
1603
1604 static gboolean
1605 gdk_pixbuf_real_save (GdkPixbuf     *pixbuf, 
1606                       FILE          *filehandle, 
1607                       const char    *type, 
1608                       gchar        **keys,
1609                       gchar        **values,
1610                       GError       **error)
1611 {
1612         gboolean ret;
1613         GdkPixbufModule *image_module = NULL;       
1614         gboolean locked;
1615
1616         image_module = _gdk_pixbuf_get_named_module (type, error);
1617
1618         if (image_module == NULL)
1619                 return FALSE;
1620        
1621         if (image_module->module == NULL)
1622                 if (!_gdk_pixbuf_load_module (image_module, error))
1623                         return FALSE;
1624
1625         locked = _gdk_pixbuf_lock (image_module);
1626
1627         if (image_module->save) {
1628                 /* save normally */
1629                 ret = (* image_module->save) (filehandle, pixbuf,
1630                                               keys, values,
1631                                               error);
1632         } else if (image_module->save_to_callback) {
1633                 /* save with simple callback */
1634                 ret = (* image_module->save_to_callback) (save_to_file_callback,
1635                                                           filehandle, pixbuf,
1636                                                           keys, values,
1637                                                           error);
1638         } else {
1639                 /* can't save */
1640                 g_set_error (error,
1641                              GDK_PIXBUF_ERROR,
1642                              GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
1643                              _("This build of gdk-pixbuf does not support saving the image format: %s"),
1644                              type);
1645                 ret = FALSE;
1646         }
1647
1648         if (locked)
1649                 _gdk_pixbuf_unlock (image_module);
1650         return ret;
1651 }
1652
1653 #define TMP_FILE_BUF_SIZE 4096
1654
1655 static gboolean
1656 save_to_callback_with_tmp_file (GdkPixbufModule   *image_module,
1657                                 GdkPixbuf         *pixbuf,
1658                                 GdkPixbufSaveFunc  save_func,
1659                                 gpointer           user_data,
1660                                 gchar            **keys,
1661                                 gchar            **values,
1662                                 GError           **error)
1663 {
1664         int fd;
1665         FILE *f = NULL;
1666         gboolean retval = FALSE;
1667         gchar *buf = NULL;
1668         gsize n;
1669         gchar *filename = NULL;
1670         gboolean locked;
1671
1672         buf = g_try_malloc (TMP_FILE_BUF_SIZE);
1673         if (buf == NULL) {
1674                 g_set_error (error,
1675                              GDK_PIXBUF_ERROR,
1676                              GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1677                              _("Insufficient memory to save image to callback"));
1678                 goto end;
1679         }
1680
1681         fd = g_file_open_tmp ("gdkpixbuf-save-tmp.XXXXXX", &filename, error);
1682         if (fd == -1)
1683                 goto end;
1684         f = fdopen (fd, "wb+");
1685         if (f == NULL) {
1686                 gint save_errno = errno;
1687                 g_set_error (error,
1688                              G_FILE_ERROR,
1689                              g_file_error_from_errno (save_errno),
1690                              _("Failed to open temporary file"));
1691                 goto end;
1692         }
1693
1694         locked = _gdk_pixbuf_lock (image_module);
1695         retval = (image_module->save) (f, pixbuf, keys, values, error);
1696         if (locked)
1697                 _gdk_pixbuf_unlock (image_module);
1698         if (!retval)
1699                 goto end;
1700
1701         rewind (f);
1702         for (;;) {
1703                 n = fread (buf, 1, TMP_FILE_BUF_SIZE, f);
1704                 if (n > 0) {
1705                         if (!save_func (buf, n, error, user_data))
1706                                 goto end;
1707                 }
1708                 if (n != TMP_FILE_BUF_SIZE) 
1709                         break;
1710         }
1711         if (ferror (f)) {
1712                 gint save_errno = errno;
1713                 g_set_error (error,
1714                              G_FILE_ERROR,
1715                              g_file_error_from_errno (save_errno),
1716                              _("Failed to read from temporary file"));
1717                 goto end;
1718         }
1719         retval = TRUE;
1720
1721  end:
1722         /* cleanup and return retval */
1723         if (f)
1724                 fclose (f);
1725         if (filename) {
1726                 g_unlink (filename);
1727                 g_free (filename);
1728         }
1729         g_free (buf);
1730
1731         return retval;
1732 }
1733
1734 static gboolean
1735 gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
1736                                   GdkPixbufSaveFunc  save_func,
1737                                   gpointer           user_data,
1738                                   const char        *type, 
1739                                   gchar            **keys,
1740                                   gchar            **values,
1741                                   GError           **error)
1742 {
1743         gboolean ret;
1744         GdkPixbufModule *image_module = NULL;       
1745         gboolean locked;
1746
1747         image_module = _gdk_pixbuf_get_named_module (type, error);
1748
1749         if (image_module == NULL)
1750                 return FALSE;
1751        
1752         if (image_module->module == NULL)
1753                 if (!_gdk_pixbuf_load_module (image_module, error))
1754                         return FALSE;
1755
1756         locked = _gdk_pixbuf_lock (image_module);
1757
1758         if (image_module->save_to_callback) {
1759                 /* save normally */
1760                 ret = (* image_module->save_to_callback) (save_func, user_data, 
1761                                                           pixbuf, keys, values,
1762                                                           error);
1763         } else if (image_module->save) {
1764                 /* use a temporary file */
1765                 ret = save_to_callback_with_tmp_file (image_module, pixbuf,
1766                                                       save_func, user_data, 
1767                                                       keys, values,
1768                                                       error);
1769         } else {
1770                 /* can't save */
1771                 g_set_error (error,
1772                              GDK_PIXBUF_ERROR,
1773                              GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
1774                              _("This build of gdk-pixbuf does not support saving the image format: %s"),
1775                              type);
1776                 ret = FALSE;
1777         }
1778
1779         if (locked)
1780                 _gdk_pixbuf_unlock (image_module);
1781         return ret;
1782 }
1783
1784  
1785 /**
1786  * gdk_pixbuf_save:
1787  * @pixbuf: a #GdkPixbuf.
1788  * @filename: name of file to save.
1789  * @type: name of file format.
1790  * @error: return location for error, or %NULL
1791  * @Varargs: list of key-value save options
1792  *
1793  * Saves pixbuf to a file in format @type. By default, "jpeg", "png", "ico" 
1794  * and "bmp" are possible file formats to save in, but more formats may be
1795  * installed. The list of all writable formats can be determined in the 
1796  * following way:
1797  *
1798  * |[
1799  * void add_if_writable (GdkPixbufFormat *data, GSList **list)
1800  * {
1801  *   if (gdk_pixbuf_format_is_writable (data))
1802  *     *list = g_slist_prepend (*list, data);
1803  * }
1804  * 
1805  * GSList *formats = gdk_pixbuf_get_formats ();
1806  * GSList *writable_formats = NULL;
1807  * g_slist_foreach (formats, add_if_writable, &writable_formats);
1808  * g_slist_free (formats);
1809  * ]|
1810  *
1811  * If @error is set, %FALSE will be returned. Possible errors include 
1812  * those in the #GDK_PIXBUF_ERROR domain and those in the #G_FILE_ERROR domain.
1813  *
1814  * The variable argument list should be %NULL-terminated; if not empty,
1815  * it should contain pairs of strings that modify the save
1816  * parameters. For example:
1817  * <informalexample><programlisting>
1818  * gdk_pixbuf_save (pixbuf, handle, "jpeg", &amp;error,
1819  *                  "quality", "100", NULL);
1820  * </programlisting></informalexample>
1821  *
1822  * Currently only few parameters exist. JPEG images can be saved with a
1823  * "quality" parameter; its value should be in the range [0,100].
1824  *
1825  * Text chunks can be attached to PNG images by specifying parameters of
1826  * the form "tEXt::key", where key is an ASCII string of length 1-79.
1827  * The values are UTF-8 encoded strings. The PNG compression level can
1828  * be specified using the "compression" parameter; it's value is in an
1829  * integer in the range of [0,9].
1830  *
1831  * ICO images can be saved in depth 16, 24, or 32, by using the "depth"
1832  * parameter. When the ICO saver is given "x_hot" and "y_hot" parameters,
1833  * it produces a CUR instead of an ICO.
1834  *
1835  * Return value: whether an error was set
1836  **/
1837
1838 gboolean
1839 gdk_pixbuf_save (GdkPixbuf  *pixbuf, 
1840                  const char *filename, 
1841                  const char *type, 
1842                  GError    **error,
1843                  ...)
1844 {
1845         gchar **keys = NULL;
1846         gchar **values = NULL;
1847         va_list args;
1848         gboolean result;
1849
1850         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1851         
1852         va_start (args, error);
1853         
1854         collect_save_options (args, &keys, &values);
1855         
1856         va_end (args);
1857
1858         result = gdk_pixbuf_savev (pixbuf, filename, type,
1859                                    keys, values,
1860                                    error);
1861
1862         g_strfreev (keys);
1863         g_strfreev (values);
1864
1865         return result;
1866 }
1867
1868 #ifdef G_OS_WIN32
1869
1870 #undef gdk_pixbuf_save
1871
1872 gboolean
1873 gdk_pixbuf_save (GdkPixbuf  *pixbuf, 
1874                  const char *filename, 
1875                  const char *type, 
1876                  GError    **error,
1877                  ...)
1878 {
1879         char *utf8_filename;
1880         gchar **keys = NULL;
1881         gchar **values = NULL;
1882         va_list args;
1883         gboolean result;
1884
1885         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1886         
1887         utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
1888
1889         if (utf8_filename == NULL)
1890                 return FALSE;
1891
1892         va_start (args, error);
1893         
1894         collect_save_options (args, &keys, &values);
1895         
1896         va_end (args);
1897
1898         result = gdk_pixbuf_savev_utf8 (pixbuf, utf8_filename, type,
1899                                         keys, values,
1900                                         error);
1901
1902         g_free (utf8_filename);
1903
1904         g_strfreev (keys);
1905         g_strfreev (values);
1906
1907         return result;
1908 }
1909
1910 #endif
1911
1912 /**
1913  * gdk_pixbuf_savev:
1914  * @pixbuf: a #GdkPixbuf.
1915  * @filename: name of file to save.
1916  * @type: name of file format.
1917  * @option_keys: name of options to set, %NULL-terminated
1918  * @option_values: values for named options
1919  * @error: return location for error, or %NULL
1920  *
1921  * Saves pixbuf to a file in @type, which is currently "jpeg", "png", "tiff", "ico" or "bmp".
1922  * If @error is set, %FALSE will be returned. 
1923  * See gdk_pixbuf_save () for more details.
1924  *
1925  * Return value: whether an error was set
1926  **/
1927
1928 gboolean
1929 gdk_pixbuf_savev (GdkPixbuf  *pixbuf, 
1930                   const char *filename, 
1931                   const char *type,
1932                   char      **option_keys,
1933                   char      **option_values,
1934                   GError    **error)
1935 {
1936         FILE *f = NULL;
1937         gboolean result;
1938        
1939         g_return_val_if_fail (filename != NULL, FALSE);
1940         g_return_val_if_fail (type != NULL, FALSE);
1941         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1942        
1943         f = g_fopen (filename, "wb");
1944         
1945         if (f == NULL) {
1946                 gint save_errno = errno;
1947                 gchar *display_name = g_filename_display_name (filename);
1948                 g_set_error (error,
1949                              G_FILE_ERROR,
1950                              g_file_error_from_errno (save_errno),
1951                              _("Failed to open '%s' for writing: %s"),
1952                              display_name,
1953                              g_strerror (save_errno));
1954                 g_free (display_name);
1955                 return FALSE;
1956         }
1957
1958        
1959        result = gdk_pixbuf_real_save (pixbuf, f, type,
1960                                       option_keys, option_values,
1961                                       error);
1962        
1963        
1964        if (!result) {
1965                g_return_val_if_fail (error == NULL || *error != NULL, FALSE);
1966                fclose (f);
1967                return FALSE;
1968        }
1969
1970        if (fclose (f) < 0) {
1971                gint save_errno = errno;
1972                gchar *display_name = g_filename_display_name (filename);
1973                g_set_error (error,
1974                             G_FILE_ERROR,
1975                             g_file_error_from_errno (save_errno),
1976                             _("Failed to close '%s' while writing image, all data may not have been saved: %s"),
1977                             display_name,
1978                             g_strerror (save_errno));
1979                g_free (display_name);
1980                return FALSE;
1981        }
1982        
1983        return TRUE;
1984 }
1985
1986 #ifdef G_OS_WIN32
1987
1988 #undef gdk_pixbuf_savev
1989
1990 gboolean
1991 gdk_pixbuf_savev (GdkPixbuf  *pixbuf, 
1992                   const char *filename, 
1993                   const char *type,
1994                   char      **option_keys,
1995                   char      **option_values,
1996                   GError    **error)
1997 {
1998         char *utf8_filename;
1999         gboolean retval;
2000
2001         g_return_val_if_fail (filename != NULL, FALSE);
2002        
2003         utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
2004
2005         if (utf8_filename == NULL)
2006                 return FALSE;
2007
2008         retval = gdk_pixbuf_savev_utf8 (pixbuf, utf8_filename, type,
2009                                         option_keys, option_values, error);
2010
2011         g_free (utf8_filename);
2012
2013         return retval;
2014 }
2015
2016 #endif
2017
2018 /**
2019  * gdk_pixbuf_save_to_callback:
2020  * @pixbuf: a #GdkPixbuf.
2021  * @save_func: a function that is called to save each block of data that
2022  *   the save routine generates.
2023  * @user_data: user data to pass to the save function.
2024  * @type: name of file format.
2025  * @error: return location for error, or %NULL
2026  * @Varargs: list of key-value save options
2027  *
2028  * Saves pixbuf in format @type by feeding the produced data to a 
2029  * callback. Can be used when you want to store the image to something 
2030  * other than a file, such as an in-memory buffer or a socket.  
2031  * If @error is set, %FALSE will be returned. Possible errors
2032  * include those in the #GDK_PIXBUF_ERROR domain and whatever the save
2033  * function generates.
2034  *
2035  * See gdk_pixbuf_save() for more details.
2036  *
2037  * Return value: whether an error was set
2038  *
2039  * Since: 2.4
2040  **/
2041 gboolean
2042 gdk_pixbuf_save_to_callback    (GdkPixbuf  *pixbuf,
2043                                 GdkPixbufSaveFunc save_func,
2044                                 gpointer user_data,
2045                                 const char *type, 
2046                                 GError    **error,
2047                                 ...)
2048 {
2049         gchar **keys = NULL;
2050         gchar **values = NULL;
2051         va_list args;
2052         gboolean result;
2053         
2054         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2055         
2056         va_start (args, error);
2057         
2058         collect_save_options (args, &keys, &values);
2059         
2060         va_end (args);
2061
2062         result = gdk_pixbuf_save_to_callbackv (pixbuf, save_func, user_data,
2063                                                type, keys, values,
2064                                                error);
2065
2066         g_strfreev (keys);
2067         g_strfreev (values);
2068
2069         return result;
2070 }
2071
2072 /**
2073  * gdk_pixbuf_save_to_callbackv:
2074  * @pixbuf: a #GdkPixbuf.
2075  * @save_func: a function that is called to save each block of data that
2076  *   the save routine generates.
2077  * @user_data: user data to pass to the save function.
2078  * @type: name of file format.
2079  * @option_keys: name of options to set, %NULL-terminated
2080  * @option_values: values for named options
2081  * @error: return location for error, or %NULL
2082  *
2083  * Saves pixbuf to a callback in format @type, which is currently "jpeg",
2084  * "png", "tiff", "ico" or "bmp".  If @error is set, %FALSE will be returned. See
2085  * gdk_pixbuf_save_to_callback () for more details.
2086  *
2087  * Return value: whether an error was set
2088  *
2089  * Since: 2.4
2090  **/
2091 gboolean
2092 gdk_pixbuf_save_to_callbackv   (GdkPixbuf  *pixbuf, 
2093                                 GdkPixbufSaveFunc save_func,
2094                                 gpointer user_data,
2095                                 const char *type,
2096                                 char      **option_keys,
2097                                 char      **option_values,
2098                                 GError    **error)
2099 {
2100         gboolean result;
2101         
2102        
2103         g_return_val_if_fail (save_func != NULL, FALSE);
2104         g_return_val_if_fail (type != NULL, FALSE);
2105         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2106        
2107        result = gdk_pixbuf_real_save_to_callback (pixbuf,
2108                                                   save_func, user_data, type,
2109                                                   option_keys, option_values,
2110                                                   error);
2111        
2112        if (!result) {
2113                g_return_val_if_fail (error == NULL || *error != NULL, FALSE);
2114                return FALSE;
2115        }
2116
2117        return TRUE;
2118 }
2119
2120 /**
2121  * gdk_pixbuf_save_to_buffer:
2122  * @pixbuf: a #GdkPixbuf.
2123  * @buffer: location to receive a pointer to the new buffer.
2124  * @buffer_size: location to receive the size of the new buffer.
2125  * @type: name of file format.
2126  * @error: return location for error, or %NULL
2127  * @Varargs: list of key-value save options
2128  *
2129  * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
2130  * "png", "tiff", "ico" or "bmp".  This is a convenience function that uses
2131  * gdk_pixbuf_save_to_callback() to do the real work. Note that the buffer 
2132  * is not nul-terminated and may contain embedded  nuls.
2133  * If @error is set, %FALSE will be returned and @string will be set to
2134  * %NULL. Possible errors include those in the #GDK_PIXBUF_ERROR
2135  * domain.
2136  *
2137  * See gdk_pixbuf_save() for more details.
2138  *
2139  * Return value: whether an error was set
2140  *
2141  * Since: 2.4
2142  **/
2143 gboolean
2144 gdk_pixbuf_save_to_buffer      (GdkPixbuf  *pixbuf,
2145                                 gchar     **buffer,
2146                                 gsize      *buffer_size,
2147                                 const char *type, 
2148                                 GError    **error,
2149                                 ...)
2150 {
2151         gchar **keys = NULL;
2152         gchar **values = NULL;
2153         va_list args;
2154         gboolean result;
2155         
2156         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2157         
2158         va_start (args, error);
2159         
2160         collect_save_options (args, &keys, &values);
2161         
2162         va_end (args);
2163
2164         result = gdk_pixbuf_save_to_bufferv (pixbuf, buffer, buffer_size,
2165                                              type, keys, values,
2166                                              error);
2167
2168         g_strfreev (keys);
2169         g_strfreev (values);
2170
2171         return result;
2172 }
2173
2174 struct SaveToBufferData {
2175         gchar *buffer;
2176         gsize len, max;
2177 };
2178
2179 static gboolean
2180 save_to_buffer_callback (const gchar *data,
2181                          gsize count,
2182                          GError **error,
2183                          gpointer user_data)
2184 {
2185         struct SaveToBufferData *sdata = user_data;
2186         gchar *new_buffer;
2187         gsize new_max;
2188
2189         if (sdata->len + count > sdata->max) {
2190                 new_max = MAX (sdata->max*2, sdata->len + count);
2191                 new_buffer = g_try_realloc (sdata->buffer, new_max);
2192                 if (!new_buffer) {
2193                         g_set_error (error,
2194                                      GDK_PIXBUF_ERROR,
2195                                      GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
2196                                      _("Insufficient memory to save image into a buffer"));
2197                         return FALSE;
2198                 }
2199                 sdata->buffer = new_buffer;
2200                 sdata->max = new_max;
2201         }
2202         memcpy (sdata->buffer + sdata->len, data, count);
2203         sdata->len += count;
2204         return TRUE;
2205 }
2206
2207 /**
2208  * gdk_pixbuf_save_to_bufferv:
2209  * @pixbuf: a #GdkPixbuf.
2210  * @buffer: location to receive a pointer to the new buffer.
2211  * @buffer_size: location to receive the size of the new buffer.
2212  * @type: name of file format.
2213  * @option_keys: name of options to set, %NULL-terminated
2214  * @option_values: values for named options
2215  * @error: return location for error, or %NULL
2216  *
2217  * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
2218  * "tiff", "png", "ico" or "bmp".  See gdk_pixbuf_save_to_buffer() 
2219  * for more details.
2220  *
2221  * Return value: whether an error was set
2222  *
2223  * Since: 2.4
2224  **/
2225 gboolean
2226 gdk_pixbuf_save_to_bufferv     (GdkPixbuf  *pixbuf,
2227                                 gchar     **buffer,
2228                                 gsize      *buffer_size,
2229                                 const char *type, 
2230                                 char      **option_keys,
2231                                 char      **option_values,
2232                                 GError    **error)
2233 {
2234         static const gint initial_max = 1024;
2235         struct SaveToBufferData sdata;
2236
2237         *buffer = NULL;
2238         *buffer_size = 0;
2239
2240         sdata.buffer = g_try_malloc (initial_max);
2241         sdata.max = initial_max;
2242         sdata.len = 0;
2243         if (!sdata.buffer) {
2244                 g_set_error (error,
2245                              GDK_PIXBUF_ERROR,
2246                              GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
2247                              _("Insufficient memory to save image into a buffer"));
2248                 return FALSE;
2249         }
2250
2251         if (!gdk_pixbuf_save_to_callbackv (pixbuf,
2252                                            save_to_buffer_callback, &sdata,
2253                                            type, option_keys, option_values,
2254                                            error)) {
2255                 g_free (sdata.buffer);
2256                 return FALSE;
2257         }
2258
2259         *buffer = sdata.buffer;
2260         *buffer_size = sdata.len;
2261         return TRUE;
2262 }
2263
2264 typedef struct {
2265         GOutputStream *stream;
2266         GCancellable  *cancellable;
2267 } SaveToStreamData;
2268
2269 static gboolean
2270 save_to_stream (const gchar  *buffer,
2271                 gsize         count,
2272                 GError      **error,
2273                 gpointer      data)
2274 {
2275         SaveToStreamData *sdata = (SaveToStreamData *)data;
2276         gsize remaining;
2277         gssize written;
2278         GError *my_error = NULL;
2279
2280         remaining = count;
2281         written = 0;
2282         while (remaining > 0) {
2283                 buffer += written;
2284                 remaining -= written;
2285                 written = g_output_stream_write (sdata->stream, 
2286                                                  buffer, remaining, 
2287                                                  sdata->cancellable, 
2288                                                  &my_error);
2289                 if (written < 0) {
2290                         if (!my_error) {
2291                                 g_set_error (error,
2292                                              G_IO_ERROR, 0,
2293                                              _("Error writing to image stream"));
2294                         }
2295                         else {
2296                                 g_propagate_error (error, my_error);
2297                         }
2298                         return FALSE;
2299                 }
2300         }
2301
2302         return TRUE;
2303 }
2304
2305 /** 
2306  * gdk_pixbuf_save_to_stream:
2307  * @pixbuf: a #GdkPixbuf
2308  * @stream: a #GOutputStream to save the pixbuf to
2309  * @type: name of file format
2310  * @cancellable: optional #GCancellable object, %NULL to ignore
2311  * @error: return location for error, or %NULL
2312  * @Varargs: list of key-value save options
2313  *
2314  * Saves @pixbuf to an output stream.
2315  *
2316  * Supported file formats are currently "jpeg", "tiff", "png", "ico" or 
2317  * "bmp". See gdk_pixbuf_save_to_buffer() for more details.
2318  *
2319  * The @cancellable can be used to abort the operation from another 
2320  * thread. If the operation was cancelled, the error %GIO_ERROR_CANCELLED 
2321  * will be returned. Other possible errors are in the #GDK_PIXBUF_ERROR 
2322  * and %G_IO_ERROR domains. 
2323  *
2324  * The stream is not closed.
2325  *
2326  * Returns: %TRUE if the pixbuf was saved successfully, %FALSE if an
2327  *     error was set.
2328  *
2329  * Since: 2.14
2330  */
2331 gboolean
2332 gdk_pixbuf_save_to_stream (GdkPixbuf      *pixbuf,
2333                            GOutputStream  *stream,
2334                            const char     *type,
2335                            GCancellable   *cancellable,
2336                            GError        **error,
2337                            ...)
2338 {
2339         gboolean res;
2340         gchar **keys = NULL;
2341         gchar **values = NULL;
2342         va_list args;
2343         SaveToStreamData data;
2344
2345         va_start (args, error);
2346         collect_save_options (args, &keys, &values);
2347         va_end (args);
2348
2349         data.stream = stream;
2350         data.cancellable = cancellable;
2351
2352         if (!gdk_pixbuf_save_to_callbackv (pixbuf, save_to_stream, 
2353                                            &data, type, 
2354                                            keys, values, 
2355                                            error)) {
2356                 error = NULL; /* Ignore further errors */
2357                 res = FALSE;
2358         }
2359
2360         g_strfreev (keys);
2361         g_strfreev (values);
2362
2363         return res;
2364 }
2365
2366 /**
2367  * gdk_pixbuf_format_get_name:
2368  * @format: a #GdkPixbufFormat
2369  *
2370  * Returns the name of the format.
2371  * 
2372  * Return value: the name of the format. 
2373  *
2374  * Since: 2.2
2375  */
2376 gchar *
2377 gdk_pixbuf_format_get_name (GdkPixbufFormat *format)
2378 {
2379         g_return_val_if_fail (format != NULL, NULL);
2380
2381         return g_strdup (format->name);
2382 }
2383
2384 /**
2385  * gdk_pixbuf_format_get_description:
2386  * @format: a #GdkPixbufFormat
2387  *
2388  * Returns a description of the format.
2389  * 
2390  * Return value: a description of the format.
2391  *
2392  * Since: 2.2
2393  */
2394 gchar *
2395 gdk_pixbuf_format_get_description (GdkPixbufFormat *format)
2396 {
2397         gchar *domain;
2398         gchar *description;
2399         g_return_val_if_fail (format != NULL, NULL);
2400
2401         if (format->domain != NULL) 
2402                 domain = format->domain;
2403         else 
2404                 domain = GETTEXT_PACKAGE;
2405         description = dgettext (domain, format->description);
2406
2407         return g_strdup (description);
2408 }
2409
2410 /**
2411  * gdk_pixbuf_format_get_mime_types:
2412  * @format: a #GdkPixbufFormat
2413  *
2414  * Returns the mime types supported by the format.
2415  * 
2416  * Return value: a %NULL-terminated array of mime types which must be freed with 
2417  * g_strfreev() when it is no longer needed.
2418  *
2419  * Since: 2.2
2420  */
2421 gchar **
2422 gdk_pixbuf_format_get_mime_types (GdkPixbufFormat *format)
2423 {
2424         g_return_val_if_fail (format != NULL, NULL);
2425
2426         return g_strdupv (format->mime_types);
2427 }
2428
2429 /**
2430  * gdk_pixbuf_format_get_extensions:
2431  * @format: a #GdkPixbufFormat
2432  *
2433  * Returns the filename extensions typically used for files in the 
2434  * given format.
2435  * 
2436  * Return value: a %NULL-terminated array of filename extensions which must be
2437  * freed with g_strfreev() when it is no longer needed.
2438  *
2439  * Since: 2.2
2440  */
2441 gchar **
2442 gdk_pixbuf_format_get_extensions (GdkPixbufFormat *format)
2443 {
2444         g_return_val_if_fail (format != NULL, NULL);
2445
2446         return g_strdupv (format->extensions);
2447 }
2448
2449 /**
2450  * gdk_pixbuf_format_is_writable:
2451  * @format: a #GdkPixbufFormat
2452  *
2453  * Returns whether pixbufs can be saved in the given format.
2454  * 
2455  * Return value: whether pixbufs can be saved in the given format.
2456  *
2457  * Since: 2.2
2458  */
2459 gboolean
2460 gdk_pixbuf_format_is_writable (GdkPixbufFormat *format)
2461 {
2462         g_return_val_if_fail (format != NULL, FALSE);
2463
2464         return (format->flags & GDK_PIXBUF_FORMAT_WRITABLE) != 0;
2465 }
2466
2467 /**
2468  * gdk_pixbuf_format_is_scalable:
2469  * @format: a #GdkPixbufFormat
2470  *
2471  * Returns whether this image format is scalable. If a file is in a 
2472  * scalable format, it is preferable to load it at the desired size, 
2473  * rather than loading it at the default size and scaling the 
2474  * resulting pixbuf to the desired size.
2475  * 
2476  * Return value: whether this image format is scalable.
2477  *
2478  * Since: 2.6
2479  */
2480 gboolean
2481 gdk_pixbuf_format_is_scalable (GdkPixbufFormat *format)
2482 {
2483         g_return_val_if_fail (format != NULL, FALSE);
2484
2485         return (format->flags & GDK_PIXBUF_FORMAT_SCALABLE) != 0;
2486 }
2487
2488 /**
2489  * gdk_pixbuf_format_is_disabled:
2490  * @format: a #GdkPixbufFormat
2491  *
2492  * Returns whether this image format is disabled. See
2493  * gdk_pixbuf_format_set_disabled().
2494  * 
2495  * Return value: whether this image format is disabled.
2496  *
2497  * Since: 2.6
2498  */
2499 gboolean   
2500 gdk_pixbuf_format_is_disabled (GdkPixbufFormat *format)
2501 {
2502         g_return_val_if_fail (format != NULL, FALSE);
2503
2504         return format->disabled;        
2505 }
2506
2507 /**
2508  * gdk_pixbuf_format_set_disabled:
2509  * @format: a #GdkPixbufFormat
2510  * @disabled: %TRUE to disable the format @format
2511  *
2512  * Disables or enables an image format. If a format is disabled, 
2513  * gdk-pixbuf won't use the image loader for this format to load 
2514  * images. Applications can use this to avoid using image loaders 
2515  * with an inappropriate license, see gdk_pixbuf_format_get_license().
2516  *
2517  * Since: 2.6
2518  */
2519 void 
2520 gdk_pixbuf_format_set_disabled (GdkPixbufFormat *format,
2521                                 gboolean         disabled)
2522 {
2523         g_return_if_fail (format != NULL);
2524         
2525         format->disabled = disabled != FALSE;
2526 }
2527
2528 /**
2529  * gdk_pixbuf_format_get_license:
2530  * @format: a #GdkPixbufFormat
2531  *
2532  * Returns information about the license of the image loader for the format. The
2533  * returned string should be a shorthand for a wellknown license, e.g. "LGPL",
2534  * "GPL", "QPL", "GPL/QPL", or "other" to indicate some other license.  This
2535  * string should be freed with g_free() when it's no longer needed.
2536  *
2537  * Returns: a string describing the license of @format. 
2538  *
2539  * Since: 2.6
2540  */
2541 gchar*
2542 gdk_pixbuf_format_get_license (GdkPixbufFormat *format)
2543 {
2544         g_return_val_if_fail (format != NULL, NULL);
2545
2546         return g_strdup (format->license);
2547 }
2548
2549 GdkPixbufFormat *
2550 _gdk_pixbuf_get_format (GdkPixbufModule *module)
2551 {
2552         g_return_val_if_fail (module != NULL, NULL);
2553
2554         return module->info;
2555 }
2556
2557 /**
2558  * gdk_pixbuf_get_formats:
2559  *
2560  * Obtains the available information about the image formats supported
2561  * by GdkPixbuf.
2562  *
2563  * Returns: A list of #GdkPixbufFormat<!-- -->s describing the supported 
2564  * image formats.  The list should be freed when it is no longer needed, 
2565  * but the structures themselves are owned by #GdkPixbuf and should not be 
2566  * freed.  
2567  *
2568  * Since: 2.2
2569  */
2570 GSList *
2571 gdk_pixbuf_get_formats (void)
2572 {
2573         GSList *result = NULL;
2574         GSList *modules;
2575
2576         for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
2577                 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
2578                 GdkPixbufFormat *info = _gdk_pixbuf_get_format (module);
2579                 result = g_slist_prepend (result, info);
2580         }
2581
2582         return result;
2583 }
2584
2585
2586 #define __GDK_PIXBUF_IO_C__
2587 #include "gdk-pixbuf-aliasdef.c"