Index: src/catalog-web-exporter.c
===================================================================
--- src/catalog-web-exporter.c	(revision 1274)
+++ src/catalog-web-exporter.c	(working copy)
@@ -2241,8 +2241,7 @@
 		if (transform > 1)
 			apply_transformation_jpeg(GTK_WINDOW (ce->window),
 						  dest_filename,
-						  transform,
-						  FALSE);
+						  transform);
 	}
 }
 
Index: src/dlg-photo-importer.c
===================================================================
--- src/dlg-photo-importer.c	(revision 1274)
+++ src/dlg-photo-importer.c	(working copy)
@@ -1360,7 +1360,7 @@
 		FileData     *fd = file_data_new (filepath, &info);
 		GthTransform transform = read_orientation_field (fd->path);
 		if (image_is_jpeg (filepath))
-			apply_transformation_jpeg (window, fd->path, transform, FALSE);
+			apply_transformation_jpeg (window, fd->path, transform);
 		else
 			apply_transformation_generic (window, fd->path, transform);
 
Index: src/rotation-utils.c
===================================================================
--- src/rotation-utils.c	(revision 1274)
+++ src/rotation-utils.c	(working copy)
@@ -81,48 +81,52 @@
 }
 
 
-gboolean
-jtransform_perfect_transform(gint image_width, gint image_height,
-				gint MCU_width, gint MCU_height,
-				GthTransform transform)
+static boolean
+jpeg_mcu_dialog (JXFORM_CODE *transform, boolean *trim, GtkWindow *parent)
 {
-	/* This function determines if it is possible to perform a lossless
-	   jpeg transformation without trimming, based on the image dimensions 
-	   and MCU size. Further details at http://jpegclub.org/jpegtran. */
+	/*
+	 * Image dimensions are not multiples of the jpeg minimal coding unit (mcu).
+	 * Warn about possible image distortions along one or more edges.
+	 */
+ 
+ 	GtkWidget *d =  _gtk_message_dialog_new (parent,
+		GTK_DIALOG_MODAL,
+		GTK_STOCK_DIALOG_WARNING,
+		_("This transformation may introduce small image distortions along "
+		"one or more edges, because the image dimensions are not multiples of 8.\n\nThe distortion "
+		"is reversible, however. If the resulting image is unacceptable, simply apply the reverse "
+		"transformation to return to the original image.\n\ngThumb can also discard (or trim) any "
+		"untransformable edge pixels. For practical use, this mode gives the best looking results, "
+		"but the transformation is not strictly lossless anymore.\n\nTo avoid this problem in the "
+		"future, consider disabling the \"Apply physical transform\" option in the rotation dialog."),
+		NULL,
+		_("Trim"), 1,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		NULL);
 
-	gboolean result = TRUE;
+	gint result = gtk_dialog_run (GTK_DIALOG (d));
 
-	switch (transform) {
-	case GTH_TRANSFORM_FLIP_H:
-	case GTH_TRANSFORM_ROTATE_270:
-		if (image_width % MCU_width)
-			result = FALSE;
-		break;
-	case GTH_TRANSFORM_FLIP_V:
-	case GTH_TRANSFORM_ROTATE_90:
-		if (image_height % MCU_height)
-			result = FALSE;
-		break;
-	case GTH_TRANSFORM_TRANSVERSE:
-	case GTH_TRANSFORM_ROTATE_180:
-		if (image_width % MCU_width)
-			result = FALSE;
-		if (image_height % MCU_height)
-			result = FALSE;
-		break;
+ 	gtk_widget_destroy (d);
+
+	switch (result) {
+	case GTK_RESPONSE_OK:
+		return TRUE;
+	case GTK_RESPONSE_CANCEL:
+		return FALSE;
+	case 1:
+		*trim = TRUE;
+		return TRUE;
 	default:
-		break;
+		return FALSE;
 	}
-
-	return result;
 }
 
 
 void
 apply_transformation_jpeg (GtkWindow    *win,
 			   const char   *path,
-			   GthTransform  transform,
-			   gboolean	 trim)
+			   GthTransform  transform)
 {
 	char        *line;
 	char        *tmp;
@@ -175,7 +179,7 @@
 		break;
 	}
 
-	if (jpegtran ((char*)path, tmp, transf, trim, &err) != 0) {
+	if (jpegtran ((char*)path, tmp, transf, (jpegtran_mcu_callback)jpeg_mcu_dialog, win, &err) != 0) {
 		g_free (tmp);
 		if (err != NULL) 
 			_gtk_error_dialog_from_gerror_run (win, &err);
Index: src/rotation-utils.h
===================================================================
--- src/rotation-utils.h	(revision 1274)
+++ src/rotation-utils.h	(working copy)
@@ -29,14 +29,9 @@
 
 #include "gth-exif-utils.h"
 
-gboolean	jtransform_perfect_transform   (gint image_width, gint image_height,
-						gint MCU_width, gint MCU_height,
-						GthTransform transform);
-
 void		apply_transformation_jpeg      (GtkWindow    *win,
 						const char   *filename,
-						GthTransform  transform,
-						gboolean	     trim);
+						GthTransform  transform);
 void		apply_transformation_generic   (GtkWindow    *win,
 						const char   *filename,
 						GthTransform  transform);
Index: src/dlg-jpegtran.c
===================================================================
--- src/dlg-jpegtran.c	(revision 1274)
+++ src/dlg-jpegtran.c	(working copy)
@@ -228,36 +228,6 @@
 }
 
 
