diff options
| -rw-r--r-- | sample/src/setup.xml | 2 | ||||
| -rw-r--r-- | src/jpeg-utils.cpp | 81 |
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; } } |
