Index: src/catalog-web-exporter.c
===================================================================
--- src/catalog-web-exporter.c	(revision 1739)
+++ src/catalog-web-exporter.c	(working copy)
@@ -2066,68 +2066,40 @@
 
 static void
 copy_exif_from_orig_and_reset_orientation (const char *src_filename,
-		     const char *dest_filename)
+					   const char *dest_filename)
 {
-	JPEGData     *jdata_src, *jdata_dest;
-	ExifData     *edata_src;
 	char         *local_src_filename = NULL;
 	char         *local_dest_filename = NULL;
 	gboolean      is_local;
 
-	/* Due to shortcomings in libexif, this function may corrupt
-	   the MakerNotes in the exif data. */
-
 	is_local = is_local_file (dest_filename);
 
-        local_src_filename = obtain_local_file (src_filename);
-        if (local_src_filename == NULL)
-                return;
-
-        local_dest_filename = obtain_local_file (dest_filename);
-        if (local_dest_filename == NULL) {
-                g_free (local_src_filename);
-                return;
-        }
-
-	jdata_src = jpeg_data_new_from_file (local_src_filename);
-	if (jdata_src == NULL)
+	local_src_filename = obtain_local_file (src_filename);
+	if (local_src_filename == NULL)
 		return;
 
-	edata_src = jpeg_data_get_exif_data (jdata_src);
-	if (edata_src == NULL) {
-		jpeg_data_unref (jdata_src);
+	local_dest_filename = obtain_local_file (dest_filename);
+	if (local_dest_filename == NULL) {
+		g_free (local_src_filename);
 		return;
 	}
 
-	jdata_dest = jpeg_data_new_from_file (local_dest_filename);
-	if (jdata_dest == NULL)
-		return;
+	copy_exif_data (local_src_filename, local_dest_filename);
 
-	/* The exif orientation tag, if present, must be reset to "top-left", 	 
-           because the jpeg was saved from a gthumb-generated pixbuf, and 	 
-           the pixbug image loader always rotates the pixbuf to account for 	 
+       /* The exif orientation tag, if present, must be reset to "top-left",    
+           because the jpeg was saved from a gthumb-generated pixbuf, and       
+           the pixbug image loader always rotates the pixbuf to account for     
            the orientation tag. */
-	update_exif_orientation (edata_src);
 
-	/* Update the exif data within the jpeg data, in memory. */
-	jpeg_data_set_exif_data (jdata_dest, edata_src);
+	write_orientation_field (local_dest_filename, GTH_TRANSFORM_NONE);
 
-	/* Commit the jpeg data in memory to a file. */
-	jpeg_data_save_file (jdata_dest, local_dest_filename);
-
-	/* Remove the jpeg and exif data in memory. */
-	exif_data_unref (edata_src);
-	jpeg_data_unref (jdata_src);
-	jpeg_data_unref (jdata_dest);
-
-        if (!is_local)
+	if (!is_local)
 		copy_cache_file_to_remote_uri (local_dest_filename, dest_filename);
-
+	
 	g_free (local_src_filename);
 	g_free (local_dest_filename);
 }
 
-
 static gboolean
 save_thumbnail_cb (gpointer data)
 {
Index: libgthumb/gth-exif-utils.c
===================================================================
--- libgthumb/gth-exif-utils.c	(revision 1739)
+++ libgthumb/gth-exif-utils.c	(working copy)
@@ -333,24 +333,6 @@
 }
 
 
-void 
-copy_exif_data (const char *src,
-		const char *dest)
-{
-	ExifData *edata;
-
-	if (!image_is_jpeg (src) || !image_is_jpeg (dest))
-		return;
-
-	edata = gth_exif_data_new_from_uri (src);
-	if (edata == NULL) 
-		return;
-	save_exif_data_to_uri (dest, edata);
-
-	exif_data_unref (edata);
-}
-
-
 const char leth[]  = {0x49, 0x49, 0x2a, 0x00}; // Little endian TIFF header
 const char beth[]  = {0x4d, 0x4d, 0x00, 0x2a}; // Big endian TIFF header
 const char types[] = {0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x00, 0x08, 0x00, 0x04, 0x08}; // size in bytes for EXIF types
@@ -602,3 +584,176 @@
 
 	gth_minimal_exif_tag_write (path, EXIF_TAG_ORIENTATION, &tf, 2, 0);
 }
