summaryrefslogtreecommitdiff
path: root/thumbnailer
diff options
context:
space:
mode:
authorDebarshi Ray <debarshir@gnome.org>2017-02-12 02:43:19 +0100
committerDebarshi Ray <debarshir@gnome.org>2018-05-01 17:02:10 +0200
commitdd1f222f78eed2b7d70a5e8507199c78e3f9e12b (patch)
tree21dec9c2e58a8a3be432671eb9583105ac226923 /thumbnailer
parent3b0fa197fe3fb76ed3698155001ecc53f64b50bb (diff)
downloadgdk-pixbuf-dd1f222f78eed2b7d70a5e8507199c78e3f9e12b.tar.gz
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
Diffstat (limited to 'thumbnailer')
-rw-r--r--thumbnailer/gdk-pixbuf-thumbnailer.c209
1 files changed, 8 insertions, 201 deletions
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;
}