Commit 73523344 authored by Michael J. Chudobiak's avatar Michael J. Chudobiak Committed by Michael J. Chudobiak

Purged libexif from gthumb! Use exiv2 to write exif data to files after

2008-02-07  Michael J. Chudobiak  <mjc@svn.gnome.org>

        * NEWS:
        * README:
        * configure.in:
        * libgthumb/Makefile.am:
        * libgthumb/gth-exif-utils.c: (simple_add_metadata), (swap_fields):
        * libgthumb/gth-exif-utils.h:
        * libgthumb/jpegutils/Makefile.am:
        * libgthumb/jpegutils/jpegtran.c: (update_exif_dimensions),
        (jpegtran_internal), (jpegtran):
        * libgthumb/pixbuf-utils.c: (_gdk_pixbuf_savev):
        * src/Makefile.am:
        Purged libexif from gthumb!
        Use exiv2 to write exif data to files after jpeg transformation.


svn path=/trunk/; revision=2266
parent 77460b75
2008-02-07 Michael J. Chudobiak <mjc@svn.gnome.org>
* NEWS:
* README:
* configure.in:
* libgthumb/Makefile.am:
* libgthumb/gth-exif-utils.c: (simple_add_metadata), (swap_fields):
* libgthumb/gth-exif-utils.h:
* libgthumb/jpegutils/Makefile.am:
* libgthumb/jpegutils/jpegtran.c: (update_exif_dimensions),
(jpegtran_internal), (jpegtran):
* libgthumb/pixbuf-utils.c: (_gdk_pixbuf_savev):
* src/Makefile.am:
Purged libexif from gthumb!
Use exiv2 to write exif data to files after jpeg transformation.
2008-02-07 Michael J. Chudobiak <mjc@svn.gnome.org>
* libgthumb/Makefile.am:
......
......@@ -59,6 +59,7 @@ trunk, since last 2.10.x
Library changes:
* exiv2 0.15 or higher is now required.
* libiptcdata is no longer used.
* libexif is no longer used.
version 2.10.9
......
......@@ -93,7 +93,6 @@ Compiling
* gnome-vfs version >= 2.6.0
* libglade version >= 2.4.0
* intltool version >= 0.35.0
* libexif version >= 0.6.13
* exiv2 version >= 0.15
* libjpeg
* gtkunique version >= 0.9.1 (optional)
......
......@@ -30,7 +30,6 @@ LIBGNOMEUI_REQUIRED=2.6.0
LIBGNOMECANVAS_REQUIRED=2.6.0
GNOME_VFS_REQUIRED=2.6.0
LIBGLADE_REQUIRED=2.4.0
LIBEXIF_REQUIRED=0.6.13
LIBGPHOTO_REQUIRED=2.1.3
BONOBO_REQUIRED=2.6.0
LIBOPENRAW_REQUIRED=0.0.2
......@@ -45,7 +44,6 @@ AC_SUBST(LIBGNOMEUI_REQUIRED)
AC_SUBST(LIBGNOMECANVAS_REQUIRED)
AC_SUBST(GNOME_VFS_REQUIRED)
AC_SUBST(LIBGLADE_REQUIRED)
AC_SUBST(LIBEXIF_REQUIRED)
AC_SUBST(LIBGPHOTO_REQUIRED)
AC_SUBST(BONOBO_REQUIRED)
AC_SUBST(LIBOPENRAW_REQUIRED)
......@@ -69,7 +67,6 @@ PKG_CHECK_MODULES(GTHUMB, \
bonobo-activation-2.0 >= $BONOBO_REQUIRED \
gnome-vfs-2.0 >= $GNOME_VFS_REQUIRED \
gnome-vfs-module-2.0 \
libexif >= $LIBEXIF_REQUIRED \
exiv2 >= $EXIV2_REQUIRED \
libxml-2.0 >= $LIBXML_REQUIRED \
libglade-2.0 >= $LIBGLADE_REQUIRED)
......
......@@ -10,7 +10,6 @@ endif
gladedir = $(datadir)/gthumb/glade
INCLUDES = \
$(EXIF_CFLAGS) \
$(GTHUMB_CFLAGS) \
-DGTHUMB_MODULEDIR=\""$(libdir)/gthumb/modules"\" \
-DGTHUMB_GLADEDIR=\""$(gladedir)"\" \
......@@ -140,7 +139,6 @@ libgthumb_la_SOURCES = \
libgthumb_la_LIBADD = \
$(top_builddir)/libgthumb/jpegutils/libgthumb-jpegutils.la \
$(EXIF_LIBS) \
$(JPEG_LIBS) \
$(TIFF_LIBS) \
$(GTHUMB_LIBS) \
......
......@@ -355,18 +355,28 @@ simple_add_metadata (GList *metadata,
metadata items into a single structure, to supply to
update_and_save_metadata. */
GthMetadata *new_entry;
if (value != NULL) {
new_entry = g_new (GthMetadata, 1);
new_entry->category = GTH_METADATA_CATEGORY_OTHER;
new_entry->full_name = g_strdup (key);
new_entry->display_name = g_strdup (key);
new_entry->formatted_value = g_strdup (value);
new_entry->raw_value = g_strdup (value);
new_entry->position = 0;
new_entry->writeable = TRUE;
metadata = g_list_prepend (metadata, new_entry);
GthMetadata *entry;
GList *search_result = g_list_find_custom (metadata, key, (GCompareFunc) metadata_search);
if (search_result != NULL) {
/* Update value of existing tag */
entry = search_result->data;
g_free (entry->formatted_value);
g_free (entry->raw_value);
entry->formatted_value = g_strdup (value);
entry->raw_value = g_strdup (value);
}
else {
/* Add a new tag entry */
entry = g_new (GthMetadata, 1);
entry->category = GTH_METADATA_CATEGORY_OTHER;
entry->full_name = g_strdup (key);
entry->display_name = g_strdup (key);
entry->formatted_value = g_strdup (value);
entry->raw_value = g_strdup (value);
entry->position = 0;
entry->writeable = TRUE;
metadata = g_list_prepend (metadata, entry);
}
return metadata;
......@@ -545,3 +555,32 @@ update_metadata (FileData *fd)
return;
}
void
swap_fields (GList *metadata, const char *tag1, const char *tag2)
{
char *tmp;
GthMetadata *entry1;
GthMetadata *entry2;
GList *search_result1 = g_list_find_custom (metadata, tag1, (GCompareFunc) metadata_search);
if (search_result1 == NULL)
return;
else
entry1 = search_result1->data;
GList *search_result2 = g_list_find_custom (metadata, tag2, (GCompareFunc) metadata_search);
if (search_result2 == NULL)
return;
else
entry2 = search_result2->data;
tmp = entry1->formatted_value;
entry1->formatted_value = entry2->formatted_value;
entry2->formatted_value = tmp;
tmp = entry1->raw_value;
entry1->raw_value = entry2->raw_value;
entry2->raw_value = tmp;
}
......@@ -107,4 +107,7 @@ void write_orientation_field (const char *filename,
GList * gth_read_exiv2 (const char *filename,
GList *metadata);
void update_metadata (FileData *fd);
void swap_fields (GList *metadata,
const char *tag1,
const char *tag2);
#endif /* EXIF_UTILS_H */
......@@ -7,7 +7,6 @@ endif
INCLUDES = \
-I$(top_srcdir)/libgthumb \
$(DISABLE_DEPRECATED) \
$(EXIF_CFLAGS) \
$(GTHUMB_CFLAGS)
......
......@@ -51,16 +51,7 @@
#include "transupp.h" /* Support routines for jpegtran */
#include "jpeg-memory-mgr.h"
#include "jpegtran.h"
#include <libexif/exif-data.h>
static int
jpegtran_thumbnail (const void *idata,
size_t isize,
void **odata,
size_t *osize,
JXFORM_CODE transformation);
#include "gth-exif-utils.h"
/* error handler data */
......@@ -133,41 +124,10 @@ set_exif_orientation_to_top_left (ExifData *edata)
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,
update_exif_dimensions (GList *metadata,
JXFORM_CODE transform)
{
unsigned int i;
if (edata == NULL)
if (metadata == NULL)
return;
switch (transform) {
......@@ -180,111 +140,11 @@ update_exif_dimensions (ExifData *edata,
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)
{
size_t osize;
unsigned char *out;
if (edata == NULL || edata->data == NULL)
return;
if (transform == JXFORM_NONE)
return;
/* Allocate a new thumbnail buffer (twice the size of the original thumbnail).
* WARNING: If this buffer is too small (very unlikely, but not impossible),
* jpegtran will return an error and the thumbnail will be discarded.
* To prevent this, the size of the buffer should be increased somehow.
*/
osize = edata->size * 2;
out = g_malloc (osize);
/* Transform thumbnail */
if (jpegtran_thumbnail (edata->data, edata->size,
(void**)&out, &osize, transform) != 0) {
/* Failed: Discard thumbnail */
g_free (out);
g_free (edata->data);
edata->data = NULL;
edata->size = 0;
}
else {
/* Success: Replace thumbnail */
g_free (edata->data);
edata->data = out;
edata->size = osize;
}
}
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) */
set_exif_orientation_to_top_left (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);
swap_fields (metadata, "Exif.Photo.PixelXDimension", "Exif.Photo.PixelYDimension");
swap_fields (metadata, "Exif.Image.XResolution", "Exif.Image.YResolution");
swap_fields (metadata, "Exif.Photo.FocalPlaneXResolution", "Exif.Photo.FocalPlaneYResolution");
swap_fields (metadata, "Exif.Image.ImageWidth", "Exif.Image.ImageLength");
swap_fields (metadata, "Exif.Iop.RelatedImageWidth", "Exif.Iop.RelatedImageLength");
}
......@@ -365,9 +225,6 @@ jpegtran_internal (struct jpeg_decompress_struct *srcinfo,
return FALSE;
}
/* 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.
*/
......@@ -421,79 +278,6 @@ jpegtran_internal (struct jpeg_decompress_struct *srcinfo,
}
static int
jpegtran_thumbnail (const void *idata,
size_t isize,
void **odata,
size_t *osize,
JXFORM_CODE transformation)
{
struct jpeg_decompress_struct srcinfo;
struct jpeg_compress_struct dstinfo;
struct error_handler_data jsrcerr, jdsterr;
/* Initialize the JPEG decompression object with default error
* handling. */
srcinfo.err = jpeg_std_error (&(jsrcerr.pub));
jsrcerr.pub.error_exit = fatal_error_handler;
jsrcerr.pub.output_message = output_message_handler;
jsrcerr.filename = NULL;
jsrcerr.error = NULL;
jpeg_create_decompress (&srcinfo);
/* Initialize the JPEG compression object with default error
* handling. */
dstinfo.err = jpeg_std_error (&(jdsterr.pub));
jdsterr.pub.error_exit = fatal_error_handler;
jdsterr.pub.output_message = output_message_handler;
jdsterr.filename = NULL;
jdsterr.error = NULL;
jpeg_create_compress (&dstinfo);
dstinfo.err->trace_level = 0;
dstinfo.arith_code = FALSE;
dstinfo.optimize_coding = FALSE;
jsrcerr.pub.trace_level = jdsterr.pub.trace_level;
srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use;
/* Decompression error handler */
if (sigsetjmp (jsrcerr.setjmp_buffer, 1)) {
jpeg_destroy_compress (&dstinfo);
jpeg_destroy_decompress (&srcinfo);
return 1;
}
/* Compression error handler */
if (sigsetjmp (jdsterr.setjmp_buffer, 1)) {
jpeg_destroy_compress (&dstinfo);
jpeg_destroy_decompress (&srcinfo);
return 1;
}
/* Specify data source for decompression */
jpeg_memory_src (&srcinfo, idata, isize);
/* Specify data destination for compression */
jpeg_memory_dest (&dstinfo, odata, osize);
/* Apply transformation */
if (! jpegtran_internal (&srcinfo, &dstinfo, transformation, JCOPYOPT_NONE, JPEG_MCU_ACTION_DONT_TRIM, NULL)) {
jpeg_destroy_compress (&dstinfo);
jpeg_destroy_decompress (&srcinfo);
return 1;
}
/* Release memory */
jpeg_destroy_compress (&dstinfo);
jpeg_destroy_decompress (&srcinfo);
return 0;
}
gboolean
jpegtran (const char *input_filename,
const char *output_filename,
......@@ -587,37 +371,15 @@ jpegtran (const char *input_filename,
fclose (input_file);
fclose (output_file);
return TRUE;
}
#ifdef TEST
/* Update Exif data */
FileData *file = file_data_new (output_filename, NULL);
file_data_update_all (file, FALSE);
update_metadata (file);
update_exif_dimensions (file->metadata, transformation);
file->metadata = simple_add_metadata (file->metadata, "Exif.Image.Orientation", "1");
update_and_save_metadata (output_filename, output_filename, file->metadata);
file_data_unref (file);
int
main (int argc,
char **argv)
{
char *input_filename;
char *output_filename;
if (argc != 3) {
fprintf (stderr, "%s input_image output_image", argv[0]);
return 1;
}
input_filename = argv[1];
output_filename = argv[2];
/*
JXFORM_ROT_90
JXFORM_ROT_180
JXFORM_ROT_270
JXFORM_FLIP_H
JXFORM_FLIP_V
*/
return jpegtran (input_filename, output_filename, JXFORM_FLIP_H);
return TRUE;
}
#endif /* TEST */
......@@ -1234,10 +1234,8 @@ _gdk_pixbuf_savev (GdkPixbuf *pixbuf,
error);
if (result == TRUE) {
metadata = simple_add_metadata (metadata, "Exif.Image.Orientation", "1");
update_and_save_metadata (local_file, local_file, metadata);
/* Saving from pixbuf always implies top-left orientation */
update_and_save_metadatum (local_file, local_file, "Exif.Image.Orientation", "1");
}
......
......@@ -13,7 +13,6 @@ INCLUDES = \
-I$(top_srcdir)/libgthumb \
-I../libgthumb \
$(GTHUMB_CFLAGS) \
$(EXIF_CFLAGS) \
$(DISABLE_DEPRECATED) \
$(GPHOTO_CFLAGS) \
$(GTKUNIQUE_CFLAGS) \
......@@ -155,7 +154,6 @@ endif
gthumb_LDADD = \
$(top_builddir)/libgthumb/jpegutils/libgthumb-jpegutils.la \
$(top_builddir)/libgthumb/libgthumb.la \
$(EXIF_LIBS) \
$(GTHUMB_LIBS) \
$(JPEG_LIBS) \
$(TIFF_LIBS) \
......@@ -181,7 +179,7 @@ libduplicates_la_DEPENDENCIES = gthumb$(EXEEXT)
libjpegtran_la_SOURCES = dlg-jpegtran.c dlg-jpegtran.h
libjpegtran_la_LDFLAGS = $(MODULE_LIBTOOL_FLAGS)
libjpegtran_la_LIBADD = $(top_builddir)/libgthumb/jpegutils/libgthumb-jpegutils.la $(top_builddir)/libgthumb/libgthumb.la $(EXIF_LIBS) $(JPEG_LIBS) $(GTHUMB_LIBS)
libjpegtran_la_LIBADD = $(top_builddir)/libgthumb/jpegutils/libgthumb-jpegutils.la $(top_builddir)/libgthumb/libgthumb.la $(JPEG_LIBS) $(GTHUMB_LIBS)
libjpegtran_la_DEPENDENCIES = gthumb$(EXEEXT)
libpngexporter_la_SOURCES = \
......@@ -207,12 +205,12 @@ libwebexporter_la_SOURCES = \
dlg-web-exporter.c \
dlg-web-exporter.h
libwebexporter_la_LDFLAGS = $(MODULE_LIBTOOL_FLAGS)
libwebexporter_la_LIBADD = $(top_builddir)/libgthumb/libgthumb.la $(GTHUMB_LIBS) $(EXIF_LIBS)
libwebexporter_la_LIBADD = $(top_builddir)/libgthumb/libgthumb.la $(GTHUMB_LIBS)
libwebexporter_la_DEPENDENCIES = gthumb$(EXEEXT)
libphotoimporter_la_SOURCES = dlg-photo-importer.c dlg-photo-importer.h
libphotoimporter_la_LDFLAGS = $(MODULE_LIBTOOL_FLAGS)
libphotoimporter_la_LIBADD = $(top_builddir)/libgthumb/jpegutils/libgthumb-jpegutils.la $(top_builddir)/libgthumb/libgthumb.la $(GTHUMB_LIBS) $(EXIF_LIBS) $(JPEG_LIBS) $(GPHOTO_LIBS)
libphotoimporter_la_LIBADD = $(top_builddir)/libgthumb/jpegutils/libgthumb-jpegutils.la $(top_builddir)/libgthumb/libgthumb.la $(GTHUMB_LIBS) $(JPEG_LIBS) $(GPHOTO_LIBS)
libphotoimporter_la_DEPENDENCIES = gthumb$(EXEEXT)
EXTRA_DIST = \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment