rotate thumbnails by exif
authorVladimir Nadvornik <nadvornik@suse.cz>
Sun, 15 Jun 2008 21:52:15 +0000 (21:52 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Sun, 15 Jun 2008 21:52:15 +0000 (21:52 +0000)
src/pixbuf_util.c
src/pixbuf_util.h
src/thumb.c
src/thumb_standard.c

index 55e289d..8479850 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "main.h"
 #include "pixbuf_util.h"
+#include "exif.h"
 
 #include "icons/icons_inline.h"
 
@@ -382,6 +383,53 @@ GdkPixbuf *pixbuf_copy_mirror(GdkPixbuf *src, gint mirror, gint flip)
        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;
+
+}
+
 
 /*
  *-----------------------------------------------------------------------------
index 2f74d88..2535732 100644 (file)
@@ -41,7 +41,7 @@ GdkPixbuf *pixbuf_inline(const gchar *key);
 
 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,
index 4dfcfae..d6fb883 100644 (file)
@@ -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 @@ static void thumb_loader_done_cb(ImageLoader *il, gpointer data)
        GdkPixbuf *pixbuf;
        gint pw, ph;
        gint save;
+       GdkPixbuf *rotated = NULL;
 
        DEBUG_1("thumb done: %s", tl->fd->path);
 
@@ -158,6 +160,24 @@ static void thumb_loader_done_cb(ImageLoader *il, gpointer data)
                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 @@ static void thumb_loader_done_cb(ImageLoader *il, gpointer data)
                save = il->shrunk;
                }
 
+       if (rotated) gdk_pixbuf_unref(rotated);
+       
        /* save it ? */
        if (tl->cache_enable && save)
                {
index 5b47510..0640565 100644 (file)
@@ -20,6 +20,7 @@
 #include "pixbuf_util.h"
 #include "ui_fileops.h"
 #include "filedata.h"
+#include "exif.h"
 
 
 /*
@@ -398,8 +399,27 @@ static GdkPixbuf *thumb_loader_std_finish(ThumbLoaderStd *tl, GdkPixbuf *pixbuf,
 {
        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 @@ static GdkPixbuf *thumb_loader_std_finish(ThumbLoaderStd *tl, GdkPixbuf *pixbuf,
                }
 
        if (pixbuf_thumb) g_object_unref(pixbuf_thumb);
+       if (rotated) g_object_unref(rotated);
 
        return result;
 }