Index: libgthumb/gth-exif-utils.h
===================================================================
RCS file: /cvs/gnome/gthumb/libgthumb/gth-exif-utils.h,v
retrieving revision 1.2
diff -u -p -r1.2 gth-exif-utils.h
--- libgthumb/gth-exif-utils.h	8 Oct 2006 08:45:27 -0000	1.2
+++ libgthumb/gth-exif-utils.h	12 Oct 2006 14:04:01 -0000
@@ -33,19 +33,6 @@
 #include "jpegutils/jpeg-data.h"
 
 
-typedef enum { /*< skip >*/
-	GTH_EXIF_ORIENTATION_NONE = 0,
-	GTH_EXIF_ORIENTATION_TOP_LEFT,
-	GTH_EXIF_ORIENTATION_TOP_RIGHT,
-	GTH_EXIF_ORIENTATION_BOTTOM_RIGHT,
-	GTH_EXIF_ORIENTATION_BOTTOM_LEFT,
-	GTH_EXIF_ORIENTATION_LEFT_TOP,
-	GTH_EXIF_ORIENTATION_RIGHT_TOP,
-	GTH_EXIF_ORIENTATION_RIGHT_BOTTOM,
-	GTH_EXIF_ORIENTATION_LEFT_BOTTOM
-} GthExifOrientation;
-
-
 char *      get_exif_tag            (const char *filename,
 				     ExifTag     etag);
 ExifShort   get_exif_tag_short      (const char *filename,
Index: libgthumb/image-loader.c
===================================================================
RCS file: /cvs/gnome/gthumb/libgthumb/image-loader.c,v
retrieving revision 1.28
diff -u -p -r1.28 image-loader.c
--- libgthumb/image-loader.c	8 Oct 2006 08:45:27 -0000	1.28
+++ libgthumb/image-loader.c	12 Oct 2006 14:04:01 -0000
@@ -407,70 +407,23 @@ image_loader_set_pixbuf (ImageLoader *il
 	g_mutex_unlock (priv->yes_or_no);
 }
 
-/*
- * Returns an image, transformed according
- * to the Exif orientation data.
- */
-static GdkPixbuf *
-_gdk_pixbuf_transform_exif_orientation (GdkPixbuf* src, 
-				GthExifOrientation orientation)
-{
-	GdkPixbuf *temp = NULL, *dest = NULL;
-	
-	if (!src) return NULL;
-	
-	switch (orientation) {
-	case GTH_EXIF_ORIENTATION_TOP_LEFT:
-		dest = src;
-		g_object_ref (dest);
-		break;
-	case GTH_EXIF_ORIENTATION_TOP_RIGHT:
-		dest = _gdk_pixbuf_copy_mirror (src, TRUE, FALSE);
-		break;
-	case GTH_EXIF_ORIENTATION_BOTTOM_RIGHT:
-		dest = _gdk_pixbuf_copy_mirror (src, TRUE, TRUE);
-		break;
-	case GTH_EXIF_ORIENTATION_BOTTOM_LEFT:
-		dest = _gdk_pixbuf_copy_mirror (src, FALSE, TRUE);
-		break;
-	case GTH_EXIF_ORIENTATION_LEFT_TOP:
-		temp = _gdk_pixbuf_copy_rotate_90 (src, FALSE);
-		dest = _gdk_pixbuf_copy_mirror (temp, TRUE, FALSE);
-		g_object_unref (temp);
-		break;
-	case GTH_EXIF_ORIENTATION_RIGHT_TOP:
-		dest = _gdk_pixbuf_copy_rotate_90 (src, FALSE);
-		break;
-	case GTH_EXIF_ORIENTATION_RIGHT_BOTTOM:
-		temp = _gdk_pixbuf_copy_rotate_90 (src, FALSE);
-		dest = _gdk_pixbuf_copy_mirror (temp, FALSE, TRUE);
-		g_object_unref (temp);
-		break;
-	case GTH_EXIF_ORIENTATION_LEFT_BOTTOM:
-		dest = _gdk_pixbuf_copy_rotate_90 (src, TRUE);
-		break;
-	default:
-		dest = src;
-		g_object_ref (dest);
-		break;
-	}
-	
-	return dest;
-}
-
 static void 
 image_loader_sync_pixbuf (ImageLoader *il)
 {
 	GdkPixbuf              *pixbuf;
 	GdkPixbuf              *temp;
 	ImageLoaderPrivateData *priv;
-	GthExifOrientation     orientation;
+	ExifShort				orientation;
+	GthTransform			transform;
   
 	g_return_if_fail (il != NULL);
      
 	priv = il->priv;
 
 	orientation = get_exif_tag_short (image_loader_get_path(il), EXIF_TAG_ORIENTATION);
+	transform =  (orientation >= 1 && orientation <= 8 ? 
+						orientation : 
+						GTH_TRANSFORM_NONE);
 
 	g_mutex_lock (priv->yes_or_no);
 
@@ -483,7 +436,7 @@ image_loader_sync_pixbuf (ImageLoader *i
 	}
 
 	temp = gdk_pixbuf_animation_get_static_image (priv->animation);
-	pixbuf = _gdk_pixbuf_transform_exif_orientation (temp, orientation);
+	pixbuf = _gdk_pixbuf_transform (temp, transform);
 
 	if (priv->pixbuf == pixbuf) {
 		g_object_unref (pixbuf);
Index: libgthumb/pixbuf-utils.c
===================================================================
RCS file: /cvs/gnome/gthumb/libgthumb/pixbuf-utils.c,v
retrieving revision 1.18
diff -u -p -r1.18 pixbuf-utils.c
--- libgthumb/pixbuf-utils.c	8 Oct 2006 08:45:26 -0000	1.18
+++ libgthumb/pixbuf-utils.c	12 Oct 2006 14:04:02 -0000
@@ -213,6 +213,57 @@ _gdk_pixbuf_copy_mirror (GdkPixbuf *src,
 }
 
 
+/*
+ * Returns a transformed image.
+ */
+GdkPixbuf *
+_gdk_pixbuf_transform (GdkPixbuf* src, 
+				GthTransform transform)
+{
+	GdkPixbuf *temp = NULL, *dest = NULL;
+	
+	if (!src) return NULL;
+	
+	switch (transform) {
+	case GTH_TRANSFORM_NONE:
+		dest = src;
+		g_object_ref (dest);
+		break;
+	case GTH_TRANSFORM_FLIP_H:
+		dest = _gdk_pixbuf_copy_mirror (src, TRUE, FALSE);
+		break;
+	case GTH_TRANSFORM_ROTATE_180:
+		dest = _gdk_pixbuf_copy_mirror (src, TRUE, TRUE);
+		break;
+	case GTH_TRANSFORM_FLIP_V:
+		dest = _gdk_pixbuf_copy_mirror (src, FALSE, TRUE);
+		break;
+	case GTH_TRANSFORM_TRANSPOSE:
+		temp = _gdk_pixbuf_copy_rotate_90 (src, FALSE);
+		dest = _gdk_pixbuf_copy_mirror (temp, TRUE, FALSE);
+		g_object_unref (temp);
+		break;
+	case GTH_TRANSFORM_ROTATE_90:
+		dest = _gdk_pixbuf_copy_rotate_90 (src, FALSE);
+		break;
+	case GTH_TRANSFORM_TRANSVERSE:
+		temp = _gdk_pixbuf_copy_rotate_90 (src, FALSE);
+		dest = _gdk_pixbuf_copy_mirror (temp, FALSE, TRUE);
+		g_object_unref (temp);
+		break;
+	case GTH_TRANSFORM_ROTATE_270:
+		dest = _gdk_pixbuf_copy_rotate_90 (src, TRUE);
+		break;
+	default:
+		dest = src;
+		g_object_ref (dest);
+		break;
+	}
+	
+	return dest;
+}
+
+
 void
 pixmap_from_xpm (const char **data, 
 		 GdkPixmap **pixmap, 
Index: libgthumb/pixbuf-utils.h
===================================================================
RCS file: /cvs/gnome/gthumb/libgthumb/pixbuf-utils.h,v
retrieving revision 1.7
diff -u -p -r1.7 pixbuf-utils.h
--- libgthumb/pixbuf-utils.h	11 Dec 2005 14:18:17 -0000	1.7
+++ libgthumb/pixbuf-utils.h	12 Oct 2006 14:04:02 -0000
@@ -27,6 +27,8 @@
 #include <gdk/gdk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
+#include "typedefs.h"
+
 void        pixmap_from_xpm                   (const char **data, 
 					       GdkPixmap  **pixmap, 
 					       GdkBitmap  **mask);
@@ -51,6 +53,9 @@ GdkPixbuf *_gdk_pixbuf_copy_rotate_90   
 GdkPixbuf *_gdk_pixbuf_copy_mirror            (GdkPixbuf *src, 
 					       gboolean   mirror, 
 					       gboolean   flip);
+
+GdkPixbuf *_gdk_pixbuf_transform              (GdkPixbuf* src, 
+					       GthTransform transform);
 
 gboolean   _gdk_pixbuf_save                   (GdkPixbuf       *pixbuf,
 					       const char      *filename,
Index: libgthumb/typedefs.h
===================================================================
RCS file: /cvs/gnome/gthumb/libgthumb/typedefs.h,v
retrieving revision 1.16
diff -u -p -r1.16 typedefs.h
--- libgthumb/typedefs.h	31 Dec 2005 16:41:45 -0000	1.16
+++ libgthumb/typedefs.h	12 Oct 2006 14:04:02 -0000
@@ -204,13 +204,14 @@ typedef enum { /*< skip >*/
 
 
 typedef enum { /*< skip >*/
-	GTH_TRANSFORM_ROTATE_0,
-	GTH_TRANSFORM_ROTATE_90,
-	GTH_TRANSFORM_ROTATE_180,
-	GTH_TRANSFORM_ROTATE_270,
-	GTH_TRANSFORM_NONE,
-	GTH_TRANSFORM_MIRROR,
-	GTH_TRANSFORM_FLIP
+	GTH_TRANSFORM_NONE = 1,		/* no transformation */
+	GTH_TRANSFORM_FLIP_H,		/* horizontal flip */
+	GTH_TRANSFORM_ROTATE_180, 	/* 180-degree rotation */
+	GTH_TRANSFORM_FLIP_V,		/* vertical flip */
+	GTH_TRANSFORM_TRANSPOSE,	/* transpose across UL-to-LR axis (= rotate_90 + flip_h) */
+	GTH_TRANSFORM_ROTATE_90,	/* 90-degree clockwise rotation */
+	GTH_TRANSFORM_TRANSVERSE,	/* transpose across UR-to-LL axis (= rotate_90 + flip_v) */
+	GTH_TRANSFORM_ROTATE_270	/* 270-degree clockwise */
 } GthTransform;
 
 
Index: src/dlg-jpegtran.c
===================================================================
RCS file: /cvs/gnome/gthumb/src/dlg-jpegtran.c,v
retrieving revision 1.38
diff -u -p -r1.38 dlg-jpegtran.c
--- src/dlg-jpegtran.c	10 Oct 2006 20:29:27 -0000	1.38
+++ src/dlg-jpegtran.c	12 Oct 2006 14:04:03 -0000
@@ -75,7 +75,7 @@ typedef struct {
 	GList        *current_image;
 	ImageLoader  *loader;
 	GdkPixbuf    *original_preview;
-	RotationData *rot_data;
+	GthTransform	transform;
 } DialogData;
 
 
@@ -95,7 +95,6 @@ dialog_data_free (DialogData *data)
 		g_object_unref (data->loader);
 	if (data->gui != NULL)
 		g_object_unref (data->gui);
-	g_free (data->rot_data);
 	g_free (data);
 }
 
@@ -192,8 +191,7 @@ load_current_image (DialogData *data)
 	image_loader_set_path (data->loader, path);
 	image_loader_start (data->loader);
 
-	data->rot_data->rot_type = GTH_TRANSFORM_ROTATE_0;
-	data->rot_data->tran_type = GTH_TRANSFORM_NONE;
+	data->transform = GTH_TRANSFORM_NONE;
 }
 
 
@@ -265,14 +263,14 @@ apply_transformation (DialogData *data,
                            transform the data using the "lossless" jpeg
                            mathematical transform (only really lossless if
                            dimensions are multiples of 8 */
-                        apply_transformation_jpeg (window, path, data->rot_data);
+                        apply_transformation_jpeg (window, path, data->transform);
                 }
                 else {
                         /* Calculate a new orientation tag, based on the
                            input tag and the requested rotation. This saves
 			   the jpeg, so no further action is required if
 			   "adjust photo orientation" is not selected. */
-                        update_orientation_field (path, data->rot_data);
+                        update_orientation_field (path, data->transform);
 
                         /* if "adjust photo orientation" is selected mathematically transform
 			   the data so that the viewed image remains the same, but the 
@@ -285,15 +283,15 @@ apply_transformation (DialogData *data,
 				if (!(height%8) && !(width%8)) {
 					/* Don't do this if the dimensions are not multiples
 					   of the jpeg minimum coding unit (iMCU = 8) */
-	                		update_rotation_from_exif_data (path, data->rot_data);
-					apply_transformation_jpeg (window, path, data->rot_data);
+	             			data->transform = read_orientation_field (path);
+					apply_transformation_jpeg (window, path, data->transform);
 				}
                         }
                 }
 
         }
 	else 
-		apply_transformation_generic (window, path, data->rot_data);
+		apply_transformation_generic (window, path, data->transform);
 	gnome_vfs_set_file_info (path, &info, GNOME_VFS_SET_FILE_INFO_PERMISSIONS|GNOME_VFS_SET_FILE_INFO_OWNER);
 
 	notify_file_changed (data, path, notify_soon);
@@ -381,23 +379,11 @@ ok_clicked (GtkWidget  *button, 
 }
 
 
-static int 
-get_next_rot (int rot)
-{
-	int next_rot [4] = {GTH_TRANSFORM_ROTATE_90, 
-			    GTH_TRANSFORM_ROTATE_180, 
-			    GTH_TRANSFORM_ROTATE_270,
-			    GTH_TRANSFORM_ROTATE_0};
-	return next_rot [rot];
-}
-
-
 static void
 revert_clicked (GtkWidget  *button, 
 		DialogData *data)
 {
-	data->rot_data->rot_type = GTH_TRANSFORM_ROTATE_0;
-	data->rot_data->tran_type = GTH_TRANSFORM_NONE;
+	data->transform = GTH_TRANSFORM_NONE;
 
 	if (data->original_preview != NULL)
 		gtk_image_set_from_pixbuf (GTK_IMAGE (data->j_preview_image), data->original_preview);
@@ -405,26 +391,21 @@ revert_clicked (GtkWidget  *button, 
 
 
 static void
-rot90_clicked (GtkWidget  *button, 
-	       DialogData *data)
+transform_clicked_impl (GtkWidget  *button, 
+	       DialogData *data,
+	       GthTransform transform)
 {
-	GdkPixbuf *src_pixbuf;
-	GdkPixbuf *dest_pixbuf;
+	GdkPixbuf *src_pixbuf = NULL;
+	GdkPixbuf *dest_pixbuf = NULL;
 
-	if (data->rot_data->tran_type == GTH_TRANSFORM_NONE)
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-	else {
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-	}
+	data->transform = get_next_transformation (data->transform, transform);
 
 	src_pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (data->j_preview_image));
 
 	if (src_pixbuf == NULL) 
 		return;
 
-	dest_pixbuf = _gdk_pixbuf_copy_rotate_90 (src_pixbuf, FALSE);
+	dest_pixbuf = _gdk_pixbuf_transform (src_pixbuf, transform);
 	gtk_image_set_from_pixbuf (GTK_IMAGE (data->j_preview_image), dest_pixbuf);
 
 	if (dest_pixbuf != NULL) 
@@ -433,29 +414,18 @@ rot90_clicked (GtkWidget  *button, 
 
 
 static void
-rot270_clicked (GtkWidget  *button, 
-		DialogData *data)
+rot90_clicked (GtkWidget  *button, 
+	       DialogData *data)
 {
-	GdkPixbuf *src_pixbuf;
-	GdkPixbuf *dest_pixbuf;
-
-	if (data->rot_data->tran_type == GTH_TRANSFORM_NONE) {
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-	} else
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-
-	src_pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (data->j_preview_image));
-
-	if (src_pixbuf == NULL) 
-		return;
+	transform_clicked_impl (button, data, GTH_TRANSFORM_ROTATE_90);
+}
 
-	dest_pixbuf = _gdk_pixbuf_copy_rotate_90 (src_pixbuf, TRUE);
-	gtk_image_set_from_pixbuf (GTK_IMAGE (data->j_preview_image), dest_pixbuf);
 
-	if (dest_pixbuf != NULL) 
-		g_object_unref (dest_pixbuf);
+static void
+rot270_clicked (GtkWidget  *button, 
+		DialogData *data)
+{
+	transform_clicked_impl (button, data, GTH_TRANSFORM_ROTATE_270);
 }
 
 
@@ -463,30 +433,7 @@ static void
 mirror_clicked (GtkWidget  *button, 
 		DialogData *data)
 {
-	GdkPixbuf *src_pixbuf;
-	GdkPixbuf *dest_pixbuf;
-
-	src_pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (data->j_preview_image));
-
-	if (src_pixbuf == NULL) 
-		return;
-
-	if (data->rot_data->tran_type == GTH_TRANSFORM_FLIP) {
-		data->rot_data->tran_type = GTH_TRANSFORM_NONE;
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-
-	} else if (data->rot_data->tran_type == GTH_TRANSFORM_MIRROR)
-		data->rot_data->tran_type = GTH_TRANSFORM_NONE;
-
-	else
-		data->rot_data->tran_type = GTH_TRANSFORM_MIRROR;
-	
-	dest_pixbuf = _gdk_pixbuf_copy_mirror (src_pixbuf, TRUE, FALSE);
-	gtk_image_set_from_pixbuf (GTK_IMAGE (data->j_preview_image), dest_pixbuf);
-	
-	if (dest_pixbuf != NULL) 
-		g_object_unref (dest_pixbuf);
+	transform_clicked_impl (button, data, GTH_TRANSFORM_FLIP_H);
 }
 
 
@@ -494,30 +441,7 @@ static void
 flip_clicked (GtkWidget  *button, 
 	      DialogData *data)
 {
-	GdkPixbuf *src_pixbuf;
-	GdkPixbuf *dest_pixbuf;
-
-	if (data->rot_data->tran_type == GTH_TRANSFORM_MIRROR) {
-		data->rot_data->tran_type = GTH_TRANSFORM_NONE;
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-		data->rot_data->rot_type = get_next_rot (data->rot_data->rot_type);
-
-	} else if (data->rot_data->tran_type == GTH_TRANSFORM_FLIP)
-		data->rot_data->tran_type = GTH_TRANSFORM_NONE;
-
-	else
-		data->rot_data->tran_type = GTH_TRANSFORM_FLIP;
-
-	src_pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (data->j_preview_image));
-
-	if (src_pixbuf == NULL) 
-		return;
-
-	dest_pixbuf = _gdk_pixbuf_copy_mirror (src_pixbuf, FALSE, TRUE);
-	gtk_image_set_from_pixbuf (GTK_IMAGE (data->j_preview_image), dest_pixbuf);
-
-	if (dest_pixbuf != NULL) 
-		g_object_unref (dest_pixbuf);
+	transform_clicked_impl (button, data, GTH_TRANSFORM_FLIP_V);
 }
 
 
@@ -603,7 +527,7 @@ dlg_jpegtran (GthWindow *window)
 		return;
 	}
 
-	data->rot_data = rotation_data_new ();
+	data->transform = GTH_TRANSFORM_NONE;
 
 	/* Get the widgets. */
 
@@ -712,8 +636,7 @@ dlg_jpegtran (GthWindow *window)
 
 void
 dlg_apply_jpegtran (GthWindow    *window,
-		    GthTransform  rot_type,
-		    GthTransform  tran_type)
+		    GthTransform  transform)
 {
 	DialogData  *data;
 	GList       *list;
@@ -730,10 +653,7 @@ dlg_apply_jpegtran (GthWindow    *window
 	data->window = window;
 	data->file_list = list;
 	data->current_image = list;
-
-	data->rot_data = rotation_data_new();
-	data->rot_data->rot_type = rot_type;
-	data->rot_data->tran_type = tran_type;
+	data->transform = transform;
 
 	apply_transformation_to_all (data);
 }
Index: src/dlg-jpegtran.h
===================================================================
RCS file: /cvs/gnome/gthumb/src/dlg-jpegtran.h,v
retrieving revision 1.4
diff -u -p -r1.4 dlg-jpegtran.h
--- src/dlg-jpegtran.h	8 Oct 2006 08:45:16 -0000	1.4
+++ src/dlg-jpegtran.h	12 Oct 2006 14:04:03 -0000
@@ -29,7 +29,6 @@
 
 void dlg_jpegtran                 (GthWindow    *window);
 void dlg_apply_jpegtran           (GthWindow    *window,
-				   GthTransform  rot_type,
-				   GthTransform  tran_type);
+				   GthTransform  transform);
 
 #endif /* DLG_JPEGTRAN_H */
