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

Removed libiptcdata from gthumb. We use exiv2 instead, now. The comment

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

        * NEWS:
        * README:
        * configure.in:
        * libgthumb/comments.c: (comment_data_new), (comment_data_free),
        (comment_data_dup), (comment_delete), (load_comment_from_metadata),
        (save_comment_to_metadata), (save_comment),
        (comments_load_comment):
        * libgthumb/gth-exiv2-utils.cpp:
        Removed libiptcdata from gthumb. We use exiv2 instead, now.
        The comment <-> metadata code has been updated to reflect this.
        The comment <-> metadata mapping is still unstable and may change.


svn path=/trunk/; revision=2257
parent 12167207
2008-02-06 Michael J. Chudobiak <mjc@svn.gnome.org>
* NEWS:
* README:
* configure.in:
* libgthumb/comments.c: (comment_data_new), (comment_data_free),
(comment_data_dup), (comment_delete), (load_comment_from_metadata),
(save_comment_to_metadata), (save_comment),
(comments_load_comment):
* libgthumb/gth-exiv2-utils.cpp:
Removed libiptcdata from gthumb. We use exiv2 instead, now.
The comment <-> metadata code has been updated to reflect this.
The comment <-> metadata mapping is still unstable and may change.
2008-02-05 Michael J. Chudobiak <mjc@svn.gnome.org> 2008-02-05 Michael J. Chudobiak <mjc@svn.gnome.org>
* libgthumb/gth-exif-utils.c: * libgthumb/gth-exif-utils.c:
......
...@@ -58,6 +58,7 @@ trunk, since last 2.10.x ...@@ -58,6 +58,7 @@ trunk, since last 2.10.x
Library changes: Library changes:
* exiv2 0.15 or higher is now required. * exiv2 0.15 or higher is now required.
* libiptcdata is no longer used.
version 2.10.9 version 2.10.9
......
...@@ -104,9 +104,6 @@ Compiling ...@@ -104,9 +104,6 @@ Compiling
If the libgphoto2 library version >= 2.1.3 is present you can import If the libgphoto2 library version >= 2.1.3 is present you can import
photos from your camera. photos from your camera.
If the libiptc library version >= 0.2.1 is present you can store
comments in the IPTC metadata of a JPEG image.
If the libopenraw library version >= 0.0.2 is present you can view If the libopenraw library version >= 0.0.2 is present you can view
RAW photo thumbnails. RAW photo thumbnails.
......
...@@ -31,7 +31,6 @@ LIBGNOMECANVAS_REQUIRED=2.6.0 ...@@ -31,7 +31,6 @@ LIBGNOMECANVAS_REQUIRED=2.6.0
GNOME_VFS_REQUIRED=2.6.0 GNOME_VFS_REQUIRED=2.6.0
LIBGLADE_REQUIRED=2.4.0 LIBGLADE_REQUIRED=2.4.0
LIBEXIF_REQUIRED=0.6.13 LIBEXIF_REQUIRED=0.6.13
LIBIPTCDATA_REQUIRED=0.2.1
LIBGPHOTO_REQUIRED=2.1.3 LIBGPHOTO_REQUIRED=2.1.3
BONOBO_REQUIRED=2.6.0 BONOBO_REQUIRED=2.6.0
LIBOPENRAW_REQUIRED=0.0.2 LIBOPENRAW_REQUIRED=0.0.2
...@@ -47,7 +46,6 @@ AC_SUBST(LIBGNOMECANVAS_REQUIRED) ...@@ -47,7 +46,6 @@ AC_SUBST(LIBGNOMECANVAS_REQUIRED)
AC_SUBST(GNOME_VFS_REQUIRED) AC_SUBST(GNOME_VFS_REQUIRED)
AC_SUBST(LIBGLADE_REQUIRED) AC_SUBST(LIBGLADE_REQUIRED)
AC_SUBST(LIBEXIF_REQUIRED) AC_SUBST(LIBEXIF_REQUIRED)
AC_SUBST(LIBIPTCDATA_REQUIRED)
AC_SUBST(LIBGPHOTO_REQUIRED) AC_SUBST(LIBGPHOTO_REQUIRED)
AC_SUBST(BONOBO_REQUIRED) AC_SUBST(BONOBO_REQUIRED)
AC_SUBST(LIBOPENRAW_REQUIRED) AC_SUBST(LIBOPENRAW_REQUIRED)
...@@ -194,29 +192,6 @@ fi ...@@ -194,29 +192,6 @@ fi
AC_SUBST(XF86GAMMA_LIBS) AC_SUBST(XF86GAMMA_LIBS)
#
# Checks for libiptcdata
#
AC_ARG_ENABLE([iptcdata],
[AC_HELP_STRING([--disable-iptcdata],[disable support for iptc data])],,
[enable_iptcdata=yes])
HAVE_IPTC=no
if test x$enable_iptcdata = xyes ; then
AC_MSG_CHECKING(IPTC Data Support)
IPTCDATA_LIBS=""
IPTCDATA_CFLAGS=""
if pkg-config --atleast-version=$LIBIPTCDATA_REQUIRED libiptcdata; then
HAVE_IPTC="yes"
IPTCDATA_LIBS=`pkg-config --libs libiptcdata`
IPTCDATA_CFLAGS=`pkg-config --cflags libiptcdata`
AC_DEFINE(HAVE_LIBIPTCDATA, 1, [Have libiptcdata])
fi
AC_MSG_RESULT($HAVE_IPTC)
fi
AC_SUBST(IPTCDATA_LIBS)
AC_SUBST(IPTCDATA_CFLAGS)
# #
# Checks for libgphoto2 # Checks for libgphoto2
# #
...@@ -389,7 +364,6 @@ Configuration: ...@@ -389,7 +364,6 @@ Configuration:
Have XRender: ${HAVE_RENDER} Have XRender: ${HAVE_RENDER}
Have XTest: ${have_xtest} Have XTest: ${have_xtest}
Have XF86VidModeSetGamma: ${have_xf86gamma} Have XF86VidModeSetGamma: ${have_xf86gamma}
Have libiptcdata: ${HAVE_IPTC}
Have libtiff: ${HAVE_TIFF} Have libtiff: ${HAVE_TIFF}
Have libgphoto: ${HAVE_GPHOTO2} Have libgphoto: ${HAVE_GPHOTO2}
Have libopenraw: ${HAVE_LIBOPENRAW} Have libopenraw: ${HAVE_LIBOPENRAW}
......
...@@ -41,16 +41,12 @@ ...@@ -41,16 +41,12 @@
#include <libxml/xmlmemory.h> #include <libxml/xmlmemory.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#ifdef HAVE_LIBIPTCDATA
#include <libiptcdata/iptc-data.h>
#include <libiptcdata/iptc-jpeg.h>
#endif /* HAVE_LIBIPTCDATA */
#include "typedefs.h" #include "typedefs.h"
#include "comments.h" #include "comments.h"
#include "file-utils.h" #include "file-utils.h"
#include "glib-utils.h" #include "glib-utils.h"
#include "gtk-utils.h" #include "gtk-utils.h"
#include "gth-exif-utils.h"
#define COMMENT_TAG ((xmlChar *)"Comment") #define COMMENT_TAG ((xmlChar *)"Comment")
#define PLACE_TAG ((xmlChar *)"Place") #define PLACE_TAG ((xmlChar *)"Place")
...@@ -78,11 +74,6 @@ comment_data_new (void) ...@@ -78,11 +74,6 @@ comment_data_new (void)
data->keywords_n = 0; data->keywords_n = 0;
data->keywords = NULL; data->keywords = NULL;
data->utf8_format = TRUE; data->utf8_format = TRUE;
#ifdef HAVE_LIBIPTCDATA
data->iptc_data = NULL;
#endif /* HAVE_LIBIPTCDATA */
data->changed = FALSE; data->changed = FALSE;
return data; return data;
...@@ -131,12 +122,6 @@ comment_data_free (CommentData *data) ...@@ -131,12 +122,6 @@ comment_data_free (CommentData *data)
comment_data_free_comment (data); comment_data_free_comment (data);
comment_data_free_keywords (data); comment_data_free_keywords (data);
#ifdef HAVE_LIBIPTCDATA
if (data->iptc_data != NULL)
iptc_data_unref (data->iptc_data);
#endif /* HAVE_LIBIPTCDATA */
g_free (data); g_free (data);
} }
...@@ -169,12 +154,6 @@ comment_data_dup (CommentData *data) ...@@ -169,12 +154,6 @@ comment_data_dup (CommentData *data)
} }
new_data->utf8_format = data->utf8_format; new_data->utf8_format = data->utf8_format;
#ifdef HAVE_LIBIPTCDATA
new_data->iptc_data = data->iptc_data;
if (new_data->iptc_data != NULL)
iptc_data_ref (new_data->iptc_data);
#endif /* HAVE_LIBIPTCDATA */
return new_data; return new_data;
} }
...@@ -248,331 +227,6 @@ comments_get_comment_filename (const char *uri, ...@@ -248,331 +227,6 @@ comments_get_comment_filename (const char *uri,
} }
#ifdef HAVE_LIBIPTCDATA
static CommentData *
load_comment_from_iptc (const char *uri)
{
CommentData *data;
IptcData *d;
struct tm t;
int i;
int got_date = 0, got_time = 0;
char *local_file = NULL;
if (uri == NULL)
return NULL;
local_file = get_cache_filename_from_uri (uri);
if (local_file == NULL)
return NULL;
d = iptc_data_new_from_jpeg (local_file);
g_free (local_file);
if (d == NULL)
return NULL;
data = comment_data_new ();
bzero (&t, sizeof (t));
t.tm_isdst = -1;
for (i = 0; i < d->count; i++) {
IptcDataSet * ds = d->datasets[i];
if ((ds->record == IPTC_RECORD_APP_2)
&& (ds->tag == IPTC_TAG_CAPTION)) {
if (data->comment)
continue;
data->comment = g_new (char, ds->size + 1);
if (data->comment)
iptc_dataset_get_data (ds, (guchar*)data->comment, ds->size + 1);
}
else if ((ds->record == IPTC_RECORD_APP_2)
&& (ds->tag == IPTC_TAG_CONTENT_LOC_NAME)) {
if (data->place)
continue;
data->place = g_new (char, ds->size + 1);
if (data->place)
iptc_dataset_get_data (ds, (guchar*)data->place, ds->size + 1);
}
else if ((ds->record == IPTC_RECORD_APP_2)
&& (ds->tag == IPTC_TAG_KEYWORDS)) {
char keyword[64];
if (iptc_dataset_get_data (ds, (guchar*)keyword, sizeof(keyword)) < 0)
continue;
comment_data_add_keyword (data, keyword);
}
else if ((ds->record == IPTC_RECORD_APP_2)
&& (ds->tag == IPTC_TAG_DATE_CREATED)) {
int year, month;
iptc_dataset_get_date (ds, &year, &month, &t.tm_mday);
t.tm_year = year - 1900;
t.tm_mon = month - 1;
got_date = 1;
}
else if ((ds->record == IPTC_RECORD_APP_2)
&& (ds->tag == IPTC_TAG_TIME_CREATED)) {
iptc_dataset_get_time (ds, &t.tm_hour, &t.tm_min, &t.tm_sec, NULL);
got_time = 1;
}
}
if (got_date && got_time)
data->time = mktime (&t);
data->iptc_data = d;
return data;
}
static void
clear_iptc_comment (IptcData *d)
{
IptcTag deletetag[] = {
IPTC_TAG_DATE_CREATED, IPTC_TAG_TIME_CREATED, IPTC_TAG_KEYWORDS,
IPTC_TAG_CAPTION, IPTC_TAG_CONTENT_LOC_NAME, 0
};
int i;
for (i = 0; deletetag[i] != 0; i++) {
IptcDataSet *ds;
while ((ds = iptc_data_get_dataset (d,
IPTC_RECORD_APP_2,
deletetag[i]))) {
iptc_data_remove_dataset (d, ds);
iptc_dataset_unref (ds);
}
}
}
static void
save_iptc_data (const char *filename,
IptcData *d)
{
guint buf_len = 256 * 256;
FILE *infile, *outfile;
guchar *ps3_buf;
guchar *ps3_out_buf;
guchar *iptc_buf;
guint ps3_len, iptc_len;
gchar *tmpfile;
struct stat statinfo;
if (filename == NULL)
return;
ps3_buf = g_malloc (buf_len);
if (!ps3_buf)
return;
ps3_out_buf = g_malloc (buf_len);
if (!ps3_out_buf)
goto abort1;
infile = fopen (filename, "r");
if (!infile)
goto abort2;
ps3_len = iptc_jpeg_read_ps3 (infile, ps3_buf, buf_len);
if (ps3_len < 0)
goto abort3;
if (iptc_data_save (d, &iptc_buf, &iptc_len) < 0)
goto abort3;
ps3_len = iptc_jpeg_ps3_save_iptc (ps3_buf, ps3_len,
iptc_buf, iptc_len,
ps3_out_buf, buf_len);
iptc_data_free_buf (d, iptc_buf);
if (ps3_len < 0)
goto abort3;
rewind (infile);
tmpfile = g_strdup_printf ("%s.%d", filename, getpid());
if (!tmpfile)
goto abort3;
outfile = fopen (tmpfile, "w");
if (!outfile)
goto abort4;
if (iptc_jpeg_save_with_ps3 (infile, outfile, (guchar*)ps3_out_buf, ps3_len) < 0)
goto abort5;
fclose (outfile);
fclose (infile);
stat (filename, &statinfo);
if (rename (tmpfile, filename) < 0)
file_unlink (tmpfile);
else {
chown (filename, -1, statinfo.st_gid);
chmod (filename, statinfo.st_mode);
}
g_free (tmpfile);
g_free (ps3_out_buf);
g_free (ps3_buf);
return;
abort5:
fclose (outfile);
file_unlink (tmpfile);
abort4:
g_free (tmpfile);
abort3:
fclose (infile);
abort2:
g_free (ps3_out_buf);
abort1:
g_free (ps3_buf);
}
static void
save_comment_iptc (const char *uri,
CommentData *data)
{
char *local_file;
char *local_uri;
time_t mtime;
IptcData *d;
IptcDataSet *ds;
int i;
local_file = get_cache_filename_from_uri (uri);
if (local_file == NULL)
return;
local_uri = get_uri_from_local_path (local_file);
mtime = get_file_mtime (local_uri);
d = iptc_data_new_from_jpeg (local_file);
if (d != NULL)
clear_iptc_comment (d);
else {
d = iptc_data_new ();
if (d == NULL)
return;
}
if (data->time > 0) {
struct tm t;
localtime_r (&data->time, &t);
ds = iptc_dataset_new ();
if (ds != NULL) {
iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2,
IPTC_TAG_DATE_CREATED);
iptc_dataset_set_date (ds, t.tm_year + 1900, t.tm_mon + 1,
t.tm_mday, IPTC_DONT_VALIDATE);
iptc_data_add_dataset (d, ds);
iptc_dataset_unref (ds);
}
ds = iptc_dataset_new ();
if (ds != NULL) {
iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2,
IPTC_TAG_TIME_CREATED);
iptc_dataset_set_time (ds, t.tm_hour, t.tm_min, t.tm_sec,
0, IPTC_DONT_VALIDATE);
iptc_data_add_dataset (d, ds);
iptc_dataset_unref (ds);
}
}
for (i = 0; i < data->keywords_n; i++) {
ds = iptc_dataset_new ();
if (ds != NULL) {
iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2,
IPTC_TAG_KEYWORDS);
iptc_dataset_set_data (ds, (guchar*)data->keywords[i],
strlen (data->keywords[i]), IPTC_DONT_VALIDATE);
iptc_data_add_dataset (d, ds);
iptc_dataset_unref (ds);
}
}
if (data->comment != NULL && data->comment[0]) {
ds = iptc_dataset_new ();
if (ds != NULL) {
iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2,
IPTC_TAG_CAPTION);
iptc_dataset_set_data (ds, (guchar*)data->comment,
strlen (data->comment), IPTC_DONT_VALIDATE);
iptc_data_add_dataset (d, ds);
iptc_dataset_unref (ds);
}
}
if (data->place != NULL && data->place[0]) {
ds = iptc_dataset_new ();
if (ds != NULL) {
iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2,
IPTC_TAG_CONTENT_LOC_NAME);
iptc_dataset_set_data (ds, (guchar*)data->place,
strlen (data->place), IPTC_DONT_VALIDATE);
iptc_data_add_dataset (d, ds);
iptc_dataset_unref (ds);
}
}
/* The iptc_data_set_version and iptc_data_set_encoding_utf8
functions cause Picasa to choke, as indicated in the libiptc
API docs. So we'll disable them and see if that fixes more
things than it breaks. Bug 438716. */
/* iptc_data_set_version (d, IPTC_IIM_VERSION); */
/* iptc_data_set_encoding_utf8 (d); */
iptc_data_sort (d);
save_iptc_data (local_file, d);
set_file_mtime (local_uri, mtime);
iptc_data_unref (d);
g_free (local_file);
g_free (local_uri);
}
static void
delete_comment_iptc (const char *uri)
{
IptcData *d;
time_t mtime;
char *local_file;
if ((uri == NULL) || ! is_local_file (uri))
return;
mtime = get_file_mtime (uri);
local_file = get_cache_filename_from_uri (uri);
d = iptc_data_new_from_jpeg (local_file);
if (d == NULL) {
g_free (local_file);
return;
}
clear_iptc_comment (d);
save_iptc_data (local_file, d);
iptc_data_unref (d);
g_free (local_file);
set_file_mtime (uri, mtime);
}
#endif /* HAVE_LIBIPTCDATA */
void void
comment_copy (const char *src, comment_copy (const char *src,
const char *dest) const char *dest)
...@@ -638,11 +292,6 @@ comment_delete (const char *uri) ...@@ -638,11 +292,6 @@ comment_delete (const char *uri)
comment_uri = comments_get_comment_filename (uri, TRUE); comment_uri = comments_get_comment_filename (uri, TRUE);
file_unlink (comment_uri); file_unlink (comment_uri);
g_free (comment_uri); g_free (comment_uri);
#ifdef HAVE_LIBIPTCDATA
if (image_is_jpeg (uri))
delete_comment_iptc (uri);
#endif /* HAVE_LIBIPTCDATA */
} }
...@@ -713,6 +362,108 @@ get_keywords (CommentData *data, ...@@ -713,6 +362,108 @@ get_keywords (CommentData *data,
} }
static CommentData *
load_comment_from_metadata (const char *uri)
{
CommentData *data;
FileData *file;
char *metadata_string = NULL;
time_t metadata_time = 0;
file = file_data_new (uri, NULL);
file_data_update_all (file, FALSE);
data = comment_data_new ();
metadata_string = get_metadata_tagset_string (file, TAG_NAME_SETS[COMMENT_TAG_NAMES]);
if ((metadata_string != NULL) && (metadata_string[0] != 0)) {
data->comment = g_strdup (metadata_string);
g_free (metadata_string);
}
metadata_string = get_metadata_tagset_string (file, TAG_NAME_SETS[LOCATION_TAG_NAMES]);
if ((metadata_string != NULL) && (metadata_string[0] != 0)) {
data->place = g_strdup (metadata_string);
g_free (metadata_string);
}
metadata_time = get_exif_time (file);
if (metadata_time > (time_t) 0)
data->time = metadata_time;
metadata_string = get_metadata_tagset_string (file, TAG_NAME_SETS[KEYWORD_TAG_NAMES]);
if ((metadata_string != NULL) && (metadata_string[0] != 0)) {
char **keywords_v;
int i = 0;
comment_data_free_keywords (data);
keywords_v = g_strsplit (metadata_string, ",", 0);
while (keywords_v[i] != NULL) {
i++;
}
data->keywords_n = i;
data->keywords = g_new0 (char*, data->keywords_n + 1);
for (i = 0; i < data->keywords_n; i++)
data->keywords[i] = g_strdup (keywords_v[i]);
data->keywords[i] = NULL;
g_strfreev (keywords_v);
g_free (metadata_string);
}
file_data_unref (file);
return data;
}
static void
save_comment_to_metadata (const char *uri,
CommentData *data)
{
char *keywords_str = NULL;
GList *add_metadata = NULL;
FileData *file;
char *buf;
struct tm tm;
file = file_data_new (uri, NULL);
file_data_update_all (file, FALSE);
add_metadata = simple_add_metadata (add_metadata, "Exif.Photo.UserComment", data->comment);
add_metadata = simple_add_metadata (add_metadata, "Xmp.iptc.Location", data->place);
localtime_r (&data->time, &tm);
buf = g_strdup_printf ("%04d:%02d:%02d %02d:%02d:%02d ",
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec );