summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sample/src/setup.xml2
-rw-r--r--src/jpeg-utils.cpp81
2 files changed, 82 insertions, 1 deletions
diff --git a/sample/src/setup.xml b/sample/src/setup.xml
index 6b55c16..a2bb2b2 100644
--- a/sample/src/setup.xml
+++ b/sample/src/setup.xml
@@ -32,6 +32,8 @@
<!-- in case of supplied external EXIF data, shall these be written in generated images? -->
<!-- This will make image files carry the same data as used for pages -->
<!-- (allowed values: "yes", "no") default = "no" as this could overwrite important data -->
+ <!-- WARNING: this may possibly import mismatching metadata -->
+ <!-- (think of source RAW file vs. processed JPEG image differences) -->
<write_supplied_exif value="no" />
<!-- don't copy full size (original) images -->
diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp
index e0c4fdf..965d751 100644
--- a/src/jpeg-utils.cpp
+++ b/src/jpeg-utils.cpp
@@ -722,6 +722,85 @@ override_iptc_time (Exiv2::IptcData &iptcData, const char *date_key, const char
return FALSE;
}
+
+/* List of tags we don't want to copy from external EXIF data since they are related to the RAW file,
+ * not the processed image. Note that this list is not by far complete.
+ */
+static const gchar * image_size_tags[] = {
+ "Exif.Image.ImageWidth",
+ "Exif.Image.ImageHeight",
+ "Exif.Image.ImageLength",
+ "Exif.Image.Orientation",
+ "Exif.Photo.PixelXDimension",
+ "Exif.Photo.PixelYDimension",
+ "Exif.Image.XResolution",
+ "Exif.Image.YResolution",
+ "Exif.Image.ResolutionUnit",
+ "Exif.Image.Compression",
+ "Exif.Image.BitsPerSample",
+ "Exif.Image.SamplesPerPixel",
+ "Exif.Photo.ComponentsConfiguration",
+ "Exif.Photo.CompressedBitsPerPixel",
+ "Exif.Image.JPEGTables",
+ "Exif.Image.JPEGProc",
+ "Exif.Image.JPEGInterchangeFormat",
+ "Exif.Image.JPEGInterchangeFormatLength",
+ "Exif.Image.JPEGRestartInterval",
+ "Exif.Image.JPEGLosslessPredictors",
+ "Exif.Image.JPEGPointTransforms",
+ "Exif.Image.JPEGQTables",
+ "Exif.Image.JPEGDCTables",
+ "Exif.Image.JPEGACTables",
+ "Exif.Image.YCbCrCoefficients",
+ "Exif.Image.YCbCrSubSampling",
+ "Exif.Image.YCbCrPositioning",
+ "Exif.Image.ReferenceBlackWhite",
+ "Exif.Image.PhotometricInterpretation",
+ "Exif.Image.PlanarConfiguration",
+};
+
+static gboolean
+is_image_size_tag (const gchar *s)
+{
+ unsigned int i;
+
+ for (i = 0; i < G_N_ELEMENTS (image_size_tags); i++)
+ if (g_str_equal (s, image_size_tags[i]))
+ return TRUE;
+ return FALSE;
+}
+
+static void
+copy_metadata (Exiv2::Image::AutoPtr &img, Exiv2::Image::AutoPtr &external_img)
+{
+ Exiv2::ExifData exifData;
+ Exiv2::ExifData &img_exifData = img->exifData();
+ Exiv2::ExifData &ext_exifData = external_img->exifData();
+
+ /* First copy metadata from the external image excluding size tags */
+ Exiv2::ExifData::const_iterator end = ext_exifData.end();
+ for (Exiv2::ExifData::const_iterator i = ext_exifData.begin(); i != end; ++i) {
+ gchar *s = g_strdup (i->key().c_str());
+ if (! is_image_size_tag (s))
+ exifData[s] = ext_exifData[s];
+ g_free (s);
+ }
+
+ /* Copy selected size tags from the processed image */
+ end = img_exifData.end();
+ for (Exiv2::ExifData::const_iterator i = img_exifData.begin(); i != end; ++i) {
+ gchar *s = g_strdup (i->key().c_str());
+ if (is_image_size_tag (s))
+ exifData[s] = img_exifData[s];
+ g_free (s);
+ }
+
+ img->setMetadata (*external_img);
+ img->setExifData (exifData);
+}
+
+
+
/*
* modify_exif: - strip thumbnail stored in EXIF table
* - write down overriden keys
@@ -750,7 +829,7 @@ modify_exif (const gchar *filename, ExifData *exif, gboolean strip_thumbnail, gb
if (ext_image.get() != 0) {
ext_image->clearMetadata();
ext_image->readMetadata();
- image->setMetadata (*ext_image);
+ copy_metadata (image, ext_image);
modified = TRUE;
}
}