Revision: 1298
          http://geeqie.svn.sourceforge.net/geeqie/?rev=1298&view=rev
Author:   nadvornik
Date:     2008-12-15 22:47:31 +0000 (Mon, 15 Dec 2008)

Log Message:
-----------
prepared infrastructure for delayed metadata writting - refreshing
metadata immediately before writting is now possible

modified metadata are stored in fd->modified_xmp

Modified Paths:
--------------
    trunk/src/exif-common.c
    trunk/src/exif.c
    trunk/src/exif.h
    trunk/src/exiv2.cc
    trunk/src/metadata.c
    trunk/src/typedefs.h

Modified: trunk/src/exif-common.c
===================================================================
--- trunk/src/exif-common.c     2008-12-15 18:04:42 UTC (rev 1297)
+++ trunk/src/exif-common.c     2008-12-15 22:47:31 UTC (rev 1298)
@@ -627,10 +627,27 @@
                        }
                }
 
-       fd->exif = exif_read(fd->path, sidecar_path);
+       fd->exif = exif_read(fd->path, sidecar_path, fd->modified_xmp);
        return fd->exif;
 }
 
+gint exif_write_fd(FileData *fd)
+{
+       gint success;
+       ExifData *exif;
+       
+       /*  exif_read_fd can either use cached metadata which have 
fd->modified_xmp already applied 
+                                    or read metadata from file and apply 
fd->modified_xmp
+           metadata are read also if the file was modified meanwhile */
+       exif = exif_read_fd(fd); 
+       if (!exif) return FALSE;
+       success = exif_write(exif); /* write modified metadata */
+       exif_free_fd(fd, exif);
+       g_hash_table_destroy(fd->modified_xmp);
+       fd->modified_xmp = NULL;
+       return success;
+}
+
 void exif_free_fd(FileData *fd, ExifData *exif)
 {
        if (!fd) return;

Modified: trunk/src/exif.c
===================================================================
--- trunk/src/exif.c    2008-12-15 18:04:42 UTC (rev 1297)
+++ trunk/src/exif.c    2008-12-15 22:47:31 UTC (rev 1298)
@@ -1209,7 +1209,7 @@
        g_free(exif);
 }
 
-ExifData *exif_read(gchar *path, gchar *sidecar_path)
+ExifData *exif_read(gchar *path, gchar *sidecar_path, GHashTable *modified_xmp)
 {
        ExifData *exif;
        gpointer f;
@@ -1584,22 +1584,12 @@
        return 0;
 }
 
-ExifItem *exif_add_item(ExifData *exif, const gchar *key)
-{
-       return NULL;
-}
 
-gint exif_item_delete(ExifData *exif, ExifItem *item)
+gint exif_update_metadata(ExifData *exif, const gchar *key, const GList 
*values)
 {
        return 0;
 }
 
