summaryrefslogtreecommitdiff
path: root/src/jpeg-utils.cpp
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2013-03-16 19:16:18 +0100
committerTomas Bzatek <tbzatek@users.sourceforge.net>2013-03-16 19:16:18 +0100
commitc5cb4c32d746fd0e0648b386f5528fee7e39b731 (patch)
tree7382dddff3f70152a73eb1e14a2327bbd782adca /src/jpeg-utils.cpp
parent13459096ccf173a4251b4e1ad6fdebaf61b33afd (diff)
downloadcataract-c5cb4c32d746fd0e0648b386f5528fee7e39b731.tar.xz
Support IPTC timestamps when shifting or faking
There are more date-related IPTC tags in the specs but so far I haven't seen anything else than Iptc.Application2.{Date,Time}Created
Diffstat (limited to 'src/jpeg-utils.cpp')
-rw-r--r--src/jpeg-utils.cpp118
1 files changed, 99 insertions, 19 deletions
diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp
index 646763a..6483563 100644
--- a/src/jpeg-utils.cpp
+++ b/src/jpeg-utils.cpp
@@ -155,6 +155,20 @@ get_real_key_name (const gchar *key)
return key;
}
+static gboolean
+iptc_has_key (Exiv2::IptcData iptcData, const char *key)
+{
+ Exiv2::IptcData::const_iterator md;
+
+ if (! iptcData.empty()) {
+ md = iptcData.findKey(Exiv2::IptcKey(std::string(key)));
+ if (md != iptcData.end() && iptcData[key].count() > 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
/*
* Retrieves value of the specified key or NULL if the key does not exist.
* The key argument belongs to Exiv2 namespace - see http://exiv2.org/tags.html
@@ -181,7 +195,7 @@ get_exif_data (ExifData *exif, const gchar *key)
if (g_str_has_prefix (key, "Iptc.")) {
Exiv2::IptcData &iptcData = exif->priv->image->iptcData();
- if (! iptcData.empty()) {
+ if (iptc_has_key (iptcData, key)) {
return g_strdup (iptcData[key].toString().c_str());
}
}
@@ -329,7 +343,7 @@ exif_has_key (ExifData *exif, const gchar *key)
if (g_str_has_prefix (key, "Iptc.")) {
Exiv2::IptcData &iptcData = exif->priv->image->iptcData();
- return !iptcData.empty() && iptcData[key].count() > 0;
+ return iptc_has_key (iptcData, key);
}
return FALSE;
@@ -562,7 +576,39 @@ shift_exif_time (Exiv2::ExifData& exifData, const char *key, int amount)
}
static gboolean
-fake_exif_time (Exiv2::ExifData& exifData, const char *key, time_t datetime)
+shift_iptc_time (Exiv2::IptcData &iptcData, int amount)
+{
+ struct tm *tt;
+ long int orig_time;
+ gboolean res;
+ Exiv2::DateValue dval;
+ Exiv2::TimeValue tval;
+
+ res = FALSE;
+ if (iptc_has_key (iptcData, "Iptc.Application2.DateCreated") ||
+ iptc_has_key (iptcData, "Iptc.Application2.TimeCreated")) {
+ orig_time = (iptc_has_key (iptcData, "Iptc.Application2.DateCreated") ? iptcData["Iptc.Application2.DateCreated"].toLong() : 0) +
+ (iptc_has_key (iptcData, "Iptc.Application2.TimeCreated") ? iptcData["Iptc.Application2.TimeCreated"].toLong() : 0);
+ if (orig_time > 0) {
+ orig_time += amount * 60;
+ tt = localtime (&orig_time);
+ mktime (tt);
+ if (tt->tm_isdst)
+ shift_time (tt, -60);
+
+ dval = Exiv2::DateValue(tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday);
+ tval = Exiv2::TimeValue(tt->tm_hour, tt->tm_min, tt->tm_sec, 0, 0);
+ iptcData["Iptc.Application2.DateCreated"].setValue(&dval);
+ iptcData["Iptc.Application2.TimeCreated"].setValue(&tval);
+ res = TRUE;
+ }
+ }
+
+ return res;
+}
+
+static gboolean
+fake_exif_time (Exiv2::ExifData &exifData, const char *key, time_t datetime)
{
struct tm *tt;
gchar *st;
@@ -583,6 +629,21 @@ fake_exif_time (Exiv2::ExifData& exifData, const char *key, time_t datetime)
return res;
}
+static void
+fake_iptc_time (Exiv2::IptcData &iptcData, time_t datetime)
+{
+ struct tm *tt;
+ Exiv2::DateValue dval;
+ Exiv2::TimeValue tval;
+
+ tt = localtime (&datetime);
+
+ dval = Exiv2::DateValue(tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday);
+ tval = Exiv2::TimeValue(tt->tm_hour, tt->tm_min, tt->tm_sec, 0, 0);
+ iptcData["Iptc.Application2.DateCreated"].setValue(&dval);
+ iptcData["Iptc.Application2.TimeCreated"].setValue(&tval);
+}
+
/*
* modify_exif: - strip thumbnail stored in EXIF table
* - write down overriden keys
@@ -603,33 +664,52 @@ modify_exif (const gchar *filename, ExifData *exif, gboolean strip_thumbnail)
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
+ Exiv2::IptcData &iptcData = image->iptcData();
if (exif) {
if (exif->override_copyright) {
- exifData["Exif.Image.Copyright"] = exif->override_copyright;
- image->iptcData()["Iptc.Application2.Copyright"] = exif->override_copyright;
- modified = TRUE;
+ if (! exifData.empty()) {
+ exifData["Exif.Image.Copyright"] = exif->override_copyright;
+ modified = TRUE;
+ }
+ if (! iptcData.empty()) {
+ iptcData["Iptc.Application2.Copyright"] = exif->override_copyright;
+ modified = TRUE;
+ }
}
- 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;
- if (! res)
- /* usually a modification date, shift as a last option */
- shift_exif_time (exifData, "Exif.Image.DateTime", exif->timezone_shift);
- modified = TRUE;
+ if (exif->timezone_shift != 0 && exif->fake_datetime == (time_t) -1) {
+ if (! exifData.empty()) {
+ res = shift_exif_time (exifData, "Exif.Photo.DateTimeOriginal", exif->timezone_shift);
+ res = shift_exif_time (exifData, "Exif.Photo.DateTimeDigitized", exif->timezone_shift) || res;
+ if (! res)
+ /* usually a modification date, shift as a last option */
+ shift_exif_time (exifData, "Exif.Image.DateTime", exif->timezone_shift);
+ modified = TRUE;
+ }
+ if (! iptcData.empty()) {
+ res = shift_iptc_time (iptcData, exif->timezone_shift);
+ if (res)
+ 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 (! 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 (! iptcData.empty()) {
+ fake_iptc_time (iptcData, exif->fake_datetime);
+ modified = TRUE;
+ }
}
}
+
if (strip_thumbnail && ! exifData.empty()) {
#ifdef HAVE_EXIFTHUMB
Exiv2::ExifThumb exifThumb(image->exifData());