+
+
+void
+copy_exif_data (const char *local_src_filename,
+		const char *local_dest_filename)
+{
+	/* This exif-copy function avoids the uses of the libexif routines,
+	   because they can re-write and corrupt some tags (MakerNotes
+	   especially). This routine is a "bulk copy", which does not
+	   modify the data. */
+
+	const unsigned char soiapp1[] = {0xff, 0xd8, 0xff, 0xe1};
+	const unsigned char app2[]    = {0xff, 0xe2};
+
+	int           msize;            /* generic placeholder for marker sizes */
+	int           appsize[3];       /* Sizes for APP0 to APP2 */
+	int          *asize;            /* Pointer to current APP marker slot of appsize */
+	char         *app[3];           /* pointer into imagggge data pointing to APP0 to APP2 */
+	char         *ptr;              /* working pointer through image data */
+
+	/* vars for setting tag in target file */
+	guint16       tf = (guint16) 1; /* top-left value of EXIF_TAG_ORIENTATION tag */
+	int           res;              /* result from call gth_minimal_exif_tag_write() */
+
+	/* vars for file copy */
+	char          *tmp_dir;
+	char          *tmp_filename;     /* temporary filename */
+	FILE          *src, *dest, *tfd; /* file descriptors */
+	size_t        fsize;             /* number of bytes read */
+
+	char          buf[1024 * 129];   /* Read buffer for EXIF data (Should be first and within 1 + 2 x 64Kb).
+	                                    Re-used for copying the rest of the file to the temp destination file. */
+
+	debug (DEBUG_INFO, "copy_exif_from_orig_and_reset_orientation: %s -> %s\n",local_src_filename, local_dest_filename);
+
+	g_assert (!uri_has_scheme (local_src_filename));
+	g_assert (!uri_has_scheme (local_dest_filename));
+
+	/* Open exif source file */
+	if ((src = fopen(local_src_filename, "r")) == (void *) 0L){
+		fprintf(stderr, "catalog_web_exporter: Error opening file: %s\n", local_src_filename);
+		return;
+	}
+
+	/* Try to read a buffer from the beginning of the source file */
+	fsize = fread(buf, 1, sizeof(buf), src); 
+
+	/* Scan for markers */
+	ptr = buf;                      /* Get point for start of search */
+	memset(app, 0L, sizeof(app));   /* Zero table for APP marker starts */
+
+	/* Loop through buffer as long as we find a marker start (0xff) */
+	while (ptr - buf < fsize && (ptr = memchr(ptr, 0xff, fsize - (ptr - buf))) != NULL){
+
+		debug (DEBUG_INFO, ".");
+	
+	       	/* Step over the marker start (0xff) to avoid it the next search */
+		ptr++;
+
+		/* Lookup what kind of marker, if any, we found */
+		switch((int)ptr[0] & 0xff){
+		case 0xd8: 
+			debug (DEBUG_INFO, "SOI found\n "); 
+			continue;
+		case 0xe0: 
+			debug (DEBUG_INFO, "APP0 found ");
+			app[0] = ptr + 1;
+			asize = &appsize[0];
+			break;
+		case 0xe1: 
+			debug (DEBUG_INFO, "APP1 found ");
+			app[1] = ptr + 1;
+			asize = &appsize[1];
+			break;
+		case 0xe2: 
+			debug (DEBUG_INFO, "APP2 found ");
+			app[2] = ptr + 1;
+			asize = &appsize[2]; 
+			break;
+		case 0xda:
+			debug (DEBUG_INFO, "SOS found\n "); ptr = buf + fsize; 
+			/* We are done */
+			continue;
+		case 0xdb: /* DQT */
+		case 0xc4: /* DHT */
+		case 0xdd: /* DRI */
+		case 0xc0: /* SOF */
+			debug (DEBUG_INFO, "Valid marker found\n "); asize = &msize; 
+			continue;
+
+		default: 
+			/* False marker sync byte, continue to look for real ones */
+			continue;
+		}
+
+		debug (DEBUG_INFO, "Sizebytes: %02x and %02x\n", ptr[1], ptr[2]);
+
+		/* Get size of marker */
+		*asize = GUINT16_FROM_BE(*(guint16 *)&ptr[1]);
+		ptr = ptr + 1 + *asize;
+	}
+
+	/* Open dest file which is already assumed to contain a JFIF (APP0 only) image */
+	if ((dest = fopen(local_dest_filename, "r")) == (void *) 0L){
+		fprintf(stderr, "catalog_web_exporter: Error opening file: %s\n", local_dest_filename);
+		fclose(src);
+		return;
+	}
+	
+	/* Open temp file that will contain the merged files */
+
+        tmp_dir = get_temp_dir_name ();
+        if (tmp_dir == NULL) {
+                /* should we display an error message here? */
+                return;
+        }
+        tmp_filename = get_temp_file_name (tmp_dir, NULL);
+	g_free (tmp_dir);
+
+	if ((tfd = fopen (tmp_filename, "w+")) == (void *) 0L){
+		fprintf (stderr, "catalog_web_exporter: Error opening file: %s\n", tmp_filename);
+		fclose (dest);
+		fclose (src);
+		remove_temp_file_and_dir (tmp_filename);
+		g_free (tmp_filename);
+		return;
+	}
+	    
+	/* Check that we found some EXIF data */
+	if (app[1] != 0L){
+		/* write SOI + APP1 marker */
+		fwrite(soiapp1, sizeof(soiapp1), 1, tfd);
+
+		/* write APP1 data */
+		fwrite(app[1],  appsize[1], 1, tfd);
+
+		/* Write APP2 if available */
+		if (app[2] != 0L){
+			/* write APP2 marker */
+			fwrite(app2, sizeof(app2), 1, tfd);
+
+			/* write APP2 data */
+			fwrite(app[2],  appsize[2], 1, tfd);
+		}
+		
+		/* Write rest of dest file to the tmp file from APP0 onwards.
+		   Skip SOI since we already got that written. */
+		fseek(dest, 2L, SEEK_SET);
+	} else {
+		debug (DEBUG_INFO, "catalog_web_exporter: No EXIF data found in %s\n", local_src_filename);
+
+		/* Just copy the whole file */
+		fseek(dest, 0L, SEEK_SET); 
+	}
+
+	while (!feof (dest)){
+		fsize = fread (buf, 1, sizeof (buf), dest);
+		fwrite (buf, 1, fsize, tfd);
+        }
+
+	/* Close files */
+	fclose(src);
+	fclose(dest);
+	fclose(tfd);
+
+	/* Move tmp to dest */
+	file_move (tmp_filename, local_dest_filename);
+
+	/* Clean up */
+	remove_temp_file_and_dir (tmp_filename);
+	g_free (tmp_filename);
+}
+
Index: libgthumb/gth-exif-utils.h
===================================================================
--- libgthumb/gth-exif-utils.h	(revision 1739)
+++ libgthumb/gth-exif-utils.h	(working copy)
@@ -54,8 +54,6 @@
 const char   *get_exif_entry_value        (ExifEntry    *entry);
 void          save_exif_data_to_uri       (const char   *filename,
 				           ExifData     *edata);
-void          copy_exif_data              (const char   *src,
-				           const char   *dest);
 int           gth_minimal_exif_tag_write  (const char   *filename,
                                            ExifTag       etag,
                                            void         *data,
@@ -64,5 +62,7 @@
 GthTransform  read_orientation_field      (const char   *path);
 void	      write_orientation_field     (const char   *filename, 
 				  	   GthTransform  transform);
+void 	      copy_exif_data              (const char *local_src_filename,
+                                           const char *local_dest_filename);
 
 #endif /* EXIF_UTILS_H */
