[maemo-commits] [maemo-commits] r16054 - in projects/haf/branches/hildon-thumbnail/daemonize: . daemon daemon/plugins

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Mon Sep 8 15:38:04 EEST 2008
Author: pvanhoof
Date: 2008-09-08 15:38:00 +0300 (Mon, 08 Sep 2008)
New Revision: 16054

Modified:
   projects/haf/branches/hildon-thumbnail/daemonize/ChangeLog
   projects/haf/branches/hildon-thumbnail/daemonize/daemon/plugins/gdkpixbuf-plugin.c
   projects/haf/branches/hildon-thumbnail/daemonize/daemon/plugins/pixbuf-io-loader.c
   projects/haf/branches/hildon-thumbnail/daemonize/daemon/thumbnailer.c
   projects/haf/branches/hildon-thumbnail/daemonize/daemon/utils.c
   projects/haf/branches/hildon-thumbnail/daemonize/daemon/utils.h
Log:
2008-09-08  Philip Van Hoof  <pvanhoof at gnome.org>

	* daemon/plugins/gdkpixbuf-plugin.c
	* daemon/plugins/pixbuf-io-loader.c
	* daemon/utils.c
	* daemon/utils.h
	* daemon/thumbnailer.c: Support for cropped thumbnails


Modified: projects/haf/branches/hildon-thumbnail/daemonize/ChangeLog
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/ChangeLog	2008-09-08 11:39:57 UTC (rev 16053)
+++ projects/haf/branches/hildon-thumbnail/daemonize/ChangeLog	2008-09-08 12:38:00 UTC (rev 16054)
@@ -1,5 +1,13 @@
 2008-09-08  Philip Van Hoof  <pvanhoof at gnome.org>
 
+	* daemon/plugins/gdkpixbuf-plugin.c
+	* daemon/plugins/pixbuf-io-loader.c
+	* daemon/utils.c
+	* daemon/utils.h
+	* daemon/thumbnailer.c: Support for cropped thumbnails
+
+2008-09-08  Philip Van Hoof  <pvanhoof at gnome.org>
+
 	* daemon/plugin-runner.c
 	* daemon/manager.c
 	* daemon/thumbnailer.h

Modified: projects/haf/branches/hildon-thumbnail/daemonize/daemon/plugins/gdkpixbuf-plugin.c
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/daemon/plugins/gdkpixbuf-plugin.c	2008-09-08 11:39:57 UTC (rev 16053)
+++ projects/haf/branches/hildon-thumbnail/daemonize/daemon/plugins/gdkpixbuf-plugin.c	2008-09-08 12:38:00 UTC (rev 16054)
@@ -44,12 +44,18 @@
 
 #ifndef gdk_pixbuf_new_from_stream_at_scale
 /* It's implemented in pixbuf-io-loader.c in this case */
-
 GdkPixbuf* gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream, gint width,
 			gint height, gboolean preserve_aspect_ratio,
 			GCancellable *cancellable, GError **error);
 #endif
 
+#ifndef gdk_pixbuf_new_from_stream
+/* It's implemented in pixbuf-io-loader.c in this case */
+GdkPixbuf * gdk_pixbuf_new_from_stream (GInputStream  *stream,
+			    GCancellable  *cancellable,
+			    GError       **error);
+#endif 
+
 static gchar **supported = NULL;
 
 const gchar** 
@@ -116,6 +122,86 @@
 
 
 
