summaryrefslogtreecommitdiff
path: root/libnautilus-private/nautilus-thumbnails.c
diff options
context:
space:
mode:
authorChristian Neumair <chris@gnome-de.org>2006-05-30 17:42:10 +0000
committerChristian Neumair <cneumair@src.gnome.org>2006-05-30 17:42:10 +0000
commit39e753ee5f0ff838b5603239f8777df2288a7615 (patch)
treea7716766d1bb80f1e3b8db717ba87f101a0da37a /libnautilus-private/nautilus-thumbnails.c
parent3b315234454087fb6c447972393c85cb4009c0b7 (diff)
downloadnautilus-39e753ee5f0ff838b5603239f8777df2288a7615.tar.gz
Use GdkPixbufLoader for thumbnailing.
2006-05-30 Christian Neumair <chris@gnome-de.org> * libnautilus-private/nautilus-icon-factory.c: * libnautilus-private/nautilus-thumbnails.c: * libnautilus-private/nautilus-thumbnails.h: Use GdkPixbufLoader for thumbnailing.
Diffstat (limited to 'libnautilus-private/nautilus-thumbnails.c')
-rw-r--r--libnautilus-private/nautilus-thumbnails.c142
1 files changed, 133 insertions, 9 deletions
diff --git a/libnautilus-private/nautilus-thumbnails.c b/libnautilus-private/nautilus-thumbnails.c
index 33f3ca3c0..64f61757c 100644
--- a/libnautilus-private/nautilus-thumbnails.c
+++ b/libnautilus-private/nautilus-thumbnails.c
@@ -30,6 +30,7 @@
#include "nautilus-global-preferences.h"
#include "nautilus-icon-factory-private.h"
#include "nautilus-icon-factory.h"
+#include <math.h>
#include <eel/eel-gdk-pixbuf-extensions.h>
#include <eel/eel-graphic-effects.h>
#include <eel/eel-string.h>
@@ -263,22 +264,145 @@ nautilus_thumbnail_frame_image (GdkPixbuf **pixbuf)
*pixbuf=pixbuf_with_frame;
}
-/* routine to load an image from the passed-in path, and then embed it in
- * a frame if necessary
+typedef struct {
+ gboolean is_thumbnail;
+ guint base_size;
+ guint nominal_size;
+ gboolean force_nominal;
+ int original_height;
+ int original_width;
+ double *scale_x_out;
+ double *scale_y_out;
+} ThumbnailLoadArgs;
+
+static void
+thumbnail_loader_size_prepared (GdkPixbufLoader *loader,
+ int width,
+ int height,
+ ThumbnailLoadArgs *args)
+{
+ int size = MAX (width, height);
+
+ args->original_width = width;
+ args->original_height = height;
+
+ if (args->force_nominal) {
+ args->base_size = size;
+ } else if (args->base_size == 0) {
+ if (args->is_thumbnail) {
+ args->base_size = 128 * NAUTILUS_ICON_SIZE_STANDARD / NAUTILUS_ICON_SIZE_THUMBNAIL;
+ } else {
+ if (size > args->nominal_size * NAUTILUS_ICON_SIZE_THUMBNAIL / NAUTILUS_ICON_SIZE_STANDARD) {
+ args->base_size = size * NAUTILUS_ICON_SIZE_STANDARD / NAUTILUS_ICON_SIZE_THUMBNAIL;
+ } else if (size > NAUTILUS_ICON_SIZE_STANDARD) {
+ args->base_size = args->nominal_size;
+ } else {
+ /* Don't scale up small icons */
+ args->base_size = NAUTILUS_ICON_SIZE_STANDARD;
+ }
+ }
+ }
+
+ if (args->base_size != args->nominal_size) {
+ double scale;
+
+ scale = (double) args->nominal_size / args->base_size;
+
+ if ((int) (width * scale) > NAUTILUS_ICON_MAXIMUM_SIZE ||
+ (int) (height * scale) > NAUTILUS_ICON_MAXIMUM_SIZE) {
+ scale = MIN ((double) NAUTILUS_ICON_MAXIMUM_SIZE / width,
+ (double) NAUTILUS_ICON_MAXIMUM_SIZE / height);
+ }
+
+ width = MAX (1, floor (width * scale + 0.5));
+ height = MAX (1, floor (height * scale + 0.5));
+
+ gdk_pixbuf_loader_set_size (loader, width, height);
+ }
+
+}
+
+static void
+thumbnail_loader_area_prepared (GdkPixbufLoader *loader,
+ ThumbnailLoadArgs *args)
+{
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ *args->scale_x_out = (double) gdk_pixbuf_get_width (pixbuf) / args->original_width;
+ *args->scale_y_out = (double) gdk_pixbuf_get_height (pixbuf) / args->original_height;
+}
+
+/* routine to load an image from the passed-in path
*/
GdkPixbuf *
-nautilus_thumbnail_load_framed_image (const char *path)
+nautilus_thumbnail_load_image (const char *path,
+ guint base_size,
+ guint nominal_size,
+ gboolean force_nominal,
+ double *scale_x_out,
+ double *scale_y_out)
{
+ guchar *buffer;
+ GdkPixbufLoader *loader;
GdkPixbuf *pixbuf;
-
- pixbuf = gdk_pixbuf_new_from_file (path, NULL);
- if (pixbuf == NULL) {
+ GError *error;
+ gsize buflen;
+ ThumbnailLoadArgs args;
+
+ error = NULL;
+
+ if (!g_file_get_contents (path, (gchar **) &buffer, &buflen, &error)) {
+ g_message ("Failed to load %s into memory: %s", path, error->message);
+
+ g_error_free (error);
+
return NULL;
}
- if (!gdk_pixbuf_get_has_alpha (pixbuf)) {
- nautilus_thumbnail_frame_image (&pixbuf);
+
+ loader = gdk_pixbuf_loader_new ();
+ g_signal_connect (loader, "size-prepared",
+ G_CALLBACK (thumbnail_loader_size_prepared),
+ &args);
+ g_signal_connect (loader, "area-prepared",
+ G_CALLBACK (thumbnail_loader_area_prepared),
+ &args);
+
+ args.is_thumbnail = strstr (path, "/.thumbnails/") != NULL;
+ args.base_size = base_size;
+ args.nominal_size = nominal_size;
+ args.force_nominal = force_nominal;
+ args.scale_x_out = scale_x_out;
+ args.scale_y_out = scale_y_out;
+
+ if (!gdk_pixbuf_loader_write (loader, buffer, buflen, &error)) {
+ g_message ("Failed to write %s to thumbnail pixbuf loader: %s", path, error->message);
+
+ gdk_pixbuf_loader_close (loader, NULL);
+ g_object_unref (G_OBJECT (loader));
+ g_error_free (error);
+ g_free (buffer);
+
+ return NULL;
+ }
+
+ if (!gdk_pixbuf_loader_close (loader, &error)) {
+ g_message ("Failed to close thumbnail pixbuf loader for %s: %s", path, error->message);
+
+ g_object_unref (G_OBJECT (loader));
+ g_error_free (error);
+ g_free (buffer);
+
+ return NULL;
}
- return pixbuf;
+
+ pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
+
+ g_object_unref (G_OBJECT (loader));
+ g_free (buffer);
+
+ return pixbuf;
}
void