changeset 839:14520c3a91f8

rotate thumbnails by exif
author nadvornik
date Sun, 15 Jun 2008 21:52:15 +0000
parents 9bd49e725ad3
children cb957189e723
files src/pixbuf_util.c src/pixbuf_util.h src/thumb.c src/thumb_standard.c
diffstat 4 files changed, 92 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/pixbuf_util.c	Sun Jun 15 20:09:15 2008 +0000
+++ b/src/pixbuf_util.c	Sun Jun 15 21:52:15 2008 +0000
@@ -13,6 +13,7 @@
 
 #include "main.h"
 #include "pixbuf_util.h"
+#include "exif.h"
 
 #include "icons/icons_inline.h"
 
@@ -382,6 +383,53 @@
 	return dest;
 }
 
+GdkPixbuf* pixbuf_apply_orientation(GdkPixbuf *pixbuf, gint orientation)
+{
+	GdkPixbuf *dest;
+	GdkPixbuf *tmp = NULL;
+	
+	switch (orientation)
+		{
+		case EXIF_ORIENTATION_TOP_LEFT:
+			dest = gdk_pixbuf_copy(pixbuf);
+			break;
+		case EXIF_ORIENTATION_TOP_RIGHT:
+			/* mirrored */
+			dest = pixbuf_copy_mirror(pixbuf, TRUE, FALSE);
+			break;
+		case EXIF_ORIENTATION_BOTTOM_RIGHT:
+			/* upside down */
+			dest = pixbuf_copy_mirror(pixbuf, TRUE, TRUE);
+			break;
+		case EXIF_ORIENTATION_BOTTOM_LEFT:
+			/* flipped */
+			dest = pixbuf_copy_mirror(pixbuf, FALSE, TRUE);
+			break;
+		case EXIF_ORIENTATION_LEFT_TOP:
+			tmp = pixbuf_copy_mirror(pixbuf, FALSE, TRUE);
+			dest = pixbuf_copy_rotate_90(tmp, FALSE);
+			break;
+		case EXIF_ORIENTATION_RIGHT_TOP:
+			/* rotated -90 (270) */
+			dest = pixbuf_copy_rotate_90(pixbuf, FALSE);
+			break;
+		case EXIF_ORIENTATION_RIGHT_BOTTOM:
+			tmp = pixbuf_copy_mirror(pixbuf, FALSE, TRUE);
+			dest = pixbuf_copy_rotate_90(tmp, TRUE);
+			break;
+		case EXIF_ORIENTATION_LEFT_BOTTOM:
+			/* rotated 90 */
+			dest = pixbuf_copy_rotate_90(pixbuf, TRUE);
+			break;
+		default:
+			dest = gdk_pixbuf_copy(pixbuf);
+			break;
+		}
+	if (tmp) gdk_pixbuf_unref(tmp);
+	return dest;
+
+}
+
 
 /*
  *-----------------------------------------------------------------------------
--- a/src/pixbuf_util.h	Sun Jun 15 20:09:15 2008 +0000
+++ b/src/pixbuf_util.h	Sun Jun 15 21:52:15 2008 +0000
@@ -41,7 +41,7 @@
 
 GdkPixbuf *pixbuf_copy_rotate_90(GdkPixbuf *src, gint counter_clockwise);
 GdkPixbuf *pixbuf_copy_mirror(GdkPixbuf *src, gint mirror, gint flip);
-
+GdkPixbuf* pixbuf_apply_orientation(GdkPixbuf *pixbuf, gint orientation);
 
 void pixbuf_draw_rect_fill(GdkPixbuf *pb,
 			   gint x, gint y, gint w, gint h,
--- a/src/thumb.c	Sun Jun 15 20:09:15 2008 +0000
+++ b/src/thumb.c	Sun Jun 15 21:52:15 2008 +0000
@@ -20,6 +20,7 @@
 #include "pixbuf_util.h"
 #include "thumb_standard.h"
 #include "ui_fileops.h"
+#include "exif.h"
 
 #include <utime.h>
 
@@ -147,6 +148,7 @@
 	GdkPixbuf *pixbuf;
 	gint pw, ph;
 	gint save;
+	GdkPixbuf *rotated = NULL;
 
 	DEBUG_1("thumb done: %s", tl->fd->path);
 
@@ -158,6 +160,24 @@
 		return;
 		}
 
+
+	if (!tl->cache_hit && options->image.exif_rotate_enable)
+		{
+		if (!tl->fd->exif_orientation)
+			{
+			ExifData *exif = exif_read_fd(tl->fd);
+			gint orientation;
+
+			if (exif && exif_get_integer(exif, "Exif.Image.Orientation", &orientation))
+				tl->fd->exif_orientation = orientation;
+			else
+				tl->fd->exif_orientation = 1;
+			}
+		
+		rotated = pixbuf_apply_orientation(pixbuf, tl->fd->exif_orientation);
+		pixbuf = rotated;
+		}
+
 	pw = gdk_pixbuf_get_width(pixbuf);
 	ph = gdk_pixbuf_get_height(pixbuf);
 
@@ -217,6 +237,8 @@
 		save = il->shrunk;
 		}
 
+	if (rotated) gdk_pixbuf_unref(rotated);
+	
 	/* save it ? */
 	if (tl->cache_enable && save)
 		{
--- a/src/thumb_standard.c	Sun Jun 15 20:09:15 2008 +0000
+++ b/src/thumb_standard.c	Sun Jun 15 21:52:15 2008 +0000
@@ -20,6 +20,7 @@
 #include "pixbuf_util.h"
 #include "ui_fileops.h"
 #include "filedata.h"
+#include "exif.h"
 
 
 /*
@@ -398,8 +399,27 @@
 {
 	GdkPixbuf *pixbuf_thumb = NULL;
 	GdkPixbuf *result;
+	GdkPixbuf *rotated = NULL;
 	gint sw, sh;
 
+
+	if (!tl->cache_hit && options->image.exif_rotate_enable)
+		{
+		if (!tl->fd->exif_orientation)
+			{
+			ExifData *exif = exif_read_fd(tl->fd);
+			gint orientation;
+
+			if (exif && exif_get_integer(exif, "Exif.Image.Orientation", &orientation))
+				tl->fd->exif_orientation = orientation;
+			else
+				tl->fd->exif_orientation = 1;
+			}
+		
+		rotated = pixbuf_apply_orientation(pixbuf, tl->fd->exif_orientation);
+		pixbuf = rotated;
+		}
+
 	sw = gdk_pixbuf_get_width(pixbuf);
 	sh = gdk_pixbuf_get_height(pixbuf);
 
@@ -484,6 +504,7 @@
 		}
 
 	if (pixbuf_thumb) g_object_unref(pixbuf_thumb);
+	if (rotated) g_object_unref(rotated);
 
 	return result;
 }