From dd1f222f78eed2b7d70a5e8507199c78e3f9e12b Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Sun, 12 Feb 2017 02:43:19 +0100 Subject: thumbnailer: Simplify the code by reusing existing GdkPixbuf API Existing GdkPixbuf API like gdk_pixbuf_new_from_file_at_size and gdk_pixbuf_get_file_info have grown smarter since this code was written. They are now better at selecting the best GdkPixbufLoader for a given file. As a side-effect, this also prevents leaking the GFile and its URI, but those are minor issues since the thumbnailer has a very short life span https://bugzilla.gnome.org/show_bug.cgi?id=778517 --- thumbnailer/gdk-pixbuf-thumbnailer.c | 209 ++--------------------------------- 1 file changed, 8 insertions(+), 201 deletions(-) (limited to 'thumbnailer') diff --git a/thumbnailer/gdk-pixbuf-thumbnailer.c b/thumbnailer/gdk-pixbuf-thumbnailer.c index 85df4b3a8..d50ede8ee 100644 --- a/thumbnailer/gdk-pixbuf-thumbnailer.c +++ b/thumbnailer/gdk-pixbuf-thumbnailer.c @@ -24,225 +24,32 @@ #include "gnome-thumbnailer-skeleton.h" -typedef struct { - gint size; - gint input_width; - gint input_height; -} SizePrepareContext; - -#define LOAD_BUFFER_SIZE 65536 - -static void -size_prepared_cb (GdkPixbufLoader *loader, - int width, - int height, - gpointer data) -{ - SizePrepareContext *info = data; - - g_return_if_fail (width > 0 && height > 0); - - info->input_width = width; - info->input_height = height; - - if (width < info->size && height < info->size) return; - if (info->size <= 0) return; - - if (height > width) { - width = 0.5 + (double)width * (double)info->size / (double)height; - height = info->size; - } else { - height = 0.5 + (double)height * (double)info->size / (double)width; - width = info->size; - } - - gdk_pixbuf_loader_set_size (loader, width, height); -} - -static GdkPixbufLoader * -create_loader (GFile *file, - const guchar *data, - gsize size) -{ - GdkPixbufLoader *loader; - GError *error = NULL; - char *mime_type; - char *filename; - - loader = NULL; - - /* need to specify the type here because the gdk_pixbuf_loader_write - doesn't have access to the filename in order to correct detect - the image type. */ - filename = g_file_get_basename (file); - mime_type = g_content_type_guess (filename, data, size, NULL); - g_free (filename); - - if (mime_type != NULL) { - loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, &error); - } - - if (loader == NULL) { - g_debug ("Unable to create loader for mime type %s: %s", mime_type, - (error != NULL) ? error->message : "(null)"); - g_clear_error (&error); - loader = gdk_pixbuf_loader_new (); - } - g_free (mime_type); - - return loader; -} - -static GdkPixbuf * -_gdk_pixbuf_new_from_uri_at_scale (const char *uri, - gint size, - GError **error) -{ - gboolean result; - guchar buffer[LOAD_BUFFER_SIZE]; - gssize bytes_read; - GdkPixbufLoader *loader = NULL; - GdkPixbuf *pixbuf; - GdkPixbufAnimation *animation; - GdkPixbufAnimationIter *iter; - gboolean has_frame; - SizePrepareContext info; - GFile *file; - GInputStream *input_stream; - - g_return_val_if_fail (uri != NULL, NULL); - - file = g_file_new_for_uri (uri); - - input_stream = G_INPUT_STREAM (g_file_read (file, NULL, error)); - if (input_stream == NULL) { - g_object_unref (file); - return NULL; - } - - has_frame = FALSE; - - result = FALSE; - while (!has_frame) { - - bytes_read = g_input_stream_read (input_stream, - buffer, - sizeof (buffer), - NULL, - error); - if (bytes_read == -1) { - break; - } - result = TRUE; - if (bytes_read == 0) { - break; - } - - if (loader == NULL) { - loader = create_loader (file, buffer, bytes_read); - if (1 <= size) { - info.size = size; - info.input_width = info.input_height = 0; - g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info); - } - g_assert (loader != NULL); - } - - if (!gdk_pixbuf_loader_write (loader, - (unsigned char *)buffer, - bytes_read, - error)) { - result = FALSE; - break; - } - - animation = gdk_pixbuf_loader_get_animation (loader); - if (animation) { - iter = gdk_pixbuf_animation_get_iter (animation, NULL); - if (!gdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) { - has_frame = TRUE; - } - g_object_unref (iter); - } - } - - if (loader == NULL) { - /* This can happen if the above loop was exited due to the - * g_input_stream_read() call failing. */ - result = FALSE; - } else if (*error != NULL) { - gdk_pixbuf_loader_close (loader, NULL); - result = FALSE; - } else if (gdk_pixbuf_loader_close (loader, error) == FALSE) { - if (!g_error_matches (*error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INCOMPLETE_ANIMATION)) - result = FALSE; - else - g_clear_error (error); - } - - if (!result) { - g_clear_object (&loader); - g_input_stream_close (input_stream, NULL, NULL); - g_object_unref (input_stream); - g_object_unref (file); - return NULL; - } - - g_input_stream_close (input_stream, NULL, NULL); - g_object_unref (input_stream); - g_object_unref (file); - - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - if (pixbuf != NULL) { - g_object_ref (G_OBJECT (pixbuf)); - g_object_set_data (G_OBJECT (pixbuf), "gnome-original-width", - GINT_TO_POINTER (info.input_width)); - g_object_set_data (G_OBJECT (pixbuf), "gnome-original-height", - GINT_TO_POINTER (info.input_height)); - } - g_object_unref (G_OBJECT (loader)); - - return pixbuf; -} - GdkPixbuf * file_to_pixbuf (const char *path, guint destination_size, GError **error) { GdkPixbuf *pixbuf, *tmp_pixbuf; - GFile *file; - char *uri; - int original_width, original_height; + const char *original_width_str, *original_height_str; - file = g_file_new_for_path (path); - uri = g_file_get_uri (file); - pixbuf = _gdk_pixbuf_new_from_uri_at_scale (uri, destination_size, error); + pixbuf = gdk_pixbuf_new_from_file_at_size (path, destination_size, destination_size, error); if (pixbuf == NULL) return NULL; - original_width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pixbuf), - "gnome-original-width")); - original_height = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pixbuf), - "gnome-original-height")); - tmp_pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf); gdk_pixbuf_copy_options (pixbuf, tmp_pixbuf); gdk_pixbuf_remove_option (tmp_pixbuf, "orientation"); g_object_unref (pixbuf); pixbuf = tmp_pixbuf; - if (original_width > 0 && original_height > 0) { - char *tmp; + original_width_str = gdk_pixbuf_get_option (pixbuf, "original-width"); + original_height_str = gdk_pixbuf_get_option (pixbuf, "original-height"); - tmp = g_strdup_printf ("%d", original_width); - gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Width", tmp); - g_free (tmp); + if (original_width_str != NULL) + gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Width", original_width_str); - tmp = g_strdup_printf ("%d", original_height); - gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Height", tmp); - g_free (tmp); - } + if (original_height_str != NULL) + gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Height", original_height_str); return pixbuf; } -- cgit v1.2.1