-#define GTK_RESPONSE_TRIM 1
-static gint jpeg_mcu_dialog (GtkWindow *parent)
-{
- 	GtkWidget *d =  _gtk_message_dialog_new (parent,
-		GTK_DIALOG_MODAL,
-		GTK_STOCK_DIALOG_WARNING,
-		_("This transformation may introduce small image distortions along "
-		"one or more edges, because the image dimensions are not multiples of 8.\n\nThe distortion "
-		"is reversible, however. If the resulting image is unacceptable, simply apply the reverse "
-		"transformation to return to the original image.\n\ngThumb can also discard (or trim) any "
-		"untransformable edge pixels. For practical use, this mode gives the best looking results, "
-		"but the transformation is not strictly lossless anymore.\n\nTo avoid this problem in the "
-		"future, consider disabling the \"Apply physical transform\" option in the rotation dialog."),
-		NULL,
-		_("Trim"), GTK_RESPONSE_TRIM,
-		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-		GTK_STOCK_OK, GTK_RESPONSE_OK,
-		NULL);
-
-	gint result = gtk_dialog_run (GTK_DIALOG (d));
-
- 	gtk_widget_destroy (d);
-
-	if (result == GTK_RESPONSE_DELETE_EVENT)
-		return GTK_RESPONSE_CANCEL;
-	else
- 		return result;
-}
-
-
 static void
 apply_transformation (DialogData *data,
 		      GList      *current_image,
@@ -297,19 +267,7 @@
 		write_orientation_field (path, required_transform);
 	} else if (jpeg) {
  		// Lossless jpeg transform.
-		gint width, height;
-		gdk_pixbuf_get_file_info (get_file_path_from_uri (path), &width, &height);
-		if (!jtransform_perfect_transform (width, height, 8, 8, required_transform)) {
- 			// Image dimensions are not multiples of the jpeg minimal coding unit (mcu).
- 			// Warn about possible image distortions along one or more edges.
- 			gint result = jpeg_mcu_dialog (window);
-			if (result != GTK_RESPONSE_CANCEL) {
-				gboolean trim = (result == GTK_RESPONSE_TRIM);
-				apply_transformation_jpeg (window, path, required_transform, trim);
-			}
- 		} else {
-			apply_transformation_jpeg (window, path, required_transform, FALSE);
-		}
+		apply_transformation_jpeg (window, path, required_transform);
 	} else {
 		// Generic image transform.
 		apply_transformation_generic (window, path, required_transform);
Index: libgthumb/jpegutils/jpegtran.h
===================================================================
--- libgthumb/jpegutils/jpegtran.h	(revision 1274)
+++ libgthumb/jpegutils/jpegtran.h	(working copy)
@@ -28,11 +28,17 @@
 #include <glib.h>
 #include "transupp.h"
 
+typedef boolean (*jpegtran_mcu_callback) (JXFORM_CODE *transform, boolean *trim, void *userdata);
 
+#define JPEGTRAN_MCU_CONTINUE	((jpegtran_mcu_callback)0)
+#define JPEGTRAN_MCU_TRIM	((jpegtran_mcu_callback)-1)
+#define JPEGTRAN_MCU_CANCEL	((jpegtran_mcu_callback)-2)
+
 int jpegtran (const char *input_filename,
 		const char *output_filename,
 		JXFORM_CODE transformation,
-		gboolean trim,
+		jpegtran_mcu_callback callback,
+		void *userdata,
 		GError **error);
 
 #endif /* JPEGTRAN_H */
Index: libgthumb/jpegutils/jpegtran.c
===================================================================
--- libgthumb/jpegutils/jpegtran.c	(revision 1274)
+++ libgthumb/jpegutils/jpegtran.c	(working copy)
@@ -50,6 +50,7 @@
 #include "file-utils.h"
 #include "transupp.h"		/* Support routines for jpegtran */
 #include "jpeg-memory-mgr.h"
+#include "jpegtran.h"
 
 #include <libexif/exif-data.h>
 
@@ -59,8 +60,7 @@
 		    size_t        isize,
 		    void        **odata,
 		    size_t       *osize,
-		    JXFORM_CODE   transformation,
-		    gboolean      trim);
+		    JXFORM_CODE   transformation);
 
 
 /* error handler data */
@@ -230,7 +230,7 @@
 
 	/* Transform thumbnail */
 	if (jpegtran_thumbnail (edata->data, edata->size,
-			(void**)&out, &osize, transform, FALSE) != 0) {
+			(void**)&out, &osize, transform) != 0) {
 		/* Failed: Discard thumbnail */
 		g_free (out);
 		g_free (edata->data);
@@ -289,18 +289,54 @@
 }
 
 