-gint exif_item_set_string(ExifItem *item, const gchar *str)
-{
-       return 0;
-}
-
-
 typedef struct _UnmapData UnmapData;
 struct _UnmapData
 {

Modified: trunk/src/exif.h
===================================================================
--- trunk/src/exif.h    2008-12-15 18:04:42 UTC (rev 1297)
+++ trunk/src/exif.h    2008-12-15 22:47:31 UTC (rev 1298)
@@ -107,10 +107,11 @@
  *-----------------------------------------------------------------------------
  */
 
-ExifData *exif_read(gchar *path, gchar *sidecar_path);
+ExifData *exif_read(gchar *path, gchar *sidecar_path, GHashTable 
*modified_xmp);
 
 ExifData *exif_read_fd(FileData *fd);
 void exif_free_fd(FileData *fd, ExifData *exif);
+gint exif_write_fd(FileData *fd);
 
 /* exif_read returns processed data (merged from image and sidecar, etc.)
    this function gives access to the original data from the image.
@@ -125,7 +126,6 @@
 ExifRational *exif_get_rational(ExifData *exif, const gchar *key, gint *sign);
 
 ExifItem *exif_get_item(ExifData *exif, const gchar *key);
-ExifItem *exif_add_item(ExifData *exif, const gchar *key);
 ExifItem *exif_get_first_item(ExifData *exif);
 ExifItem *exif_get_next_item(ExifData *exif);
 
@@ -148,8 +148,7 @@
 
 gchar *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint 
*key_valid);
 
-gint exif_item_delete(ExifData *exif, ExifItem *item);
-gint exif_item_set_string(ExifItem *item, const gchar *str);
+gint exif_update_metadata(ExifData *exif, const gchar *key, const GList 
*values);
 
 guchar *exif_get_color_profile(ExifData *exif, guint *data_len);
 

Modified: trunk/src/exiv2.cc
===================================================================
--- trunk/src/exiv2.cc  2008-12-15 18:04:42 UTC (rev 1297)
+++ trunk/src/exiv2.cc  2008-12-15 22:47:31 UTC (rev 1298)
@@ -201,6 +201,10 @@
        }
 };
 
+extern "C" {
+static void _ExifDataProcessed_update_xmp(gpointer key, gpointer value, 
gpointer data);
+}
+
 // This allows read-write access to the metadata
 struct _ExifDataProcessed : public _ExifData
 {
@@ -215,7 +219,7 @@
 #endif
 
 public:
-       _ExifDataProcessed(gchar *path, gchar *sidecar_path)
+       _ExifDataProcessed(gchar *path, gchar *sidecar_path, GHashTable 
*modified_xmp)
        {
                imageData_ = new _ExifDataOriginal(path);
                sidecarData_ = NULL;
@@ -233,6 +237,10 @@
 #if EXIV2_TEST_VERSION(0,17,0)
                syncExifWithXmp(exifData_, xmpData_);
 #endif
+               if (modified_xmp)
+                       {
+                       g_hash_table_foreach(modified_xmp, 
_ExifDataProcessed_update_xmp, this);
+                       }
        }
 
        virtual ~_ExifDataProcessed()
@@ -326,11 +334,16 @@
 
 extern "C" {
 
-ExifData *exif_read(gchar *path, gchar *sidecar_path)
+static void _ExifDataProcessed_update_xmp(gpointer key, gpointer value, 
gpointer data)
 {
+       exif_update_metadata((ExifData *)data, (gchar *)key, (GList *)value);
+}
+
+ExifData *exif_read(gchar *path, gchar *sidecar_path, GHashTable *modified_xmp)
+{
        DEBUG_1("exif read %s, sidecar: %s", path, sidecar_path ? sidecar_path 
: "-");
        try {
-               return new _ExifDataProcessed(path, sidecar_path);
+               return new _ExifDataProcessed(path, sidecar_path, modified_xmp);
        }
        catch (Exiv2::AnyError& e) {
                std::cout << "Caught Exiv2 exception '" << e << "'\n";
@@ -731,49 +744,71 @@
        }
 }
 
-int exif_item_set_string(ExifItem *item, const char *str)
+gint exif_update_metadata(ExifData *exif, const gchar *key, const GList 
*values)
 {
        try {
-               if (!item) return 0;
-               ((Exiv2::Metadatum *)item)->setValue(std::string(str));
-               return 1;
+               const GList *work = values;
+
+               Exiv2::Metadatum *item = NULL;
+               try {
+                       Exiv2::ExifKey ekey(key);
+                       
+                       Exiv2::ExifData::iterator pos = 
exif->exifData().findKey(ekey);
+                       while (pos != exif->exifData().end())
+                               {
+                               exif->exifData().erase(pos);
+                               pos = exif->exifData().findKey(ekey);
+                               }
+
+                       while (work)
+                               {
+                               exif->exifData()[key] = (gchar *)work->data;
+                               work = work->next;
+                               }
                }
-       catch (Exiv2::AnyError& e) {
-               return 0;
-       }
-}
+               catch (Exiv2::AnyError& e) {
+                       try {
+                               Exiv2::IptcKey ekey(key);
+                               Exiv2::IptcData::iterator pos = 
exif->iptcData().findKey(ekey);
+                               while (pos != exif->iptcData().end())
+                                       {
+                                       exif->iptcData().erase(pos);
+                                       pos = exif->iptcData().findKey(ekey);
+                                       }
 
-int exif_item_delete(ExifData *exif, ExifItem *item)
-{
-       try {
-               if (!item) return 0;
-               for (Exiv2::ExifData::iterator i = exif->exifData().begin(); i 
!= exif->exifData().end(); ++i) {
-                       if (((Exiv2::Metadatum *)item) == &*i) {
-                               i = exif->exifData().erase(i);
-                               return 1;
+                               while (work)
+                                       {
+                                       exif->iptcData()[key] = (gchar 
*)work->data;
+                                       work = work->next;
+                                       }
                        }
-               }
-               for (Exiv2::IptcData::iterator i = exif->iptcData().begin(); i 
!= exif->iptcData().end(); ++i) {
-                       if (((Exiv2::Metadatum *)item) == &*i) {
-                               i = exif->iptcData().erase(i);
-                               return 1;
-                       }
-               }
+                       catch (Exiv2::AnyError& e) {
 #if EXIV2_TEST_VERSION(0,16,0)
-               for (Exiv2::XmpData::iterator i = exif->xmpData().begin(); i != 
exif->xmpData().end(); ++i) {
-                       if (((Exiv2::Metadatum *)item) == &*i) {
-                               i = exif->xmpData().erase(i);
-                               return 1;
+                               Exiv2::XmpKey ekey(key);
+                               Exiv2::XmpData::iterator pos = 
exif->xmpData().findKey(ekey);
+                               while (pos != exif->xmpData().end())
+                                       {
+                                       exif->xmpData().erase(pos);
+                                       pos = exif->xmpData().findKey(ekey);
+                                       }
+
+                               while (work)
+                                       {
+                                       exif->xmpData()[key] = (gchar 
*)work->data;
+                                       work = work->next;
+                                       }
+#endif
                        }
                }
-#endif
-               return 0;
+               return 1;
        }
        catch (Exiv2::AnyError& e) {
+               std::cout << "Caught Exiv2 exception '" << e << "'\n";
                return 0;
        }
 }
 
+
 void exif_add_jpeg_color_profile(ExifData *exif, unsigned char *cp_data, guint 
cp_length)
 {
        exif->add_jpeg_color_profile(cp_data, cp_length);

Modified: trunk/src/metadata.c
===================================================================
--- trunk/src/metadata.c        2008-12-15 18:04:42 UTC (rev 1297)
+++ trunk/src/metadata.c        2008-12-15 22:47:31 UTC (rev 1298)
@@ -30,6 +30,26 @@
 } MetadataKey;
 
 
+gint metadata_write_list(FileData *fd, const gchar *key, GList *values)
+{
+       if (!fd->modified_xmp)
+               {
+               fd->modified_xmp = g_hash_table_new_full(g_str_hash, 
g_str_equal, g_free, (GDestroyNotify)string_list_free);
+               }
+       g_hash_table_insert(fd->modified_xmp, g_strdup(key), values);
+       if (fd->exif)
+               {
+               exif_update_metadata(fd->exif, key, values);
+               }
+       return TRUE;
+}
+       
+gint metadata_write_string(FileData *fd, const gchar *key, const char *value)
+{
+       return metadata_write_list(fd, key, g_list_append(NULL, 
g_strdup(value)));
+}
+
+
 /*
  *-------------------------------------------------------------------
  * keyword / comment read/write
@@ -341,47 +361,17 @@
 
 static gint metadata_xmp_write(FileData *fd, GList *keywords, const gchar 
*comment)
 {
-       gint success;
+       gint success = TRUE;
        gint write_comment = (comment && comment[0]);
-       ExifData *exif;
-       ExifItem *item;
 
-       exif = exif_read_fd(fd);
-       if (!exif) return FALSE;
+       if (write_comment) success = success && metadata_write_string(fd, 
COMMENT_KEY, comment);
+       
+       if (keywords) success = success && metadata_write_list(fd, KEYWORD_KEY, 
string_list_copy(keywords));
 
-       item = exif_get_item(exif, COMMENT_KEY);
-       if (item && !write_comment)
-               {
-               exif_item_delete(exif, item);
-               item = NULL;
-               }
 
-       if (!item && write_comment) item = exif_add_item(exif, COMMENT_KEY);
-       if (item) exif_item_set_string(item, comment);
+/* FIXME - actual writting should be triggered in metadata_write_list and 
should be delayed */
+       success = exif_write_fd(fd);
 
-       while ((item = exif_get_item(exif, KEYWORD_KEY)))
-               {
-               exif_item_delete(exif, item);
-               }
-
-       if (keywords)
-               {
-               GList *work;
-
-               item = exif_add_item(exif, KEYWORD_KEY);
-
-               work = keywords;
-               while (work)
-                       {
-                       exif_item_set_string(item, (gchar *) work->data);
-                       work = work->next;
-                       }
-               }
-
-       success = exif_write(exif);
-
-       exif_free_fd(fd, exif);
-
        return success;
 }
 

Modified: trunk/src/typedefs.h
===================================================================
--- trunk/src/typedefs.h        2008-12-15 18:04:42 UTC (rev 1297)
+++ trunk/src/typedefs.h        2008-12-15 22:47:31 UTC (rev 1298)
@@ -440,6 +440,7 @@
        gint exif_orientation;
        
        ExifData *exif;
+       GHashTable *modified_xmp; // hash table which contains unwritten xmp 
metadata in format: key->list of string values
 };
 
 struct _LayoutWindow


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn

Reply via email to