summaryrefslogtreecommitdiff
path: root/src/jpeg-utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jpeg-utils.cpp')
-rw-r--r--src/jpeg-utils.cpp112
1 files changed, 79 insertions, 33 deletions
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()) {