diff options
| -rw-r--r-- | src/generators.c | 3 | ||||
| -rw-r--r-- | src/items.c | 52 | ||||
| -rw-r--r-- | src/items.h | 2 | ||||
| -rw-r--r-- | src/jpeg-utils.cpp | 112 | ||||
| -rw-r--r-- | src/jpeg-utils.h | 1 |
5 files changed, 135 insertions, 35 deletions
diff --git a/src/generators.c b/src/generators.c index fe62b39..133c4c1 100644 --- a/src/generators.c +++ b/src/generators.c @@ -159,6 +159,9 @@ metadata_apply_overrides (ExifData *exif_data, exif_data->timezone_shift = item->metadata_tz_shift; if (exif_data->timezone_shift == 0) exif_data->timezone_shift = items->metadata_tz_shift; + exif_data->fake_datetime = item->metadata_fake_datetime; + if (exif_data->fake_datetime == (time_t) -1) + exif_data->fake_datetime = items->metadata_fake_datetime; } diff --git a/src/items.c b/src/items.c index 6ac7e56..85f0a26 100644 --- a/src/items.c +++ b/src/items.c @@ -15,9 +15,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#define _XOPEN_SOURCE 600 #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <time.h> #include <libxml/xmlmemory.h> #include <libxml/parser.h> @@ -53,6 +55,36 @@ parse_timezone_string (const gchar *str) return hour * 60 + min; } +static time_t +parse_datetime_string (const gchar *str) +{ + struct tm tm; + char *res; + time_t rt; + + memset (&tm, 0, sizeof (struct tm)); + + res = strptime (str, "%Y-%m-%d %H:%M:%S", &tm); + if (res == NULL || *res != '\0') { + res = strptime (str, "%Y:%m:%d %H:%M:%S", &tm); + if (res == NULL || *res != '\0') { + res = strptime (str, "%Y-%m-%dT%H:%M:%S", &tm); + if (res == NULL || res < str + 19) { + log_error ("Invalid datetime string \"%s\", ignoring.\n", str); + return (time_t) -1; + } + } + } + + /* EXIF datetime carries no DST information while mktime() will correct + * the tm_isdst field resulting in unnecessary +- 1 hour shift. */ + rt = mktime (&tm); + if (tm.tm_isdst) + rt -= 60*60; + + return rt; +} + /* * parse_album_xml: XML parser for gallery index.xml files @@ -118,8 +150,15 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info) s = xml_file_get_node_attribute (xml, "/gallery/general/metadata/timezone", "shift"); if (s != NULL) { - index->metadata_tz_shift = parse_timezone_string (s2); - g_free (s2); + index->metadata_tz_shift = parse_timezone_string (s); + g_free (s); + } + + index->metadata_fake_datetime = (time_t) -1; + s = xml_file_get_node_attribute (xml, "/gallery/general/metadata/fake", "date"); + if (s != NULL) { + index->metadata_fake_datetime = parse_datetime_string (s); + g_free (s); } @@ -258,6 +297,15 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info) g_free (s2); } + item->metadata_fake_datetime = (time_t) -1; + s = g_strdup_printf ("/gallery/items/*[%d]/metadata/fake", i + 1); + s2 = xml_file_get_node_attribute (xml, s, "date"); + g_free (s); + if (s2 != NULL) { + item->metadata_fake_datetime = parse_datetime_string (s2); + g_free (s2); + } + if (item->path || item->preview) { g_ptr_array_add (index->items, item); } else { diff --git a/src/items.h b/src/items.h index 2b36927..331f29e 100644 --- a/src/items.h +++ b/src/items.h @@ -65,6 +65,7 @@ typedef struct { gchar *auth_passwd; TAuthType auth_type; int metadata_tz_shift; /* minutes */ + time_t metadata_fake_datetime; } TAlbum; typedef struct { @@ -83,6 +84,7 @@ typedef struct { gboolean hidden; gchar *metadata_external_exif; int metadata_tz_shift; /* minutes */ + time_t metadata_fake_datetime; } TIndexItem; typedef struct { diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp index df3c94e..646763a 100644 --- a/src/jpeg-utils.cpp +++ b/src/jpeg-utils.cpp @@ -35,28 +35,6 @@ struct ExifDataPrivate { }; -static struct tm * -parse_exif_date (const char *str) -{ - struct tm *tm; - char *res; - - tm = (struct tm *) g_malloc0 (sizeof (struct tm)); - - res = strptime (str, "%Y:%m:%d %H:%M:%S", tm); - if (res == NULL || *res != '\0') - return NULL; - - /* FIXME: what was this used for? */ -#if 0 - tm->tm_year -= 1900; - tm->tm_mon--; -#endif - mktime (tm); - - return tm; -} - static void shift_time (struct tm *tm, int offset_min) { @@ -78,6 +56,37 @@ shift_time (struct tm *tm, int offset_min) } } +static struct tm * +parse_exif_date (const char *str) +{ + struct tm *tm; + char *res; + + tm = (struct tm *) g_malloc0 (sizeof (struct tm)); + + res = strptime (str, "%Y:%m:%d %H:%M:%S", tm); + if (res == NULL || *res != '\0') + return NULL; + + mktime (tm); + + if (tm->tm_isdst) + shift_time (tm, -60); + + return tm; +} + +static gchar * +format_exif_time (struct tm *tm) +{ + char conv[1024]; + + memset (&conv, 0, sizeof(conv)); + if (strftime (&conv[0], sizeof(conv), "%Y:%m:%d %H:%M:%S", tm)) + return g_strdup (&conv[0]); + + return NULL; +} /* * EXIF and IPTC info retrieval, keeps the source file open until freed @@ -203,7 +212,10 @@ get_exif_data_fixed (ExifData *exif, const gchar *key) return g_strdup_printf ("f/%.1f", val); } - if (g_str_equal (key, EXIF_DATETIME)) { + if (g_str_equal (key, EXIF_DATETIME) || + g_str_equal (key, "Exif.Photo.DateTimeOriginal") || + g_str_equal (key, "Exif.Photo.DateTimeDigitized") || + g_str_equal (key, "Exif.Image.DateTime")) { const char *val = NULL; try { val = exifData["Exif.Photo.DateTimeOriginal"].toString().c_str(); @@ -224,6 +236,12 @@ get_exif_data_fixed (ExifData *exif, const gchar *key) memset (&conv, 0, sizeof (conv)); + if (exif->fake_datetime != (time_t) -1) { + tt = localtime (&exif->fake_datetime); + if (strftime (&conv[0], sizeof (conv), "%c", tt)) + return g_strdup (&conv[0]); + } + tt = parse_exif_date (val); if (tt) { shift_time (tt, exif->timezone_shift); @@ -515,7 +533,9 @@ calculate_sizes (const unsigned long max_width, const unsigned long max_height, static gboolean shift_exif_time (Exiv2::ExifData& exifData, const char *key, int amount) { + struct tm *tt; const char *s; + gchar *st; gboolean res; res = FALSE; @@ -524,19 +544,15 @@ shift_exif_time (Exiv2::ExifData& exifData, const char *key, int amount) s = exifData[key].toString().c_str(); if (s && strlen (s) > 0) { - struct tm *tt; - char conv[1024]; - - memset (&conv, 0, sizeof (conv)); - tt = parse_exif_date (s); if (tt) { shift_time (tt, amount); - if (strftime (&conv[0], sizeof (conv), "%Y:%m:%d %H:%M:%S", tt)) { - exifData[key] = (const char *) &conv[0]; - res = TRUE; - } + st = format_exif_time (tt); + if (st) + exifData[key] = st; + g_free (st); g_free (tt); + res = TRUE; } } } @@ -545,6 +561,28 @@ shift_exif_time (Exiv2::ExifData& exifData, const char *key, int amount) return res; } +static gboolean +fake_exif_time (Exiv2::ExifData& exifData, const char *key, time_t datetime) +{ + struct tm *tt; + gchar *st; + gboolean res; + + res = FALSE; + try { + if (exifData[key].count() > 0) { + tt = localtime (&datetime); + st = format_exif_time (tt); + if (st) + exifData[key] = st; + g_free (st); + res = TRUE; + } + } catch (...) { } + + return res; +} + /* * modify_exif: - strip thumbnail stored in EXIF table * - write down overriden keys @@ -573,7 +611,7 @@ modify_exif (const gchar *filename, ExifData *exif, gboolean strip_thumbnail) modified = TRUE; } - if (exif->timezone_shift != 0 && !exifData.empty()) { + if (exif->timezone_shift != 0 && exif->fake_datetime != (time_t) -1 && !exifData.empty()) { /* need original data to calculate the shift from */ res = shift_exif_time (exifData, "Exif.Photo.DateTimeOriginal", exif->timezone_shift); res = shift_exif_time (exifData, "Exif.Photo.DateTimeDigitized", exif->timezone_shift) || res; @@ -582,6 +620,14 @@ modify_exif (const gchar *filename, ExifData *exif, gboolean strip_thumbnail) shift_exif_time (exifData, "Exif.Image.DateTime", exif->timezone_shift); modified = TRUE; } + + if (exif->fake_datetime != (time_t) -1 && !exifData.empty()) { + res = fake_exif_time (exifData, "Exif.Photo.DateTimeOriginal", exif->fake_datetime); + res = fake_exif_time (exifData, "Exif.Photo.DateTimeDigitized", exif->fake_datetime) || res; + if (! res) + fake_exif_time (exifData, "Exif.Image.DateTime", exif->fake_datetime); + modified = TRUE; + } } if (strip_thumbnail && ! exifData.empty()) { diff --git a/src/jpeg-utils.h b/src/jpeg-utils.h index 89a2cd4..cc6c5c7 100644 --- a/src/jpeg-utils.h +++ b/src/jpeg-utils.h @@ -52,6 +52,7 @@ typedef struct { gchar *override_copyright; int timezone_shift; + time_t fake_datetime; } ExifData; |