+static gboolean 
+save_thumb_file_cropped (GdkPixbuf *pixbuf, gchar *file, guint64 mtime, const gchar *uri, GError **error)
+{
+	gboolean ret;
+
+	ret = gdk_pixbuf_save (pixbuf, file, "jpeg", error, NULL);
+
+	return ret;
+}
+
+
+static GdkPixbuf*
+crop_resize (GdkPixbuf *src, int width, int height) {
+	int x = width, y = height;
+	int a = gdk_pixbuf_get_width(src);
+	int b = gdk_pixbuf_get_height(src);
+
+	GdkPixbuf *dest;
+
+	// This is the automagic cropper algorithm 
+	// It is an optimized version of a system of equations
+	// Basically it maximizes the final size while minimizing the scale
+
+	int nx, ny;
+	double na, nb;
+	double offx = 0, offy = 0;
+	double scax, scay;
+
+	na = a;
+	nb = b;
+
+	if(a < x && b < y) {
+		//nx = a;
+		//ny = b;
+		g_object_ref(src);
+		return src;
+	} else {
+		int u, v;
+
+		nx = u = x;
+		ny = v = y;
+
+		if(a < x) {
+			nx = a;
+			u = a;
+		}
+
+		if(b < y) {
+			ny = b;
+		 	v = b;
+		}
+
+		if(a * y < b * x) {
+			nb = (double)a * v / u;
+			// Center
+			offy = (double)(b - nb) / 2;
+		} else {
+			na = (double)b * u / v;
+			// Center
+			offx = (double)(a - na) / 2;
+		}
+	}
+
+	// gdk_pixbuf_scale has crappy inputs
+	scax = scay = (double)nx / na;
+
+	offx = -offx * scax;
+	offy = -offy * scay;
+
+	dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace(src),
+			       gdk_pixbuf_get_has_alpha(src), 
+			       gdk_pixbuf_get_bits_per_sample(src), 
+			       nx, ny);
+
+	gdk_pixbuf_scale (src, dest, 0, 0, nx, ny, offx, offy, scax, scay,
+			  GDK_INTERP_BILINEAR);
+
+	return dest;
+}
+
 void
 hildon_thumbnail_plugin_create (GStrv uris, GError **error)
 {
@@ -130,12 +216,13 @@
 		gchar *uri = uris[i];
 		GdkPixbuf *pixbuf_large;
 		GdkPixbuf *pixbuf_normal;
+		GdkPixbuf *pixbuf, *pixbuf_cropped;
 		guint64 mtime;
-		gchar *large = NULL, *normal = NULL;
+		gchar *large = NULL, *normal = NULL, *cropped = NULL;
 
 		//g_print ("%s\n", uri);
 
-		hildon_thumbnail_util_get_thumb_paths (uri, &large, &normal, &nerror);
+		hildon_thumbnail_util_get_thumb_paths (uri, &large, &normal, &cropped, &nerror);
 
 		//g_print ("L %s\n", large);
 		//g_print ("N %s\n", normal);
@@ -160,10 +247,10 @@
 			goto nerror_handler;
 
 		pixbuf_large = gdk_pixbuf_new_from_stream_at_scale (G_INPUT_STREAM (stream),
-							      256, 256,
-							      TRUE,
-							      NULL,
-							      &nerror);
+								    256, 256,
+								    TRUE,
+								    NULL,
+								    &nerror);
 
 		if (nerror)
 			goto nerror_handler;
@@ -181,13 +268,11 @@
 			goto nerror_handler;
 
 		pixbuf_normal = gdk_pixbuf_new_from_stream_at_scale (G_INPUT_STREAM (stream),
-							      128, 128,
-							      TRUE,
-							      NULL,
-							      &nerror);
+								     128, 128,
+								     TRUE,
+								     NULL,
+								     &nerror);
 
-		g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
-
 		if (nerror)
 			goto nerror_handler;
 
@@ -195,8 +280,34 @@
 
 		gdk_pixbuf_unref (pixbuf_normal);
 
+		if (nerror)
+			goto nerror_handler;
+
+		g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &nerror);
+
+		if (nerror)
+			goto nerror_handler;
+
+		pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (stream),
+						     NULL,
+						     &nerror);
+
+		if (nerror)
+			goto nerror_handler;
+
+		pixbuf_cropped = crop_resize (pixbuf, 94, 94);
+
+		gdk_pixbuf_unref (pixbuf);
+
+		save_thumb_file_cropped (pixbuf_cropped, cropped, mtime, uri, &nerror);
+
+		gdk_pixbuf_unref (pixbuf_cropped);
+
 		nerror_handler:
 
+		if (stream)
+			g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
+
 		if (nerror) {
 			if (!errors)
 				errors = g_string_new ("");
@@ -215,6 +326,7 @@
 
 		g_free (large);
 		g_free (normal);
+		g_free (cropped);
 
 		i++;
 	}

Modified: projects/haf/branches/hildon-thumbnail/daemonize/daemon/plugins/pixbuf-io-loader.c
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/daemon/plugins/pixbuf-io-loader.c	2008-09-08 11:39:57 UTC (rev 16053)
+++ projects/haf/branches/hildon-thumbnail/daemonize/daemon/plugins/pixbuf-io-loader.c	2008-09-08 12:38:00 UTC (rev 16054)
@@ -192,4 +192,43 @@
 	return pixbuf;
 }
 
+/**
+ * gdk_pixbuf_new_from_stream:
+ * @stream:  a #GInputStream to load the pixbuf from
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @error: Return location for an error
+ *
+ * Creates a new pixbuf by loading an image from an input stream.
+ *
+ * The file format is detected automatically. If %NULL is returned, then
+ * @error will be set. The @cancellable can be used to abort the operation
+ * from another thread. If the operation was cancelled, the error
+ * %GIO_ERROR_CANCELLED will be returned. Other possible errors are in
+ * the #GDK_PIXBUF_ERROR and %G_IO_ERROR domains.
+ *
+ * The stream is not closed.
+ *
+ * Return value: A newly-created pixbuf, or %NULL if any of several error
+ * conditions occurred: the file could not be opened, the image format is
+ * not supported, there was not enough memory to allocate the image buffer,
+ * the stream contained invalid data, or the operation was cancelled.
+ *
+ * Since: 2.14
+ **/
+GdkPixbuf *
+gdk_pixbuf_new_from_stream (GInputStream  *stream,
+			    GCancellable  *cancellable,
+			    GError       **error)
+{
+	GdkPixbuf *pixbuf;
+	GdkPixbufLoader *loader;
+
+	loader = gdk_pixbuf_loader_new ();
+	pixbuf = load_from_stream (loader, stream, cancellable, error);
+	g_object_unref (loader);
+
+	return pixbuf;
+}
+
 #endif
