--- gthumb-cvs/libgthumb/jpegutils/jpeg-memory-mgr.h	1970-01-01 01:00:00.000000000 +0100
+++ gthumb/libgthumb/jpegutils/jpeg-memory-mgr.h	2006-11-14 13:25:32.000000000 +0100
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2001, 2002 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef JPEG_MEMORY_MGR_H
+#define JPEG_MEMORY_MGR_H
+
+#include <stdio.h>
+#include <jpeglib.h>
+
+GLOBAL(void)
+jpeg_memory_src (j_decompress_ptr cinfo, void *data, size_t size);
+
+GLOBAL(void)
+jpeg_memory_dest (j_compress_ptr cinfo, void **data, size_t *size);
+
+#endif /* JPEG_MEMORY_MGR_H */
--- gthumb-cvs/libgthumb/jpegutils/jpeg-memory-mgr.c	1970-01-01 01:00:00.000000000 +0100
+++ gthumb/libgthumb/jpegutils/jpeg-memory-mgr.c	2006-11-14 15:23:26.000000000 +0100
@@ -0,0 +1,167 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2001, 2002 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, wr/usr/include/jerror.hite to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include "jpeg-memory-mgr.h"
+
+#include <jerror.h>
+
+
+/* Expanded data source object for memory input */
+
+typedef struct {
+	struct jpeg_source_mgr pub;	/* public fields */
+	JOCTET *data;	/* source data buffer */
+  	size_t size;	/* size of source data buffer */
+} my_source_mgr;
+
+typedef my_source_mgr * my_src_ptr;
+
+/* Expanded data source object for memory output */
+
+typedef struct {
+	struct jpeg_destination_mgr pub;	/* public fields */
+	JOCTET **data;	/* destination data buffer */
+  	size_t *size;	/* size of destination data buffer */
+} my_destination_mgr;
+
+typedef my_destination_mgr * my_dest_ptr;
+
+
+METHODDEF(void)
+init_source (j_decompress_ptr cinfo)
+{
+	my_src_ptr src = (my_src_ptr) cinfo->src;
+
+	src->pub.next_input_byte = src->data;
+	src->pub.bytes_in_buffer = src->size;
+}
+
+ 
+METHODDEF(boolean)
+fill_input_buffer (j_decompress_ptr cinfo)
+{
+	ERREXIT(cinfo, JERR_INPUT_EOF);
+	return TRUE;
+}
+
+
+METHODDEF(void)
+skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+	my_src_ptr src = (my_src_ptr) cinfo->src;
+
+	if (num_bytes > 0) {
+		if ((size_t)num_bytes > src->pub.bytes_in_buffer) {
+			ERREXIT(cinfo, JERR_INPUT_EOF);
+		}
+		src->pub.next_input_byte += (size_t) num_bytes;
+		src->pub.bytes_in_buffer -= (size_t) num_bytes;
+	}
+}
+
+
+METHODDEF(void)
+term_source (j_decompress_ptr cinfo)
+{
+	/* no work necessary here */
+}
+
+METHODDEF(void)
+init_destination (j_compress_ptr cinfo)
+{
+	my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+
+	dest->pub.next_output_byte = *dest->data;
+	dest->pub.free_in_buffer = *dest->size;
+}
+
+
+METHODDEF(boolean)
+empty_output_buffer (j_compress_ptr cinfo)
+{
+	ERREXIT(cinfo, JERR_BUFFER_SIZE);
+	return TRUE;
+}
+
+
+METHODDEF(void)
+term_destination (j_compress_ptr cinfo)
+{
+	my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+
+	*dest->size -= dest->pub.free_in_buffer;
+}
+
+/*
+ * Prepare for input from a memory buffer.
+ * The caller must have already allocated the buffer, and is
+ * responsible for freeing it after finishing decompression.
+ */
+
+GLOBAL(void)
+jpeg_memory_src (j_decompress_ptr cinfo, void *data, size_t size)
+{
+	my_src_ptr src = NULL;
+
+	if (cinfo->src == NULL) {	/* first time for this JPEG object? */
+		cinfo->src = (struct jpeg_source_mgr *)
+			(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+			sizeof(my_source_mgr));
+	}
+
+	src = (my_src_ptr) cinfo->src;
+	src->pub.init_source = init_source;
+	src->pub.fill_input_buffer = fill_input_buffer;
+	src->pub.skip_input_data = skip_input_data;
+	src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+	src->pub.term_source = term_source;
+	src->pub.next_input_byte = NULL;
+	src->pub.bytes_in_buffer = 0;
+	src->data = (JOCTET *) data;
+	src->size = (size_t) size;
+}
+
+/*
+ * Prepare for output to a memory buffer.
+ * The caller must have already allocated the buffer, and is
+ * responsible for freeing it after finishing compression.
+ */
+
+GLOBAL(void)
+jpeg_memory_dest (j_compress_ptr cinfo, void **data, size_t *size)
+{
+	my_dest_ptr dest = NULL;
+
+	if (cinfo->dest == NULL) {	/* first time for this JPEG object? */
+		cinfo->dest = (struct jpeg_destination_mgr *)
+			(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+			sizeof(my_destination_mgr));
+	}
+
+	dest = (my_dest_ptr) cinfo->dest;
+	dest->pub.init_destination = init_destination;
+	dest->pub.empty_output_buffer = empty_output_buffer;
+	dest->pub.term_destination = term_destination;
+	dest->pub.next_output_byte = NULL;
+	dest->pub.free_in_buffer = 0;
+	dest->data = (JOCTET **) data;
+	dest->size = (size_t *) size;
+}
--- gthumb-cvs/libgthumb/jpegutils/jpegtran.c	2006-11-07 11:15:33.000000000 +0100
+++ gthumb/libgthumb/jpegutils/jpegtran.c	2006-11-15 10:39:26.000000000 +0100
@@ -49,6 +49,7 @@
 #include "gthumb-error.h"
 #include "file-utils.h"
 #include "transupp.h"		/* Support routines for jpegtran */
