Annotate debug_exception() with source file, line, and function.
[geeqie.git] / src / exiv2.cc
index edb1c0b..455c8d3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Geeqie
- * Copyright (C) 2008 - 2009 The Geeqie Team
+ * Copyright (C) 2008 - 2012 The Geeqie Team
  *
  * Author: Vladimir Nadvornik
  *
@@ -76,12 +76,42 @@ struct _AltKey
 
 /* this is a list of keys that should be converted, even with the older Exiv2 which does not support it directly */
 static const AltKey alt_keys[] = {
-       {"Xmp.tiff.Orientation", "Exif.Image.Orientation", NULL},
-       {"Xmp.dc.subject", NULL, "Iptc.Application2.Keywords"},
-       {"Xmp.dc.description", NULL, "Iptc.Application2.Caption"},
+       {"Xmp.tiff.Orientation",                "Exif.Image.Orientation",       NULL},
+       {"Xmp.dc.title",                        NULL,                           "Iptc.Application2.ObjectName"          },
+       {"Xmp.photoshop.Urgency",               NULL,                           "Iptc.Application2.Urgency"             },
+       {"Xmp.photoshop.Category",              NULL,                           "Iptc.Application2.Category"            },
+       {"Xmp.photoshop.SupplementalCategory",  NULL,                           "Iptc.Application2.SuppCategory"        },
+       {"Xmp.dc.subject",                      NULL,                           "Iptc.Application2.Keywords"            },
+       {"Xmp.iptc.Location",                   NULL,                           "Iptc.Application2.LocationName"        },
+       {"Xmp.photoshop.Instruction",           NULL,                           "Iptc.Application2.SpecialInstructions" },
+       {"Xmp.photoshop.DateCreated",           NULL,                           "Iptc.Application2.DateCreated"         },
+       {"Xmp.dc.creator",                      NULL,                           "Iptc.Application2.Byline"              },
+       {"Xmp.photoshop.AuthorsPosition",       NULL,                           "Iptc.Application2.BylineTitle"         },
+       {"Xmp.photoshop.City",                  NULL,                           "Iptc.Application2.City"                },
+       {"Xmp.photoshop.State",                 NULL,                           "Iptc.Application2.ProvinceState"       },
+       {"Xmp.iptc.CountryCode",                NULL,                           "Iptc.Application2.CountryCode"         },
+       {"Xmp.photoshop.Country",               NULL,                           "Iptc.Application2.CountryName"         },
+       {"Xmp.photoshop.TransmissionReference", NULL,                           "Iptc.Application2.TransmissionReference"},
+       {"Xmp.photoshop.Headline",              NULL,                           "Iptc.Application2.Headline"            },
+       {"Xmp.photoshop.Credit",                NULL,                           "Iptc.Application2.Credit"              },
+       {"Xmp.photoshop.Source",                NULL,                           "Iptc.Application2.Source"              },
+       {"Xmp.dc.rights",                       NULL,                           "Iptc.Application2.Copyright"           },
+       {"Xmp.dc.description",                  NULL,                           "Iptc.Application2.Caption"             },
+       {"Xmp.photoshop.CaptionWriter",         NULL,                           "Iptc.Application2.Writer"              },
        {NULL, NULL, NULL}
        };
 
+static void _debug_exception(const char* file,
+                             int line,
+                             const char* func,
+                             Exiv2::AnyError& e)
+{
+       gchar *str = g_locale_from_utf8(e.what(), -1, NULL, NULL, NULL);
+       DEBUG_1("%s:%d:%s:Exiv2: %s", file, line, func, str);
+       g_free(str);
+}
+
+#define debug_exception(e) _debug_exception(__FILE__, __LINE__, __func__, e)
 
 struct _ExifData
 {
@@ -278,7 +308,14 @@ public:
                exifData_ = imageData_->exifData();
                iptcData_ = imageData_->iptcData();
 #if EXIV2_TEST_VERSION(0,17,0)
-               syncExifWithXmp(exifData_, xmpData_);
+               try
+                       {
+                       syncExifWithXmp(exifData_, xmpData_);
+                       }
+               catch (...)
+                       {
+                       DEBUG_1("Exiv2: Catching bug\n");
+                       }
 #endif
                if (modified_xmp)
                        {
@@ -396,7 +433,7 @@ ExifData *exif_read(gchar *path, gchar *sidecar_path, GHashTable *modified_xmp)
                return new _ExifDataProcessed(path, sidecar_path, modified_xmp);
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
        
@@ -409,7 +446,7 @@ gboolean exif_write(ExifData *exif)
                return TRUE;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return FALSE;
        }
 }
@@ -421,7 +458,7 @@ gboolean exif_write_sidecar(ExifData *exif, gchar *path)
                return TRUE;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return FALSE;
        }
        
@@ -470,7 +507,7 @@ ExifItem *exif_get_item(ExifData *exif, const gchar *key)
                return (ExifItem *)item;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -507,7 +544,7 @@ ExifItem *exif_add_item(ExifData *exif, const gchar *key)
                return (ExifItem *)item;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -545,7 +582,7 @@ ExifItem *exif_get_first_item(ExifData *exif)
                        
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -576,7 +613,7 @@ ExifItem *exif_get_next_item(ExifData *exif)
                return NULL;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -588,7 +625,7 @@ char *exif_item_get_tag_name(ExifItem *item)
                return g_strdup(((Exiv2::Metadatum *)item)->key().c_str());
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -600,7 +637,7 @@ guint exif_item_get_tag_id(ExifItem *item)
                return ((Exiv2::Metadatum *)item)->tag();
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return 0;
        }
 }
@@ -612,7 +649,7 @@ guint exif_item_get_elements(ExifItem *item)
                return ((Exiv2::Metadatum *)item)->count();
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return 0;
        }
 }
@@ -629,7 +666,7 @@ char *exif_item_get_data(ExifItem *item, guint *data_len)
                return data;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -641,7 +678,7 @@ char *exif_item_get_description(ExifItem *item)
                return utf8_validate_or_convert(((Exiv2::Metadatum *)item)->tagLabel().c_str());
        }
        catch (std::exception& e) {
-//             std::cout << "Caught Exiv2 exception '" << e << "'\n";
+//             debug_exception(e);
                return NULL;
        }
 }
@@ -688,7 +725,7 @@ guint exif_item_get_format_id(ExifItem *item)
                return format_id_trans_tbl[id];
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return EXIF_FORMAT_UNKNOWN;
        }
 }
@@ -700,7 +737,7 @@ const char *exif_item_get_format_name(ExifItem *item, gboolean brief)
                return ((Exiv2::Metadatum *)item)->typeName();
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -765,12 +802,12 @@ gchar *exif_item_get_string(ExifItem *item, int idx)
 gint exif_item_get_integer(ExifItem *item, gint *value)
 {
        try {
-               if (!item) return 0;
+               if (!item || exif_item_get_elements(item) == 0) return 0;
                *value = ((Exiv2::Metadatum *)item)->toLong();
                return 1;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return 0;
        }
 }
@@ -788,7 +825,7 @@ ExifRational *exif_item_get_rational(ExifItem *item, gint *sign, guint n)
                return &ret;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -797,12 +834,27 @@ gchar *exif_get_tag_description_by_key(const gchar *key)
 {
        try {
                Exiv2::ExifKey ekey(key);
-               return utf8_validate_or_convert(Exiv2::ExifTags::tagLabel(ekey.tag(), ekey.ifdId ()));
+               return utf8_validate_or_convert(ekey.tagLabel().c_str());
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
-               return NULL;
+               try {
+                       Exiv2::IptcKey ikey(key);
+                       return utf8_validate_or_convert(ikey.tagLabel().c_str());
+               }
+               catch (Exiv2::AnyError& e) {
+                       try {
+#if EXIV2_TEST_VERSION(0,16,0)
+                               Exiv2::XmpKey xkey(key);
+                               return utf8_validate_or_convert(xkey.tagLabel().c_str());
+#endif
+                       }
+                       catch (Exiv2::AnyError& e) {
+                               debug_exception(e);
+                               return NULL;
+                       }
+               }
        }
+       return NULL;
 }
 
 static const AltKey *find_alt_key(const gchar *xmp_key)
@@ -878,7 +930,7 @@ static gint exif_update_metadata_simple(ExifData *exif, const gchar *key, const
                return 1;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return 0;
        }
 }
@@ -942,12 +994,12 @@ static GList *exif_add_value_to_glist(GList *list, Exiv2::Metadatum &item, Metad
 #if EXIV2_TEST_VERSION(0,16,0)
                        Exiv2::Xmpdatum *xmpdatum;
 #endif
-                       if ((exifdatum = dynamic_cast<Exiv2::Exifdatum *>(metadatum)))
+                       if ((exifdatum = dynamic_cast<Exiv2::Exifdatum *>(&item)))
                                stream << *exifdatum;
-                       else if ((iptcdatum = dynamic_cast<Exiv2::Iptcdatum *>(metadatum)))
+                       else if ((iptcdatum = dynamic_cast<Exiv2::Iptcdatum *>(&item)))
                                stream << *iptcdatum;
 #if EXIV2_TEST_VERSION(0,16,0)
-                       else if ((xmpdatum = dynamic_cast<Exiv2::Xmpdatum *>(metadatum)))
+                       else if ((xmpdatum = dynamic_cast<Exiv2::Xmpdatum *>(&item)))
                                stream << *xmpdatum;
 #endif
                        str = stream.str();
@@ -962,11 +1014,11 @@ static GList *exif_add_value_to_glist(GList *list, Exiv2::Metadatum &item, Metad
                else
                        {
                        str = item.toString();
-                       if (str.length() > 5 && str.substr(0, 5) == "lang=")
-                               {
-                               std::string::size_type pos = str.find_first_of(' ');
-                               if (pos != std::string::npos) str = str.substr(pos+1);
-                               }
+                       }
+               if (str.length() > 5 && str.substr(0, 5) == "lang=")
+                       {
+                       std::string::size_type pos = str.find_first_of(' ');
+                       if (pos != std::string::npos) str = str.substr(pos+1);
                        }
                list = g_list_append(list, utf8_validate_or_convert(str.c_str())); 
 #if EXIV2_TEST_VERSION(0,16,0)
@@ -1016,7 +1068,7 @@ static GList *exif_get_metadata_simple(ExifData *exif, const gchar *key, Metadat
                }
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
        }
        return list;
 }
@@ -1127,7 +1179,7 @@ guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width,
                return NULL;
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
                return NULL;
        }
 }
@@ -1225,7 +1277,7 @@ extern "C" guchar *exif_get_preview(ExifData *exif, guint *data_len, gint reques
                
        }
        catch (Exiv2::AnyError& e) {
-               std::cout << "Caught Exiv2 exception '" << e << "'\n";
+               debug_exception(e);
        }
        return NULL;