summaryrefslogtreecommitdiff
path: root/src/jpeg-utils.cpp
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2015-08-29 16:09:11 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2015-08-29 16:09:11 +0200
commit5879c2a9aa8daf148d6ef7694f5e959c5207f40f (patch)
treea91e2e0a06a45ecb3748407402a1df1f51dada56 /src/jpeg-utils.cpp
parent9f927315eb2536ac37d67ed304c02bcd4ea755c9 (diff)
downloadcataract-5879c2a9aa8daf148d6ef7694f5e959c5207f40f.tar.xz
jpeg-utils: Filter out certain tags from external EXIF file
Turned out that we shouldn't blindly copy all metadata from the supplied external EXIF file since they belong to a different image. This includes image size, JPEG compression parameters, rotation etc. This commit adds tag filtering so that not all tags are copied, retaining the important ones from the gallery image. The list of retained tags is by no means complete and is subject to future tweaks. For the moment this feature is recommended to be turned off (and is by default).
Diffstat (limited to 'src/jpeg-utils.cpp')
-rw-r--r--src/jpeg-utils.cpp81
1 files changed, 80 insertions, 1 deletions
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;
}
}