Index: libgthumb/jpegutils/jpegtran.c
===================================================================
RCS file: /cvs/gnome/gthumb/libgthumb/jpegutils/jpegtran.c,v
retrieving revision 1.3
diff -u -p -r1.3 jpegtran.c
--- libgthumb/jpegutils/jpegtran.c	19 Oct 2006 17:42:32 -0000	1.3
+++ libgthumb/jpegutils/jpegtran.c	9 Nov 2006 15:52:21 -0000
@@ -48,6 +48,7 @@
 #include "file-utils.h"
 #include "transupp.h"		/* Support routines for jpegtran */
 
+#include <libexif/exif-data.h>
 
 /* error handler data */
 struct error_handler_data {
@@ -95,6 +96,159 @@ output_message_handler (j_common_ptr cin
 }
 
 
+static void
+update_exif_orientation(ExifData *edata)
+{
+	unsigned int i;
+	ExifByteOrder byte_order;
+	
+	if (edata == NULL)
+		return;
+	
+	byte_order = exif_data_get_byte_order (edata);
+
+	for (i = 0; i < EXIF_IFD_COUNT; i++) {
+		ExifContent *content = edata->ifd[i];
+		ExifEntry   *entry;
+
+		if ((content == NULL) || (content->count == 0)) 
+			continue;
+
+		entry = exif_content_get_entry (content, EXIF_TAG_ORIENTATION);
+		if (entry != NULL)
+			exif_set_short (entry->data, byte_order, 1);
+	}
+}
+
+
+static void
+swap_fields (ExifContent *content,
+	     ExifTag      tag1,
+	     ExifTag      tag2)
+{
+	ExifEntry     *entry1 = NULL;
+	ExifEntry     *entry2 = NULL;
+	unsigned char *data;
+	unsigned int   size;
+	
+	entry1 = exif_content_get_entry (content, tag1);
+	if (entry1 == NULL) 
+		return;
+	
+	entry2 = exif_content_get_entry (content, tag2);
+	if (entry2 == NULL)
+		return;
+
+	data = entry1->data;
+	size = entry1->size;
+	
+	entry1->data = entry2->data;
+	entry1->size = entry2->size;
+	
+	entry2->data = data;
+	entry2->size = size;
+}
+
+
+static void
+update_exif_dimensions (ExifData *edata, JXFORM_CODE transform)
+{
+	unsigned int i;
+	
+	if (edata == NULL)
+		return;
+
+	switch (transform) {
+	case JXFORM_ROT_90:
+	case JXFORM_ROT_270:
+	case JXFORM_TRANSPOSE:
+	case JXFORM_TRANSVERSE:
+	    break;
+	default:
+	    return;
+	}
+
+	for (i = 0; i < EXIF_IFD_COUNT; i++) {
+		ExifContent *content = edata->ifd[i];
+
+		if ((content == NULL) || (content->count == 0)) 
+			continue;
+		
+		swap_fields (content, 
+			     EXIF_TAG_RELATED_IMAGE_WIDTH,
+			     EXIF_TAG_RELATED_IMAGE_LENGTH);
+		swap_fields (content, 
+			     EXIF_TAG_IMAGE_WIDTH,
+			     EXIF_TAG_IMAGE_LENGTH);
+		swap_fields (content, 
+			     EXIF_TAG_PIXEL_X_DIMENSION,
+			     EXIF_TAG_PIXEL_Y_DIMENSION);
+		swap_fields (content, 
+			     EXIF_TAG_X_RESOLUTION,
+			     EXIF_TAG_Y_RESOLUTION);
+		swap_fields (content, 
+			     EXIF_TAG_FOCAL_PLANE_X_RESOLUTION,
+			     EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION);
+	}
+}
+
+
+static void
+update_exif_thumbnail (ExifData *edata, JXFORM_CODE transform)
+{
+	if (edata == NULL)
+		return;
+
+	if (transform == JXFORM_NONE)
+		return;
+
+	// TODO: Transform thumbnail here
+}
+
+
+static void
+update_exif_data(struct jpeg_decompress_struct *src, JXFORM_CODE transform)
+{
+	jpeg_saved_marker_ptr mark = NULL;
+	ExifData *edata = NULL;
+	unsigned char *data = NULL;
+	unsigned int size;
+   
+   if (src == NULL)
+		return;
+   
+   // Find exif data.
+	for (mark = src->marker_list; mark != NULL; mark = mark->next) {
+		if (mark->marker != JPEG_APP0 +1)
+			continue;
+		edata = exif_data_new_from_data(mark->data, mark->data_length);
+		break;
+	}
+   if (edata == NULL)
+		return;
+
+	// Adjust exif orientation (set to top-left)
+	update_exif_orientation(edata);
+
+	// Adjust exif dimensions (swap values if necessary)
+	update_exif_dimensions(edata, transform);
+
+	// Adjust thumbnail (transform)
+	update_exif_thumbnail(edata, transform);
+
+	// Build new exif data block
+	exif_data_save_data(edata, &data, &size);
+	exif_data_unref(edata);
+
+	// Update jpeg APP1 (EXIF) marker
+	mark->data = src->mem->alloc_large((j_common_ptr)src, JPOOL_IMAGE, size);
+	mark->original_length = size;
+	mark->data_length = size;
+	memcpy(mark->data, data, size);
+	free(data);
+}
+
+
 int
 jpegtran (char         *input_filename,
 	  char         *output_filename,
@@ -173,6 +327,9 @@ jpegtran (char         *input_filename,
 
 	/* Read file header */
 	(void) jpeg_read_header (&srcinfo, TRUE);
+
+	/* Update exif data */
+	update_exif_data(&srcinfo, transformation);
 
 	/* Any space needed by a transform option must be requested before
 	 * jpeg_read_coefficients so that memory allocation will be done right.
Index: src/rotation-utils.h
===================================================================
RCS file: /cvs/gnome/gthumb/src/rotation-utils.h,v
retrieving revision 1.7
diff -u -p -r1.7 rotation-utils.h
--- src/rotation-utils.h	2 Nov 2006 20:26:13 -0000	1.7
+++ src/rotation-utils.h	9 Nov 2006 15:52:21 -0000
@@ -43,16 +43,9 @@ void		apply_transformation_generic   (Gt
 
 GthTransform	get_next_transformation	       (GthTransform  original, 
 						GthTransform  transform);
-GthTransform	get_rotation_part	       (GthTransform  transform);
-GthTransform	get_mirror_part	               (GthTransform  transform);
 
 GthTransform	read_orientation_field	       (const char   *path);
 void		write_orientation_field        (const char   *filename, 
 						GthTransform  transform);
-							
-gboolean	swap_fields                    (ExifContent  *content,
-						ExifTag       tag1,
-						ExifTag       tag2);
-void	        swap_xy_exif_fields            (const char   *filename);
 
 #endif /* ROTATION_UTILS_H */
Index: src/rotation-utils.c
===================================================================
RCS file: /cvs/gnome/gthumb/src/rotation-utils.c,v
retrieving revision 1.13
diff -u -p -r1.13 rotation-utils.c
--- src/rotation-utils.c	8 Nov 2006 18:18:33 -0000	1.13
+++ src/rotation-utils.c	9 Nov 2006 15:52:21 -0000
@@ -192,17 +192,9 @@ apply_transformation_jpeg (GtkWindow    
 	dir_remove (tmpdir);
 	g_free (tmpdir);
 
-	if (err != NULL) {
+	if (err != NULL)
 		_gtk_error_dialog_from_gerror_run (win, &err);
 
-	} else {
-		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);
-		write_orientation_field (path, GTH_TRANSFORM_NONE);
-	}
-
 	g_free (e1);
 	g_free (e2);
 	g_free (line);
@@ -315,118 +307,3 @@ get_next_transformation(GthTransform ori
 	
 	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;
-}
-
-
-gboolean
-swap_fields (ExifContent *content,
-	     ExifTag      tag1,
-	     ExifTag      tag2)
-{
-	ExifEntry     *entry1;
-	ExifEntry     *entry2;
-	unsigned char *data;
-	unsigned int   size;
-	
-	entry1 = exif_content_get_entry (content, tag1);
-	if (entry1 == NULL) 
-		return FALSE;
-	
-	entry2 = exif_content_get_entry (content, tag2);
-	if (entry2 == NULL)
-		return FALSE;
-
-	data = entry1->data;
-	size = entry1->size;
-	
-	entry1->data = entry2->data;
-	entry1->size = entry2->size;
-	
-	entry2->data = data;
-	entry2->size = size;
-
-	return TRUE;
-}
-
-
-void
-swap_xy_exif_fields (const char *filename)
-{
-	JPEGData     *jdata;
-	ExifData     *edata;
-	unsigned int  i;
-
-	filename = get_file_path_from_uri (filename);
-	if (filename == NULL)
-		return;
-
-	jdata = jpeg_data_new_from_file (filename);
-	if (jdata == NULL)
-		return;
-
-	edata = jpeg_data_get_exif_data (jdata);
-	if (edata == NULL) {
-		jpeg_data_unref (jdata);
-		return;
-	}
-
-	for (i = 0; i < EXIF_IFD_COUNT; i++) {
-		ExifContent *content = edata->ifd[i];
-
-		if ((content == NULL) || (content->count == 0)) 
-			continue;
-		
-		swap_fields (content, 
-			     EXIF_TAG_RELATED_IMAGE_WIDTH,
-			     EXIF_TAG_RELATED_IMAGE_LENGTH);
-		swap_fields (content, 
-			     EXIF_TAG_IMAGE_WIDTH,
-			     EXIF_TAG_IMAGE_LENGTH);
-		swap_fields (content, 
-			     EXIF_TAG_PIXEL_X_DIMENSION,
-			     EXIF_TAG_PIXEL_Y_DIMENSION);
-		swap_fields (content, 
-			     EXIF_TAG_X_RESOLUTION,
-			     EXIF_TAG_Y_RESOLUTION);
-		swap_fields (content, 
-			     EXIF_TAG_FOCAL_PLANE_X_RESOLUTION,
-			     EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION);
-	}
-
-	jpeg_data_save_file (jdata, filename);
-
-	exif_data_unref (edata);
-	jpeg_data_unref (jdata);
-}
-