+#include "jpeg-memory-mgr.h"
 
 #include <libexif/exif-data.h>
 
@@ -201,82 +202,12 @@ update_exif_dimensions (ExifData *edata,
 }
 
 
-#define container_of(ptr, type, member) ({			\
-        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
-        (type *)( (char *)__mptr - offsetof(type,member) );})
-
-struct th {
-    struct jpeg_decompress_struct src;
-    struct jpeg_compress_struct   dst;
-    struct jpeg_error_mgr jsrcerr, jdsterr;
-    unsigned char *in;
-    unsigned char *out;
-    int isize, osize;
-};
-
-static void thumbnail_src_init(struct jpeg_decompress_struct *cinfo)
-{
-    struct th *h  = container_of(cinfo, struct th, src);
-    cinfo->src->next_input_byte = h->in;
-    cinfo->src->bytes_in_buffer = h->isize;
-}
-
-static int thumbnail_src_fill(struct jpeg_decompress_struct *cinfo)
-{
-    fprintf(stderr,"jpeg: panic: no more thumbnail input data\n");
-    exit(1);
-}
-
-static void thumbnail_src_skip(struct jpeg_decompress_struct *cinfo,
-			       long num_bytes)
-{
-    cinfo->src->next_input_byte += num_bytes;
-}
-
-static void thumbnail_src_term(struct jpeg_decompress_struct *cinfo)
-{
-    /* nothing */
-}
-
-static void thumbnail_dest_init(struct jpeg_compress_struct *cinfo)
-{
-    struct th *h  = container_of(cinfo, struct th, dst);
-    h->osize = h->isize * 2;
-    h->out   = malloc(h->osize);
-    cinfo->dest->next_output_byte = h->out;
-    cinfo->dest->free_in_buffer   = h->osize;
-}
-
-static boolean thumbnail_dest_flush(struct jpeg_compress_struct *cinfo)
-{
-    fprintf(stderr,"jpeg: panic: output buffer full\n");
-    exit(1);
-}
-
-static void thumbnail_dest_term(struct jpeg_compress_struct *cinfo)
-{
-    struct th *h  = container_of(cinfo, struct th, dst);
-    h->osize -= cinfo->dest->free_in_buffer;
-}
-
-static struct jpeg_source_mgr thumbnail_src = {
-	.init_source         = thumbnail_src_init,
-	.fill_input_buffer   = thumbnail_src_fill,
-	.skip_input_data     = thumbnail_src_skip,
-	.resync_to_restart   = jpeg_resync_to_restart,
-	.term_source         = thumbnail_src_term,
-};
-
-static struct jpeg_destination_mgr thumbnail_dst = {
-	.init_destination    = thumbnail_dest_init,
-	.empty_output_buffer = thumbnail_dest_flush,
-	.term_destination    = thumbnail_dest_term,
-};
-
 static void
 update_exif_thumbnail (ExifData *edata, JXFORM_CODE transform)
 {
-	struct th th;
+	struct jpeg_decompress_struct src;
+	struct jpeg_compress_struct dst;
+	struct jpeg_error_mgr jsrcerr, jdsterr;
 	
 	if (edata == NULL)
 		return;
@@ -285,31 +216,37 @@ update_exif_thumbnail (ExifData *edata, 
 		return;
 
 	if (edata->data && edata->data[0] == 0xff && edata->data[1] == 0xd8) {
-		memset(&th, 0, sizeof(th));
-		th.in    = edata->data;
-		th.isize = edata->size;
-		   
-		/* setup src */
-		th.src.err = jpeg_std_error(&th.jsrcerr);
-		jpeg_create_decompress(&th.src);
-		th.src.src = &thumbnail_src;
-
-		/* setup dst */
-		th.dst.err = jpeg_std_error(&th.jdsterr);
-		jpeg_create_compress(&th.dst);
-		th.dst.dest = &thumbnail_dst;
+    	/* Allocate output buffer */
+    	unsigned int osize = edata->size * 2;
+    	unsigned char *out = malloc(osize);
+
+		/* Initialize the JPEG decompression object
+		 * with default error handling. */
+		src.err = jpeg_std_error(&jsrcerr);
+		jpeg_create_decompress(&src);	
+
+		/* Initialize the JPEG compression object
+		 * with default error handling. */
+		dst.err = jpeg_std_error(&jdsterr);
+		jpeg_create_compress(&dst);
+		
+		/* Specify data source for decompression */
+		jpeg_memory_src (&src, edata->data, edata->size);
+		
+		/* Specify data source for decompression */
+		jpeg_memory_dest (&dst, &out, &osize);
 
 		/* transform image */
-		jpegtran_internal(&th.src, &th.dst, transform, FALSE);
+		jpegtran_internal(&src, &dst, transform, FALSE);
 
 		/* cleanup */
-		jpeg_destroy_decompress(&th.src);
-		jpeg_destroy_compress(&th.dst);
+		jpeg_destroy_decompress(&src);
+		jpeg_destroy_compress(&dst);
 
 		/* replace thumbnail */
 		free(edata->data);
-		edata->data = th.out;
-		edata->size = th.osize;
+		edata->data = out;
+		edata->size = osize;
 	}
 }
 
--- gthumb-cvs/libgthumb/jpegutils/Makefile.am	2006-11-06 10:05:29.000000000 +0100
+++ gthumb/libgthumb/jpegutils/Makefile.am	2006-11-14 15:21:47.000000000 +0100
@@ -14,6 +14,8 @@ INCLUDES = 				\
 noinst_LTLIBRARIES = libgthumb-jpegutils.la
 
 libgthumb_jpegutils_la_SOURCES =	\
+	jpeg-memory-mgr.c			\
+	jpeg-memory-mgr.h			\
 	jpeg-data.c			\
 	jpeg-data.h			\
 	jpeg-marker.c			\
