1 /* -*- mode: C; c-file-style: "linux" -*- */
2 /* GdkPixbuf library - Main loading interface.
4 * Copyright (C) 1999 The Free Software Foundation
6 * Authors: Miguel de Icaza <miguel@gnu.org>
7 * Federico Mena-Quintero <federico@gimp.org>
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.
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.
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.
36 #include "gdk-pixbuf-alias.h"
37 #include "gdk-pixbuf-private.h"
38 #include "gdk-pixbuf-io.h"
47 format_check (GdkPixbufModule *module, guchar *buffer, int size)
51 GdkPixbufModulePattern *pattern;
53 for (pattern = module->info->signature; pattern->prefix; pattern++) {
54 for (j = 0; j < size && pattern->prefix[j] != 0; j++) {
55 m = pattern->mask ? pattern->mask[j] : ' ';
57 if (buffer[j] != pattern->prefix[j])
61 if (buffer[j] == pattern->prefix[j])
73 if (pattern->prefix[j] == 0)
74 return pattern->relevance;
79 static GSList *file_formats = NULL;
81 static void gdk_pixbuf_io_init ();
84 get_file_formats (void)
86 if (file_formats == NULL)
87 gdk_pixbuf_io_init ();
96 scan_string (const char **pos, GString *out)
98 const char *p = *pos, *q = *pos;
102 while (g_ascii_isspace (*p))
107 else if (*p == '"') {
110 for (q = p; (*q != '"') || quoted; q++) {
113 quoted = (*q == '\\') && !quoted;
116 tmp = g_strndup (p, q - p);
117 tmp2 = g_strcompress (tmp);
118 g_string_truncate (out, 0);
119 g_string_append (out, tmp2);
131 scan_int (const char **pos, int *out)
135 const char *p = *pos;
137 while (g_ascii_isspace (*p))
140 if (*p < '0' || *p > '9')
143 while ((*p >= '0') && (*p <= '9') && i < sizeof (buf)) {
149 if (i == sizeof (buf))
162 skip_space (const char **pos)
164 const char *p = *pos;
166 while (g_ascii_isspace (*p))
171 return !(*p == '\0');
176 /* DllMain function needed to tuck away the gdk-pixbuf DLL name */
177 G_WIN32_DLLMAIN_FOR_DLL_NAME (static, dll_name)
182 static char *toplevel = NULL;
184 if (toplevel == NULL)
185 toplevel = g_win32_get_package_installation_subdirectory
186 (GETTEXT_PACKAGE, dll_name, "");
192 get_sysconfdir (void)
194 static char *sysconfdir = NULL;
196 if (sysconfdir == NULL)
197 sysconfdir = g_win32_get_package_installation_subdirectory
198 (GETTEXT_PACKAGE, dll_name, "etc");
203 #undef GTK_SYSCONFDIR
204 #define GTK_SYSCONFDIR get_sysconfdir()
207 correct_prefix (gchar **path)
209 if (strncmp (*path, GTK_PREFIX "/", strlen (GTK_PREFIX "/")) == 0 ||
210 strncmp (*path, GTK_PREFIX "\\", strlen (GTK_PREFIX "\\")) == 0)
212 /* This is an entry put there by gdk-pixbuf-query-loaders on the
213 * packager's system. On Windows a prebuilt GTK+ package can be
214 * installed in a random location. The gdk-pixbuf.loaders file
215 * distributed in such a package contains paths from the package
216 * builder's machine. Replace the build-time prefix with the
217 * installation prefix on this machine.
220 *path = g_strconcat (get_toplevel (), tem + strlen (GTK_PREFIX), NULL);
228 gdk_pixbuf_get_module_file (void)
230 gchar *result = g_strdup (g_getenv ("GDK_PIXBUF_MODULE_FILE"));
233 result = g_build_filename (GTK_SYSCONFDIR, "gtk-2.0", "gdk-pixbuf.loaders", NULL);
239 gdk_pixbuf_io_init (void)
244 GString *tmp_buf = g_string_new (NULL);
245 gboolean have_error = FALSE;
246 GdkPixbufModule *module = NULL;
247 gchar *filename = gdk_pixbuf_get_module_file ();
250 GdkPixbufModulePattern *pattern;
251 GError *error = NULL;
253 channel = g_io_channel_new_file (filename, "r", &error);
255 g_warning ("Cannot open pixbuf loader module file '%s': %s",
256 filename, error->message);
260 while (!have_error && g_io_channel_read_line (channel, &line_buf, NULL, &term, NULL) == G_IO_STATUS_NORMAL) {
267 if (!skip_space (&p)) {
268 /* Blank line marking the end of a module
270 if (module && *p != '#') {
272 correct_prefix (&module->module_path);
274 file_formats = g_slist_prepend (file_formats, module);
285 /* Read a module location
287 module = g_new0 (GdkPixbufModule, 1);
290 if (!scan_string (&p, tmp_buf)) {
291 g_warning ("Error parsing loader info in '%s'\n %s",
295 module->module_path = g_strdup (tmp_buf->str);
297 else if (!module->module_name) {
298 module->info = g_new0 (GdkPixbufFormat, 1);
299 if (!scan_string (&p, tmp_buf)) {
300 g_warning ("Error parsing loader info in '%s'\n %s",
304 module->info->name = g_strdup (tmp_buf->str);
305 module->module_name = module->info->name;
307 if (!scan_int (&p, &flags)) {
308 g_warning ("Error parsing loader info in '%s'\n %s",
312 module->info->flags = flags;
314 if (!scan_string (&p, tmp_buf)) {
315 g_warning ("Error parsing loader info in '%s'\n %s",
319 if (tmp_buf->str[0] != 0)
320 module->info->domain = g_strdup (tmp_buf->str);
322 if (!scan_string (&p, tmp_buf)) {
323 g_warning ("Error parsing loader info in '%s'\n %s",
327 module->info->description = g_strdup (tmp_buf->str);
329 else if (!module->info->mime_types) {
331 module->info->mime_types = g_new0 (gchar*, 1);
332 while (scan_string (&p, tmp_buf)) {
333 if (tmp_buf->str[0] != 0) {
334 module->info->mime_types =
335 g_realloc (module->info->mime_types, (n + 1) * sizeof (gchar*));
336 module->info->mime_types[n - 1] = g_strdup (tmp_buf->str);
337 module->info->mime_types[n] = NULL;
342 else if (!module->info->extensions) {
344 module->info->extensions = g_new0 (gchar*, 1);
345 while (scan_string (&p, tmp_buf)) {
346 if (tmp_buf->str[0] != 0) {
347 module->info->extensions =
348 g_realloc (module->info->extensions, (n + 1) * sizeof (gchar*));
349 module->info->extensions[n - 1] = g_strdup (tmp_buf->str);
350 module->info->extensions[n] = NULL;
357 module->info->signature = (GdkPixbufModulePattern *)
358 g_realloc (module->info->signature, (n_patterns + 1) * sizeof (GdkPixbufModulePattern));
359 pattern = module->info->signature + n_patterns;
360 pattern->prefix = NULL;
361 pattern->mask = NULL;
362 pattern->relevance = 0;
364 if (!scan_string (&p, tmp_buf))
366 pattern->prefix = g_strdup (tmp_buf->str);
368 if (!scan_string (&p, tmp_buf))
371 pattern->mask = g_strdup (tmp_buf->str);
373 pattern->mask = NULL;
375 if (!scan_int (&p, &pattern->relevance))
381 g_free (pattern->prefix);
382 g_free (pattern->mask);
384 g_warning ("Error parsing loader info in '%s'\n %s",
391 g_string_free (tmp_buf, TRUE);
392 g_io_channel_unref (channel);
396 /* actually load the image handler - gdk_pixbuf_get_module only get a */
397 /* reference to the module to load, it doesn't actually load it */
398 /* perhaps these actions should be combined in one function */
400 _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
407 g_return_val_if_fail (image_module->module == NULL, FALSE);
409 path = image_module->module_path;
410 module = g_module_open (path, G_MODULE_BIND_LAZY);
415 GDK_PIXBUF_ERROR_FAILED,
416 _("Unable to load image-loading module: %s: %s"),
417 path, g_module_error ());
421 image_module->module = module;
423 if (g_module_symbol (module, "fill_vtable", &sym)) {
424 GdkPixbufModuleFillVtableFunc func = (GdkPixbufModuleFillVtableFunc) sym;
425 (* func) (image_module);
430 GDK_PIXBUF_ERROR_FAILED,
431 _("Image-loading module %s does not export the proper interface; perhaps it's from a different GTK version?"),
438 #define module(type) \
439 extern void MODULE_ENTRY (type, fill_info) (GdkPixbufFormat *info); \
440 extern void MODULE_ENTRY (type, fill_vtable) (GdkPixbufModule *module)
458 _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
461 GdkPixbufModuleFillInfoFunc fill_info = NULL;
462 GdkPixbufModuleFillVtableFunc fill_vtable = NULL;
464 image_module->module = (void *) 1;
467 /* Ugly hack so we can use else if unconditionally below ;-) */
471 else if (strcmp (image_module->module_name, "png") == 0) {
472 fill_info = MODULE_ENTRY (png, fill_info);
473 fill_vtable = MODULE_ENTRY (png, fill_vtable);
478 else if (strcmp (image_module->module_name, "bmp") == 0) {
479 fill_info = MODULE_ENTRY (bmp, fill_info);
480 fill_vtable = MODULE_ENTRY (bmp, fill_vtable);
485 else if (strcmp (image_module->module_name, "wbmp") == 0) {
486 fill_info = MODULE_ENTRY (wbmp, fill_info);
487 fill_vtable = MODULE_ENTRY (wbmp, fill_vtable);
492 else if (strcmp (image_module->module_name, "gif") == 0) {
493 fill_info = MODULE_ENTRY (gif, fill_info);
494 fill_vtable = MODULE_ENTRY (gif, fill_vtable);
499 else if (strcmp (image_module->module_name, "ico") == 0) {
500 fill_info = MODULE_ENTRY (ico, fill_info);
501 fill_vtable = MODULE_ENTRY (ico, fill_vtable);
506 else if (strcmp (image_module->module_name, "ani") == 0) {
507 fill_info = MODULE_ENTRY (ani, fill_info);
508 fill_vtable = MODULE_ENTRY (ani, fill_vtable);
513 else if (strcmp (image_module->module_name, "jpeg") == 0) {
514 fill_info = MODULE_ENTRY (jpeg, fill_info);
515 fill_vtable = MODULE_ENTRY (jpeg, fill_vtable);
520 else if (strcmp (image_module->module_name, "pnm") == 0) {
521 fill_info = MODULE_ENTRY (pnm, fill_info);
522 fill_vtable = MODULE_ENTRY (pnm, fill_vtable);
527 else if (strcmp (image_module->module_name, "ras") == 0) {
528 fill_info = MODULE_ENTRY (ras, fill_info);
529 fill_vtable = MODULE_ENTRY (ras, fill_vtable);
534 else if (strcmp (image_module->module_name, "tiff") == 0) {
535 fill_info = MODULE_ENTRY (tiff, fill_info);
536 fill_vtable = MODULE_ENTRY (tiff, fill_vtable);
541 else if (strcmp (image_module->module_name, "xpm") == 0) {
542 fill_info = MODULE_ENTRY (xpm, fill_info);
543 fill_vtable = MODULE_ENTRY (xpm, fill_vtable);
548 else if (strcmp (image_module->module_name, "xbm") == 0) {
549 fill_info = MODULE_ENTRY (xbm, fill_info);
550 fill_vtable = MODULE_ENTRY (xbm, fill_vtable);
555 else if (strcmp (image_module->module_name, "tga") == 0) {
556 fill_info = MODULE_ENTRY (tga, fill_info);
557 fill_vtable = MODULE_ENTRY (tga, fill_vtable);
562 else if (strcmp (image_module->module_name, "pcx") == 0) {
563 fill_info = MODULE_ENTRY (pcx, fill_info);
564 fill_vtable = MODULE_ENTRY (pcx, fill_vtable);
569 (* fill_vtable) (image_module);
570 image_module->info = g_new0 (GdkPixbufFormat, 1);
571 (* fill_info) (image_module->info);
577 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
578 _("Image type '%s' is not supported"),
579 image_module->module_name);
586 gdk_pixbuf_io_init ()
588 gchar *included_formats[] = {
589 "ani", "png", "bmp", "wbmp", "gif",
590 "ico", "jpeg", "pnm", "ras", "tiff",
591 "xpm", "xbm", "tga", "pcx",
595 GdkPixbufModule *module = NULL;
597 for (name = included_formats; *name; name++) {
598 module = g_new0 (GdkPixbufModule, 1);
599 module->module_name = *name;
600 if (_gdk_pixbuf_load_module (module, NULL))
601 file_formats = g_slist_prepend (file_formats, module);
612 _gdk_pixbuf_get_named_module (const char *name,
617 for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
618 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
620 if (module->info->disabled)
623 if (!strcmp (name, module->module_name))
629 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
630 _("Image type '%s' is not supported"),
637 _gdk_pixbuf_get_module (guchar *buffer, guint size,
638 const gchar *filename,
643 gint score, best = 0;
644 GdkPixbufModule *selected = NULL;
645 gchar *utf8_filename = NULL;
647 for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
648 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
650 if (module->info->disabled)
653 score = format_check (module, buffer, size);
661 if (selected != NULL)
665 utf8_filename = g_filename_to_utf8 (filename, -1,
671 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
672 _("Couldn't recognize the image file format for file '%s'"),
674 g_free (utf8_filename);
679 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
680 _("Unrecognized image file format"));
688 prepared_notify (GdkPixbuf *pixbuf,
689 GdkPixbufAnimation *anim,
693 g_object_ref (pixbuf);
694 *((GdkPixbuf **)user_data) = pixbuf;
698 _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
704 GdkPixbuf *pixbuf = NULL;
705 GdkPixbufAnimation *animation = NULL;
708 if (module->load != NULL)
709 return (* module->load) (f, error);
711 if (module->begin_load != NULL) {
713 context = module->begin_load (NULL, prepared_notify, NULL, &pixbuf, error);
718 while (!feof (f) && !ferror (f)) {
719 length = fread (buffer, 1, sizeof (buffer), f);
721 if (!module->load_increment (context, buffer, length, error)) {
722 module->stop_load (context, NULL);
724 g_object_unref (pixbuf);
729 if (!module->stop_load (context, error)) {
731 g_object_unref (pixbuf);
738 if (module->load_animation != NULL) {
739 animation = (* module->load_animation) (f, error);
740 if (animation != NULL) {
741 pixbuf = gdk_pixbuf_animation_get_static_image (animation);
743 g_object_ref (pixbuf);
745 g_object_unref (animation);
755 * gdk_pixbuf_new_from_file:
756 * @filename: Name of file to load.
757 * @error: Return location for an error
759 * Creates a new pixbuf by loading an image from a file. The file format is
760 * detected automatically. If %NULL is returned, then @error will be set.
761 * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
763 * Return value: A newly-created pixbuf with a reference count of 1, or %NULL if
764 * any of several error conditions occurred: the file could not be opened,
765 * there was no loader for the file's format, there was not enough memory to
766 * allocate the image buffer, or the image file contained invalid data.
769 gdk_pixbuf_new_from_file (const char *filename,
776 GdkPixbufModule *image_module;
778 g_return_val_if_fail (filename != NULL, NULL);
779 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
781 f = fopen (filename, "rb");
783 gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
787 g_file_error_from_errno (errno),
788 _("Failed to open file '%s': %s"),
789 utf8_filename ? utf8_filename : "???",
791 g_free (utf8_filename);
795 size = fread (&buffer, 1, sizeof (buffer), f);
797 gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
801 GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
802 _("Image file '%s' contains no data"),
803 utf8_filename ? utf8_filename : "???");
804 g_free (utf8_filename);
809 image_module = _gdk_pixbuf_get_module (buffer, size, filename, error);
810 if (image_module == NULL) {
815 if (image_module->module == NULL)
816 if (!_gdk_pixbuf_load_module (image_module, error)) {
821 fseek (f, 0, SEEK_SET);
822 pixbuf = _gdk_pixbuf_generic_image_load (image_module, f, error);
825 if (pixbuf == NULL && error != NULL && *error == NULL) {
827 /* I don't trust these crufty longjmp()'ing image libs
828 * to maintain proper error invariants, and I don't
829 * want user code to segfault as a result. We need to maintain
830 * the invariant that error gets set if NULL is returned.
833 gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
836 g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", image_module->module_name);
839 GDK_PIXBUF_ERROR_FAILED,
840 _("Failed to load image '%s': reason not known, probably a corrupt image file"),
841 utf8_filename ? utf8_filename : "???");
842 g_free (utf8_filename);
843 } else if (error != NULL && *error != NULL) {
845 /* Add the filename to the error message */
848 gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
853 e->message = g_strdup_printf (_("Failed to load image '%s': %s"),
854 utf8_filename ? utf8_filename : "???",
857 g_free (utf8_filename);
865 size_prepared_cb (GdkPixbufLoader *loader,
873 gboolean preserve_aspect_ratio;
876 g_return_if_fail (width > 0 && height > 0);
878 if(info->preserve_aspect_ratio) {
879 if ((double)height * (double)info->width >
880 (double)width * (double)info->height) {
881 width = 0.5 + (double)width * (double)info->height / (double)height;
882 height = info->height;
884 height = 0.5 + (double)height * (double)info->width / (double)width;
889 height = info->height;
892 gdk_pixbuf_loader_set_size (loader, width, height);
896 * gdk_pixbuf_new_from_file_at_scale:
897 * @filename: Name of file to load.
898 * @width: The width the image should have
899 * @height: The height the image should have
900 * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio
901 * @error: Return location for an error
903 * Creates a new pixbuf by loading an image from a file. The file format is
904 * detected automatically. If %NULL is returned, then @error will be set.
905 * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
906 * The image will be scaled to fit in the requested size, optionally preserving
907 * the image's aspect ratio.
909 * Return value: A newly-created pixbuf with a reference count of 1, or %NULL
910 * if any of several error conditions occurred: the file could not be opened,
911 * there was no loader for the file's format, there was not enough memory to
912 * allocate the image buffer, or the image file contained invalid data.
917 gdk_pixbuf_new_from_file_at_scale (const char *filename,
920 gboolean preserve_aspect_ratio,
924 GdkPixbufLoader *loader;
927 guchar buffer [4096];
933 gboolean preserve_aspect_ratio;
936 g_return_val_if_fail (filename != NULL, NULL);
937 g_return_val_if_fail (width > 0 && height > 0, NULL);
939 f = fopen (filename, "rb");
941 gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
945 g_file_error_from_errno (errno),
946 _("Failed to open file '%s': %s"),
947 utf8_filename ? utf8_filename : "???",
949 g_free (utf8_filename);
953 loader = gdk_pixbuf_loader_new ();
956 info.height = height;
957 info.preserve_aspect_ratio = preserve_aspect_ratio;
959 g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
961 while (!feof (f) && !ferror (f)) {
962 length = fread (buffer, 1, sizeof (buffer), f);
964 if (!gdk_pixbuf_loader_write (loader, buffer, length, error)) {
965 gdk_pixbuf_loader_close (loader, NULL);
967 g_object_unref (loader);
974 if (!gdk_pixbuf_loader_close (loader, error)) {
975 g_object_unref (loader);
979 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
982 gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
985 g_object_unref (loader);
989 GDK_PIXBUF_ERROR_FAILED,
990 _("Failed to load image '%s': reason not known, probably a corrupt image file"),
991 utf8_filename ? utf8_filename : "???");
992 g_free (utf8_filename);
996 g_object_ref (pixbuf);
998 g_object_unref (loader);
1004 * gdk_pixbuf_new_from_file_at_size:
1005 * @filename: Name of file to load.
1006 * @width: The width the image should have
1007 * @height: The height the image should have
1008 * @error: Return location for an error
1010 * Creates a new pixbuf by loading an image from a file. The file format is
1011 * detected automatically. If %NULL is returned, then @error will be set.
1012 * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
1013 * The image will be scaled to fit in the requested size, preserving
1014 * the image's aspect ratio.
1016 * Return value: A newly-created pixbuf with a reference count of 1, or
1017 * %NULL if any of several error conditions occurred: the file could not
1018 * be opened, there was no loader for the file's format, there was not
1019 * enough memory to allocate the image buffer, or the image file contained
1025 gdk_pixbuf_new_from_file_at_size (const char *filename,
1030 return gdk_pixbuf_new_from_file_at_scale (filename,
1036 info_cb (GdkPixbufLoader *loader,
1042 GdkPixbufFormat *format;
1047 g_return_if_fail (width > 0 && height > 0);
1049 info->format = gdk_pixbuf_loader_get_format (loader);
1050 info->width = width;
1051 info->height = height;
1053 gdk_pixbuf_loader_set_size (loader, 0, 0);
1057 * gdk_pixbuf_get_file_info:
1058 * @filename: The name of the file to identify.
1059 * @width: Return location for the width of the image, or %NULL
1060 * @height: Return location for the height of the image, or %NULL
1062 * Parses an image file far enough to determine its format and size.
1064 * Returns: A #GdkPixbufFormat describing the image format of the file
1065 * or %NULL if the image format wasn't recognized. The return value
1066 * is owned by GdkPixbuf and should not be freed.
1071 gdk_pixbuf_get_file_info (const gchar *filename,
1075 GdkPixbufLoader *loader;
1076 guchar buffer [4096];
1080 GdkPixbufFormat *format;
1085 g_return_val_if_fail (filename != NULL, NULL);
1087 f = fopen (filename, "rb");
1091 loader = gdk_pixbuf_loader_new ();
1097 g_signal_connect (loader, "size-prepared", G_CALLBACK (info_cb), &info);
1099 while (!feof (f) && !ferror (f)) {
1100 length = fread (buffer, 1, sizeof (buffer), f);
1102 if (!gdk_pixbuf_loader_write (loader, buffer, length, NULL))
1105 if (info.format != NULL)
1110 gdk_pixbuf_loader_close (loader, NULL);
1111 g_object_unref (loader);
1114 *width = info.width;
1116 *height = info.height;
1122 * gdk_pixbuf_new_from_xpm_data:
1123 * @data: Pointer to inline XPM data.
1125 * Creates a new pixbuf by parsing XPM data in memory. This data is commonly
1126 * the result of including an XPM file into a program's C source.
1128 * Return value: A newly-created pixbuf with a reference count of 1.
1131 gdk_pixbuf_new_from_xpm_data (const char **data)
1133 GdkPixbuf *(* load_xpm_data) (const char **data);
1135 GError *error = NULL;
1136 GdkPixbufModule *xpm_module = _gdk_pixbuf_get_named_module ("xpm", &error);
1137 if (xpm_module == NULL) {
1138 g_warning ("Error loading XPM image loader: %s", error->message);
1139 g_error_free (error);
1143 if (xpm_module->module == NULL) {
1144 if (!_gdk_pixbuf_load_module (xpm_module, &error)) {
1145 g_warning ("Error loading XPM image loader: %s", error->message);
1146 g_error_free (error);
1151 if (xpm_module->load_xpm_data == NULL) {
1152 g_warning ("gdk-pixbuf XPM module lacks XPM data capability");
1155 load_xpm_data = xpm_module->load_xpm_data;
1157 pixbuf = (* load_xpm_data) (data);
1162 collect_save_options (va_list opts,
1175 next = va_arg (opts, gchar*);
1179 val = va_arg (opts, gchar*);
1184 *keys = g_realloc (*keys, sizeof(gchar*) * (count + 1));
1185 *vals = g_realloc (*vals, sizeof(gchar*) * (count + 1));
1187 (*keys)[count-1] = g_strdup (key);
1188 (*vals)[count-1] = g_strdup (val);
1190 (*keys)[count] = NULL;
1191 (*vals)[count] = NULL;
1193 next = va_arg (opts, gchar*);
1198 save_to_file_callback (const gchar *buf,
1203 FILE *filehandle = data;
1206 n = fwrite (buf, 1, count, filehandle);
1210 g_file_error_from_errno (errno),
1211 _("Error writing to image file: %s"),
1212 g_strerror (errno));
1219 gdk_pixbuf_real_save (GdkPixbuf *pixbuf,
1226 GdkPixbufModule *image_module = NULL;
1228 image_module = _gdk_pixbuf_get_named_module (type, error);
1230 if (image_module == NULL)
1233 if (image_module->module == NULL)
1234 if (!_gdk_pixbuf_load_module (image_module, error))
1237 if (image_module->save) {
1239 return (* image_module->save) (filehandle, pixbuf,
1243 else if (image_module->save_to_callback) {
1244 /* save with simple callback */
1245 return (* image_module->save_to_callback) (save_to_file_callback,
1254 GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
1255 _("This build of gdk-pixbuf does not support saving the image format: %s"),
1261 #define TMP_FILE_BUF_SIZE 4096
1264 save_to_callback_with_tmp_file (GdkPixbufModule *image_module,
1266 GdkPixbufSaveFunc save_func,
1274 gboolean retval = FALSE;
1277 gchar *filename = NULL;
1279 buf = g_try_malloc (TMP_FILE_BUF_SIZE);
1283 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1284 _("Insufficient memory to save image to callback"));
1288 fd = g_file_open_tmp ("gdkpixbuf-save-tmp.XXXXXX", &filename, error);
1291 f = fdopen (fd, "wb+");
1295 g_file_error_from_errno (errno),
1296 _("Failed to open temporary file"));
1299 if (!(* image_module->save) (f, pixbuf, keys, values, error))
1303 n = fread (buf, 1, TMP_FILE_BUF_SIZE, f);
1305 if (!save_func (buf, n, error, user_data))
1308 if (n != TMP_FILE_BUF_SIZE)
1314 g_file_error_from_errno (errno),
1315 _("Failed to read from temporary file"));
1321 /* cleanup and return retval */
1334 gdk_pixbuf_real_save_to_callback (GdkPixbuf *pixbuf,
1335 GdkPixbufSaveFunc save_func,
1342 GdkPixbufModule *image_module = NULL;
1344 image_module = _gdk_pixbuf_get_named_module (type, error);
1346 if (image_module == NULL)
1349 if (image_module->module == NULL)
1350 if (!_gdk_pixbuf_load_module (image_module, error))
1353 if (image_module->save_to_callback) {
1355 return (* image_module->save_to_callback) (save_func, user_data,
1356 pixbuf, keys, values,
1359 else if (image_module->save) {
1360 /* use a temporary file */
1361 return save_to_callback_with_tmp_file (image_module, pixbuf,
1362 save_func, user_data,
1370 GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
1371 _("This build of gdk-pixbuf does not support saving the image format: %s"),
1380 * @pixbuf: a #GdkPixbuf.
1381 * @filename: name of file to save.
1382 * @type: name of file format.
1383 * @error: return location for error, or %NULL
1384 * @Varargs: list of key-value save options
1386 * Saves pixbuf to a file in format @type. By default, "jpeg", "png" and
1387 * "ico" are possible file formats to save in, but more formats may be
1388 * installed. The list of all writable formats can be determined in the
1391 * <informalexample><programlisting>
1392 * void add_if_writable (GdkPixbufFormat *data, GSList **list)
1394 * if (gdk_pixbuf_format_is_writable (data))
1395 * *list = g_slist_prepend (*list, data);
1398 * GSList *formats = gdk_pixbuf_get_formats (<!-- -->);
1399 * GSList *writable_formats = NULL;
1400 * g_slist_foreach (formats, add_if_writable, &writable_formats);
1401 * g_slist_free (formats);
1402 * </programlisting></informalexample>
1404 * If @error is set, %FALSE will be returned. Possible errors include
1405 * those in the #GDK_PIXBUF_ERROR domain and those in the #G_FILE_ERROR domain.
1407 * The variable argument list should be %NULL-terminated; if not empty,
1408 * it should contain pairs of strings that modify the save
1409 * parameters. For example:
1410 * <informalexample><programlisting>
1411 * gdk_pixbuf_save (pixbuf, handle, "jpeg", &error,
1412 * "quality", "100", NULL);
1413 * </programlisting></informalexample>
1415 * Currently only few parameters exist. JPEG images can be saved with a
1416 * "quality" parameter; its value should be in the range [0,100].
1417 * Text chunks can be attached to PNG images by specifying parameters of
1418 * the form "tEXt::key", where key is an ASCII string of length 1-79.
1419 * The values are UTF-8 encoded strings.
1420 * ICO images can be saved in depth 16, 24, or 32, by using the "depth"
1421 * parameter. When the ICO saver is given "x_hot" and "y_hot" parameters,
1422 * it produces a CUR instead of an ICO.
1424 * Return value: whether an error was set
1428 gdk_pixbuf_save (GdkPixbuf *pixbuf,
1429 const char *filename,
1434 gchar **keys = NULL;
1435 gchar **values = NULL;
1439 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1441 va_start (args, error);
1443 collect_save_options (args, &keys, &values);
1447 result = gdk_pixbuf_savev (pixbuf, filename, type,
1452 g_strfreev (values);
1459 * @pixbuf: a #GdkPixbuf.
1460 * @filename: name of file to save.
1461 * @type: name of file format.
1462 * @option_keys: name of options to set, %NULL-terminated
1463 * @option_values: values for named options
1464 * @error: return location for error, or %NULL
1466 * Saves pixbuf to a file in @type, which is currently "jpeg", "png" or "ico".
1467 * If @error is set, %FALSE will be returned.
1468 * See gdk_pixbuf_save () for more details.
1470 * Return value: whether an error was set
1474 gdk_pixbuf_savev (GdkPixbuf *pixbuf,
1475 const char *filename,
1478 char **option_values,
1485 g_return_val_if_fail (filename != NULL, FALSE);
1486 g_return_val_if_fail (type != NULL, FALSE);
1487 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1489 f = fopen (filename, "wb");
1492 gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
1496 g_file_error_from_errno (errno),
1497 _("Failed to open '%s' for writing: %s"),
1498 utf8_filename ? utf8_filename : "???",
1499 g_strerror (errno));
1500 g_free (utf8_filename);
1505 result = gdk_pixbuf_real_save (pixbuf, f, type,
1506 option_keys, option_values,
1511 g_return_val_if_fail (error == NULL || *error != NULL, FALSE);
1516 if (fclose (f) < 0) {
1517 gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
1521 g_file_error_from_errno (errno),
1522 _("Failed to close '%s' while writing image, all data may not have been saved: %s"),
1523 utf8_filename ? utf8_filename : "???",
1524 g_strerror (errno));
1525 g_free (utf8_filename);
1533 * gdk_pixbuf_save_to_callback:
1534 * @pixbuf: a #GdkPixbuf.
1535 * @save_func: a function that is called to save each block of data that
1536 * the save routine generates.
1537 * @user_data: user data to pass to the save function.
1538 * @type: name of file format.
1539 * @error: return location for error, or %NULL
1540 * @Varargs: list of key-value save options
1542 * Saves pixbuf in format @type by feeding the produced data to a
1543 * callback. Can be used when you want to store the image to something
1544 * other than a file, such as an in-memory buffer or a socket.
1545 * If @error is set, %FALSE will be returned. Possible errors
1546 * include those in the #GDK_PIXBUF_ERROR domain and whatever the save
1547 * function generates.
1549 * See gdk_pixbuf_save() for more details.
1551 * Return value: whether an error was set
1556 gdk_pixbuf_save_to_callback (GdkPixbuf *pixbuf,
1557 GdkPixbufSaveFunc save_func,
1563 gchar **keys = NULL;
1564 gchar **values = NULL;
1568 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1570 va_start (args, error);
1572 collect_save_options (args, &keys, &values);
1576 result = gdk_pixbuf_save_to_callbackv (pixbuf, save_func, user_data,
1581 g_strfreev (values);
1587 * gdk_pixbuf_save_to_callbackv:
1588 * @pixbuf: a #GdkPixbuf.
1589 * @save_func: a function that is called to save each block of data that
1590 * the save routine generates.
1591 * @user_data: user data to pass to the save function.
1592 * @type: name of file format.
1593 * @option_keys: name of options to set, %NULL-terminated
1594 * @option_values: values for named options
1595 * @error: return location for error, or %NULL
1597 * Saves pixbuf to a callback in format @type, which is currently "jpeg",
1598 * "png" or "ico". If @error is set, %FALSE will be returned. See
1599 * gdk_pixbuf_save_to_callback () for more details.
1601 * Return value: whether an error was set
1606 gdk_pixbuf_save_to_callbackv (GdkPixbuf *pixbuf,
1607 GdkPixbufSaveFunc save_func,
1611 char **option_values,
1617 g_return_val_if_fail (save_func != NULL, FALSE);
1618 g_return_val_if_fail (type != NULL, FALSE);
1619 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1621 result = gdk_pixbuf_real_save_to_callback (pixbuf,
1622 save_func, user_data, type,
1623 option_keys, option_values,
1627 g_return_val_if_fail (error == NULL || *error != NULL, FALSE);
1635 * gdk_pixbuf_save_to_buffer:
1636 * @pixbuf: a #GdkPixbuf.
1637 * @buffer: location to receive a pointer to the new buffer.
1638 * @buffer_size: location to receive the size of the new buffer.
1639 * @type: name of file format.
1640 * @error: return location for error, or %NULL
1641 * @Varargs: list of key-value save options
1643 * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
1644 * "png" or "ico". This is a convenience function that uses
1645 * gdk_pixbuf_save_to_callback() to do the real work. Note that the buffer
1646 * is not nul-terminated and may contain embedded nuls.
1647 * If @error is set, %FALSE will be returned and @string will be set to
1648 * %NULL. Possible errors include those in the #GDK_PIXBUF_ERROR
1651 * See gdk_pixbuf_save() for more details.
1653 * Return value: whether an error was set
1658 gdk_pixbuf_save_to_buffer (GdkPixbuf *pixbuf,
1665 gchar **keys = NULL;
1666 gchar **values = NULL;
1670 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1672 va_start (args, error);
1674 collect_save_options (args, &keys, &values);
1678 result = gdk_pixbuf_save_to_bufferv (pixbuf, buffer, buffer_size,
1683 g_strfreev (values);
1688 struct SaveToBufferData {
1694 save_to_buffer_callback (const gchar *data,
1699 struct SaveToBufferData *sdata = user_data;
1703 if (sdata->len + count > sdata->max) {
1704 new_max = MAX (sdata->max*2, sdata->len + count);
1705 new_buffer = g_try_realloc (sdata->buffer, new_max);
1709 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1710 _("Insufficient memory to save image into a buffer"));
1713 sdata->buffer = new_buffer;
1714 sdata->max = new_max;
1716 memcpy (sdata->buffer + sdata->len, data, count);
1717 sdata->len += count;
1722 * gdk_pixbuf_save_to_bufferv:
1723 * @pixbuf: a #GdkPixbuf.
1724 * @buffer: location to receive a pointer to the new buffer.
1725 * @buffer_size: location to receive the size of the new buffer.
1726 * @type: name of file format.
1727 * @option_keys: name of options to set, %NULL-terminated
1728 * @option_values: values for named options
1729 * @error: return location for error, or %NULL
1731 * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
1732 * "png" or "ico". See gdk_pixbuf_save_to_buffer() for more details.
1734 * Return value: whether an error was set
1739 gdk_pixbuf_save_to_bufferv (GdkPixbuf *pixbuf,
1744 char **option_values,
1747 static const gint initial_max = 1024;
1748 struct SaveToBufferData sdata;
1753 sdata.buffer = g_try_malloc (initial_max);
1754 sdata.max = initial_max;
1756 if (!sdata.buffer) {
1759 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1760 _("Insufficient memory to save image into a buffer"));
1764 if (!gdk_pixbuf_save_to_callbackv (pixbuf,
1765 save_to_buffer_callback, &sdata,
1766 type, option_keys, option_values,
1768 g_free (sdata.buffer);
1772 *buffer = sdata.buffer;
1773 *buffer_size = sdata.len;
1778 * gdk_pixbuf_format_get_name:
1779 * @format: a #GdkPixbufFormat
1781 * Returns the name of the format.
1783 * Return value: the name of the format.
1788 gdk_pixbuf_format_get_name (GdkPixbufFormat *format)
1790 g_return_val_if_fail (format != NULL, NULL);
1792 return g_strdup (format->name);
1796 * gdk_pixbuf_format_get_description:
1797 * @format: a #GdkPixbufFormat
1799 * Returns a description of the format.
1801 * Return value: a description of the format.
1806 gdk_pixbuf_format_get_description (GdkPixbufFormat *format)
1810 g_return_val_if_fail (format != NULL, NULL);
1812 if (format->domain != NULL)
1813 domain = format->domain;
1815 domain = GETTEXT_PACKAGE;
1816 description = dgettext (domain, format->description);
1818 return g_strdup (description);
1822 * gdk_pixbuf_format_get_mime_types:
1823 * @format: a #GdkPixbufFormat
1825 * Returns the mime types supported by the format.
1827 * Return value: a %NULL-terminated array of mime types which must be freed with
1828 * g_strfreev() when it is no longer needed.
1833 gdk_pixbuf_format_get_mime_types (GdkPixbufFormat *format)
1835 g_return_val_if_fail (format != NULL, NULL);
1837 return g_strdupv (format->mime_types);
1841 * gdk_pixbuf_format_get_extensions:
1842 * @format: a #GdkPixbufFormat
1844 * Returns the filename extensions typically used for files in the
1847 * Return value: a %NULL-terminated array of filename extensions which must be
1848 * freed with g_strfreev() when it is no longer needed.
1853 gdk_pixbuf_format_get_extensions (GdkPixbufFormat *format)
1855 g_return_val_if_fail (format != NULL, NULL);
1857 return g_strdupv (format->extensions);
1861 * gdk_pixbuf_format_is_writable:
1862 * @format: a #GdkPixbufFormat
1864 * Returns whether pixbufs can be saved in the given format.
1866 * Return value: whether pixbufs can be saved in the given format.
1871 gdk_pixbuf_format_is_writable (GdkPixbufFormat *format)
1873 g_return_val_if_fail (format != NULL, FALSE);
1875 return (format->flags & GDK_PIXBUF_FORMAT_WRITABLE) != 0;
1879 * gdk_pixbuf_format_is_scalable:
1880 * @format: a #GdkPixbufFormat
1882 * Returns whether this image format is scalable. If a file is in a
1883 * scalable format, it is preferable to load it at the desired size,
1884 * rather than loading it at the default size and scaling the
1885 * resulting pixbuf to the desired size.
1887 * Return value: whether this image format is scalable.
1892 gdk_pixbuf_format_is_scalable (GdkPixbufFormat *format)
1894 g_return_val_if_fail (format != NULL, FALSE);
1896 return (format->flags & GDK_PIXBUF_FORMAT_SCALABLE) != 0;
1900 * gdk_pixbuf_format_is_disabled:
1901 * @format: a #GdkPixbufFormat
1903 * Returns whether this image format is disabled. See
1904 * gdk_pixbuf_format_set_disabled().
1906 * Return value: whether this image format is disabled.
1911 gdk_pixbuf_format_is_disabled (GdkPixbufFormat *format)
1913 g_return_val_if_fail (format != NULL, FALSE);
1915 return format->disabled;
1919 * gdk_pixbuf_format_set_disabled:
1920 * @format: a #GdkPixbufFormat
1921 * @disabled: %TRUE to disable the format @format
1923 * Disables or enables an image format. If a format is disabled,
1924 * gdk-pixbuf won't use the image loader for this format to load
1925 * images. Applications can use this to avoid using image loaders
1926 * with an inappropriate license, see gdk_pixbuf_format_get_license().
1931 gdk_pixbuf_format_set_disabled (GdkPixbufFormat *format,
1934 g_return_if_fail (format != NULL);
1936 format->disabled = disabled != FALSE;
1940 * gdk_pixbuf_format_get_license:
1941 * @format: a #GdkPixbufFormat
1943 * Returns information about the license of the image loader
1944 * for the format. The returned string should be a shorthand for
1945 * a wellknown license, e.g. "LGPL", "GPL", "QPL", "GPL/QPL",
1946 * or "other" to indicate some other license.
1948 * Returns: a string describing the license of @format.
1953 gdk_pixbuf_format_get_license (GdkPixbufFormat *format)
1955 g_return_val_if_fail (format != NULL, NULL);
1957 return g_strdup (format->license);
1961 _gdk_pixbuf_get_format (GdkPixbufModule *module)
1963 g_return_val_if_fail (module != NULL, NULL);
1965 return module->info;
1969 * gdk_pixbuf_get_formats:
1971 * Obtains the available information about the image formats supported
1974 * Returns: A list of #GdkPixbufFormat<!-- -->s describing the supported
1975 * image formats. The list should be freed when it is no longer needed,
1976 * but the structures themselves are owned by #GdkPixbuf and should not be
1982 gdk_pixbuf_get_formats (void)
1984 GSList *result = NULL;
1987 for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
1988 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
1989 GdkPixbufFormat *info = _gdk_pixbuf_get_format (module);
1990 result = g_slist_prepend (result, info);