Index: src/catalog-web-exporter.c
===================================================================
--- src/catalog-web-exporter.c	(revision 1529)
+++ src/catalog-web-exporter.c	(working copy)
@@ -1747,20 +1747,38 @@
 	export__copy_to_destination (ce);
 }
 
+#define DEBUG(x) //x
 
+const unsigned char soiapp1[] = {0xff, 0xd8, 0xff, 0xe1};
+const unsigned char app2[]    = {0xff, 0xe2};
+
 static void
 copy_exif_from_orig_and_reset_orientation (const char *src_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. */
+	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          *tmpfile;       // 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
+
 	is_local = is_local_file (dest_filename);
 
 	local_src_filename = obtain_local_file (src_filename);
@@ -1769,45 +1787,129 @@
 	if ((local_src_filename == NULL) || (local_dest_filename == NULL))
 		return;
 
-	jdata_src = jpeg_data_new_from_file (local_src_filename);
-	if (jdata_src == NULL)
-		return;
+	DEBUG(printf("copy_exif_from_orig_and_reset_orientation: %s -> %s\n",local_src_filename, local_dest_filename));
 
-	edata_src = jpeg_data_get_exif_data (jdata_src);
-	if (edata_src == NULL) {
-		jpeg_data_unref (jdata_src);
+	// 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);
+		perror("bad!");
 		return;
 	}
 
-	jdata_dest = jpeg_data_new_from_file (local_dest_filename);
-	if (jdata_dest == NULL)
+	// 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(printf("."));
+		ptr++; // Step over the marker start (0xff) to avoid it the next search
+
+		// Lookup what kind of marker, if one, we found
+		switch((int)ptr[0] & 0xff){
+		case 0xd8: DEBUG(printf("SOI found\n ")); continue;
+		case 0xe0: DEBUG(printf("APP0 found ")); app[0] = ptr + 1; asize = &appsize[0]; break;
+		case 0xe1: DEBUG(printf("APP1 found ")); app[1] = ptr + 1; asize = &appsize[1]; break;
+		case 0xe2: DEBUG(printf("APP2 found ")); app[2] = ptr + 1; asize = &appsize[2]; break;
+		case 0xda: DEBUG(printf("SOS found\n ")); ptr = buf + fsize; continue; // We are done
+		case 0xdb: // DQT
+		case 0xc4: // DHT
+		case 0xdd: // DRI
+		case 0xc0: DEBUG(printf("Valid marker found\n ")); asize = &msize; continue; // SOF
+
+		default: continue;   // False marker sync byte, continue to look for real ones
+		}
+
+		DEBUG(printf("Sizebytes: %02x and %02x\n", ptr[1], ptr[2]));
+
+		*asize = GUINT16_FROM_BE(*(guint16 *)&ptr[1]); // Get size of marker
+		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
+	tmpfile = g_strdup_printf ("%s.%d", local_dest_filename, getpid());
+	if ((tfd = fopen(tmpfile, "w+")) == (void *) 0L){
+		fprintf(stderr, "catalog_web_exporter: Error opening file: %s\n", tmpfile);
+		fclose(dest);
+		fclose(src);
+		free(tmpfile);
+		return;
+	}
+	    
+	// Check that we found some EXIF data
+	if (app[1] != 0L){
+		// write SOI + APP1 marker
+		fwrite(soiapp1, sizeof(soiapp1), 1, tfd);
 
-	/* 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);
+		// write APP1 data
+		fwrite(app[1],  appsize[1], 1, tfd);
 
-	/* Update the exif data within the jpeg data, in memory. */
-	jpeg_data_set_exif_data (jdata_dest, edata_src);
+		// Write APP2 if available
 
-	/* Commit the jpeg data in memory to a file. */
-	jpeg_data_save_file (jdata_dest, local_dest_filename);
+		if (app[2] != 0L){
+			// write APP2 marker
+			fwrite(app2, sizeof(app2), 1, tfd);
 
-	/* Remove the jpeg and exif data in memory. */
-	exif_data_unref (edata_src);
-	jpeg_data_unref (jdata_src);
-	jpeg_data_unref (jdata_dest);
+			// write APP2 data
+			fwrite(app[2],  appsize[2], 1, tfd);
+		}
+		
+		// write rest of dest file to the tmp file from APP0 onwards
+		fseek(dest, 2L, SEEK_SET); // Skip SOI since we already got that written
+	} else {
+		fprintf(stderr, "catalog_web_exporter: No EXIF data found in %s\n", src_filename);
 
-        if (!is_local)
+		// 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 filename
+	unlink(local_dest_filename);
+	link(tmpfile, local_dest_filename);
+	unlink(tmpfile);
+
+       /* 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. */
+	
+	if ((res = gth_minimal_exif_tag_write(local_dest_filename, EXIF_TAG_ORIENTATION, &tf, 2, 0)) != PATCH_EXIF_OK){
+		fprintf(stderr, 
+		  "copy_exif_from_orig_and_reset_orientation called gth_minimal_exif_tag_write: error %d in %s\n", 
+		   res, local_dest_filename );
+	}
+
+	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)
 {
