diff --git a/ChangeLog b/ChangeLog index 2e739e33dd..c7e96cb097 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2003-12-08 Sven Neumann + + * Makefile.am (SUBDIRS): added libgimpthumb. + + * libgimpthumb/gimpthumb-utils.c + * libgimpthumb/gimpthumbnail.c: basic functionality is implemented + and seems to be working. + + * app/Makefile.am: link the application against libgimpthumb. + + * app/core/core-types.h: include libgimpthumb/gimpthumb-types.h. + + * app/core/gimpimagefile.[ch]: removed thumbnail handling routines + and use libgimpthumb instead. Fixes bug #127914. + + * app/gui/file-open-dialog.c + * app/widgets/gimpdocumentview.c: changed accordingly. + 2003-12-07 Dave Neary * NEWS: Updated. diff --git a/Makefile.am b/Makefile.am index d94580539d..7175d640d9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,6 +16,7 @@ SUBDIRS = \ libgimpcolor \ libgimpmath \ libgimpmodule \ + libgimpthumb \ libgimpwidgets \ libgimp \ app \ diff --git a/app/Makefile.am b/app/Makefile.am index 45320c6207..c22b0749c1 100644 --- a/app/Makefile.am +++ b/app/Makefile.am @@ -91,6 +91,7 @@ gimp_1_3_LDADD = \ $(top_builddir)/libgimpmath/libgimpmath-$(LT_RELEASE).la \ $(top_builddir)/libgimpbase/libgimpbase-$(LT_RELEASE).la \ $(top_builddir)/libgimpmodule/libgimpmodule-$(LT_RELEASE).la \ + $(top_builddir)/libgimpthumb/libgimpthumb-$(LT_RELEASE).la \ $(top_builddir)/libgimpwidgets/libgimpwidgets-$(LT_RELEASE).la \ $(GTK_LIBS) \ $(LIBART_LIBS) \ @@ -121,6 +122,7 @@ gimp_console_1_3_LDADD = \ $(top_builddir)/libgimpcolor/libgimpcolor-$(LT_RELEASE).la \ $(top_builddir)/libgimpmath/libgimpmath-$(LT_RELEASE).la \ $(top_builddir)/libgimpbase/libgimpbase-$(LT_RELEASE).la \ + $(top_builddir)/libgimpthumb/libgimpthumb-$(LT_RELEASE).la \ $(top_builddir)/libgimpmodule/libgimpmodule-$(LT_RELEASE).la \ $(GDK_PIXBUF_LIBS) \ $(LIBART_LIBS) \ diff --git a/app/core/core-types.h b/app/core/core-types.h index 6912d3eb27..f4b87bf7b4 100644 --- a/app/core/core-types.h +++ b/app/core/core-types.h @@ -22,6 +22,7 @@ #include "libgimpmath/gimpmath.h" #include "libgimpmodule/gimpmoduletypes.h" +#include "libgimpthumb/gimpthumb-types.h" #include "base/base-types.h" diff --git a/app/core/gimpimagefile.c b/app/core/gimpimagefile.c index 26aff6874c..994ccd4318 100644 --- a/app/core/gimpimagefile.c +++ b/app/core/gimpimagefile.c @@ -25,22 +25,12 @@ #include "config.h" -#include -#include #include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif #include -#ifdef G_OS_WIN32 -#include -#endif - #include "libgimpbase/gimpbase.h" +#include "libgimpthumb/gimpthumb.h" #include "core-types.h" @@ -60,86 +50,30 @@ #include "gimp-intl.h" -#define TAG_DESCRIPTION "tEXt::Description" -#define TAG_SOFTWARE "tEXt::Software" -#define TAG_THUMB_URI "tEXt::Thumb::URI" -#define TAG_THUMB_MTIME "tEXt::Thumb::MTime" -#define TAG_THUMB_SIZE "tEXt::Thumb::Size" -#define TAG_THUMB_IMAGE_WIDTH "tEXt::Thumb::Image::Width" -#define TAG_THUMB_IMAGE_HEIGHT "tEXt::Thumb::Image::Height" -#define TAG_THUMB_GIMP_TYPE "tEXt::Thumb::X-GIMP::Type" -#define TAG_THUMB_GIMP_LAYERS "tEXt::Thumb::X-GIMP::Layers" - - enum { INFO_CHANGED, LAST_SIGNAL }; -typedef struct -{ - const gchar *dirname; - gint size; -} ThumbnailSize; +static void gimp_imagefile_class_init (GimpImagefileClass *klass); +static void gimp_imagefile_init (GimpImagefile *imagefile); +static void gimp_imagefile_finalize (GObject *object); +static void gimp_imagefile_name_changed (GimpObject *object); +static TempBuf * gimp_imagefile_get_new_preview (GimpViewable *viewable, + gint width, + gint height); +static TempBuf * gimp_imagefile_load_thumb (GimpImagefile *imagefile, + gint size); +static gboolean gimp_imagefile_save_thumb (GimpImagefile *imagefile, + GimpImage *gimage, + gint size, + GError **error); -static void gimp_imagefile_class_init (GimpImagefileClass *klass); -static void gimp_imagefile_init (GimpImagefile *imagefile); -static void gimp_imagefile_finalize (GObject *object); -static void gimp_imagefile_name_changed (GimpObject *object); -static void gimp_imagefile_set_info (GimpImagefile *imagefile, - gboolean emit_always, - gint width, - gint height, - GimpImageType type, - gint n_layers); -static TempBuf * gimp_imagefile_get_new_preview (GimpViewable *viewable, - gint width, - gint height); -static gchar * gimp_imagefile_get_description (GimpViewable *viewable, - gchar **tooltip); +static gchar * gimp_imagefile_get_description (GimpViewable *viewable, + gchar **tooltip); -static TempBuf * gimp_imagefile_read_png_thumb (GimpImagefile *imagefile, - gint thumb_size); -static gboolean gimp_imagefile_save_png_thumb (GimpImagefile *imagefile, - GimpImage *gimage, - const gchar *thumb_name, - gint thumb_size, - time_t image_mtime, - off_t image_size); -static void gimp_imagefile_save_fail_thumb (GimpImagefile *imagefile, - time_t image_mtime, - off_t image_size); -static const gchar * gimp_imagefile_png_thumb_name (const gchar *uri); -static gchar * gimp_imagefile_png_thumb_path (const gchar *uri, - gint *thumb_size); -static gchar * gimp_imagefile_find_png_thumb (const gchar *uri, - gint *thumb_size); - -static TempBuf * gimp_imagefile_read_xv_thumb (GimpImagefile *imagefile); -static guchar * readXVThumb (const gchar *filename, - gint *width, - gint *height, - gchar **imginfo); - -static gboolean gimp_imagefile_test (const gchar *filename, - time_t *mtime, - off_t *size); - - -#define THUMB_SIZE_FAIL -1 - -static const ThumbnailSize thumb_sizes[] = -{ - { "fail", THUMB_SIZE_FAIL }, - { "normal", 128 }, - { "large", 256 } -}; - -static gchar *thumb_dir = NULL; -static gchar *thumb_subdirs[G_N_ELEMENTS (thumb_sizes)] = { 0 }; -static gchar *thumb_fail_subdir = NULL; static guint gimp_imagefile_signals[LAST_SIGNAL] = { 0 }; @@ -180,7 +114,7 @@ gimp_imagefile_class_init (GimpImagefileClass *klass) GObjectClass *object_class; GimpObjectClass *gimp_object_class; GimpViewableClass *viewable_class; - gint i; + gchar *creator; parent_class = g_type_class_peek_parent (klass); @@ -205,43 +139,40 @@ gimp_imagefile_class_init (GimpImagefileClass *klass) viewable_class->get_new_preview = gimp_imagefile_get_new_preview; viewable_class->get_description = gimp_imagefile_get_description; - g_type_class_ref (GIMP_TYPE_IMAGE_TYPE); + creator = g_strdup_printf ("gimp-%d.%d", + GIMP_MAJOR_VERSION, GIMP_MINOR_VERSION); - thumb_dir = g_build_filename (g_get_home_dir(), ".thumbnails", NULL); + gimp_thumb_init (creator, NULL); - for (i = 0; i < G_N_ELEMENTS (thumb_sizes); i++) - thumb_subdirs[i] = g_build_filename (g_get_home_dir(), ".thumbnails", - thumb_sizes[i].dirname, NULL); - - thumb_fail_subdir = thumb_subdirs[0]; - thumb_subdirs[0] = g_strdup_printf ("%s%cgimp-%d.%d", - thumb_fail_subdir, G_DIR_SEPARATOR, - GIMP_MAJOR_VERSION, GIMP_MINOR_VERSION); + g_free (creator); } static void gimp_imagefile_init (GimpImagefile *imagefile) { imagefile->gimp = NULL; - imagefile->state = GIMP_IMAGEFILE_STATE_UNKNOWN; - imagefile->image_mtime = 0; - imagefile->image_size = -1; - - imagefile->width = -1; - imagefile->height = -1; - imagefile->type = -1; - imagefile->n_layers = -1; - + imagefile->thumbnail = gimp_thumbnail_new (); imagefile->description = NULL; } static void gimp_imagefile_finalize (GObject *object) { - GimpImagefile *imagefile = (GimpImagefile *) object; + GimpImagefile *imagefile = GIMP_IMAGEFILE (object); - if (imagefile->description && ! imagefile->static_desc) - g_free (imagefile->description); + if (imagefile->description) + { + if (! imagefile->static_desc) + g_free (imagefile->description); + + imagefile->description = NULL; + } + + if (imagefile->thumbnail) + { + g_object_unref (imagefile->thumbnail); + imagefile->thumbnail = NULL; + } G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -256,73 +187,33 @@ gimp_imagefile_new (Gimp *gimp, imagefile = g_object_new (GIMP_TYPE_IMAGEFILE, NULL); + imagefile->gimp = gimp; + if (uri) gimp_object_set_name (GIMP_OBJECT (imagefile), uri); - imagefile->gimp = gimp; - return imagefile; } void gimp_imagefile_update (GimpImagefile *imagefile, - gint thumb_size) + gint size) { - const gchar *uri; - g_return_if_fail (GIMP_IS_IMAGEFILE (imagefile)); - g_return_if_fail (thumb_size <= 256); + g_return_if_fail (size <= 256); - if (thumb_size < 1) + if (size < 1) return; - uri = gimp_object_get_name (GIMP_OBJECT (imagefile)); - - if (uri) - { - gchar *filename = NULL; - gchar *thumbname = NULL; - off_t image_size; - - filename = g_filename_from_uri (uri, NULL, NULL); - - imagefile->image_mtime = 0; - imagefile->image_size = -1; - - if (! filename) - { - /* no thumbnails of remote images :-( */ - - imagefile->state = GIMP_IMAGEFILE_STATE_REMOTE; - goto cleanup; - } - - if (! gimp_imagefile_test (filename, - &imagefile->image_mtime, - &image_size)) - { - imagefile->state = GIMP_IMAGEFILE_STATE_NOT_FOUND; - goto cleanup; - } - - /* found the image, now look for the thumbnail */ - imagefile->image_size = image_size; - imagefile->state = GIMP_IMAGEFILE_STATE_THUMBNAIL_NOT_FOUND; - - thumbname = gimp_imagefile_find_png_thumb (uri, &thumb_size); - - if (thumbname) - imagefile->state = GIMP_IMAGEFILE_STATE_THUMBNAIL_EXISTS; - - cleanup: - g_free (filename); - g_free (thumbname); - - gimp_imagefile_set_info (imagefile, TRUE, -1, -1, -1, -1); - } + gimp_thumbnail_set_uri (imagefile->thumbnail, + gimp_object_get_name (GIMP_OBJECT (imagefile))); gimp_viewable_invalidate_preview (GIMP_VIEWABLE (imagefile)); + gimp_thumbnail_peek_image (imagefile->thumbnail); + gimp_thumbnail_peek_thumb (imagefile->thumbnail, size); + +#if 0 if (uri) { GimpImagefile *documents_imagefile; @@ -333,56 +224,38 @@ gimp_imagefile_update (GimpImagefile *imagefile, if (GIMP_IS_IMAGEFILE (documents_imagefile) && (documents_imagefile != imagefile)) { - gimp_imagefile_update (GIMP_IMAGEFILE (documents_imagefile), - thumb_size); + gimp_imagefile_update (GIMP_IMAGEFILE (documents_imagefile), size); } } +#endif } void gimp_imagefile_create_thumbnail (GimpImagefile *imagefile, - gint thumb_size) + gint size) { - const gchar *uri; - g_return_if_fail (GIMP_IS_IMAGEFILE (imagefile)); - g_return_if_fail (thumb_size <= 256); + g_return_if_fail (size <= 256); if (! imagefile->gimp->config->layer_previews) return; - if (thumb_size < 1) + if (size < 1) return; - uri = gimp_object_get_name (GIMP_OBJECT (imagefile)); + gimp_thumbnail_set_uri (imagefile->thumbnail, + gimp_object_get_name (GIMP_OBJECT (imagefile))); - if (strstr (uri, "/.thumbnails/")) - return; - - if (uri) + if (gimp_thumbnail_peek_image (imagefile->thumbnail) >= GIMP_THUMB_STATE_EXISTS) { - gchar *filename; - gboolean file_exists; - time_t image_mtime; - off_t image_size; GimpImage *gimage; GimpPDBStatusType dummy; - - filename = g_filename_from_uri (uri, NULL, NULL); - - /* no thumbnails of remote images :-( */ - if (! filename) - return; - - file_exists = gimp_imagefile_test (filename, &image_mtime, &image_size); - g_free (filename); - - if (! file_exists) - return; + gboolean success; + GError *error = NULL; gimage = file_open_image (imagefile->gimp, - uri, - uri, + imagefile->thumbnail->image_uri, + imagefile->thumbnail->image_uri, NULL, GIMP_RUN_NONINTERACTIVE, &dummy, @@ -390,240 +263,59 @@ gimp_imagefile_create_thumbnail (GimpImagefile *imagefile, if (gimage) { - gchar *thumb_name; - - thumb_size = MIN (thumb_size, MAX (gimage->width, gimage->height)); - thumb_name = gimp_imagefile_png_thumb_path (uri, &thumb_size); - - if (thumb_name) - { - gimp_imagefile_save_png_thumb (imagefile, - gimage, - thumb_name, - thumb_size, - image_mtime, - image_size); - g_free (thumb_name); - } + success = gimp_imagefile_save_thumb (imagefile, + gimage, size, &error); g_object_unref (gimage); } else { - imagefile->state = GIMP_IMAGEFILE_STATE_THUMBNAIL_FAILED; + success = gimp_thumbnail_save_failure (imagefile->thumbnail, + "The GIMP " GIMP_VERSION, + &error); + } - gimp_imagefile_set_info (imagefile, TRUE, -1, -1, -1, -1); - - gimp_imagefile_save_fail_thumb (imagefile, image_mtime, image_size); + if (!success) + { + g_message (error->message); + g_error_free (error); } } } -static void -gimp_imagefile_save_fail_thumb (GimpImagefile *imagefile, - time_t image_mtime, - off_t image_size) -{ - GdkPixbuf *pixbuf; - const gchar *uri; - gint thumb_size = THUMB_SIZE_FAIL; - gchar *thumb_name; - gchar *desc; - gchar *t_str; - gchar *s_str; - GError *error = NULL; - - uri = gimp_object_get_name (GIMP_OBJECT (imagefile)); - - thumb_name = gimp_imagefile_png_thumb_path (uri, &thumb_size); - - if (!thumb_name) - return; - - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 1, 1); - - desc = g_strdup_printf ("Thumbnail failure for %s", uri); - t_str = g_strdup_printf ("%ld", image_mtime); - s_str = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) image_size); - - if (! gdk_pixbuf_save (pixbuf, thumb_name, "png", &error, - TAG_DESCRIPTION, desc, - TAG_SOFTWARE, ("The GIMP " - GIMP_VERSION), - TAG_THUMB_URI, uri, - TAG_THUMB_MTIME, t_str, - TAG_THUMB_SIZE, s_str, - NULL)) - { - g_message (_("Could not write thumbnail for '%s' as '%s': %s"), - uri, thumb_name, error->message); - g_error_free (error); - } - else if (chmod (thumb_name, 0600)) - { - g_message (_("Could not set permissions of thumbnail '%s': %s"), - thumb_name, g_strerror (errno)); - } - - g_object_unref (pixbuf); - - g_free (desc); - g_free (t_str); - g_free (s_str); - g_free (thumb_name); -} - gboolean gimp_imagefile_save_thumbnail (GimpImagefile *imagefile, GimpImage *gimage) { - const gchar *uri; - const gchar *image_uri; - gchar *filename; - gint thumb_size; - gchar *thumb_name; - time_t image_mtime; - off_t image_size; - gboolean success = FALSE; + gboolean success; + GError *error = NULL; g_return_val_if_fail (GIMP_IS_IMAGEFILE (imagefile), FALSE); g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); - thumb_size = imagefile->gimp->config->thumbnail_size; + success = gimp_imagefile_save_thumb (imagefile, + gimage, + gimage->gimp->config->thumbnail_size, + &error); - g_return_val_if_fail (thumb_size <= 256, FALSE); - - if (! imagefile->gimp->config->layer_previews) - return TRUE; - - if (thumb_size < 1) - return TRUE; - - uri = gimp_object_get_name (GIMP_OBJECT (imagefile)); - image_uri = gimp_object_get_name (GIMP_OBJECT (gimage)); - - g_return_val_if_fail (uri && image_uri && ! strcmp (uri, image_uri), FALSE); - - if (strstr (uri, "/.thumbnails/")) - return FALSE; - - filename = g_filename_from_uri (uri, NULL, NULL); - - /* no thumbnails of remote images :-( */ - if (! filename) - return FALSE; - - thumb_size = MIN (thumb_size, MAX (gimage->width, gimage->height)); - thumb_name = gimp_imagefile_png_thumb_path (uri, &thumb_size); - - /* the thumbnail directory exists or could be created */ - if (thumb_name) + if (! success) { - if (gimp_imagefile_test (filename, &image_mtime, &image_size)) - { - success = gimp_imagefile_save_png_thumb (imagefile, - gimage, - thumb_name, - thumb_size, - image_mtime, - image_size); - } - - g_free (thumb_name); + g_message (error->message); + g_error_free (error); } - g_free (filename); - return success; } static void gimp_imagefile_name_changed (GimpObject *object) { - GimpImagefile *imagefile; - - imagefile = GIMP_IMAGEFILE (object); + GimpImagefile *imagefile = GIMP_IMAGEFILE (object); if (GIMP_OBJECT_CLASS (parent_class)->name_changed) GIMP_OBJECT_CLASS (parent_class)->name_changed (object); - imagefile->state = GIMP_IMAGEFILE_STATE_UNKNOWN; - imagefile->image_mtime = 0; - imagefile->image_size = -1; - - gimp_imagefile_set_info (imagefile, TRUE, -1, -1, -1, -1); -} - -static void -gimp_imagefile_set_info (GimpImagefile *imagefile, - gboolean emit_always, - gint width, - gint height, - GimpImageType type, - gint n_layers) -{ - gboolean changed; - - changed = (imagefile->width != width || - imagefile->height != height || - imagefile->type != type || - imagefile->n_layers != n_layers); - - imagefile->width = width; - imagefile->height = height; - imagefile->type = type; - imagefile->n_layers = n_layers; - - if (imagefile->description) - { - if (!imagefile->static_desc) - g_free (imagefile->description); - imagefile->description = NULL; - } - - if (changed || emit_always) - g_signal_emit (imagefile, gimp_imagefile_signals[INFO_CHANGED], 0); -} - -static void -gimp_imagefile_set_info_from_pixbuf (GimpImagefile *imagefile, - gboolean emit_always, - GdkPixbuf *pixbuf) -{ - const gchar *option; - gint img_width = -1; - gint img_height = -1; - GimpImageType img_type = -1; - gint img_layers = -1; - - option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_IMAGE_WIDTH); - if (!option || sscanf (option, "%d", &img_width) != 1) - img_width = -1; - - option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_IMAGE_HEIGHT); - if (!option || sscanf (option, "%d", &img_height) != 1) - img_height = -1; - - option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_GIMP_TYPE); - if (option) - { - GEnumClass *enum_class; - GEnumValue *enum_value; - - enum_class = g_type_class_peek (GIMP_TYPE_IMAGE_TYPE); - enum_value = g_enum_get_value_by_nick (enum_class, option); - - if (enum_value) - img_type = enum_value->value; - } - - option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_GIMP_LAYERS); - if (!option || sscanf (option, "%d", &img_layers) != 1) - img_layers = -1; - - gimp_imagefile_set_info (imagefile, emit_always, - img_width, img_height, - img_type, img_layers); + gimp_thumbnail_set_uri (imagefile->thumbnail, gimp_object_get_name (object)); } static TempBuf * @@ -639,10 +331,9 @@ gimp_imagefile_get_new_preview (GimpViewable *viewable, if (! GIMP_OBJECT (imagefile)->name) return NULL; - temp_buf = gimp_imagefile_read_png_thumb (imagefile, MAX (width, height)); + temp_buf = gimp_imagefile_load_thumb (imagefile, MAX (width, height)); - if (! temp_buf) - temp_buf = gimp_imagefile_read_xv_thumb (imagefile); + /* FIXME: add back .xvpics compatibility */ if (temp_buf) { @@ -680,21 +371,20 @@ gimp_imagefile_get_description (GimpViewable *viewable, gchar **tooltip) { GimpImagefile *imagefile; - const gchar *uri; + GimpThumbnail *thumbnail; gchar *basename; imagefile = GIMP_IMAGEFILE (viewable); + thumbnail = imagefile->thumbnail; - uri = gimp_object_get_name (GIMP_OBJECT (imagefile)); - - basename = file_utils_uri_to_utf8_basename (uri); + g_return_val_if_fail (thumbnail->image_uri != NULL, NULL); if (tooltip) { gchar *filename; const gchar *desc; - filename = file_utils_uri_to_utf8_filename (uri); + filename = file_utils_uri_to_utf8_filename (thumbnail->image_uri); desc = gimp_imagefile_get_desc_string (imagefile); if (desc) @@ -708,14 +398,16 @@ gimp_imagefile_get_description (GimpViewable *viewable, } } - if (imagefile->width > 0 && imagefile->height > 0) + basename = file_utils_uri_to_utf8_basename (thumbnail->image_uri); + + if (thumbnail->image_width > 0 && thumbnail->image_height > 0) { gchar *tmp = basename; basename = g_strdup_printf ("%s (%d x %d)", tmp, - imagefile->width, - imagefile->height); + thumbnail->image_width, + thumbnail->image_height); g_free (tmp); } @@ -725,39 +417,39 @@ gimp_imagefile_get_description (GimpViewable *viewable, const gchar * gimp_imagefile_get_desc_string (GimpImagefile *imagefile) { + GimpThumbnail *thumbnail; + g_return_val_if_fail (GIMP_IS_IMAGEFILE (imagefile), NULL); if (imagefile->description) return (const gchar *) imagefile->description; - switch (imagefile->state) + thumbnail = imagefile->thumbnail; + + switch (thumbnail->image_state) { - case GIMP_IMAGEFILE_STATE_UNKNOWN: + case GIMP_THUMB_STATE_UNKNOWN: imagefile->description = NULL; imagefile->static_desc = TRUE; break; - case GIMP_IMAGEFILE_STATE_REMOTE: + case GIMP_THUMB_STATE_REMOTE: imagefile->description = _("Remote image"); imagefile->static_desc = TRUE; break; - case GIMP_IMAGEFILE_STATE_NOT_FOUND: + case GIMP_THUMB_STATE_NOT_FOUND: imagefile->description = _("Could not open"); imagefile->static_desc = TRUE; break; default: { - GString *str; + GString *str = g_string_new (NULL); - str = g_string_new (NULL); - - if (imagefile->image_size > -1) + if (thumbnail->image_filesize > 0) { - gchar *size; - - size = gimp_memsize_to_string (imagefile->image_size); + gchar *size = gimp_memsize_to_string (thumbnail->image_filesize); g_string_append (str, size); g_free (size); @@ -765,53 +457,47 @@ gimp_imagefile_get_desc_string (GimpImagefile *imagefile) g_string_append_c (str, '\n'); } - switch (imagefile->state) + switch (thumbnail->thumb_state) { - case GIMP_IMAGEFILE_STATE_THUMBNAIL_NOT_FOUND: + case GIMP_THUMB_STATE_NOT_FOUND: g_string_append (str, _("No preview available")); break; - case GIMP_IMAGEFILE_STATE_THUMBNAIL_EXISTS: + case GIMP_THUMB_STATE_EXISTS: g_string_append (str, _("Loading preview ...")); break; - case GIMP_IMAGEFILE_STATE_THUMBNAIL_OLD: + case GIMP_THUMB_STATE_OLD: g_string_append (str, _("Preview is out of date")); break; - case GIMP_IMAGEFILE_STATE_THUMBNAIL_FAILED: + case GIMP_THUMB_STATE_FAILED: g_string_append (str, _("Cannot create preview")); break; - case GIMP_IMAGEFILE_STATE_THUMBNAIL_OK: + case GIMP_THUMB_STATE_OK: { - GEnumClass *enum_class; - GEnumValue *enum_value; - - if (imagefile->width > -1 && imagefile->height > -1) + if (thumbnail->image_width > 0 && thumbnail->image_height > 0) { g_string_append_printf (str, _("%d x %d pixels"), - imagefile->width, - imagefile->height); + thumbnail->image_width, + thumbnail->image_height); g_string_append_c (str, '\n'); } - enum_class = g_type_class_peek (GIMP_TYPE_IMAGE_TYPE); - enum_value = g_enum_get_value (enum_class, imagefile->type); + if (thumbnail->image_type) + g_string_append (str, gettext (thumbnail->image_type)); - if (enum_value) - g_string_append (str, gettext (enum_value->value_name)); - - if (imagefile->n_layers > -1) + if (thumbnail->image_num_layers > 0) { - if (enum_value) + if (thumbnail->image_type) g_string_append_len (str, ", ", 2); - if (imagefile->n_layers == 1) + if (thumbnail->image_num_layers == 1) g_string_append (str, _("1 Layer")); else g_string_append_printf (str, _("%d Layers"), - imagefile->n_layers); + thumbnail->image_num_layers); } } break; @@ -828,132 +514,56 @@ gimp_imagefile_get_desc_string (GimpImagefile *imagefile) return (const gchar *) imagefile->description; } -static gboolean -gimp_imagefile_test (const gchar *filename, - time_t *mtime, - off_t *size) -{ - struct stat s; - - if (stat (filename, &s) == 0 && (S_ISREG (s.st_mode))) - { - if (mtime) - *mtime = s.st_mtime; - if (size) - *size = s.st_size; - - return TRUE; - } - - return FALSE; -} - - -/* PNG thumbnail handling routines according to the - Thumbnail Managing Standard http://triq.net/~pearl/thumbnail-spec/ */ - static TempBuf * -gimp_imagefile_read_png_thumb (GimpImagefile *imagefile, - gint thumb_size) +gimp_imagefile_load_thumb (GimpImagefile *imagefile, + gint size) { - GimpImagefileState old_state; - TempBuf *temp_buf = NULL; - GdkPixbuf *pixbuf = NULL; - gchar *thumbname = NULL; - const gchar *option; - gint width; - gint height; - gint bytes; - time_t thumb_image_mtime; - gint64 thumb_image_size; - guchar *src; - guchar *dest; - gint y; - GError *error = NULL; + GimpThumbnail *thumbnail; + TempBuf *temp_buf = NULL; + GdkPixbuf *pixbuf = NULL; + GError *error = NULL; - if (imagefile->state < GIMP_IMAGEFILE_STATE_EXISTS) + thumbnail = imagefile->thumbnail; + + if (gimp_thumbnail_peek_thumb (thumbnail, size) < GIMP_THUMB_STATE_EXISTS) return NULL; - old_state = imagefile->state; - - /* try to locate a thumbnail for this image */ - imagefile->state = GIMP_IMAGEFILE_STATE_THUMBNAIL_NOT_FOUND; - - thumbname = gimp_imagefile_find_png_thumb (GIMP_OBJECT (imagefile)->name, - &thumb_size); - - if (!thumbname) - goto cleanup; - - pixbuf = gdk_pixbuf_new_from_file (thumbname, &error); + pixbuf = gimp_thumbnail_load_thumb (thumbnail, size, &error); if (!pixbuf) { - g_message (_("Could not open thumbnail '%s': %s"), - thumbname, error->message); + if (error) + g_message (_("Could not open thumbnail '%s': %s"), + thumbnail->thumb_filename, error->message); goto cleanup; } - g_free (thumbname); - thumbname = NULL; + { + gint width; + gint height; + gint bytes; + guchar *src; + guchar *dest; + gint y; - /* URI and mtime from the thumbnail need to match our file */ + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + bytes = gdk_pixbuf_get_n_channels (pixbuf); - option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_URI); - if (!option || strcmp (option, GIMP_OBJECT (imagefile)->name)) - goto cleanup; + temp_buf = temp_buf_new (width, height, bytes, 0, 0, NULL); - imagefile->state = GIMP_IMAGEFILE_STATE_THUMBNAIL_OLD; + dest = temp_buf_data (temp_buf); + src = gdk_pixbuf_get_pixels (pixbuf); - option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_MTIME); - if (!option || sscanf (option, "%ld", &thumb_image_mtime) != 1) - goto cleanup; - - option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_SIZE); - if (option && sscanf (option, "%" G_GINT64_FORMAT, &thumb_image_size) != 1) - goto cleanup; - - /* TAG_THUMB_SIZE is optional but must match if present */ - if (thumb_image_mtime == imagefile->image_mtime && - (option == NULL || thumb_image_size == (gint64) imagefile->image_size)) - { - if (thumb_size == THUMB_SIZE_FAIL) - imagefile->state = GIMP_IMAGEFILE_STATE_THUMBNAIL_FAILED; - else - imagefile->state = GIMP_IMAGEFILE_STATE_THUMBNAIL_OK; - } - - if (thumb_size == THUMB_SIZE_FAIL) - { - gimp_imagefile_set_info (imagefile, TRUE, -1, -1, -1, -1); - goto cleanup; - } - - /* now convert the pixbuf to a tempbuf */ - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - bytes = gdk_pixbuf_get_n_channels (pixbuf); - - temp_buf = temp_buf_new (width, height, bytes, 0, 0, NULL); - - dest = temp_buf_data (temp_buf); - src = gdk_pixbuf_get_pixels (pixbuf); - - for (y = 0; y < height; y++) - { - memcpy (dest, src, width * bytes); - dest += width * bytes; - src += gdk_pixbuf_get_rowstride (pixbuf); - } - - /* extract into about the original file from the pixbuf */ - gimp_imagefile_set_info_from_pixbuf (imagefile, - imagefile->state != old_state, - pixbuf); + for (y = 0; y < height; y++) + { + memcpy (dest, src, width * bytes); + dest += width * bytes; + src += gdk_pixbuf_get_rowstride (pixbuf); + } + } cleanup: - g_free (thumbname); if (pixbuf) g_object_unref (pixbuf); if (error) @@ -963,411 +573,51 @@ gimp_imagefile_read_png_thumb (GimpImagefile *imagefile, } static gboolean -gimp_imagefile_save_png_thumb (GimpImagefile *imagefile, - GimpImage *gimage, - const gchar *thumb_name, - gint thumb_size, - time_t image_mtime, - off_t image_size) +gimp_imagefile_save_thumb (GimpImagefile *imagefile, + GimpImage *gimage, + gint size, + GError **error) { const gchar *uri; - gchar *temp_name = NULL; GdkPixbuf *pixbuf; gint width, height; gboolean success = FALSE; uri = gimp_object_get_name (GIMP_OBJECT (imagefile)); - if (gimage->width <= thumb_size && gimage->height <= thumb_size) + if (gimage->width <= size && gimage->height <= size) { width = gimage->width; height = gimage->height; - thumb_size = MIN (thumb_size, MAX (width, height)); + size = MIN (size, MAX (width, height)); } else { if (gimage->width < gimage->height) { - height = thumb_size; - width = MAX (1, (thumb_size * gimage->width) / gimage->height); + height = size; + width = MAX (1, (size * gimage->width) / gimage->height); } else { - width = thumb_size; - height = MAX (1, (thumb_size * gimage->height) / gimage->width); + width = size; + height = MAX (1, (size * gimage->height) / gimage->width); } } pixbuf = gimp_viewable_get_new_preview_pixbuf (GIMP_VIEWABLE (gimage), width, height); - { - GEnumClass *enum_class; - GimpImageType type; - gchar *type_str; - gchar *desc; - gchar *t_str; - gchar *w_str; - gchar *h_str; - gchar *s_str; - gchar *l_str; - GError *error = NULL; - - type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (gimp_image_base_type (gimage)); - - if (gimp_image_has_alpha (gimage)) - type = GIMP_IMAGE_TYPE_WITH_ALPHA (type); - - enum_class = g_type_class_peek (GIMP_TYPE_IMAGE_TYPE); - type_str = g_enum_get_value (enum_class, type)->value_nick; - - desc = g_strdup_printf ("Thumbnail of %s", uri); - t_str = g_strdup_printf ("%ld", image_mtime); - w_str = g_strdup_printf ("%d", gimage->width); - h_str = g_strdup_printf ("%d", gimage->height); - s_str = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) image_size); - l_str = g_strdup_printf ("%d", gimage->layers->num_children); - - success = gdk_pixbuf_save (pixbuf, thumb_name, "png", &error, - TAG_DESCRIPTION, desc, - TAG_SOFTWARE, ("The GIMP " - GIMP_VERSION), - TAG_THUMB_URI, uri, - TAG_THUMB_MTIME, t_str, - TAG_THUMB_SIZE, s_str, - TAG_THUMB_IMAGE_WIDTH, w_str, - TAG_THUMB_IMAGE_HEIGHT, h_str, - TAG_THUMB_GIMP_TYPE, type_str, - TAG_THUMB_GIMP_LAYERS, l_str, - NULL); - - if (! success) - { - g_message (_("Could not write thumbnail for '%s' as '%s': %s"), - uri, thumb_name, error->message); - g_error_free (error); - } - else if (chmod (thumb_name, 0600)) - { - g_message (_("Could not set permissions of thumbnail '%s': %s"), - thumb_name, g_strerror (errno)); - } - - g_free (desc); - g_free (t_str); - g_free (w_str); - g_free (h_str); - g_free (s_str); - g_free (l_str); - } + success = gimp_thumbnail_save_thumb (imagefile->thumbnail, + pixbuf, + "The GIMP " GIMP_VERSION, + error); g_object_unref (pixbuf); - g_free (temp_name); - - gimp_imagefile_update (imagefile, thumb_size); + if (success) + gimp_imagefile_update (imagefile, size); return success; } - -static const gchar * -gimp_imagefile_png_thumb_name (const gchar *uri) -{ - static gchar name[40]; - guchar digest[16]; - guchar n; - gint i; - - gimp_md5_get_digest (uri, -1, digest); - - for (i = 0; i < 16; i++) - { - n = (digest[i] >> 4) & 0xF; - name[i * 2] = (n > 9) ? 'a' + n - 10 : '0' + n; - - n = digest[i] & 0xF; - name[i * 2 + 1] = (n > 9) ? 'a' + n - 10 : '0' + n; - } - - strncpy (name + 32, ".png", 5); - - return (const gchar *) name; -} - -static gchar * -gimp_imagefile_png_thumb_path (const gchar *uri, - gint *thumb_size) -{ - const gchar *name; - gchar *thumb_name = NULL; - gint i; - - if (strstr (uri, "/.thumbnails/")) - return NULL; - - name = gimp_imagefile_png_thumb_name (uri); - - if (*thumb_size == THUMB_SIZE_FAIL) - { - i = 0; - } - else - { - for (i = 1; - i < G_N_ELEMENTS (thumb_sizes) && thumb_sizes[i].size < *thumb_size; - i++) - /* nothing */; - - if (i == G_N_ELEMENTS (thumb_sizes)) - i--; - } - - *thumb_size = thumb_sizes[i].size; - - if (! g_file_test (thumb_subdirs[i], G_FILE_TEST_IS_DIR)) - { - if (g_file_test (thumb_dir, G_FILE_TEST_IS_DIR) || - (mkdir (thumb_dir, S_IRUSR | S_IWUSR | S_IXUSR) == 0)) - { - if (i == 0) - mkdir (thumb_fail_subdir, S_IRUSR | S_IWUSR | S_IXUSR); - - mkdir (thumb_subdirs[i], S_IRUSR | S_IWUSR | S_IXUSR); - } - - if (! g_file_test (thumb_subdirs[i], G_FILE_TEST_IS_DIR)) - { - g_message (_("Could not create thumbnail folder '%s'."), - thumb_subdirs[i]); - return NULL; - } - } - - thumb_name = g_build_filename (thumb_subdirs[i], name, NULL); - - return thumb_name; -} - -static gchar * -gimp_imagefile_find_png_thumb (const gchar *uri, - gint *thumb_size) -{ - const gchar *name; - gchar *thumb_name; - gint i, n; - - name = gimp_imagefile_png_thumb_name (uri); - - n = G_N_ELEMENTS (thumb_sizes); - for (i = 1; i < n && thumb_sizes[i].size < *thumb_size; i++) - /* nothing */; - - n = i; - for (; i < G_N_ELEMENTS (thumb_sizes); i++) - { - thumb_name = g_build_filename (thumb_subdirs[i], name, NULL); - - if (gimp_imagefile_test (thumb_name, NULL, NULL)) - { - *thumb_size = thumb_sizes[i].size; - return thumb_name; - } - - g_free (thumb_name); - } - - for (i = n - 1; i >= 0; i--) - { - thumb_name = g_build_filename (thumb_subdirs[i], name, NULL); - - if (gimp_imagefile_test (thumb_name, NULL, NULL)) - { - *thumb_size = thumb_sizes[i].size; - return thumb_name; - } - - g_free (thumb_name); - } - - return NULL; -} - -/* xvpics thumbnail reading routines for backward compatibility */ - -static TempBuf * -gimp_imagefile_read_xv_thumb (GimpImagefile *imagefile) -{ - gchar *filename; - gchar *basename; - gchar *dirname; - gchar *thumbname; - time_t file_mtime; - time_t thumb_mtime; - gint width; - gint height; - gint x, y; - TempBuf *temp_buf; - guchar *src; - guchar *dest; - guchar *raw_thumb = NULL; - gchar *image_info = NULL; - - filename = g_filename_from_uri (GIMP_OBJECT (imagefile)->name, NULL, NULL); - - /* can't load thumbnails of non "file:" URIs */ - if (! filename) - return NULL; - - /* check if the image file exists at all */ - if (!gimp_imagefile_test (filename, &file_mtime, NULL)) - { - g_free (filename); - return NULL; - } - - dirname = g_path_get_dirname (filename); - basename = g_path_get_basename (filename); - - g_free (filename); - - thumbname = g_build_filename (dirname, ".xvpics", basename, NULL); - - g_free (dirname); - g_free (basename); - - if (gimp_imagefile_test (thumbname, &thumb_mtime, NULL) && - thumb_mtime >= file_mtime) - { - raw_thumb = readXVThumb (thumbname, &width, &height, &image_info); - } - - g_free (thumbname); - - if (!raw_thumb) - return NULL; - - imagefile->state = GIMP_IMAGEFILE_STATE_THUMBNAIL_OLD; - - if (image_info) - { - gint img_width; - gint img_height; - - if (sscanf (image_info, "%dx%d", &img_width, &img_height) != 2) - { - img_width = 0; - img_height = 0; - } - gimp_imagefile_set_info (imagefile, FALSE, - img_width, img_height, -1, -1); - - g_free (image_info); - } - - temp_buf = temp_buf_new (width, height, 3, 0, 0, NULL); - src = raw_thumb; - dest = temp_buf_data (temp_buf); - - for (y = 0; y < height; y++) - { - for (x = 0; x < width; x++) - { - dest[x*3] = ((src[x]>>5)*255)/7; - dest[x*3+1] = (((src[x]>>2)&7)*255)/7; - dest[x*3+2] = ((src[x]&3)*255)/3; - } - src += width; - dest += width * 3; - } - - g_free (raw_thumb); - - return temp_buf; -} - - -/* The readXVThumb function source may be re-used under - the XFree86-style license. */ -static guchar * -readXVThumb (const gchar *fnam, - gint *w, - gint *h, - gchar **imginfo) -{ - FILE *fp; - const gchar *P7_332 = "P7 332"; - gchar P7_buf[7]; - gchar linebuf[200]; - guchar *buf; - gint twofivefive; - void *ptr; - - *imginfo = NULL; - - fp = fopen (fnam, "rb"); - if (!fp) - return NULL; - - fread (P7_buf, 6, 1, fp); - - if (strncmp (P7_buf, P7_332, 6)!=0) - { - g_warning ("Thumbnail does not have the 'P7 332' header."); - fclose (fp); - return NULL; - } - - /*newline*/ - fread (P7_buf, 1, 1, fp); - - do - { - ptr = fgets (linebuf, 199, fp); - if ((strncmp (linebuf, "#IMGINFO:", 9) == 0) && - (linebuf[9] != '\0') && - (linebuf[9] != '\n')) - { - if (linebuf[strlen(linebuf)-1] == '\n') - linebuf[strlen(linebuf)-1] = '\0'; - - if (linebuf[9] != '\0') - { - if (*imginfo) - g_free (*imginfo); - *imginfo = g_strdup (&linebuf[9]); - } - } - } - while (ptr && linebuf[0]=='#'); /* keep throwing away comment lines */ - - if (!ptr) - { - /* g_warning("Thumbnail ended - not an image?"); */ - fclose (fp); - return NULL; - } - - sscanf (linebuf, "%d %d %d\n", w, h, &twofivefive); - - if (twofivefive!=255) - { - g_warning ("Thumbnail depth is incorrect."); - fclose (fp); - return NULL; - } - - if ((*w)<1 || (*h)<1 || (*w)>80 || (*h)>60) - { - g_warning ("Thumbnail size is bad. Corrupted?"); - fclose (fp); - return NULL; - } - - buf = g_malloc ((*w) * (*h)); - - fread (buf, (*w) * (*h), 1, fp); - fclose (fp); - - return buf; -} diff --git a/app/core/gimpimagefile.h b/app/core/gimpimagefile.h index 96bee990e1..8a22bc6b42 100644 --- a/app/core/gimpimagefile.h +++ b/app/core/gimpimagefile.h @@ -27,25 +27,9 @@ #define __GIMP_IMAGEFILE_H__ -#include /* time_t */ - #include "gimpviewable.h" -typedef enum -{ - GIMP_IMAGEFILE_STATE_UNKNOWN, - GIMP_IMAGEFILE_STATE_REMOTE, - GIMP_IMAGEFILE_STATE_NOT_FOUND, - GIMP_IMAGEFILE_STATE_EXISTS, - GIMP_IMAGEFILE_STATE_THUMBNAIL_NOT_FOUND, - GIMP_IMAGEFILE_STATE_THUMBNAIL_EXISTS, - GIMP_IMAGEFILE_STATE_THUMBNAIL_OLD, - GIMP_IMAGEFILE_STATE_THUMBNAIL_FAILED, - GIMP_IMAGEFILE_STATE_THUMBNAIL_OK -} GimpImagefileState; - - #define GIMP_TYPE_IMAGEFILE (gimp_imagefile_get_type ()) #define GIMP_IMAGEFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_IMAGEFILE, GimpImagefile)) #define GIMP_IMAGEFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGEFILE, GimpImagefileClass)) @@ -61,17 +45,7 @@ struct _GimpImagefile GimpViewable parent_instance; Gimp *gimp; - - GimpImagefileState state; - - time_t image_mtime; - gssize image_size; - - gint width; - gint height; - GimpImageType type; - gint n_layers; - + GimpThumbnail *thumbnail; gchar *description; gboolean static_desc; }; diff --git a/app/dialogs/file-open-dialog.c b/app/dialogs/file-open-dialog.c index 5a6a2041eb..68471452dc 100644 --- a/app/dialogs/file-open-dialog.c +++ b/app/dialogs/file-open-dialog.c @@ -35,6 +35,7 @@ #include #include "libgimpmath/gimpmath.h" +#include "libgimpthumb/gimpthumb.h" #include "libgimpwidgets/gimpwidgets.h" #include "gui-types.h" @@ -440,7 +441,7 @@ file_open_create_thumbnail (Gimp *gimp, gimp_imagefile_update (imagefile, size); gimp_viewable_get_preview (GIMP_VIEWABLE (imagefile), size, size); - if (imagefile->state < GIMP_IMAGEFILE_STATE_THUMBNAIL_FAILED) + if (imagefile->thumbnail->thumb_state < GIMP_THUMB_STATE_FAILED) gimp_imagefile_create_thumbnail (imagefile, size); } diff --git a/app/gui/file-open-dialog.c b/app/gui/file-open-dialog.c index 5a6a2041eb..68471452dc 100644 --- a/app/gui/file-open-dialog.c +++ b/app/gui/file-open-dialog.c @@ -35,6 +35,7 @@ #include #include "libgimpmath/gimpmath.h" +#include "libgimpthumb/gimpthumb.h" #include "libgimpwidgets/gimpwidgets.h" #include "gui-types.h" @@ -440,7 +441,7 @@ file_open_create_thumbnail (Gimp *gimp, gimp_imagefile_update (imagefile, size); gimp_viewable_get_preview (GIMP_VIEWABLE (imagefile), size, size); - if (imagefile->state < GIMP_IMAGEFILE_STATE_THUMBNAIL_FAILED) + if (imagefile->thumbnail->thumb_state < GIMP_THUMB_STATE_FAILED) gimp_imagefile_create_thumbnail (imagefile, size); } diff --git a/app/widgets/gimpdocumentview.c b/app/widgets/gimpdocumentview.c index 1316de13e1..e2a24aca48 100644 --- a/app/widgets/gimpdocumentview.c +++ b/app/widgets/gimpdocumentview.c @@ -25,6 +25,7 @@ #include +#include "libgimpthumb/gimpthumb.h" #include "libgimpwidgets/gimpwidgets.h" #include "widgets-types.h" @@ -375,7 +376,7 @@ gimp_document_view_delete_dangling_foreach (GimpImagefile *imagefile, { gimp_imagefile_update (imagefile, container_view->preview_size); - if (imagefile->state == GIMP_IMAGEFILE_STATE_NOT_FOUND) + if (imagefile->thumbnail->image_state == GIMP_THUMB_STATE_NOT_FOUND) { gimp_container_remove (container_view->container, GIMP_OBJECT (imagefile)); diff --git a/libgimpthumb/gimpthumb-utils.c b/libgimpthumb/gimpthumb-utils.c index cef13d7b83..fe54a98751 100644 --- a/libgimpthumb/gimpthumb-utils.c +++ b/libgimpthumb/gimpthumb-utils.c @@ -81,7 +81,8 @@ gimp_thumb_init (const gchar *creator, enum_class = g_type_class_ref (GIMP_TYPE_THUMB_SIZE); thumb_num_sizes = enum_class->n_values; - thumb_subdirs = g_new (gchar *, thumb_num_sizes); + thumb_sizes = g_new (gint, thumb_num_sizes); + thumb_subdirs = g_new (gchar *, thumb_num_sizes); for (i = 0, enum_value = enum_class->values; i < enum_class->n_values; @@ -167,8 +168,8 @@ gimp_thumb_name_from_uri (const gchar *uri, } gchar * -gimp_thumb_find_png_thumb (const gchar *uri, - GimpThumbSize *size) +gimp_thumb_find_thumb (const gchar *uri, + GimpThumbSize *size) { const gchar *name; gchar *thumb_name; diff --git a/libgimpthumb/gimpthumb.def b/libgimpthumb/gimpthumb.def index aabd2247c0..e699ac2903 100644 --- a/libgimpthumb/gimpthumb.def +++ b/libgimpthumb/gimpthumb.def @@ -1 +1,18 @@ EXPORTS + gimp_thumb_ensure_thumb_dirs + gimp_thumb_error_quark + gimp_thumb_file_test + gimp_thumb_find_thumb + gimp_thumb_init + gimp_thumb_name_from_uri + gimp_thumb_size_get_type + gimp_thumb_state_get_type + gimp_thumbnail_get_type + gimp_thumbnail_load_thumb + gimp_thumbnail_new + gimp_thumbnail_peek_image + gimp_thumbnail_peek_thumb + gimp_thumbnail_save_failure + gimp_thumbnail_save_thumb + gimp_thumbnail_set_filename + gimp_thumbnail_set_uri diff --git a/libgimpthumb/gimpthumbnail.c b/libgimpthumb/gimpthumbnail.c index 76a64c46e5..c208ab27da 100644 --- a/libgimpthumb/gimpthumbnail.c +++ b/libgimpthumb/gimpthumbnail.c @@ -362,6 +362,17 @@ gimp_thumbnail_set_uri (GimpThumbnail *thumbnail, { g_return_if_fail (GIMP_IS_THUMBNAIL (thumbnail)); + if (thumbnail->image_uri) + g_free (thumbnail->image_uri); + + thumbnail->image_uri = g_strdup (uri); + + if (thumbnail->image_filename) + { + g_free (thumbnail->image_filename); + thumbnail->image_filename = NULL; + } + g_object_set (thumbnail, "image-state", GIMP_THUMB_STATE_UNKNOWN, "image-filesize", 0, @@ -434,7 +445,8 @@ gimp_thumbnail_update_image (GimpThumbnail *thumbnail) gint64 filesize = 0; gint64 mtime = 0; - g_return_if_fail (thumbnail->image_uri != NULL); + if (! thumbnail->image_uri) + return; state = thumbnail->image_state; @@ -503,6 +515,7 @@ gimp_thumbnail_update_thumb (GimpThumbnail *thumbnail) switch (state) { case GIMP_THUMB_STATE_UNKNOWN: + case GIMP_THUMB_STATE_NOT_FOUND: g_return_if_fail (thumbnail->thumb_filename == NULL); thumbnail->thumb_filename = @@ -583,7 +596,6 @@ gimp_thumbnail_load_thumb (GimpThumbnail *thumbnail, GdkPixbuf *pixbuf; g_return_val_if_fail (GIMP_IS_THUMBNAIL (thumbnail), NULL); - g_return_val_if_fail (thumbnail->image_uri != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); if (! thumbnail->image_uri) @@ -763,8 +775,6 @@ gimp_thumbnail_read_thumb (GimpThumbnail *thumbnail, gint64 image_mtime; gint64 image_size; - g_return_val_if_fail (thumbnail->thumb_state < GIMP_THUMB_STATE_EXISTS, NULL); - state = GIMP_THUMB_STATE_NOT_FOUND; name = gimp_thumb_find_thumb (thumbnail->image_uri, &thumb_size); @@ -815,7 +825,7 @@ gimp_thumbnail_read_thumb (GimpThumbnail *thumbnail, cleanup: if (state != thumbnail->thumb_state) - g_object_set (thumbnail, "state", state, NULL); + g_object_set (thumbnail, "thumb-state", state, NULL); if (pixbuf && state != GIMP_THUMB_STATE_OK) { diff --git a/po-libgimp/ChangeLog b/po-libgimp/ChangeLog index 13bee24888..c796703ed9 100644 --- a/po-libgimp/ChangeLog +++ b/po-libgimp/ChangeLog @@ -1,3 +1,9 @@ +2003-12-08 Sven Neumann + + * POTFILES.in: added files from libgimpthumb. + + * de.po: minor updates to the german translation. + 2003-12-07 Marco Ciampa * it.po: Updated italian translation diff --git a/po-libgimp/POTFILES.in b/po-libgimp/POTFILES.in index 54a10eeceb..f47d7d0299 100644 --- a/po-libgimp/POTFILES.in +++ b/po-libgimp/POTFILES.in @@ -14,6 +14,9 @@ libgimpbase/gimputils.c libgimpmodule/gimpmodule.c +libgimpthumb/gimpthumb-utils.c +libgimpthumb/gimpthumbnail.c + libgimpwidgets/gimpcolorbutton.c libgimpwidgets/gimpcolorscales.c libgimpwidgets/gimpcolorselect.c diff --git a/po-libgimp/de.po b/po-libgimp/de.po index 4cc51c64c0..38998d56f4 100644 --- a/po-libgimp/de.po +++ b/po-libgimp/de.po @@ -8,11 +8,11 @@ # msgid "" msgstr "" -"Project-Id-Version: GIMP 1.3.17\n" +"Project-Id-Version: GIMP 1.3.24\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2003-11-24 01:38+0100\n" -"PO-Revision-Date: 2003-11-15 13:55+0100\n" -"Last-Translator: Michael Natterer \n" +"POT-Creation-Date: 2003-12-08 10:08+0100\n" +"PO-Revision-Date: 2003-12-08 10:10+0100\n" +"Last-Translator: Sven Neumann \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -59,9 +59,9 @@ msgid "%s can't handle transparency" msgstr "%s kennt keine Transparenz" #: libgimp/gimpexport.c:269 -#, fuzzy, c-format +#, c-format msgid "%s can't handle layer masks" -msgstr "%s kennt keine Ebenen" +msgstr "%s kennt keine Ebenenmasken" #: libgimp/gimpexport.c:270 msgid "Apply Layer Masks" @@ -99,12 +99,11 @@ msgstr "" "(Für bessere Resultate, diesen Schritt manuell durchführen)" #: libgimp/gimpexport.c:306 -#, fuzzy, c-format +#, c-format msgid "%s can only handle bitmap (two color) indexed images" -msgstr "%s kennt nur RGB und indizierte Paletten" +msgstr "%s kennt nur Bitmaps (indizierte Palette mit 2 Farben)" #: libgimp/gimpexport.c:307 -#, fuzzy msgid "" "Convert to Indexed using bitmap default settings\n" "(Do it manually to tune the result)" @@ -310,6 +309,11 @@ msgstr "Laden fehlgeschlagen" msgid "Not loaded" msgstr "Nicht geladen" +#: libgimpthumb/gimpthumb-utils.c:130 +#, c-format +msgid "Failed to create thumbnail folder '%s'." +msgstr "" + #: libgimpwidgets/gimpcolorbutton.c:93 msgid "/_Foreground Color" msgstr "/_Vordergrundfarbe" @@ -411,15 +415,15 @@ msgstr "Verzeichnis auswählen" msgid "Select File" msgstr "Datei auswählen" -#: libgimpwidgets/gimpmemsizeentry.c:233 +#: libgimpwidgets/gimpmemsizeentry.c:234 msgid "KiloBytes" msgstr "KiloByte" -#: libgimpwidgets/gimpmemsizeentry.c:234 +#: libgimpwidgets/gimpmemsizeentry.c:235 msgid "MegaBytes" msgstr "MegaByte" -#: libgimpwidgets/gimpmemsizeentry.c:235 +#: libgimpwidgets/gimpmemsizeentry.c:236 msgid "GigaBytes" msgstr "GigaByte" @@ -537,9 +541,8 @@ msgid "Color Deficient Vision" msgstr "Farbenblindheit" #: modules/cdisplay_colorblind.c:464 -#, fuzzy msgid "Color _Deficiency Type:" -msgstr "Art der Sehschwäche:" +msgstr "Art der _Sehschwäche:" #: modules/cdisplay_colorblind.c:473 msgid "Protanopia (insensitivity to red)" @@ -562,9 +565,8 @@ msgid "Gamma" msgstr "Gamma" #: modules/cdisplay_gamma.c:311 -#, fuzzy msgid "_Gamma:" -msgstr "Gamma:" +msgstr "_Gamma:" #: modules/cdisplay_highcontrast.c:90 msgid "High Contrast color display filter" @@ -575,9 +577,8 @@ msgid "Contrast" msgstr "Kontrast" #: modules/cdisplay_highcontrast.c:308 -#, fuzzy msgid "Contrast C_ycles:" -msgstr "Kontrastverstärkung:" +msgstr "Kontrast_verstärkung:" #: modules/cdisplay_proof.c:102 msgid "Color proof filter using ICC color profile"