+

Modified: projects/haf/branches/hildon-thumbnail/daemonize/daemon/thumbnailer.c
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/daemon/thumbnailer.c	2008-09-08 11:39:57 UTC (rev 16053)
+++ projects/haf/branches/hildon-thumbnail/daemonize/daemon/thumbnailer.c	2008-09-08 12:38:00 UTC (rev 16054)
@@ -100,7 +100,7 @@
 	const gchar *content_type;
 	GFileInfo *info;
 	GFile *file;
-	gchar *normal = NULL, *large = NULL;
+	gchar *normal = NULL, *large = NULL, *cropped = NULL;
 
 	*mime_type = NULL;
 	*has_thumb = FALSE;
@@ -117,11 +117,15 @@
 		g_object_unref (info);
 	}
 
-	hildon_thumbnail_util_get_thumb_paths (uri, &large, &normal, error);
-	*has_thumb = (g_file_test (large, G_FILE_TEST_EXISTS) && g_file_test (normal, G_FILE_TEST_EXISTS));
+	hildon_thumbnail_util_get_thumb_paths (uri, &large, &normal, &cropped, error);
 
+	*has_thumb = (g_file_test (large, G_FILE_TEST_EXISTS) && 
+		      g_file_test (normal, G_FILE_TEST_EXISTS) && 
+		      g_file_test (cropped, G_FILE_TEST_EXISTS));
+
 	g_free (normal);
 	g_free (large);
+	g_free (cropped);
 
 	g_object_unref (file);
 }

Modified: projects/haf/branches/hildon-thumbnail/daemonize/daemon/utils.c
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/daemon/utils.c	2008-09-08 11:39:57 UTC (rev 16053)
+++ projects/haf/branches/hildon-thumbnail/daemonize/daemon/utils.c	2008-09-08 12:38:00 UTC (rev 16054)
@@ -53,13 +53,15 @@
 }
 
 void
-hildon_thumbnail_util_get_thumb_paths (const gchar *uri, gchar **large, gchar **normal, GError **error)
+hildon_thumbnail_util_get_thumb_paths (const gchar *uri, gchar **large, gchar **normal, gchar **cropped, GError **error)
 {
 	gchar ascii_digest[33];
 	gchar thumb_filename[128];
+	gchar cropped_filename[128];
 
 	static gchar *large_dir = NULL;
 	static gchar *normal_dir = NULL;
+	static gchar *cropped_dir = NULL;
 
 	/* I know we leak, but it's better than doing memory fragementation on 
 	 * these strings ... */
@@ -70,19 +72,27 @@
 	if (!normal_dir)
 		normal_dir = g_build_filename (g_get_home_dir (), ".thumbnails", "normal", NULL);
 
+	if (!cropped_dir)
+		cropped_dir = g_build_filename (g_get_home_dir (), ".thumbnails", "cropped", NULL);
+
 	*large = NULL;
 	*normal = NULL;
+	*cropped = NULL;
 
-	if(!g_file_test(large_dir, G_FILE_TEST_EXISTS))
+	if(!g_file_test (large_dir, G_FILE_TEST_EXISTS))
 		g_mkdir_with_parents (large_dir, 0770);
-	if(!g_file_test(normal_dir, G_FILE_TEST_EXISTS))
+	if(!g_file_test (normal_dir, G_FILE_TEST_EXISTS))
 		g_mkdir_with_parents (normal_dir, 0770);
+	if(!g_file_test (cropped_dir, G_FILE_TEST_EXISTS))
+		g_mkdir_with_parents (cropped_dir, 0770);
 
 	md5_c_string (uri, ascii_digest);
 
 	g_sprintf (thumb_filename, "%s.png", ascii_digest);
+	g_sprintf (cropped_filename, "%s.jpg", ascii_digest);
 
 	*large = g_build_filename (large_dir, thumb_filename, NULL);
 	*normal = g_build_filename (normal_dir, thumb_filename, NULL);
+	*cropped = g_build_filename (cropped_dir, cropped_filename, NULL);
 
 }

Modified: projects/haf/branches/hildon-thumbnail/daemonize/daemon/utils.h
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/daemon/utils.h	2008-09-08 11:39:57 UTC (rev 16053)
+++ projects/haf/branches/hildon-thumbnail/daemonize/daemon/utils.h	2008-09-08 12:38:00 UTC (rev 16054)
@@ -28,7 +28,7 @@
 #include <glib.h>
 #include <gio/gio.h>
 
-void hildon_thumbnail_util_get_thumb_paths (const gchar *uri, gchar **large, gchar **normal, GError **error);
+void hildon_thumbnail_util_get_thumb_paths (const gchar *uri, gchar **large, gchar **normal, gchar **cropped, GError **error);
 
 #ifndef g_sprintf
 gint g_sprintf (gchar *string, gchar const *format, ...);


More information about the maemo-commits mailing list