Revision: 1164
http://geeqie.svn.sourceforge.net/geeqie/?rev=1164&view=rev
Author: nadvornik
Date: 2008-10-18 18:22:57 +0000 (Sat, 18 Oct 2008)
Log Message:
-----------
infrastructure for preprocessing of metadata
Modified Paths:
--------------
trunk/src/bar_exif.c
trunk/src/exif.c
trunk/src/exif.h
trunk/src/exiv2.cc
Modified: trunk/src/bar_exif.c
===================================================================
--- trunk/src/bar_exif.c 2008-10-18 09:07:52 UTC (rev 1163)
+++ trunk/src/bar_exif.c 2008-10-18 18:22:57 UTC (rev 1164)
@@ -180,16 +180,27 @@
static void bar_exif_update(ExifBar *eb)
{
+ ExifData *exif_processed;
ExifData *exif;
gint i;
- exif = exif_read_fd(eb->fd);
+ exif_processed = exif_read_fd(eb->fd);
- if (!exif)
+ if (!exif_processed)
{
bar_exif_sensitive(eb, FALSE);
return;
}
+
+ if (eb->advanced_scrolled)
+ {
+ /* show the original values from the file */
+ exif = exif_get_original(exif_processed);
+ }
+ else
+ {
+ exif = exif_processed;
+ }
bar_exif_sensitive(eb, TRUE);
@@ -334,7 +345,7 @@
}
}
- exif_free_fd(eb->fd, exif);
+ exif_free_fd(eb->fd, exif_processed);
}
static void bar_exif_clear(ExifBar *eb)
Modified: trunk/src/exif.c
===================================================================
--- trunk/src/exif.c 2008-10-18 09:07:52 UTC (rev 1163)
+++ trunk/src/exif.c 2008-10-18 18:22:57 UTC (rev 1164)
@@ -1185,6 +1185,11 @@
return 0;
}
+ExifData *exif_get_original(ExifData *processed)
+{
+ return processed;
+}
+
void exif_free(ExifData *exif)
{
GList *work;
Modified: trunk/src/exif.h
===================================================================
--- trunk/src/exif.h 2008-10-18 09:07:52 UTC (rev 1163)
+++ trunk/src/exif.h 2008-10-18 18:22:57 UTC (rev 1164)
@@ -110,6 +110,10 @@
ExifData *exif_read_fd(FileData *fd);
void exif_free_fd(FileData *fd, ExifData *exif);
+/* exif_read returns processed data (merged from image and sidecar, etc.)
+ this function gives access to the original data from the image.
+ original data are part of the processed data and should not be freed
separately */
+ExifData *exif_get_original(ExifData *processed);
gint exif_write(ExifData *exif);
void exif_free(ExifData *exif);
Modified: trunk/src/exiv2.cc
===================================================================
--- trunk/src/exiv2.cc 2008-10-18 09:07:52 UTC (rev 1163)
+++ trunk/src/exiv2.cc 2008-10-18 18:22:57 UTC (rev 1164)
@@ -61,48 +61,77 @@
struct _ExifData
{
- Exiv2::Image::AutoPtr image;
- Exiv2::Image::AutoPtr sidecar;
Exiv2::ExifData::const_iterator exifIter; /* for exif_get_next_item */
Exiv2::IptcData::const_iterator iptcIter; /* for exif_get_next_item */
#if EXIV2_TEST_VERSION(0,16,0)
Exiv2::XmpData::const_iterator xmpIter; /* for exif_get_next_item */
#endif
- bool have_sidecar;
+ virtual ~_ExifData()
+ {
+ }
+
+ virtual void writeMetadata()
+ {
+ g_critical("Unsupported method of writing metadata");
+ }
+
+ virtual ExifData *original()
+ {
+ return NULL;
+ }
+
+ virtual Exiv2::Image *image() = 0;
+
+ virtual Exiv2::ExifData &exifData() = 0;
+
+ virtual Exiv2::IptcData &iptcData() = 0;
+
+#if EXIV2_TEST_VERSION(0,16,0)
+ virtual Exiv2::XmpData &xmpData() = 0;
+#endif
+
+ virtual void add_jpeg_color_profile(unsigned char *cp_data, guint
cp_length) = 0;
+
+ virtual guchar *get_jpeg_color_profile(guint *data_len) = 0;
+};
+
+// This allows read-only access to the original metadata
+struct _ExifDataOriginal : public _ExifData
+{
+protected:
+ Exiv2::Image::AutoPtr image_;
+
/* the icc profile in jpeg is not technically exif - store it here */
- unsigned char *cp_data;
- guint cp_length;
+ unsigned char *cp_data_;
+ guint cp_length_;
- _ExifData(gchar *path, gchar *sidecar_path)
+public:
+
+ _ExifDataOriginal(gchar *path)
{
- have_sidecar = false;
- cp_data = NULL;
- cp_length = 0;
+ cp_data_ = NULL;
+ cp_length_ = 0;
gchar *pathl = path_from_utf8(path);
- image = Exiv2::ImageFactory::open(pathl);
+ image_ = Exiv2::ImageFactory::open(pathl);
g_free(pathl);
// g_assert (image.get() != 0);
- image->readMetadata();
+ image_->readMetadata();
#if EXIV2_TEST_VERSION(0,16,0)
- DEBUG_2("xmp count %li", image->xmpData().count());
- if (sidecar_path && image->xmpData().empty())
+ if (image_->mimeType() == "application/rdf+xml")
{
- gchar *sidecar_pathl = path_from_utf8(sidecar_path);
- sidecar = Exiv2::ImageFactory::open(sidecar_pathl);
- g_free(sidecar_pathl);
- sidecar->readMetadata();
- have_sidecar = sidecar->good();
- DEBUG_2("sidecar xmp count %li",
sidecar->xmpData().count());
+ //Exiv2 sidecar converts xmp to exif and iptc, we don't
want it.
+ image_->clearExifData();
+ image_->clearIptcData();
}
+#endif
-#endif
#if EXIV2_TEST_VERSION(0,14,0)
- if (image->mimeType() == std::string("image/jpeg"))
+ if (image_->mimeType() == "image/jpeg")
{
/* try to get jpeg color profile */
- Exiv2::BasicIo &io = image->io();
+ Exiv2::BasicIo &io = image_->io();
gint open = io.isopen();
if (!open) io.open();
unsigned char *mapped = (unsigned char*)io.mmap();
@@ -113,43 +142,156 @@
#endif
}
- ~_ExifData()
+ virtual ~_ExifDataOriginal()
{
- if (cp_data) g_free(cp_data);
+ if (cp_data_) g_free(cp_data_);
}
- void writeMetadata()
+ virtual Exiv2::Image *image()
{
- if (have_sidecar) sidecar->writeMetadata();
- image->writeMetadata();
+ return image_.get();
}
- Exiv2::ExifData &exifData ()
+ virtual Exiv2::ExifData &exifData ()
{
- return image->exifData();
+ return image_->exifData();
}
- Exiv2::IptcData &iptcData ()
+ virtual Exiv2::IptcData &iptcData ()
{
- return image->iptcData();
+ return image_->iptcData();
}
#if EXIV2_TEST_VERSION(0,16,0)
- Exiv2::XmpData &xmpData ()
+ virtual Exiv2::XmpData &xmpData ()
{
- return have_sidecar ? sidecar->xmpData() : image->xmpData();
+ return image_->xmpData();
}
#endif
+ virtual void add_jpeg_color_profile(unsigned char *cp_data, guint
cp_length)
+ {
+ if (cp_data_) g_free(cp_data_);
+ cp_data_ = cp_data;
+ cp_length_ = cp_length;
+ }
+
+ virtual guchar *get_jpeg_color_profile(guint *data_len)
+ {
+ if (cp_data_)
+ {
+ if (data_len) *data_len = cp_length_;
+ return (unsigned char *) g_memdup(cp_data_, cp_length_);
+ }
+ return NULL;
+ }
};
+// This allows read-write access to the metadata
+struct _ExifDataProcessed : public _ExifData
+{
+protected:
+ _ExifDataOriginal *imageData_;
+ _ExifDataOriginal *sidecarData_;
+
+ Exiv2::ExifData exifData_;
+ Exiv2::IptcData iptcData_;
+#if EXIV2_TEST_VERSION(0,16,0)
+ Exiv2::XmpData xmpData_;
+#endif
+
+public:
+ _ExifDataProcessed(gchar *path, gchar *sidecar_path)
+ {
+ imageData_ = new _ExifDataOriginal(path);
+ sidecarData_ = NULL;
+#if EXIV2_TEST_VERSION(0,16,0)
+ xmpData_ = imageData_->xmpData();
+ DEBUG_2("xmp count %li", xmpData_.count());
+ if (sidecar_path && xmpData_.empty())
+ {
+ sidecarData_ = new _ExifDataOriginal(sidecar_path);
+ xmpData_ = sidecarData_->xmpData();
+ }
+#endif
+ exifData_ = imageData_->exifData();
+ iptcData_ = imageData_->iptcData();
+ }
+
+ virtual ~_ExifDataProcessed()
+ {
+ if (imageData_) delete imageData_;
+ if (sidecarData_) delete sidecarData_;
+ }
+
+ virtual ExifData *original()
+ {
+ return imageData_;
+ }
+
+ virtual void writeMetadata()
+ {
+
+ if (sidecarData_)
+ {
+ sidecarData_->image()->setXmpData(xmpData_);
+ //Exiv2 sidecar converts xmp to exif and iptc, we don't
want it.
+ sidecarData_->image()->clearExifData();
+ sidecarData_->image()->clearIptcData();
+ sidecarData_->image()->writeMetadata();
+ }
+ else
+ {
+ imageData_->image()->setExifData(exifData_);
+ imageData_->image()->setIptcData(iptcData_);
+ imageData_->image()->setXmpData(xmpData_);
+ imageData_->image()->writeMetadata();
+ }
+ }
+
+ virtual Exiv2::Image *image()
+ {
+ return imageData_->image();
+ }
+
+ virtual Exiv2::ExifData &exifData ()
+ {
+ return exifData_;
+ }
+
+ virtual Exiv2::IptcData &iptcData ()
+ {
+ return iptcData_;
+ }
+
+#if EXIV2_TEST_VERSION(0,16,0)
+ virtual Exiv2::XmpData &xmpData ()
+ {
+ return xmpData_;
+ }
+#endif
+
+ virtual void add_jpeg_color_profile(unsigned char *cp_data, guint
cp_length)
+ {
+ imageData_->add_jpeg_color_profile(cp_data, cp_length);
+ }
+
+ virtual guchar *get_jpeg_color_profile(guint *data_len)
+ {
+ return imageData_->get_jpeg_color_profile(data_len);
+ }
+};
+
+
+
+
extern "C" {
ExifData *exif_read(gchar *path, gchar *sidecar_path)
{
DEBUG_1("exif read %s, sidecar: %s", path, sidecar_path ? sidecar_path
: "-");
try {
- return new ExifData(path, sidecar_path);
+ return new _ExifDataProcessed(path, sidecar_path);
}
catch (Exiv2::AnyError& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
@@ -174,10 +316,16 @@
void exif_free(ExifData *exif)
{
-
+ g_assert(dynamic_cast<_ExifDataProcessed *>(exif)); // this should not
be called on ExifDataOriginal
delete exif;
}
+ExifData *exif_get_original(ExifData *exif)
+{
+ return exif->original();
+}
+
+
ExifItem *exif_get_item(ExifData *exif, const gchar *key)
{
try {
@@ -588,22 +736,18 @@
void exif_add_jpeg_color_profile(ExifData *exif, unsigned char *cp_data, guint
cp_length)
{
- if (exif->cp_data) g_free(exif->cp_data);
- exif->cp_data = cp_data;
- exif->cp_length =cp_length;
+ exif->add_jpeg_color_profile(cp_data, cp_length);
}
guchar *exif_get_color_profile(ExifData *exif, guint *data_len)
{
- if (exif->cp_data)
- {
- if (data_len) *data_len = exif->cp_length;
- return (unsigned char *) g_memdup(exif->cp_data,
exif->cp_length);
- }
+ guchar *ret = exif->get_jpeg_color_profile(data_len);
+ if (ret) return ret;
+
ExifItem *prof_item = exif_get_item(exif,
"Exif.Image.InterColorProfile");
if (prof_item && exif_item_get_format_id(prof_item) ==
EXIF_FORMAT_UNDEFINED)
- return (unsigned char *) exif_item_get_data(prof_item,
data_len);
- return NULL;
+ ret = (guchar *)exif_item_get_data(prof_item, data_len);
+ return ret;
}
#if EXIV2_TEST_VERSION(0,17,90)
@@ -612,7 +756,7 @@
{
if (!exif) return NULL;
- const char* path = exif->image->io().path().c_str();
+ const char* path = exif->image()->io().path().c_str();
/* given image pathname, first do simple (and fast) file extension test
*/
gboolean is_raw = filter_file_class(path, FORMAT_CLASS_RAWIMAGE);
@@ -620,7 +764,7 @@
try {
- Exiv2::PreviewManager pm(*exif->image);
+ Exiv2::PreviewManager pm(*exif->image());
Exiv2::PreviewPropertiesList list = pm.getPreviewProperties();
@@ -712,7 +856,7 @@
unsigned long offset;
if (!exif) return NULL;
- const char* path = exif->image->io().path().c_str();
+ const char* path = exif->image()->io().path().c_str();
/* given image pathname, first do simple (and fast) file extension test
*/
if (!filter_file_class(path, FORMAT_CLASS_RAWIMAGE)) return NULL;
@@ -724,7 +868,7 @@
UnmapData *ud;
int fd;
- RawFile rf(exif->image->io());
+ RawFile rf(exif->image()->io());
offset = rf.preview_offset();
DEBUG_1("%s: offset %lu", path, offset);
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn