[gnome-photos] base-item, utils: Don't scale up thumbnails



commit c073ac49739ee62cba1e10844ac4535b48830cc7
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Nov 21 19:04:18 2014 +0100

    base-item, utils: Don't scale up thumbnails
    
    Fixes: https://bugzilla.gnome.org/740417

 src/photos-base-item.c |   24 +++++++++-------
 src/photos-utils.c     |   69 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/photos-utils.h     |    2 +
 3 files changed, 85 insertions(+), 10 deletions(-)
---
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index f4fd2a8..56c95fe 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -504,9 +504,13 @@ photos_base_item_refresh_thumb_path_pixbuf (GObject *source_object, GAsyncResult
 {
   PhotosBaseItem *self = PHOTOS_BASE_ITEM (user_data);
   PhotosBaseItemPrivate *priv = self->priv;
+  GApplication *app;
   GdkPixbuf *pixbuf = NULL;
+  GdkPixbuf *scaled_pixbuf = NULL;
   GError *error = NULL;
   GInputStream *stream = G_INPUT_STREAM (source_object);
+  gint icon_size;
+  gint scale;
 
   pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
   if (error != NULL)
@@ -526,10 +530,15 @@ photos_base_item_refresh_thumb_path_pixbuf (GObject *source_object, GAsyncResult
       goto out;
     }
 
-  photos_base_item_set_original_icon (self, pixbuf);
+  app = g_application_get_default ();
+  scale = photos_application_get_scale_factor (PHOTOS_APPLICATION (app));
+  icon_size = photos_utils_get_icon_size_unscaled ();
+  scaled_pixbuf = photos_utils_downscale_pixbuf_for_scale (pixbuf, icon_size, scale);
+  photos_base_item_set_original_icon (self, scaled_pixbuf);
 
  out:
   g_input_stream_close_async (stream, G_PRIORITY_DEFAULT, NULL, NULL, NULL);
+  g_clear_object (&scaled_pixbuf);
   g_clear_object (&pixbuf);
   g_object_unref (self);
 }
@@ -543,7 +552,6 @@ photos_base_item_refresh_thumb_path_read (GObject *source_object, GAsyncResult *
   GError *error = NULL;
   GFile *file = G_FILE (source_object);
   GFileInputStream *stream;
-  gint size;
 
   stream = g_file_read_finish (file, res, &error);
   if (error != NULL)
@@ -562,14 +570,10 @@ photos_base_item_refresh_thumb_path_read (GObject *source_object, GAsyncResult *
     }
 
   g_object_set_data_full (G_OBJECT (stream), "file", g_object_ref (file), g_object_unref);
-  size = photos_utils_get_icon_size ();
-  gdk_pixbuf_new_from_stream_at_scale_async (G_INPUT_STREAM (stream),
-                                             size,
-                                             size,
-                                             TRUE,
-                                             NULL,
-                                             photos_base_item_refresh_thumb_path_pixbuf,
-                                             g_object_ref (self));
+  gdk_pixbuf_new_from_stream_async (G_INPUT_STREAM (stream),
+                                    NULL,
+                                    photos_base_item_refresh_thumb_path_pixbuf,
+                                    g_object_ref (self));
   g_object_unref (stream);
 
  out:
diff --git a/src/photos-utils.c b/src/photos-utils.c
index 777cba6..ddbd450 100644
--- a/src/photos-utils.c
+++ b/src/photos-utils.c
@@ -434,6 +434,75 @@ photos_utils_dot_dir (void)
 }
 
 
+GdkPixbuf *
+photos_utils_downscale_pixbuf_for_scale (GdkPixbuf *pixbuf, gint size, gint scale)
+{
+  GdkPixbuf *ret_val;
+  gint height;
+  gint pixbuf_size;
+  gint scaled_size;
+  gint width;
+
+  height = gdk_pixbuf_get_height (pixbuf);
+  width = gdk_pixbuf_get_width (pixbuf);
+  pixbuf_size = MAX (height, width);
+
+  scaled_size = size * scale;
+
+  /* On Hi-Dpi displays, a pixbuf should never appear smaller than on
+   * Lo-Dpi. Therefore, if a pixbuf lies between (size, size * scale)
+   * we scale it up to size * scale, so that it doesn't look smaller.
+   * Similarly, if a pixbuf is smaller than size, then we increase its
+   * dimensions by the scale factor.
+   */
+
+  if (pixbuf_size == scaled_size)
+    {
+      ret_val = g_object_ref (pixbuf);
+    }
+  else if (pixbuf_size > size)
+    {
+      if (height == width)
+        {
+          height = scaled_size;
+          width = scaled_size;
+        }
+      else if (height > width)
+        {
+          width = (gint) (0.5 + (gdouble) (width * scaled_size) / (gdouble) height);
+          height = scaled_size;
+        }
+      else
+        {
+          height = (gint) (0.5 + (gdouble) (height * scaled_size) / (gdouble) width);
+          width = scaled_size;
+        }
+
+      height = MAX (height, 1);
+      width = MAX (width, 1);
+      ret_val = gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR);
+    }
+  else /* pixbuf_size <= size */
+    {
+      if (scale == 1)
+        {
+          ret_val = g_object_ref (pixbuf);
+        }
+      else
+        {
+          height *= scale;
+          width *= scale;
+
+          height = MAX (height, 1);
+          width = MAX (width, 1);
+          ret_val = gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR);
+        }
+    }
+
+  return ret_val;
+}
+
+
 void
 photos_utils_ensure_builtins (void)
 {
diff --git a/src/photos-utils.h b/src/photos-utils.h
index 647a8ca..d6726be 100644
--- a/src/photos-utils.h
+++ b/src/photos-utils.h
@@ -64,6 +64,8 @@ GIcon           *photos_utils_get_icon_from_cursor        (TrackerSparqlCursor *
 
 const gchar     *photos_utils_dot_dir                     (void);
 
+GdkPixbuf       *photos_utils_downscale_pixbuf_for_scale  (GdkPixbuf *pixbuf, gint size, gint scale);
+
 void             photos_utils_ensure_builtins             (void);
 
 void             photos_utils_ensure_extension_points     (void);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]