-static void
+static boolean
+jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
+			     int MCU_width, int MCU_height,
+			     JXFORM_CODE transform)
+{
+	/* This function determines if it is possible to perform a lossless
+	   jpeg transformation without trimming, based on the image dimensions 
+	   and MCU size. Further details at http://jpegclub.org/jpegtran. */
+
+	boolean result = TRUE;
+
+	switch (transform) {
+	case JXFORM_FLIP_H:
+	case JXFORM_ROT_270:
+		if (image_width % (JDIMENSION) MCU_width)
+			result = FALSE;
+		break;
+	case JXFORM_FLIP_V:
+	case JXFORM_ROT_90:
+		if (image_height % (JDIMENSION) MCU_height)
+			result = FALSE;
+		break;
+	case JXFORM_TRANSVERSE:
+	case JXFORM_ROT_180:
+		if (image_width % (JDIMENSION) MCU_width)
+			result = FALSE;
+		if (image_height % (JDIMENSION) MCU_height)
+			result = FALSE;
+		break;
+	}
+
+	return result;
+}
+
+
+static int
 jpegtran_internal (struct jpeg_decompress_struct *srcinfo,
 		   struct jpeg_compress_struct   *dstinfo,
 		   JXFORM_CODE                    transformation,
-		   gboolean                       trim)
+		   jpegtran_mcu_callback          callback,
+		   void                          *userdata)
 {
 	jpeg_transform_info  transformoption;
 	jvirt_barray_ptr    *src_coef_arrays;
 	jvirt_barray_ptr    *dst_coef_arrays;
 
 	transformoption.transform = transformation;
-	transformoption.trim = trim;
+	transformoption.trim = FALSE;
 	transformoption.force_grayscale = FALSE;
 
 	/* Enable saving of extra markers that we want to copy */
@@ -308,7 +344,25 @@
 
 	/* Read file header */
 	(void) jpeg_read_header (srcinfo, TRUE);
+	
+	/* Check JPEG Minimal Coding Unit (mcu) */
+	if (callback &&	!jtransform_perfect_transform(
+			srcinfo->image_width, 
+			srcinfo->image_height, 
+			srcinfo->max_h_samp_factor * DCTSIZE, 
+			srcinfo->max_v_samp_factor * DCTSIZE,
+			transformation)) {
 
+		if (callback == JPEGTRAN_MCU_TRIM) {
+			// Continue transform and trim partial MCUs 
+			transformoption.trim = TRUE;
+		} else if ((callback == JPEGTRAN_MCU_CANCEL) ||
+			(callback (&transformoption.transform, &transformoption.trim, userdata) == FALSE)) {
+			// Abort transform
+			return 1;
+		}
+	}
+
 	/* Update exif data */
 	update_exif_data(srcinfo, transformation);
 
@@ -344,9 +398,11 @@
 					   src_coef_arrays,
 					   &transformoption);
 
-	/* Finish compression and release memory */
+	/* Finish compression */
 	jpeg_finish_compress (dstinfo);
 	jpeg_finish_decompress (srcinfo);
+	
+	return 0;
 }
 
 
@@ -355,8 +411,7 @@
 		    size_t        isize,
 		    void        **odata,
 		    size_t       *osize,
-		    JXFORM_CODE   transformation,
-		    gboolean      trim)
+		    JXFORM_CODE   transformation)
 {
 	struct jpeg_decompress_struct  srcinfo;
 	struct jpeg_compress_struct    dstinfo;
@@ -410,7 +465,11 @@
 	jpeg_memory_dest (&dstinfo, odata, osize);
 
 	/* Apply transformation */
-	jpegtran_internal(&srcinfo, &dstinfo, transformation, trim);
+	if (jpegtran_internal(&srcinfo, &dstinfo, transformation, NULL, NULL) != 0) {
+		jpeg_destroy_compress (&dstinfo);
+		jpeg_destroy_decompress (&srcinfo);
+		return 1;
+	}
 
 	/* Release memory */
 	jpeg_destroy_compress (&dstinfo);
@@ -424,7 +483,8 @@
 jpegtran (const char   *input_filename,
 	  const char   *output_filename,
 	  JXFORM_CODE   transformation,
-	  gboolean      trim,
+	  jpegtran_mcu_callback callback,
+	  void         *userdata,
 	  GError      **error)
 {
 	struct jpeg_decompress_struct  srcinfo;
@@ -497,7 +557,13 @@
 	jpeg_stdio_dest (&dstinfo, output_file);
 
 	/* Apply transformation */
-	jpegtran_internal(&srcinfo, &dstinfo, transformation, trim);
+	if (jpegtran_internal(&srcinfo, &dstinfo, transformation, callback, userdata) != 0) {
+		jpeg_destroy_compress (&dstinfo);
+		jpeg_destroy_decompress (&srcinfo);
+		fclose (input_file);
+		fclose (output_file);
+		return 1;
+	}
 
 	/* Release memory */
 	jpeg_destroy_compress (&dstinfo);