Index: src/dlg-photo-importer.c
===================================================================
RCS file: /cvs/gnome/gthumb/src/dlg-photo-importer.c,v
retrieving revision 1.40
diff -u -p -r1.40 dlg-photo-importer.c
--- src/dlg-photo-importer.c	10 Oct 2006 20:29:27 -0000	1.40
+++ src/dlg-photo-importer.c	12 Oct 2006 14:04:04 -0000
@@ -1370,16 +1370,13 @@ adjust_orientation__step (AsyncOperation
 	
 	if (file_is_image (filepath, TRUE)) {
 		FileData     *fd = file_data_new (filepath, &info);
-		RotationData *rot_data = rotation_data_new ();
-
-		update_rotation_from_exif_data (fd->path, rot_data);
+		GthTransform transform = read_orientation_field (fd->path);
 		if (image_is_jpeg (filepath))
-			apply_transformation_jpeg (window, fd->path, rot_data);
+			apply_transformation_jpeg (window, fd->path, transform);
 		else
-			apply_transformation_generic (window, fd->path, rot_data);
+			apply_transformation_generic (window, fd->path, transform);
 
 		file_data_unref (fd);
-		g_free (rot_data);
 	}
 	
 	gnome_vfs_set_file_info (filepath, &info, GNOME_VFS_SET_FILE_INFO_PERMISSIONS|GNOME_VFS_SET_FILE_INFO_OWNER);
Index: src/gth-window-actions-callbacks.c
===================================================================
RCS file: /cvs/gnome/gthumb/src/gth-window-actions-callbacks.c,v
retrieving revision 1.18
diff -u -p -r1.18 gth-window-actions-callbacks.c
--- src/gth-window-actions-callbacks.c	8 Oct 2006 08:45:14 -0000	1.18
+++ src/gth-window-actions-callbacks.c	12 Oct 2006 14:04:04 -0000
@@ -888,10 +888,10 @@ void
 gth_window_activate_action_tools_jpeg_rotate_right (GtkAction *action,
 						    GthWindow *window)
 {
-	void (*module) (GthWindow *, GthTransform, GthTransform);
+	void (*module) (GthWindow *, GthTransform);
 
 	if (gthumb_module_get ("dlg_apply_jpegtran", (gpointer*) &module))
-		(*module) (window, GTH_TRANSFORM_ROTATE_90, GTH_TRANSFORM_NONE);
+		(*module) (window, GTH_TRANSFORM_ROTATE_90);
 }
 
 
@@ -899,8 +899,8 @@ void
 gth_window_activate_action_tools_jpeg_rotate_left (GtkAction *action,
 						   GthWindow *window)
 {
-	void (*module) (GthWindow *, GthTransform, GthTransform);
+	void (*module) (GthWindow *, GthTransform);
 
 	if (gthumb_module_get ("dlg_apply_jpegtran", (gpointer*) &module))
-		(*module) (window, GTH_TRANSFORM_ROTATE_270, GTH_TRANSFORM_NONE);
+		(*module) (window, GTH_TRANSFORM_ROTATE_270);
 }
Index: src/rotation-utils.c
===================================================================
RCS file: /cvs/gnome/gthumb/src/rotation-utils.c,v
retrieving revision 1.8
diff -u -p -r1.8 rotation-utils.c
--- src/rotation-utils.c	10 Oct 2006 20:29:27 -0000	1.8
+++ src/rotation-utils.c	12 Oct 2006 14:04:04 -0000
@@ -34,75 +34,22 @@
 #include "jpegutils/transupp.h"
 #include "jpegutils/jpegtran.h"
 
-
-RotationData*
-rotation_data_new ()
-{
-	RotationData *rd;
-	
-	rd = g_new0 (RotationData, 1);
-	rd->rot_type = GTH_TRANSFORM_ROTATE_0;
-	rd->tran_type = GTH_TRANSFORM_NONE;
-	
-	return rd;
-}
-
-
-void
-update_rotation_from_exif_data (const char   *path,
-				RotationData *rot_data)
+GthTransform
+read_orientation_field (const char *path)
 {
-	GthExifOrientation orientation;
-
-	rot_data->rot_type = GTH_TRANSFORM_ROTATE_0;
-	rot_data->tran_type = GTH_TRANSFORM_NONE;
+	ExifShort orientation;
 
 	path = get_file_path_from_uri (path);
 	if (path == NULL)
-		return;
-	orientation = get_exif_tag_short (path, EXIF_TAG_ORIENTATION);
+		return GTH_TRANSFORM_NONE;
 
-	switch (orientation) {
-	case GTH_EXIF_ORIENTATION_TOP_LEFT:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_0;
-		rot_data->tran_type = GTH_TRANSFORM_NONE;
-		break;
-	case GTH_EXIF_ORIENTATION_TOP_RIGHT:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_0;
-		rot_data->tran_type = GTH_TRANSFORM_MIRROR;
-		break;
-	case GTH_EXIF_ORIENTATION_BOTTOM_RIGHT:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_180;
-		rot_data->tran_type = GTH_TRANSFORM_NONE;
-		break;
-	case GTH_EXIF_ORIENTATION_BOTTOM_LEFT:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_180;
-		rot_data->tran_type = GTH_TRANSFORM_MIRROR;
-		break;
-	case GTH_EXIF_ORIENTATION_LEFT_TOP:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_90;
-		rot_data->tran_type = GTH_TRANSFORM_MIRROR;
-		break;
-	case GTH_EXIF_ORIENTATION_RIGHT_TOP:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_90;
-		rot_data->tran_type = GTH_TRANSFORM_NONE;
-		break;
-	case GTH_EXIF_ORIENTATION_RIGHT_BOTTOM:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_90;
-		rot_data->tran_type = GTH_TRANSFORM_FLIP;
-		break;
-	case GTH_EXIF_ORIENTATION_LEFT_BOTTOM:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_270;
-		rot_data->tran_type = GTH_TRANSFORM_NONE;
-		break;
-	default:
-		rot_data->rot_type = GTH_TRANSFORM_ROTATE_0;
-		rot_data->tran_type = GTH_TRANSFORM_NONE;
-		break;
-	}
+	orientation = get_exif_tag_short (path, EXIF_TAG_ORIENTATION);
+	if (orientation >= 1 && orientation <= 8)
+		return orientation;
+	else
+		return GTH_TRANSFORM_NONE;
 }
 
-
 void
 reset_orientation_field (const char *path)
 {
@@ -135,7 +82,7 @@ reset_orientation_field (const char *pat
 		if (entry != NULL) {
 			ExifByteOrder byte_order;
 			byte_order = exif_data_get_byte_order (edata);
-			exif_set_short (entry->data, byte_order, 1);
+			exif_set_short (entry->data, byte_order, GTH_TRANSFORM_NONE);
 		}
 	}
 
@@ -149,12 +96,10 @@ reset_orientation_field (const char *pat
 void
 apply_transformation_jpeg (GtkWindow    *win,
 			   const char   *path,
-			   RotationData *rot_data)
+			   GthTransform transform)
 {
-	int          rot_type = rot_data->rot_type; 
-	int          tran_type = rot_data->tran_type; 
 	char        *line;
-	char        *tmp1, *tmp2;
+	char        *tmp;
 	static int   count = 0;
 	GError      *err = NULL;
 	JXFORM_CODE  transf;
@@ -164,70 +109,49 @@ apply_transformation_jpeg (GtkWindow    
 	if (path == NULL)
 		return;
 	
-	if ((rot_type == GTH_TRANSFORM_ROTATE_0) && (tran_type == GTH_TRANSFORM_NONE))
-		return;
-
-	if (rot_type == GTH_TRANSFORM_ROTATE_0)
-		tmp1 = g_strdup (path);
-	else {
-		tmp1 = g_strdup_printf ("%s/gthumb.%d.%d",
-					g_get_tmp_dir (), 
-					getpid (),
-					count++);
-
-		switch (rot_type) {
-		case GTH_TRANSFORM_ROTATE_90:
-			transf = JXFORM_ROT_90;
-			break;
-		case GTH_TRANSFORM_ROTATE_180:
-			transf = JXFORM_ROT_180;
-			break;
-		case GTH_TRANSFORM_ROTATE_270:
-			transf = JXFORM_ROT_270;
-			break;
-		default:
-			transf = JXFORM_NONE;
-			break;
-		}
-
-		if (jpegtran ((char*)path, tmp1, transf, &err) != 0) {
-			g_free (tmp1);
-			if (err != NULL) 
-				_gtk_error_dialog_from_gerror_run (win, &err);
-			return;
-		}
+	tmp = g_strdup_printf ("%s/gthumb.%d.%d",
+				g_get_tmp_dir (), 
+				getpid (),
+				count++);
+
+	switch (transform) {
+	case GTH_TRANSFORM_NONE:
+		transf = JXFORM_NONE;
+		break;
+	case GTH_TRANSFORM_FLIP_H:
+		transf = JXFORM_FLIP_H;
+		break;
+	case GTH_TRANSFORM_ROTATE_180:
+		transf = JXFORM_ROT_180;
+		break;
+	case GTH_TRANSFORM_FLIP_V:
+		transf = JXFORM_FLIP_V;
+		break;
+	case GTH_TRANSFORM_TRANSPOSE:
+		transf = JXFORM_TRANSPOSE;
+		break;
+	case GTH_TRANSFORM_ROTATE_90:
+		transf = JXFORM_ROT_90;
+		break;
+	case GTH_TRANSFORM_TRANSVERSE:
+		transf = JXFORM_TRANSVERSE;
+		break;
+	case GTH_TRANSFORM_ROTATE_270:
+		transf = JXFORM_ROT_270;
+		break;
+	default:
+		transf = JXFORM_NONE;
+		break;
 	}
 
-	if (tran_type == GTH_TRANSFORM_NONE)
-		tmp2 = g_strdup (tmp1);
-	else {
-		tmp2 = g_strdup_printf ("%s/gthumb.%d.%d",
-					g_get_tmp_dir (), 
-					getpid (),
-					count++);
-
-		switch (tran_type) {
-		case GTH_TRANSFORM_MIRROR:
-			transf = JXFORM_FLIP_H;
-			break;
-		case GTH_TRANSFORM_FLIP:
-			transf = JXFORM_FLIP_V;
-			break;
-		default:
-			transf = JXFORM_NONE;
-			break;
-		}
-
-		if (jpegtran (tmp1, tmp2, transf, &err) != 0) {
-			g_free (tmp1);
-			if (err != NULL) 
-				_gtk_error_dialog_from_gerror_run (win, &err);
-			return;
-		}
-
+	if (jpegtran ((char*)path, tmp, transf, &err) != 0) {
+		g_free (tmp);
+		if (err != NULL) 
+			_gtk_error_dialog_from_gerror_run (win, &err);
+		return;
 	}
 
-	e1 = shell_escape (tmp2);
+	e1 = shell_escape (tmp);
 	e2 = shell_escape (path);
 
 	line = g_strdup_printf ("mv -f %s %s", e1, e2);
@@ -237,7 +161,9 @@ apply_transformation_jpeg (GtkWindow    
 		_gtk_error_dialog_from_gerror_run (win, &err);
 
 	} else {
-		if ((rot_type == GTH_TRANSFORM_ROTATE_90) || (rot_type == GTH_TRANSFORM_ROTATE_270))
+		GthTransform rot_type = get_rotation_part(transform);
+		if ((rot_type == GTH_TRANSFORM_ROTATE_90) || 
+				(rot_type == GTH_TRANSFORM_ROTATE_270))
 			swap_xy_exif_fields (path);
 		reset_orientation_field (path);
 	}
@@ -245,18 +171,15 @@ apply_transformation_jpeg (GtkWindow    
 	g_free (e1);
 	g_free (e2);
 	g_free (line);
-	g_free (tmp1);
-	g_free (tmp2);
+	g_free (tmp);
 }
 
 
 void
 apply_transformation_generic (GtkWindow    *win,
 			      const char   *path,
-			      RotationData *rot_data)
+			      GthTransform transform)
 {
-	int         rot_type = rot_data->rot_type; 
-	int         tran_type = rot_data->tran_type; 
 	GdkPixbuf  *pixbuf1, *pixbuf2;
 	const char *mime_type;
 
@@ -264,49 +187,20 @@ apply_transformation_generic (GtkWindow 
 	if (path == NULL)
 		return;
 
-	if ((rot_type == GTH_TRANSFORM_ROTATE_0) && (tran_type == GTH_TRANSFORM_NONE))
+	if (transform == GTH_TRANSFORM_NONE)
 		return;
 
 	pixbuf1 = gdk_pixbuf_new_from_file (path, NULL);
 	if (pixbuf1 == NULL)
 		return;
 
-	switch (rot_type) {
-	case GTH_TRANSFORM_ROTATE_90:
-		pixbuf2 = _gdk_pixbuf_copy_rotate_90 (pixbuf1, FALSE);
-		break;
-	case GTH_TRANSFORM_ROTATE_180:
-		pixbuf2 = _gdk_pixbuf_copy_mirror (pixbuf1, TRUE, TRUE);
-		break;
-	case GTH_TRANSFORM_ROTATE_270:
-		pixbuf2 = _gdk_pixbuf_copy_rotate_90 (pixbuf1, TRUE);
-		break;
-	default:
-		pixbuf2 = pixbuf1;
-		g_object_ref (pixbuf2);
-		break;
-	}
-	g_object_unref (pixbuf1);
-
-	switch (tran_type) {
-	case GTH_TRANSFORM_MIRROR:
-		pixbuf1 = _gdk_pixbuf_copy_mirror (pixbuf2, TRUE, FALSE);
-		break;
-	case GTH_TRANSFORM_FLIP:
-		pixbuf1 = _gdk_pixbuf_copy_mirror (pixbuf2, FALSE, TRUE);
-		break;
-	default:
-		pixbuf1 = pixbuf2;
-		g_object_ref (pixbuf1);
-		break;
-	}
-	g_object_unref (pixbuf2);
+	pixbuf2 = _gdk_pixbuf_transform (pixbuf1, transform);
 
 	mime_type = gnome_vfs_mime_type_from_name (path);
 	if ((mime_type != NULL) && is_mime_type_writable (mime_type)) {
 		GError      *error = NULL;
 		const char  *image_type = mime_type + 6;
-		if (! _gdk_pixbuf_save (pixbuf1, 
+		if (! _gdk_pixbuf_save (pixbuf2, 
 					path, 
 					image_type, 
 					&error, 
@@ -318,36 +212,109 @@ apply_transformation_generic (GtkWindow 
 				       mime_type);
 
 	g_object_unref (pixbuf1);
+	g_object_unref (pixbuf2);
 }
 
 
-ExifShort
-get_next_value_rotation_90 (int value)
+static GthTransform
+get_next_value_rotation_90 (GthTransform value)
 {
-	static ExifShort new_value [8] = {6, 7, 8, 5, 2, 3, 4, 1};
+	static GthTransform new_value [8] = {6, 7, 8, 5, 2, 3, 4, 1};
 	return new_value[value - 1];
 }
 
 
-ExifShort
-get_next_value_mirror (int value)
+static GthTransform
+get_next_value_mirror (GthTransform value)
 {
-	static ExifShort new_value [8] = {2, 1, 4, 3, 6, 5, 8, 7};
+	static GthTransform new_value [8] = {2, 1, 4, 3, 6, 5, 8, 7};
 	return new_value[value - 1];
 }
 
 
-ExifShort
-get_next_value_flip (int value)
+static GthTransform
+get_next_value_flip (GthTransform value)
 {
-	static ExifShort new_value [8] = {4, 3, 2, 1, 8, 7, 6, 5};
+	static GthTransform new_value [8] = {4, 3, 2, 1, 8, 7, 6, 5};
 	return new_value[value - 1];
 }
 
 
+GthTransform
+get_next_transformation(GthTransform original, GthTransform transform)
+{			
+	GthTransform result = (original >= 1 && original <= 8 ? 
+									original : 
+									GTH_TRANSFORM_NONE);
+	
+	switch (transform) {
+	case GTH_TRANSFORM_ROTATE_90:
+		result = get_next_value_rotation_90 (result);
+		break;
+	case GTH_TRANSFORM_ROTATE_180:
+		result = get_next_value_rotation_90 (result);
+		result = get_next_value_rotation_90 (result);
+		break;
+	case GTH_TRANSFORM_ROTATE_270:
+		result = get_next_value_rotation_90 (result);
+		result = get_next_value_rotation_90 (result);
+		result = get_next_value_rotation_90 (result);
+		break;
+	case GTH_TRANSFORM_FLIP_H:
+		result = get_next_value_mirror (result);
+		break;
+	case GTH_TRANSFORM_FLIP_V:
+		result = get_next_value_flip (result);
+		break;		
+	case GTH_TRANSFORM_TRANSPOSE:
+		result = get_next_value_rotation_90 (result);
+		result = get_next_value_mirror (result);
+		break;
+	case GTH_TRANSFORM_TRANSVERSE:
+		result = get_next_value_rotation_90 (result);
+		result = get_next_value_flip (result);
+		break;			
+	}
+	
+	return result;
+}
+
+
+GthTransform
+get_rotation_part(GthTransform transform)
+{
+	static GthTransform lookup [8] = {
+		GTH_TRANSFORM_NONE, GTH_TRANSFORM_NONE, 
+		GTH_TRANSFORM_ROTATE_180, GTH_TRANSFORM_NONE, 
+		GTH_TRANSFORM_ROTATE_90, GTH_TRANSFORM_ROTATE_90, 
+		GTH_TRANSFORM_ROTATE_90, GTH_TRANSFORM_ROTATE_270};
+
+	if (transform >= 1 && transform <= 8)
+		return lookup[transform - 1];
+	else
+		return GTH_TRANSFORM_NONE;
+}
+
+
+GthTransform
+get_mirror_or_flip_part(GthTransform transform)
+{
+	static GthTransform lookup [8] = {
+		GTH_TRANSFORM_NONE, GTH_TRANSFORM_FLIP_H, 
+		GTH_TRANSFORM_NONE, GTH_TRANSFORM_FLIP_V, 
+		GTH_TRANSFORM_FLIP_H, GTH_TRANSFORM_NONE, 
+		GTH_TRANSFORM_FLIP_V, GTH_TRANSFORM_NONE};
+
+	if (transform >= 1 && transform <= 8)
+		return lookup[transform - 1];
+	else
+		return GTH_TRANSFORM_NONE;
+}
+
+
 void
 update_orientation_field (const char   *path,
-			  RotationData *rot_data)
+			  GthTransform transform)
 {
 	JPEGData     *jdata;
 	ExifData     *edata;
@@ -366,7 +333,7 @@ update_orientation_field (const char   *
 		jpeg_data_unref (jdata);
 		return;
 	}
-
+	
 	for (i = 0; i < EXIF_IFD_COUNT; i++) {
 		ExifContent *content = edata->ifd[i];
 		ExifEntry   *entry;
@@ -381,34 +348,8 @@ update_orientation_field (const char   *
 
 			byte_order = exif_data_get_byte_order (edata);
 			value = exif_get_short (entry->data, byte_order);
-
-			switch (rot_data->rot_type) {
-			case GTH_TRANSFORM_ROTATE_90:
-				value = get_next_value_rotation_90 (value);
-				break;
-			case GTH_TRANSFORM_ROTATE_180:
-				value = get_next_value_rotation_90 (value);
-				value = get_next_value_rotation_90 (value);
-				break;
-			case GTH_TRANSFORM_ROTATE_270:
-				value = get_next_value_rotation_90 (value);
-				value = get_next_value_rotation_90 (value);
-				value = get_next_value_rotation_90 (value);
-				break;
-			default:
-				break;
-			}
 			
-			switch (rot_data->tran_type) {
-			case GTH_TRANSFORM_MIRROR:
-				value = get_next_value_mirror (value);
-				break;
-			case GTH_TRANSFORM_FLIP:
-				value = get_next_value_flip (value);
-				break;
-			default:
-				break;
-			}
+			value = get_next_transformation(value, transform);
 
 			exif_set_short (entry->data, byte_order, value);
 		}
Index: src/rotation-utils.h
===================================================================
RCS file: /cvs/gnome/gthumb/src/rotation-utils.h,v
retrieving revision 1.3
diff -u -p -r1.3 rotation-utils.h
--- src/rotation-utils.h	8 Oct 2006 08:45:17 -0000	1.3
+++ src/rotation-utils.h	12 Oct 2006 14:04:04 -0000
@@ -29,31 +29,26 @@
 
 #include "gth-exif-utils.h"
 
-typedef struct _RotationData RotationData;
-struct _RotationData {
-    GthTransform  rot_type;
-    GthTransform  tran_type;
-};
-
-RotationData*	        rotation_data_new ();
-
-void			update_rotation_from_exif_data (const char      *filename,
-							RotationData 	*rot_data);
 void			apply_transformation_exif      (GtkWindow       *win,
 							const char      *filename,
-							RotationData 	*rot_data);
+							GthTransform transform);
 void			apply_transformation_jpeg      (GtkWindow       *win,
 							const char      *filename,
-							RotationData 	*rot_data);
+							GthTransform transform);
 void			apply_transformation_generic   (GtkWindow       *win,
 							const char      *filename,
-							RotationData 	*rot_data);
-ExifShort		get_next_value_rotation_90     (int value);
-ExifShort		get_next_value_mirror          (int value);
-ExifShort		get_next_value_flip            (int value);
+							GthTransform transform);
+
+GthTransform	get_next_transformation	(GthTransform original, 
+							GthTransform transform);
+GthTransform	get_rotation_part		(GthTransform transform);
+GthTransform	get_mirror_part		(GthTransform transform);
 
-void			update_orientation_field       (const char      *filename, 
-							RotationData    *rot_data);
+GthTransform	read_orientation_field		(const char *path);
+void				reset_orientation_field		(const char *path);
+void				update_orientation_field	(const char      *filename, 
+							GthTransform transform);
+							
 gboolean		swap_fields                    (ExifContent     *content,
 							ExifTag          tag1,
 							ExifTag          tag2);
