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-private.h"
37 #include "gdk-pixbuf-io.h"
46 format_check (GdkPixbufModule *module, guchar *buffer, int size)
50 GdkPixbufModulePattern *pattern;
52 for (pattern = module->info->signature; pattern->prefix; pattern++) {
53 for (j = 0; j < size && pattern->prefix[j] != 0; j++) {
54 m = pattern->mask ? pattern->mask[j] : ' ';
56 if (buffer[j] != pattern->prefix[j])
60 if (buffer[j] == pattern->prefix[j])
72 if (pattern->prefix[j] == 0)
73 return pattern->relevance;
78 static GSList *file_formats = NULL;
80 static void gdk_pixbuf_io_init ();
85 if (file_formats == NULL)
86 gdk_pixbuf_io_init ();
95 scan_string (const char **pos, GString *out)
97 const char *p = *pos, *q = *pos;
101 while (g_ascii_isspace (*p))
106 else if (*p == '"') {
109 for (q = p; (*q != '"') || quoted; q++) {
112 quoted = (*q == '\\') && !quoted;
115 tmp = g_strndup (p, q - p);
116 tmp2 = g_strcompress (tmp);
117 g_string_truncate (out, 0);
118 g_string_append (out, tmp2);
130 scan_int (const char **pos, int *out)
134 const char *p = *pos;
136 while (g_ascii_isspace (*p))
139 if (*p < '0' || *p > '9')
142 while ((*p >= '0') && (*p <= '9') && i < sizeof (buf)) {
148 if (i == sizeof (buf))
161 skip_space (const char **pos)
163 const char *p = *pos;
165 while (g_ascii_isspace (*p))
170 return !(*p == '\0');
175 /* DllMain function needed to tuck away the gdk-pixbuf DLL name */
176 G_WIN32_DLLMAIN_FOR_DLL_NAME (static, dll_name)
181 static char *toplevel = NULL;
183 if (toplevel == NULL)
184 toplevel = g_win32_get_package_installation_subdirectory
185 (GETTEXT_PACKAGE, dll_name, "");
191 get_sysconfdir (void)
193 static char *sysconfdir = NULL;
195 if (sysconfdir == NULL)
196 sysconfdir = g_win32_get_package_installation_subdirectory
197 (GETTEXT_PACKAGE, dll_name, "etc");
202 #undef GTK_SYSCONFDIR
203 #define GTK_SYSCONFDIR get_sysconfdir()
206 correct_prefix (gchar **path)
208 if (strncmp (*path, GTK_PREFIX "/", strlen (GTK_PREFIX "/")) == 0 ||
209 strncmp (*path, GTK_PREFIX "\\", strlen (GTK_PREFIX "\\")) == 0)
211 /* This is an entry put there by gdk-pixbuf-query-loaders on the
212 * packager's system. On Windows a prebuilt GTK+ package can be
213 * installed in a random location. The gdk-pixbuf.loaders file
214 * distributed in such a package contains paths from the package
215 * builder's machine. Replace the build-time prefix with the
216 * installation prefix on this machine.
219 *path = g_strconcat (get_toplevel (), tem + strlen (GTK_PREFIX), NULL);
227 gdk_pixbuf_get_module_file (void)
229 gchar *result = g_strdup (g_getenv ("GDK_PIXBUF_MODULE_FILE"));
232 result = g_build_filename (GTK_SYSCONFDIR, "gtk-2.0", "gdk-pixbuf.loaders", NULL);
238 gdk_pixbuf_io_init ()
243 GString *tmp_buf = g_string_new (NULL);
244 gboolean have_error = FALSE;
245 GdkPixbufModule *module = NULL;
246 gchar *filename = gdk_pixbuf_get_module_file ();
249 GdkPixbufModulePattern *pattern;
250 GError *error = NULL;
252 channel = g_io_channel_new_file (filename, "r", &error);
254 g_warning ("Can not open pixbuf loader module file '%s': %s",
255 filename, error->message);
259 while (!have_error && g_io_channel_read_line (channel, &line_buf, NULL, &term, NULL) == G_IO_STATUS_NORMAL) {
266 if (!skip_space (&p)) {
267 /* Blank line marking the end of a module
269 if (module && *p != '#') {
271 correct_prefix (&module->module_path);
273 file_formats = g_slist_prepend (file_formats, module);
284 /* Read a module location
286 module = g_new0 (GdkPixbufModule, 1);
289 if (!scan_string (&p, tmp_buf)) {
290 g_warning ("Error parsing loader info in '%s'\n %s",
294 module->module_path = g_strdup (tmp_buf->str);
296 else if (!module->module_name) {
297 module->info = g_new0 (GdkPixbufFormat, 1);
298 if (!scan_string (&p, tmp_buf)) {
299 g_warning ("Error parsing loader info in '%s'\n %s",
303 module->info->name = g_strdup (tmp_buf->str);
304 module->module_name = module->info->name;
306 if (!scan_int (&p, &flags)) {
307 g_warning ("Error parsing loader info in '%s'\n %s",
311 module->info->flags = flags;
313 if (!scan_string (&p, tmp_buf)) {
314 g_warning ("Error parsing loader info in '%s'\n %s",
318 if (tmp_buf->str[0] != 0)
319 module->info->domain = g_strdup (tmp_buf->str);
321 if (!scan_string (&p, tmp_buf)) {
322 g_warning ("Error parsing loader info in '%s'\n %s",
326 module->info->description = g_strdup (tmp_buf->str);
328 else if (!module->info->mime_types) {
330 module->info->mime_types = g_new0 (gchar*, 1);
331 while (scan_string (&p, tmp_buf)) {
332 if (tmp_buf->str[0] != 0) {
333 module->info->mime_types =
334 g_realloc (module->info->mime_types, (n + 1) * sizeof (gchar*));
335 module->info->mime_types[n - 1] = g_strdup (tmp_buf->str);
336 module->info->mime_types[n] = 0;
341 else if (!module->info->extensions) {
343 module->info->extensions = g_new0 (gchar*, 1);
344 while (scan_string (&p, tmp_buf)) {
345 if (tmp_buf->str[0] != 0) {
346 module->info->extensions =
347 g_realloc (module->info->extensions, (n + 1) * sizeof (gchar*));
348 module->info->extensions[n - 1] = g_strdup (tmp_buf->str);
349 module->info->extensions[n] = 0;
356 module->info->signature = (GdkPixbufModulePattern *)
357 g_realloc (module->info->signature, (n_patterns + 1) * sizeof (GdkPixbufModulePattern));
358 pattern = module->info->signature + n_patterns;
359 pattern->prefix = NULL;
360 pattern->mask = NULL;
361 pattern->relevance = 0;
363 if (!scan_string (&p, tmp_buf))
365 pattern->prefix = g_strdup (tmp_buf->str);
367 if (!scan_string (&p, tmp_buf))
370 pattern->mask = g_strdup (tmp_buf->str);
372 pattern->mask = NULL;
374 if (!scan_int (&p, &pattern->relevance))
380 g_free (pattern->prefix);
381 g_free (pattern->mask);
383 g_warning ("Error parsing loader info in '%s'\n %s",
390 g_string_free (tmp_buf, TRUE);
391 g_io_channel_unref (channel);
395 /* actually load the image handler - gdk_pixbuf_get_module only get a */
396 /* reference to the module to load, it doesn't actually load it */
397 /* perhaps these actions should be combined in one function */
399 _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
406 g_return_val_if_fail (image_module->module == NULL, FALSE);
408 path = image_module->module_path;
409 module = g_module_open (path, G_MODULE_BIND_LAZY);
414 GDK_PIXBUF_ERROR_FAILED,
415 _("Unable to load image-loading module: %s: %s"),
416 path, g_module_error ());
420 image_module->module = module;
422 if (g_module_symbol (module, "fill_vtable", &sym)) {
423 GdkPixbufModuleFillVtableFunc func = (GdkPixbufModuleFillVtableFunc) sym;
424 (* func) (image_module);
429 GDK_PIXBUF_ERROR_FAILED,
430 _("Image-loading module %s does not export the proper interface; perhaps it's from a different GTK version?"),
437 #define module(type) \
438 extern void MODULE_ENTRY (type, fill_info) (GdkPixbufFormat *info); \
439 extern void MODULE_ENTRY (type, fill_vtable) (GdkPixbufModule *module)
457 _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
460 GdkPixbufModuleFillInfoFunc fill_info = NULL;
461 GdkPixbufModuleFillVtableFunc fill_vtable = NULL;
463 image_module->module = (void *) 1;
466 /* Ugly hack so we can use else if unconditionally below ;-) */
470 else if (strcmp (image_module->module_name, "png") == 0) {
471 fill_info = MODULE_ENTRY (png, fill_info);
472 fill_vtable = MODULE_ENTRY (png, fill_vtable);
477 else if (strcmp (image_module->module_name, "bmp") == 0) {
478 fill_info = MODULE_ENTRY (bmp, fill_info);
479 fill_vtable = MODULE_ENTRY (bmp, fill_vtable);
484 else if (strcmp (image_module->module_name, "wbmp") == 0) {
485 fill_info = MODULE_ENTRY (wbmp, fill_info);
486 fill_vtable = MODULE_ENTRY (wbmp, fill_vtable);
491 else if (strcmp (image_module->module_name, "gif") == 0) {
492 fill_info = MODULE_ENTRY (gif, fill_info);
493 fill_vtable = MODULE_ENTRY (gif, fill_vtable);
498 else if (strcmp (image_module->module_name, "ico") == 0) {
499 fill_info = MODULE_ENTRY (ico, fill_info);
500 fill_vtable = MODULE_ENTRY (ico, fill_vtable);
505 else if (strcmp (image_module->module_name, "ani") == 0) {
506 fill_info = MODULE_ENTRY (ani, fill_info);
507 fill_vtable = MODULE_ENTRY (ani, fill_vtable);
512 else if (strcmp (image_module->module_name, "jpeg") == 0) {
513 fill_info = MODULE_ENTRY (jpeg, fill_info);
514 fill_vtable = MODULE_ENTRY (jpeg, fill_vtable);
519 else if (strcmp (image_module->module_name, "pnm") == 0) {
520 fill_info = MODULE_ENTRY (pnm, fill_info);
521 fill_vtable = MODULE_ENTRY (pnm, fill_vtable);
526 else if (strcmp (image_module->module_name, "ras") == 0) {
527 fill_info = MODULE_ENTRY (ras, fill_info);
528 fill_vtable = MODULE_ENTRY (ras, fill_vtable);
533 else if (strcmp (image_module->module_name, "tiff") == 0) {
534 fill_info = MODULE_ENTRY (tiff, fill_info);
535 fill_vtable = MODULE_ENTRY (tiff, fill_vtable);
540 else if (strcmp (image_module->module_name, "xpm") == 0) {
541 fill_info = MODULE_ENTRY (xpm, fill_info);
542 fill_vtable = MODULE_ENTRY (xpm, fill_vtable);
547 else if (strcmp (image_module->module_name, "xbm") == 0) {
548 fill_info = MODULE_ENTRY (xbm, fill_info);
549 fill_vtable = MODULE_ENTRY (xbm, fill_vtable);
554 else if (strcmp (image_module->module_name, "tga") == 0) {
555 fill_info = MODULE_ENTRY (tga, fill_info);
556 fill_vtable = MODULE_ENTRY (tga, fill_vtable);
561 else if (strcmp (image_module->module_name, "pcx") == 0) {
562 fill_info = MODULE_ENTRY (pcx, fill_info);
563 fill_vtable = MODULE_ENTRY (pcx, fill_vtable);
568 (* fill_vtable) (image_module);
569 image_module->info = g_new0 (GdkPixbufFormat, 1);
570 (* fill_info) (image_module->info);
576 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
577 _("Image type '%s' is not supported"),
578 image_module->module_name);
585 gdk_pixbuf_io_init ()
587 gchar *included_formats[] = {
588 "ani", "png", "bmp", "wbmp", "gif",
589 "ico", "jpeg", "pnm", "ras", "tiff",
590 "xpm", "xbm", "tga", "pcx",
594 GdkPixbufModule *module = NULL;
596 for (name = included_formats; *name; name++) {
597 module = g_new0 (GdkPixbufModule, 1);
598 module->module_name = *name;
599 if (_gdk_pixbuf_load_module (module, NULL))
600 file_formats = g_slist_prepend (file_formats, module);
611 _gdk_pixbuf_get_named_module (const char *name,
616 for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
617 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
618 if (!strcmp (name, module->module_name))
624 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
625 _("Image type '%s' is not supported"),
632 _gdk_pixbuf_get_module (guchar *buffer, guint size,
633 const gchar *filename,
638 gint score, best = 0;
639 GdkPixbufModule *selected = NULL;
640 for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
641 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
642 score = format_check (module, buffer, size);
650 if (selected != NULL)
656 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
657 _("Couldn't recognize the image file format for file '%s'"),
662 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
663 _("Unrecognized image file format"));
671 prepared_notify (GdkPixbuf *pixbuf,
672 GdkPixbufAnimation *anim,
676 g_object_ref (pixbuf);
677 *((GdkPixbuf **)user_data) = pixbuf;
681 _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
687 GdkPixbuf *pixbuf = NULL;
688 GdkPixbufAnimation *animation = NULL;
691 if (module->load != NULL)
692 return (* module->load) (f, error);
694 if (module->begin_load != NULL) {
696 context = module->begin_load (NULL, prepared_notify, NULL, &pixbuf, error);
701 while (!feof (f) && !ferror (f)) {
702 length = fread (buffer, 1, sizeof (buffer), f);
704 if (!module->load_increment (context, buffer, length, error)) {
705 module->stop_load (context, NULL);
707 g_object_unref (pixbuf);
712 if (!module->stop_load (context, error)) {
714 g_object_unref (pixbuf);
721 if (module->load_animation != NULL) {
722 animation = (* module->load_animation) (f, error);
723 if (animation != NULL) {
724 pixbuf = gdk_pixbuf_animation_get_static_image (animation);
726 g_object_ref (pixbuf);
728 g_object_unref (animation);
738 * gdk_pixbuf_new_from_file:
739 * @filename: Name of file to load.
740 * @error: Return location for an error
742 * Creates a new pixbuf by loading an image from a file. The file format is
743 * detected automatically. If %NULL is returned, then @error will be set.
744 * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
746 * Return value: A newly-created pixbuf with a reference count of 1, or %NULL if
747 * any of several error conditions occurred: the file could not be opened,
748 * there was no loader for the file's format, there was not enough memory to
749 * allocate the image buffer, or the image file contained invalid data.
752 gdk_pixbuf_new_from_file (const char *filename,
759 GdkPixbufModule *image_module;
761 g_return_val_if_fail (filename != NULL, NULL);
762 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
764 f = fopen (filename, "rb");
768 g_file_error_from_errno (errno),
769 _("Failed to open file '%s': %s"),
770 filename, g_strerror (errno));
774 size = fread (&buffer, 1, sizeof (buffer), f);
778 GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
779 _("Image file '%s' contains no data"),
786 image_module = _gdk_pixbuf_get_module (buffer, size, filename, error);
787 if (image_module == NULL) {
792 if (image_module->module == NULL)
793 if (!_gdk_pixbuf_load_module (image_module, error)) {
798 fseek (f, 0, SEEK_SET);
799 pixbuf = _gdk_pixbuf_generic_image_load (image_module, f, error);
802 if (pixbuf == NULL && error != NULL && *error == NULL) {
803 /* I don't trust these crufty longjmp()'ing image libs
804 * to maintain proper error invariants, and I don't
805 * want user code to segfault as a result. We need to maintain
806 * the invariastable/gdk-pixbuf/nt that error gets set if NULL is returned.
809 g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", image_module->module_name);
812 GDK_PIXBUF_ERROR_FAILED,
813 _("Failed to load image '%s': reason not known, probably a corrupt image file"),
816 } else if (error != NULL && *error != NULL) {
818 /* Add the filename to the error message */
824 e->message = g_strdup_printf (_("Failed to load image '%s': %s"),
834 size_prepared_cb (GdkPixbufLoader *loader,
844 g_return_if_fail (width > 0 && height > 0);
846 if ((double)height * (double)info->width >
847 (double)width * (double)info->height) {
848 width = 0.5 + (double)width * (double)info->height / (double)height;
849 height = info->height;
851 height = 0.5 + (double)height * (double)info->width / (double)width;
855 gdk_pixbuf_loader_set_size (loader, width, height);
859 * gdk_pixbuf_new_from_file_at_size:
860 * @filename: Name of file to load.
861 * @width: The width the image should have
862 * @height: The height the image should have
863 * @error: Return location for an error
865 * Creates a new pixbuf by loading an image from a file. The file format is
866 * detected automatically. If %NULL is returned, then @error will be set.
867 * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
868 * The image will be scaled to fit in the requested size, preserving its aspect ratio.
870 * Return value: A newly-created pixbuf with a reference count of 1, or %NULL if
871 * any of several error conditions occurred: the file could not be opened,
872 * there was no loader for the file's format, there was not enough memory to
873 * allocate the image buffer, or the image file contained invalid data.
878 gdk_pixbuf_new_from_file_at_size (const char *filename,
883 GdkPixbufLoader *loader;
886 guchar buffer [4096];
894 g_return_val_if_fail (filename != NULL, NULL);
895 g_return_val_if_fail (width > 0 && height > 0, NULL);
897 f = fopen (filename, "rb");
901 g_file_error_from_errno (errno),
902 _("Failed to open file '%s': %s"),
903 filename, g_strerror (errno));
907 loader = gdk_pixbuf_loader_new ();
910 info.height = height;
912 g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
914 while (!feof (f) && !ferror (f)) {
915 length = fread (buffer, 1, sizeof (buffer), f);
917 if (!gdk_pixbuf_loader_write (loader, buffer, length, error)) {
918 gdk_pixbuf_loader_close (loader, NULL);
920 g_object_unref (loader);
927 if (!gdk_pixbuf_loader_close (loader, error)) {
928 g_object_unref (loader);
932 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
935 g_object_unref (loader);
938 GDK_PIXBUF_ERROR_FAILED,
939 _("Failed to load image '%s': reason not known, probably a corrupt image file"),
944 g_object_ref (pixbuf);
946 g_object_unref (loader);
952 info_cb (GdkPixbufLoader *loader,
958 GdkPixbufFormat *format;
963 g_return_if_fail (width > 0 && height > 0);
965 info->format = gdk_pixbuf_loader_get_format (loader);
967 info->height = height;
969 gdk_pixbuf_loader_set_size (loader, 0, 0);
973 * gdk_pixbuf_get_file_info:
974 * @filename: The name of the file to identify.
975 * @width: Return location for the width of the image, or %NULL
976 * @height: Return location for the height of the image, or %NULL
978 * Parses an image file far enough to determine its format and size.
980 * Returns: A #GdkPixbufFormat describing the image format of the file
981 * or %NULL if the image format wasn't recognized. The return value
982 * is owned by GdkPixbuf and should not be freed.
987 gdk_pixbuf_get_file_info (const gchar *filename,
991 GdkPixbufLoader *loader;
992 guchar buffer [4096];
996 GdkPixbufFormat *format;
1001 g_return_val_if_fail (filename != NULL, NULL);
1003 f = fopen (filename, "rb");
1007 loader = gdk_pixbuf_loader_new ();
1013 g_signal_connect (loader, "size-prepared", G_CALLBACK (info_cb), &info);
1015 while (!feof (f) && !ferror (f)) {
1016 length = fread (buffer, 1, sizeof (buffer), f);
1018 if (!gdk_pixbuf_loader_write (loader, buffer, length, NULL))
1021 if (info.format != NULL)
1026 gdk_pixbuf_loader_close (loader, NULL);
1027 g_object_unref (loader);
1030 *width = info.width;
1032 *height = info.height;
1038 * gdk_pixbuf_new_from_xpm_data:
1039 * @data: Pointer to inline XPM data.
1041 * Creates a new pixbuf by parsing XPM data in memory. This data is commonly
1042 * the result of including an XPM file into a program's C source.
1044 * Return value: A newly-created pixbuf with a reference count of 1.
1047 gdk_pixbuf_new_from_xpm_data (const char **data)
1049 GdkPixbuf *(* load_xpm_data) (const char **data);
1051 GError *error = NULL;
1052 GdkPixbufModule *xpm_module = _gdk_pixbuf_get_named_module ("xpm", &error);
1053 if (xpm_module == NULL) {
1054 g_warning ("Error loading XPM image loader: %s", error->message);
1055 g_error_free (error);
1059 if (xpm_module->module == NULL) {
1060 if (!_gdk_pixbuf_load_module (xpm_module, &error)) {
1061 g_warning ("Error loading XPM image loader: %s", error->message);
1062 g_error_free (error);
1067 if (xpm_module->load_xpm_data == NULL) {
1068 g_warning ("gdk-pixbuf XPM module lacks XPM data capability");
1071 load_xpm_data = xpm_module->load_xpm_data;
1073 pixbuf = (* load_xpm_data) (data);
1078 collect_save_options (va_list opts,
1091 next = va_arg (opts, gchar*);
1095 val = va_arg (opts, gchar*);
1100 *keys = g_realloc (*keys, sizeof(gchar*) * (count + 1));
1101 *vals = g_realloc (*vals, sizeof(gchar*) * (count + 1));
1103 (*keys)[count-1] = g_strdup (key);
1104 (*vals)[count-1] = g_strdup (val);
1106 (*keys)[count] = NULL;
1107 (*vals)[count] = NULL;
1109 next = va_arg (opts, gchar*);
1114 save_to_file_callback (const gchar *buf,
1119 FILE *filehandle = data;
1122 n = fwrite (buf, 1, count, filehandle);
1126 g_file_error_from_errno (errno),
1127 _("Error writing to image file: %s"),
1128 g_strerror (errno));
1135 gdk_pixbuf_real_save (GdkPixbuf *pixbuf,
1142 GdkPixbufModule *image_module = NULL;
1144 image_module = _gdk_pixbuf_get_named_module (type, error);
1146 if (image_module == NULL)
1149 if (image_module->module == NULL)
1150 if (!_gdk_pixbuf_load_module (image_module, error))
1153 if (image_module->save) {
1155 return (* image_module->save) (filehandle, pixbuf,
1159 else if (image_module->save_to_callback) {
1160 /* save with simple callback */
1161 return (* image_module->save_to_callback) (save_to_file_callback,
1170 GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
1171 _("This build of gdk-pixbuf does not support saving the image format: %s"),
1177 #define TMP_FILE_BUF_SIZE 4096
1180 save_to_callback_with_tmp_file (GdkPixbufModule *image_module,
1182 GdkPixbufSaveFunc save_func,
1190 gboolean retval = FALSE;
1193 gchar *filename = NULL;
1195 buf = g_try_malloc (TMP_FILE_BUF_SIZE);
1199 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1200 _("Insufficient memory to save image to callback"));
1204 fd = g_file_open_tmp ("gdkpixbuf-save-tmp.XXXXXX", &filename, error);
1207 f = fdopen (fd, "wb+");
1211 g_file_error_from_errno (errno),
1212 _("Failed to open temporary file"));
1215 if (!(* image_module->save) (f, pixbuf, keys, values, error))
1219 n = fread (buf, 1, TMP_FILE_BUF_SIZE, f);
1221 if (!save_func (buf, n, error, user_data))
1224 if (n != TMP_FILE_BUF_SIZE)
1230 g_file_error_from_errno (errno),
1231 _("Failed to read from temporary file"));
1237 /* cleanup and return retval */
1250 gdk_pixbuf_real_save_to_callback (GdkPixbuf *pixbuf,
1251 GdkPixbufSaveFunc save_func,
1258 GdkPixbufModule *image_module = NULL;
1260 image_module = _gdk_pixbuf_get_named_module (type, error);
1262 if (image_module == NULL)
1265 if (image_module->module == NULL)
1266 if (!_gdk_pixbuf_load_module (image_module, error))
1269 if (image_module->save_to_callback) {
1271 return (* image_module->save_to_callback) (save_func, user_data,
1272 pixbuf, keys, values,
1275 else if (image_module->save) {
1276 /* use a temporary file */
1277 return save_to_callback_with_tmp_file (image_module, pixbuf,
1278 save_func, user_data,
1286 GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
1287 _("This build of gdk-pixbuf does not support saving the image format: %s"),
1296 * @pixbuf: a #GdkPixbuf.
1297 * @filename: name of file to save.
1298 * @type: name of file format.
1299 * @error: return location for error, or %NULL
1300 * @Varargs: list of key-value save options
1302 * Saves pixbuf to a file in format @type. By default, "jpeg", "png" and
1303 * "ico" are possible file formats to save in, but more formats may be
1304 * installed. The list of all writable formats can be determined in the
1307 * <informalexample><programlisting>
1308 * void add_if_writable (GdkPixbufFormat *data, GSList **list)
1310 * if (gdk_pixbuf_format_is_writable (data))
1311 * *list = g_slist_prepend (*list, data);
1314 * GSList *formats = gdk_pixbuf_get_formats (<!-- -->);
1315 * GSList *writable_formats = NULL;
1316 * g_slist_foreach (formats, add_if_writable, &writable_formats);
1317 * g_slist_free (formats);
1318 * </programlisting></informalexample>
1320 * If @error is set, %FALSE will be returned. Possible errors include
1321 * those in the #GDK_PIXBUF_ERROR domain and those in the #G_FILE_ERROR domain.
1323 * The variable argument list should be %NULL-terminated; if not empty,
1324 * it should contain pairs of strings that modify the save
1325 * parameters. For example:
1326 * <informalexample><programlisting>
1327 * gdk_pixbuf_save (pixbuf, handle, "jpeg", &error,
1328 * "quality", "100", NULL);
1329 * </programlisting></informalexample>
1331 * Currently only few parameters exist. JPEG images can be saved with a
1332 * "quality" parameter; its value should be in the range [0,100].
1333 * Text chunks can be attached to PNG images by specifying parameters of
1334 * the form "tEXt::key", where key is an ASCII string of length 1-79.
1335 * The values are UTF-8 encoded strings.
1336 * ICO images can be saved in depth 16, 24, or 32, by using the "depth"
1337 * parameter. When the ICO saver is given "x_hot" and "y_hot" parameters,
1338 * it produces a CUR instead of an ICO.
1340 * Return value: whether an error was set
1344 gdk_pixbuf_save (GdkPixbuf *pixbuf,
1345 const char *filename,
1350 gchar **keys = NULL;
1351 gchar **values = NULL;
1355 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1357 va_start (args, error);
1359 collect_save_options (args, &keys, &values);
1363 result = gdk_pixbuf_savev (pixbuf, filename, type,
1368 g_strfreev (values);
1375 * @pixbuf: a #GdkPixbuf.
1376 * @filename: name of file to save.
1377 * @type: name of file format.
1378 * @option_keys: name of options to set, %NULL-terminated
1379 * @option_values: values for named options
1380 * @error: return location for error, or %NULL
1382 * Saves pixbuf to a file in @type, which is currently "jpeg", "png" or "ico".
1383 * If @error is set, %FALSE will be returned.
1384 * See gdk_pixbuf_save () for more details.
1386 * Return value: whether an error was set
1390 gdk_pixbuf_savev (GdkPixbuf *pixbuf,
1391 const char *filename,
1394 char **option_values,
1401 g_return_val_if_fail (filename != NULL, FALSE);
1402 g_return_val_if_fail (type != NULL, FALSE);
1403 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1405 f = fopen (filename, "wb");
1410 g_file_error_from_errno (errno),
1411 _("Failed to open '%s' for writing: %s"),
1412 filename, g_strerror (errno));
1417 result = gdk_pixbuf_real_save (pixbuf, f, type,
1418 option_keys, option_values,
1423 g_return_val_if_fail (error == NULL || *error != NULL, FALSE);
1428 if (fclose (f) < 0) {
1431 g_file_error_from_errno (errno),
1432 _("Failed to close '%s' while writing image, all data may not have been saved: %s"),
1433 filename, g_strerror (errno));
1441 * gdk_pixbuf_save_to_callback:
1442 * @pixbuf: a #GdkPixbuf.
1443 * @save_func: a function that is called to save each block of data that
1444 * the save routine generates.
1445 * @user_data: user data to pass to the save function.
1446 * @type: name of file format.
1447 * @error: return location for error, or %NULL
1448 * @Varargs: list of key-value save options
1450 * Saves pixbuf in format @type by feeding the produced data to a
1451 * callback. Can be used when you want to store the image to something
1452 * other than a file, such as an in-memory buffer or a socket.
1453 * If @error is set, %FALSE will be returned. Possible errors
1454 * include those in the #GDK_PIXBUF_ERROR domain and whatever the save
1455 * function generates.
1457 * See gdk_pixbuf_save() for more details.
1459 * Return value: whether an error was set
1464 gdk_pixbuf_save_to_callback (GdkPixbuf *pixbuf,
1465 GdkPixbufSaveFunc save_func,
1471 gchar **keys = NULL;
1472 gchar **values = NULL;
1476 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1478 va_start (args, error);
1480 collect_save_options (args, &keys, &values);
1484 result = gdk_pixbuf_save_to_callbackv (pixbuf, save_func, user_data,
1489 g_strfreev (values);
1495 * gdk_pixbuf_save_to_callbackv:
1496 * @pixbuf: a #GdkPixbuf.
1497 * @save_func: a function that is called to save each block of data that
1498 * the save routine generates.
1499 * @user_data: user data to pass to the save function.
1500 * @type: name of file format.
1501 * @option_keys: name of options to set, %NULL-terminated
1502 * @option_values: values for named options
1503 * @error: return location for error, or %NULL
1505 * Saves pixbuf to a callback in format @type, which is currently "jpeg",
1506 * "png" or "ico". If @error is set, %FALSE will be returned. See
1507 * gdk_pixbuf_save_to_callback () for more details.
1509 * Return value: whether an error was set
1514 gdk_pixbuf_save_to_callbackv (GdkPixbuf *pixbuf,
1515 GdkPixbufSaveFunc save_func,
1519 char **option_values,
1525 g_return_val_if_fail (save_func != NULL, FALSE);
1526 g_return_val_if_fail (type != NULL, FALSE);
1527 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1529 result = gdk_pixbuf_real_save_to_callback (pixbuf,
1530 save_func, user_data, type,
1531 option_keys, option_values,
1535 g_return_val_if_fail (error == NULL || *error != NULL, FALSE);
1543 * gdk_pixbuf_save_to_buffer:
1544 * @pixbuf: a #GdkPixbuf.
1545 * @buffer: location to receive a pointer to the new buffer.
1546 * @buffer_size: location to receive the size of the new buffer.
1547 * @type: name of file format.
1548 * @error: return location for error, or %NULL
1549 * @Varargs: list of key-value save options
1551 * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
1552 * "png" or "ico". This is a convenience function that uses
1553 * gdk_pixbuf_save_to_callback() to do the real work. Note that the buffer
1554 * is not nul-terminated and may contain embedded nuls.
1555 * If @error is set, %FALSE will be returned and @string will be set to
1556 * %NULL. Possible errors include those in the #GDK_PIXBUF_ERROR
1559 * See gdk_pixbuf_save() for more details.
1561 * Return value: whether an error was set
1566 gdk_pixbuf_save_to_buffer (GdkPixbuf *pixbuf,
1573 gchar **keys = NULL;
1574 gchar **values = NULL;
1578 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1580 va_start (args, error);
1582 collect_save_options (args, &keys, &values);
1586 result = gdk_pixbuf_save_to_bufferv (pixbuf, buffer, buffer_size,
1591 g_strfreev (values);
1596 struct SaveToBufferData {
1602 save_to_buffer_callback (const gchar *data,
1607 struct SaveToBufferData *sdata = user_data;
1611 if (sdata->len + count > sdata->max) {
1612 new_max = MAX (sdata->max*2, sdata->len + count);
1613 new_buffer = g_try_realloc (sdata->buffer, new_max);
1617 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1618 _("Insufficient memory to save image into a buffer"));
1621 sdata->buffer = new_buffer;
1622 sdata->max = new_max;
1624 memcpy (sdata->buffer + sdata->len, data, count);
1625 sdata->len += count;
1630 * gdk_pixbuf_save_to_bufferv:
1631 * @pixbuf: a #GdkPixbuf.
1632 * @buffer: location to receive a pointer to the new buffer.
1633 * @buffer_size: location to receive the size of the new buffer.
1634 * @type: name of file format.
1635 * @option_keys: name of options to set, %NULL-terminated
1636 * @option_values: values for named options
1637 * @error: return location for error, or %NULL
1639 * Saves pixbuf to a new buffer in format @type, which is currently "jpeg",
1640 * "png" or "ico". See gdk_pixbuf_save_to_buffer() for more details.
1642 * Return value: whether an error was set
1647 gdk_pixbuf_save_to_bufferv (GdkPixbuf *pixbuf,
1652 char **option_values,
1655 static const gint initial_max = 1024;
1656 struct SaveToBufferData sdata;
1661 sdata.buffer = g_try_malloc (initial_max);
1662 sdata.max = initial_max;
1664 if (!sdata.buffer) {
1667 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1668 _("Insufficient memory to save image into a buffer"));
1672 if (!gdk_pixbuf_save_to_callbackv (pixbuf,
1673 save_to_buffer_callback, &sdata,
1674 type, option_keys, option_values,
1676 g_free (sdata.buffer);
1680 *buffer = sdata.buffer;
1681 *buffer_size = sdata.len;
1686 * gdk_pixbuf_format_get_name:
1687 * @format: a #GdkPixbufFormat
1689 * Returns the name of the format.
1691 * Return value: the name of the format.
1696 gdk_pixbuf_format_get_name (GdkPixbufFormat *format)
1698 g_return_val_if_fail (format != NULL, NULL);
1700 return g_strdup (format->name);
1704 * gdk_pixbuf_format_get_description:
1705 * @format: a #GdkPixbufFormat
1707 * Returns a description of the format.
1709 * Return value: a description of the format.
1714 gdk_pixbuf_format_get_description (GdkPixbufFormat *format)
1718 g_return_val_if_fail (format != NULL, NULL);
1720 if (format->domain != NULL)
1721 domain = format->domain;
1723 domain = GETTEXT_PACKAGE;
1724 description = dgettext (domain, format->description);
1726 return g_strdup (description);
1730 * gdk_pixbuf_format_get_mime_types:
1731 * @format: a #GdkPixbufFormat
1733 * Returns the mime types supported by the format.
1735 * Return value: a %NULL-terminated array of mime types which must be freed with
1736 * g_strfreev() when it is no longer needed.
1741 gdk_pixbuf_format_get_mime_types (GdkPixbufFormat *format)
1743 g_return_val_if_fail (format != NULL, NULL);
1745 return g_strdupv (format->mime_types);
1749 * gdk_pixbuf_format_get_extensions:
1750 * @format: a #GdkPixbufFormat
1752 * Returns the filename extensions typically used for files in the
1755 * Return value: a %NULL-terminated array of filename extensions which must be
1756 * freed with g_strfreev() when it is no longer needed.
1761 gdk_pixbuf_format_get_extensions (GdkPixbufFormat *format)
1763 g_return_val_if_fail (format != NULL, NULL);
1765 return g_strdupv (format->extensions);
1769 * gdk_pixbuf_format_is_writable:
1770 * @format: a #GdkPixbufFormat
1772 * Returns whether pixbufs can be saved in the given format.
1774 * Return value: whether pixbufs can be saved in the given format.
1779 gdk_pixbuf_format_is_writable (GdkPixbufFormat *format)
1781 g_return_val_if_fail (format != NULL, FALSE);
1783 return (format->flags & GDK_PIXBUF_FORMAT_WRITABLE) != 0;
1787 _gdk_pixbuf_get_format (GdkPixbufModule *module)
1789 g_return_val_if_fail (module != NULL, NULL);
1791 return module->info;
1795 * gdk_pixbuf_get_formats:
1797 * Obtains the available information about the image formats supported
1800 * Returns: A list of #GdkPixbufFormat<!-- -->s describing the supported
1801 * image formats. The list should be freed when it is no longer needed,
1802 * but the structures themselves are owned by #GdkPixbuf and should not be
1808 gdk_pixbuf_get_formats (void)
1810 GSList *result = NULL;
1813 for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) {
1814 GdkPixbufModule *module = (GdkPixbufModule *)modules->data;
1815 GdkPixbufFormat *info = _gdk_pixbuf_get_format (module);
1816 result = g_slist_prepend (result, info);