/* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */ /* * GImageView * Copyright (C) 2001-2002 Takuro Ashie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "pixbuf_loader.h" #ifdef HAVE_GDK_PIXBUF #include #include "pixbuf_anim.h" #include "fileutil.h" #include "gimv_plugin.h" static GimvImageLoaderPlugin gimv_pixbuf_loader[] = { { if_version: GIMV_IMAGE_LOADER_IF_VERSION, id: "GdkPixbufLoader", priority_hint: GIMV_IMAGE_LOADER_PRIORITY_DEFAULT, check_type: NULL, get_info: NULL, loader: pixbuf_load, }, { if_version: GIMV_IMAGE_LOADER_IF_VERSION, id: "GdkPixbufFile", priority_hint: GIMV_IMAGE_LOADER_PRIORITY_CANNOT_CANCEL, check_type: NULL, get_info: NULL, loader: pixbuf_load_file, }, }; /* should be fetched from GdkPixbufModule */ static const gchar *ani_extensions[] = { "ani", }; static const gchar *bmp_extensions[] = { "bmp", }; static const gchar *gif_extensions[] = { "gif", }; static const gchar *icon_extensions[] = { "ico", "cur", }; static const gchar *jpeg_extensions[] = { "jpg", "jpeg", "jpe", }; static const gchar *png_extensions[] = { "png", }; static const gchar *ppm_extensions[] = { "ppm", }; static const gchar *pgm_extensions[] = { "pgm", }; static const gchar *pbm_extensions[] = { "pbm", }; static const gchar *pnm_extensions[] = { "pnm", "pbm", "pgm", "ppm", }; static const gchar *ras_extensions[] = { "ras", }; static const gchar *tga_extensions[] = { "tga", "targa", }; static const gchar *tiff_extensions[] = { "tiff", "tif", }; static const gchar *wbmp_extensions[] = { "wbmp", }; static const gchar *xbm_extensions[] = { "xbm", }; static const gchar *xpm_extensions[] = { "xpm", }; static GimvMimeTypeEntry pixbuf_mime_types[] = { { mime_type: "application/x-navi-animation", description: N_("The ANI image format"), extensions: ani_extensions, extensions_len: sizeof (ani_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/bmp", description: N_("The BMP image format"), extensions: bmp_extensions, extensions_len: sizeof (bmp_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-bmp", description: N_("The BMP image format"), extensions: bmp_extensions, extensions_len: sizeof (bmp_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-MS-bmp", description: N_("The BMP image format"), extensions: bmp_extensions, extensions_len: sizeof (bmp_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/gif", description: N_("The GIF image format"), extensions: gif_extensions, extensions_len: sizeof (gif_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-icon", description: N_("The ICO image format"), extensions: icon_extensions, extensions_len: sizeof (icon_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/jpeg", description: N_("The JPEG image format"), extensions: jpeg_extensions, extensions_len: sizeof (jpeg_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/png", description: N_("The PNG image format"), extensions: png_extensions, extensions_len: sizeof (png_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-portable-anymap", description: N_("Portable Any Map Image"), extensions: pnm_extensions, extensions_len: sizeof (pnm_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-portable-bitmap", description: N_("The PBM image format"), extensions: pbm_extensions, extensions_len: sizeof (pbm_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-portable-graymap", description: N_("The PGM image format"), extensions: pgm_extensions, extensions_len: sizeof (pgm_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-portable-pixmap", description: N_("The PPM image format"), extensions: ppm_extensions, extensions_len: sizeof (ppm_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-cmu-raster", description: N_("The Sun raster image format"), extensions: ras_extensions, extensions_len: sizeof (ras_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-sun-raster", description: N_("The Sun raster image format"), extensions: ras_extensions, extensions_len: sizeof (ras_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-tga", description: N_("The Targa image format"), extensions: tga_extensions, extensions_len: sizeof (tga_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/tiff", description: N_("The TIFF image format"), extensions: tiff_extensions, extensions_len: sizeof (tiff_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/vnd.wap.wbmp", description: N_("The WBMP image format"), extensions: wbmp_extensions, extensions_len: sizeof (wbmp_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-xbitmap", description: N_("The XBM image format"), extensions: xbm_extensions, extensions_len: sizeof (xbm_extensions) / sizeof (gchar *), icon: NULL, }, { mime_type: "image/x-xpixmap", description: N_("The XPM image format"), extensions: xpm_extensions, extensions_len: sizeof (xpm_extensions) / sizeof (gchar *), icon: NULL, }, }; GIMV_PLUGIN_GET_IMPL(gimv_pixbuf_loader, GIMV_PLUGIN_IMAGE_LOADER) GIMV_PLUGIN_GET_MIME_TYPE(pixbuf_mime_types) GimvPluginInfo gimv_plugin_info = { if_version: GIMV_PLUGIN_IF_VERSION, name: N_("GdkPixbuf Image Loader"), version: "0.1.1", author: N_("Takuro Ashie"), description: NULL, get_implement: gimv_plugin_get_impl, get_mime_type: gimv_plugin_get_mime_type, get_prefs_ui: NULL, }; static void cb_area_prepared (GdkPixbufLoader *loader, gboolean *ret) { g_return_if_fail (ret); *ret = TRUE; } static void cb_area_updated (GdkPixbufLoader *loader, gint arg1, gint arg2, gint arg3, gint arg4, gboolean *ret) { g_return_if_fail (ret); *ret = TRUE; } #ifndef USE_GTK2 static void cb_frame_done (GdkPixbufLoader *loader, gpointer arg1, gboolean *ret) { g_return_if_fail (ret); *ret = TRUE; } #endif GimvImage * pixbuf_load (GimvImageLoader *loader, gpointer data) { GimvIO *gio; GimvImage *image = NULL; GdkPixbufLoader *pixbuf_loader; guchar buf[512]; gint buf_size = sizeof (buf) / sizeof (gchar); gint i; guint bytes; gboolean prepared = FALSE, updated = FALSE, frame_done = FALSE; gboolean cancel = FALSE; g_return_val_if_fail (loader, NULL); #warning FIXME!! if (loader->info) { if (gimv_image_info_is_movie (loader->info) || gimv_image_info_is_audio (loader->info)) { return NULL; } } gio = gimv_image_loader_get_gio (loader); if (!gio) return NULL; pixbuf_loader = gdk_pixbuf_loader_new (); g_return_val_if_fail (pixbuf_loader, NULL); /* set signals */ #ifdef USE_GTK2 g_signal_connect (G_OBJECT (pixbuf_loader), "area-prepared", G_CALLBACK (cb_area_prepared), &prepared); g_signal_connect (G_OBJECT (pixbuf_loader), "area-updated", G_CALLBACK (cb_area_updated), &updated); #else gtk_signal_connect (GTK_OBJECT (pixbuf_loader), "area-prepared", GTK_SIGNAL_FUNC (cb_area_prepared), &prepared); gtk_signal_connect (GTK_OBJECT (pixbuf_loader), "area-updated", GTK_SIGNAL_FUNC (cb_area_updated), &updated); gtk_signal_connect (GTK_OBJECT (pixbuf_loader), "frame-done", GTK_SIGNAL_FUNC (cb_frame_done), &frame_done); #endif /* load */ for (i = 0;; i++) { gimv_io_read (gio, buf, buf_size, &bytes); if ((gint) bytes > 0) { #ifdef USE_GTK2 gdk_pixbuf_loader_write (pixbuf_loader, buf, bytes, NULL); #else gdk_pixbuf_loader_write (pixbuf_loader, buf, bytes); #endif } else { break; } cancel = !gimv_image_loader_progress_update (loader); if (cancel) goto FUNC_END; if (!gimv_image_loader_load_as_animation(loader) && frame_done) break; } if (!prepared) goto FUNC_END; #ifdef USE_GTK2 if (gimv_image_loader_load_as_animation(loader)) { #else if (gimv_image_loader_load_as_animation(loader) && frame_done) { #endif GdkPixbufAnimation *anim; anim = gdk_pixbuf_loader_get_animation (pixbuf_loader); if (anim) { image = gimv_anim_new_from_gdk_pixbuf_animation (anim); } } if (!image) { image = gimv_image_new (); image->image = gdk_pixbuf_loader_get_pixbuf (pixbuf_loader); if (!image->image) { gimv_image_unref (image); image = NULL; } else { gdk_pixbuf_ref (image->image); } } FUNC_END: #ifdef USE_GTK2 gdk_pixbuf_loader_close (pixbuf_loader, NULL); g_object_unref (G_OBJECT (pixbuf_loader)); #else gdk_pixbuf_loader_close (pixbuf_loader); gtk_object_unref (GTK_OBJECT (pixbuf_loader)); #endif return image; } GimvImage * pixbuf_load_file (GimvImageLoader *loader, gpointer data) { const gchar *filename; GimvImage *image = NULL; g_return_val_if_fail (loader, NULL); #warning FIXME!! if (loader->info) { if (gimv_image_info_is_movie (loader->info) || gimv_image_info_is_audio (loader->info)) { return NULL; } } filename = gimv_image_loader_get_path (loader); if (!filename || !*filename) return NULL; if (!file_exists (filename)) return NULL; #ifdef USE_GTK2 if (gimv_image_loader_load_as_animation(loader)) { GdkPixbufAnimation *anim; anim = gdk_pixbuf_animation_new_from_file (filename, NULL); if (anim) { image = gimv_anim_new_from_gdk_pixbuf_animation (anim); gdk_pixbuf_animation_unref (anim); } } else { image = gimv_image_new (); image->image = gdk_pixbuf_new_from_file (filename, NULL); } #else if (gimv_image_loader_load_as_animation(loader)) { GdkPixbufAnimation *anim; anim = gdk_pixbuf_animation_new_from_file (filename); if (anim) { image = gimv_anim_new_from_gdk_pixbuf_animation (anim); gdk_pixbuf_animation_unref (anim); } } else { image = gimv_image_new (); image->image = gdk_pixbuf_new_from_file (filename); } #endif /* USE_GTK2 */ if (image && !image->image) { gimv_image_unref (image); image = NULL; } return image; } #endif /* HAVE_GDK_PIXBUF */