[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a

Maximiliano Curia maxy at moszumanska.debian.org
Thu Jul 13 17:36:38 UTC 2017


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=e88a307

The following commit has been merged in the master branch:
commit e88a307858e3d0830f745c9cbcdd9c51732fde7f
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Sat Sep 18 15:58:03 2004 +0000

    Improved and cleaned-up ExifKey implementation
---
 src/canonmn.hpp   |   3 +-
 src/exif.cpp      | 172 +++++++++++++++++++++++++++++++++---------------------
 src/exif.hpp      |  72 ++++++++++-------------
 src/fujimn.hpp    |   3 +-
 src/key-test.cpp  |  30 +++++++++-
 src/makernote.cpp |  58 ++++++++----------
 src/makernote.hpp |  35 ++++++-----
 src/nikonmn.cpp   |   8 ++-
 src/nikonmn.hpp   |  51 +++++++++++++++-
 src/sigmamn.hpp   |   3 +-
 src/taglist.cpp   |  30 ++--------
 src/tags.cpp      |  91 ++++++++++++-----------------
 src/tags.hpp      |  41 +++++--------
 13 files changed, 328 insertions(+), 269 deletions(-)

diff --git a/src/canonmn.hpp b/src/canonmn.hpp
index 05c958b..1f34197 100644
--- a/src/canonmn.hpp
+++ b/src/canonmn.hpp
@@ -23,7 +23,7 @@
   @brief   Canon MakerNote implemented according to the specification
            <a href="http://www.burren.cx/david/canon.html">
            EXIF MakerNote of Canon</a> by David Burren
-  @version $Name:  $ $Revision: 1.11 $
+  @version $Name:  $ $Revision: 1.12 $
   @author  Andreas Huggel (ahu)
            <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
   @date    18-Feb-04, ahu: created<BR>
@@ -177,6 +177,7 @@ namespace Exiv2 {
             {
                 MakerNoteFactory& mnf = MakerNoteFactory::instance();
                 mnf.registerMakerNote("Canon", "*", createCanonMakerNote); 
+                mnf.registerMakerNote(new CanonMakerNote);
             }
         };
         /*!
diff --git a/src/exif.cpp b/src/exif.cpp
index 1f23ad7..5cb2f63 100644
--- a/src/exif.cpp
+++ b/src/exif.cpp
@@ -20,14 +20,14 @@
  */
 /*
   File:      exif.cpp
-  Version:   $Name:  $ $Revision: 1.58 $
+  Version:   $Name:  $ $Revision: 1.59 $
   Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
   History:   26-Jan-04, ahu: created
              11-Feb-04, ahu: isolated as a component
  */
 // *****************************************************************************
 #include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.58 $ $RCSfile: exif.cpp,v $");
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.59 $ $RCSfile: exif.cpp,v $");
 
 // Define DEBUG_MAKERNOTE to output debug information to std::cerr
 #undef DEBUG_MAKERNOTE
@@ -73,22 +73,62 @@ namespace {
 // class member definitions
 namespace Exiv2 {
 
+    const char* ExifKey::familyName_ = "Exif";
+
     ExifKey::ExifKey(const std::string& key)
-        : idx_(0), pMakerNote_(0), key_(key)
+        : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""),
+          idx_(0), pMakerNote_(0), key_(key)
     {
         decomposeKey();
     }
 
+    ExifKey::ExifKey(uint16_t tag, const std::string& ifdItem)
+        : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""),
+          idx_(0), pMakerNote_(0), key_("")
+    {
+        IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
+        if (ifdId == makerIfdId) throw Error("Invalid key");
+        MakerNote* pMakerNote = 0; 
+        if (ifdId == ifdIdNotSet) {
+            pMakerNote = MakerNoteFactory::instance().create(ifdItem);
+            if (pMakerNote) ifdId = makerIfdId;
+            else throw Error("Invalid key");
+        }
+        tag_ = tag;
+        ifdId_ = ifdId;
+        ifdItem_ = ifdItem;
+        pMakerNote_ = pMakerNote;
+        makeKey();
+    }
+
     ExifKey::ExifKey(const Entry& e)
-        : tag_(e.tag()), ifdId_(e.ifdId()), idx_(e.idx()), 
-          pMakerNote_(e.makerNote()), key_(makeKey(e))
+        : tag_(e.tag()), ifdId_(e.ifdId()), ifdItem_(""),
+          idx_(e.idx()), pMakerNote_(0), key_("")
     {
+        if (ifdId_ == makerIfdId) {
+            if (e.makerNote()) {
+                ifdItem_ = e.makerNote()->ifdItem();
+                pMakerNote_ = e.makerNote()->clone();
+            }
+            else throw Error("Invalid Key");
+        }
+        else {
+            ifdItem_ = ExifTags::ifdItem(ifdId_);
+        }
+        makeKey();
     }
 
     ExifKey::ExifKey(const ExifKey& rhs)
-        : tag_(rhs.tag_), ifdId_(rhs.ifdId_), idx_(rhs.idx_), 
-          pMakerNote_(rhs.pMakerNote_), key_(rhs.key_)
+        : tag_(rhs.tag_), ifdId_(rhs.ifdId_), ifdItem_(rhs.ifdItem_),
+          idx_(rhs.idx_), 
+          pMakerNote_(rhs.pMakerNote_ ? rhs.pMakerNote_->clone() : 0),
+          key_(rhs.key_)
+    {
+    }
+
+    ExifKey::~ExifKey()
     {
+        delete pMakerNote_;
     }
 
     ExifKey& ExifKey::operator=(const ExifKey& rhs)
@@ -97,40 +137,22 @@ namespace Exiv2 {
         Key::operator=(rhs);
         tag_ = rhs.tag_;
         ifdId_ = rhs.ifdId_;
+        ifdItem_ = rhs.ifdItem_;
         idx_ = rhs.idx_;
-        pMakerNote_ = rhs.pMakerNote_;
+        pMakerNote_ = rhs.pMakerNote_ ? rhs.pMakerNote_->clone() : 0;
         key_ = rhs.key_;
         return *this;
     }
 
-    void ExifKey::setMakerNote(MakerNote* pMakerNote)
-    { 
-        if (ifdId_ == makerIfdId && pMakerNote_ != pMakerNote) {
-            pMakerNote_ = pMakerNote;
-            decomposeKey();
-        }
-    }
-
     std::string ExifKey::tagName() const
     {
-        if (ifdId_ == makerIfdId && pMakerNote_ != 0) {
+        if (ifdId_ == makerIfdId) {
+            assert(pMakerNote_);
             return pMakerNote_->tagName(tag_);
         }
-        return ExifTags::tagName(tag(), ifdId()); 
-    }
-
-    uint16_t ExifKey::tag() const
-    {
-        if (tag_ == 0xffff) throw Error("Invalid key");
-        return tag_;
-    }
-
-    IfdId ExifKey::ifdId() const 
-    {
-        if (ifdId_ == ifdIdNotSet) throw Error("Invalid key");
-        return ifdId_;
+        return ExifTags::tagName(tag_, ifdId_); 
     }
-
+    
     ExifKey* ExifKey::clone() const
     {
         return new ExifKey(*this);
@@ -138,7 +160,8 @@ namespace Exiv2 {
 
     std::string ExifKey::sectionName() const 
     {
-        if (ifdId_ == makerIfdId && pMakerNote_ != 0) {
+        if (ifdId_ == makerIfdId) {
+            assert(pMakerNote_);
             return pMakerNote_->ifdItem();
         }
         return ExifTags::sectionName(tag(), ifdId()); 
@@ -146,26 +169,57 @@ namespace Exiv2 {
 
     void ExifKey::decomposeKey()
     {
-        std::pair<uint16_t, IfdId> p;
-        if (ifdId_ == makerIfdId && pMakerNote_ != 0) {
-            p.first = pMakerNote_->decomposeKey(key_);
-            if (p.first == 0xffff) throw Error("Invalid key");
-            p.second = makerIfdId;
-        }
-        else {
-            p = ExifTags::decomposeKey(key_);
-            // If it's couldn't be parsed, we assume it is an incomplete 
-            // makernote key (pMakerNote_ not set)
-            if (p.second == ifdIdNotSet) p.second = makerIfdId;
-            // No checks as this could still be an incomplete makernote key
-        }
-        tag_ = p.first;
-        ifdId_ = p.second;
+        // Get the family name, IFD name and tag name parts of the key
+        std::string::size_type pos1 = key_.find('.');
+        if (pos1 == std::string::npos) throw Error("Invalid key");
+        std::string familyName = key_.substr(0, pos1);
+        if (familyName != std::string(familyName_)) {
+            throw Error("Invalid key");
+        }
+        std::string::size_type pos0 = pos1 + 1;
+        pos1 = key_.find('.', pos0);
+        if (pos1 == std::string::npos) throw Error("Invalid key");
+        std::string ifdItem = key_.substr(pos0, pos1 - pos0);
+        pos0 = pos1 + 1;
+        std::string tagName = key_.substr(pos0);
+        if (tagName == "") throw Error("Invalid key");
+
+        // Find IfdId
+        IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
+        if (ifdId == makerIfdId) throw Error("Invalid key");
+        MakerNote* pMakerNote = 0; 
+        if (ifdId == ifdIdNotSet) {
+            pMakerNote = MakerNoteFactory::instance().create(ifdItem);
+            if (pMakerNote) ifdId = makerIfdId;
+            else throw Error("Invalid key");
+        }
+
+        // Convert tag
+        uint16_t tag = pMakerNote ? 
+            pMakerNote->tag(tagName) : ExifTags::tag(tagName, ifdId);
+        // Translate hex tag name (0xabcd) to a real tag name if there is one
+        tagName = pMakerNote ? 
+            pMakerNote->tagName(tag) : ExifTags::tagName(tag, ifdId);
+
+        tag_ = tag;
+        ifdId_ = ifdId;
+        ifdItem_ = ifdItem;
+        pMakerNote_ = pMakerNote;
+        key_ = familyName + "." + ifdItem + "." + tagName;
+    }
+
+    void ExifKey::makeKey()
+    {
+        key_ = std::string(familyName_) 
+            + "." + ifdItem_
+            + "." + (pMakerNote_ ?
+            pMakerNote_->tagName(tag_) : ExifTags::tagName(tag_, ifdId_));
     }
 
     std::ostream& ExifKey::printTag(std::ostream& os, const Value& value) const
     {
-        if (ifdId_ == makerIfdId && pMakerNote_ != 0) {
+        if (ifdId_ == makerIfdId) {
+            assert(pMakerNote_);
             return pMakerNote_->printTag(os, tag(), value);
         }
         return ExifTags::printTag(os, tag(), ifdId(), value);
@@ -974,7 +1028,6 @@ namespace Exiv2 {
     {
         // Todo: Implement a more suitable ExifKey c'tor
         ExifKey k(key);
-        k.setMakerNote(pMakerNote_);
         add(Exifdatum(k, pValue));
     }
 
@@ -1316,7 +1369,8 @@ namespace Exiv2 {
 
         DataBuf buf(md.size());
         md.copy(buf.pData_, byteOrder);
-        e.setValue(static_cast<uint16_t>(md.typeId()), md.count(), buf.pData_, md.size()); 
+        e.setValue(static_cast<uint16_t>(md.typeId()), md.count(), 
+                   buf.pData_, md.size()); 
         ifd.add(e);
     } // addToIfd
 
@@ -1355,24 +1409,6 @@ namespace Exiv2 {
         return md.pKey_->printTag(os, md.value());
     }
 
-    std::string makeKey(const Entry& entry)
-    {
-        if (entry.ifdId() == makerIfdId && entry.makerNote() != 0) {
-            return entry.makerNote()->makeKey(entry.tag());
-        }
-        return ExifTags::makeKey(entry.tag(), entry.ifdId());
-    }
-
-    std::pair<uint16_t, IfdId> decomposeKey(const std::string& key,
-                                          const MakerNote* makerNote)
-    {
-        std::pair<uint16_t, IfdId> p = ExifTags::decomposeKey(key);
-        if (p.second == makerIfdId && makerNote != 0) {
-            p.first = makerNote->decomposeKey(key);
-        }
-        return p;
-    }
-
 }                                       // namespace Exiv2
 
 // *****************************************************************************
diff --git a/src/exif.hpp b/src/exif.hpp
index 63071da..0f4b09f 100644
--- a/src/exif.hpp
+++ b/src/exif.hpp
@@ -21,7 +21,7 @@
 /*!
   @file    exif.hpp
   @brief   Encoding and decoding of Exif data
-  @version $Name:  $ $Revision: 1.51 $
+  @version $Name:  $ $Revision: 1.52 $
   @author  Andreas Huggel (ahu)
            <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
   @date    09-Jan-04, ahu: created
@@ -73,11 +73,21 @@ namespace Exiv2 {
                  parts or the first part of the key is not '<b>Exif</b>'.
         */
         explicit ExifKey(const std::string& key);
+        /*!
+          @brief Constructor to create an Exif key from a tag and IFD item 
+                 string.
+          @param tag The tag value
+          @param ifdItem The IFD string. For MakerNote tags, this must be the 
+                 IFD item of the specific MakerNote. "MakerNote" is not allowed.
+          @throw Error ("Invalid key") if the key cannot be constructed from
+                 the tag and IFD item parameters.
+         */
+        ExifKey(uint16_t tag, const std::string& ifdItem);
         //! Constructor to build an ExifKey from an IFD entry.
         explicit ExifKey(const Entry& e);
         //! Copy constructor
         ExifKey(const ExifKey& rhs);
-        // A destructor is not needed, as we do *not* delete the makernote
+        virtual ~ExifKey();
         //@}
 
         //! @name Manipulators
@@ -86,34 +96,25 @@ namespace Exiv2 {
           @brief Assignment operator.
          */
         ExifKey& operator=(const ExifKey& rhs);
-        //! Set the makernote pointer. 
-        void setMakerNote(MakerNote* pMakerNote);
         //@}
 
         //! @name Accessors
         //@{
         virtual std::string key() const { return key_; }
-        virtual const char* familyName() const { return ExifTags::familyName(); }
+        virtual const char* familyName() const { return familyName_; }
         /*!
           @brief Return the name of the group (the second part of the key).
-                 For Exif keys, the group name is the IFD name.
+                 For Exif keys, the group name is the IFD item.
         */ 
-        virtual std::string groupName() const { return ifdName(); }
+        virtual std::string groupName() const { return ifdItem(); }
         virtual std::string tagName() const;
-        /*!
-          @brief Return the tag.
-          @throw Error ("Invalid key") if the tag is not set.
-        */
-        virtual uint16_t tag() const;
+        virtual uint16_t tag() const { return tag_; }
         virtual ExifKey* clone() const;
 
         //! Interpret and print the value of an Exif tag
         std::ostream& printTag(std::ostream& os, const Value& value) const;
-        /*!
-          @brief Return the IFD id
-          @throw Error ("Invalid key") if the IFD id is not set.
-        */
-        IfdId ifdId() const;
+        //! Return the IFD id
+        IfdId ifdId() const { return ifdId_; }
         //! Return the name of the IFD
         const char* ifdName() const { return ExifTags::ifdName(ifdId()); }
         //! Return the related image item
@@ -122,30 +123,33 @@ namespace Exiv2 {
         std::string sectionName() const;
         //! Return the index (unique id of this key within the original IFD)
         int idx() const { return idx_; }
-        //! Return the pointer to the associated MakerNote
-        MakerNote* makerNote() const { return pMakerNote_; }
         //@}
 
     protected:
         //! @name Manipulators
         //@{
         /*!
-          @brief Parse and convert the key string into tag, and IFD Id. 
-                 Forwards the request to MakerNote::decomposeKey if necessary.
-                 Updates key_ and ifdId_ if the string can be decomposed,
+          @brief Set the key corresponding to the tag and IFD id. 
+                 The key is of the form '<b>Exif</b>.ifdItem.tagName'.
+         */
+        void makeKey();
+        /*!
+          @brief Parse and convert the key string into tag and IFD Id. 
+                 Updates data memebers if the string can be decomposed,
                  or throws Error ("Invalid key").
 
-          @throw Error ("Invalid key") if pMakerNote_ is ot 0 and the key 
-                 cannot be parsed into family name, group name and tag name 
-                 parts.
+          @throw Error ("Invalid key") Todo: add conditions
          */
         void decomposeKey();
         //@}
 
     private:
         // DATA
-        uint16_t tag_;                    //!< Tag value
+        static const char* familyName_;
+
+        uint16_t tag_;                  //!< Tag value
         IfdId ifdId_;                   //!< The IFD associated with this tag
+        std::string ifdItem_;           //!< The IFD item 
         int idx_;                       //!< Unique id of an entry within one IFD
         MakerNote* pMakerNote_;         //!< Pointer to the associated MakerNote
         std::string key_;               //!< Key
@@ -951,22 +955,6 @@ namespace Exiv2 {
     void addToMakerNote(MakerNote* makerNote,
                         const Exifdatum& exifdatum,
                         ByteOrder byteOrder);
-    /*!
-      @brief Return a key for the entry.  The key is of the form
-             '<b>Exif</b>.ifdItem.tagName'. This function knows about
-             MakerNotes, i.e., it will invoke MakerNote::makeKey if necessary.
-    */
-    std::string makeKey(const Entry& entry);
-    /*!
-      @brief Return the tag and IFD id pair for the key. This function knows
-             about MakerNotes, i.e., it will forward the request to
-             MakerNote::decomposeKey if necessary.
-      @return A pair consisting of the tag and IFD id.
-      @throw Error ("Invalid key") if the key cannot be parsed into
-      item item, section name and tag name parts.
-    */
-    std::pair<uint16_t, IfdId> decomposeKey(const std::string& key,
-                                          const MakerNote* makerNote);
 
 }                                       // namespace Exiv2
 
diff --git a/src/fujimn.hpp b/src/fujimn.hpp
index bacb768..1223511 100644
--- a/src/fujimn.hpp
+++ b/src/fujimn.hpp
@@ -24,7 +24,7 @@
            in Appendix 4: Makernote of Fujifilm of the document 
            <a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
            Exif file format</a> by TsuruZoh Tachibanaya
-  @version $Name:  $ $Revision: 1.8 $
+  @version $Name:  $ $Revision: 1.9 $
   @author  Andreas Huggel (ahu)
            <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
   @date    11-Feb-04, ahu: created
@@ -141,6 +141,7 @@ namespace Exiv2 {
             {
                 MakerNoteFactory& mnf = MakerNoteFactory::instance();
                 mnf.registerMakerNote("FUJIFILM", "*", createFujiMakerNote); 
+                mnf.registerMakerNote(new FujiMakerNote);
             }
         };
         /*!
diff --git a/src/key-test.cpp b/src/key-test.cpp
index c3ad6d5..03d531b 100644
--- a/src/key-test.cpp
+++ b/src/key-test.cpp
@@ -3,7 +3,7 @@
   Abstract : Key unit tests 
 
   File     : key-test.cpp
-  Version  : $Name:  $ $Revision: 1.2 $
+  Version  : $Name:  $ $Revision: 1.3 $
   Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
   History  : 24-Aug-04, ahu: created
 
@@ -201,6 +201,34 @@ int main()
 
     // -----
 
+    ExifKey ek4("Exif.Image.0x0110");
+    tc += 1;
+    if (ek4.key() != "Exif.Image.Model") {
+        std::cout << "Testcase failed (converted key)" << std::endl;
+        rc += 1; 
+    }
+    tc += 1;
+    if (ek4.tagName() != "Model") {
+        std::cout << "Testcase failed (converted tagName)" << std::endl;
+        rc += 1; 
+    }
+
+    // -----
+
+    ExifKey ek5("Exif.Nikon3.0x0007");
+    tc += 1;
+    if (ek5.key() != "Exif.Nikon3.Focus") {
+        std::cout << "Testcase failed (converted key)" << std::endl;
+        rc += 1; 
+    }
+    tc += 1;
+    if (ek5.tagName() != "Focus") {
+        std::cout << "Testcase failed (converted tagName)" << std::endl;
+        rc += 1; 
+    }
+
+    // -----
+
     if (rc == 0) {
         std::cout << "All " << tc << " testcases passed." << std::endl;
     }
diff --git a/src/makernote.cpp b/src/makernote.cpp
index 8eb8196..99a5822 100644
--- a/src/makernote.cpp
+++ b/src/makernote.cpp
@@ -20,13 +20,13 @@
  */
 /*
   File:      makernote.cpp
-  Version:   $Name:  $ $Revision: 1.27 $
+  Version:   $Name:  $ $Revision: 1.28 $
   Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
   History:   18-Feb-04, ahu: created
  */
 // *****************************************************************************
 #include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.27 $ $RCSfile: makernote.cpp,v $");
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.28 $ $RCSfile: makernote.cpp,v $");
 
 // Define DEBUG_* to output debug information to std::cerr
 #undef DEBUG_MAKERNOTE
@@ -38,14 +38,17 @@ EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.27 $ $RCSfile: makernote.cpp,v $");
 #include "tags.hpp"                         // for ExifTags::ifdItem
 #include "error.hpp"
 
+// Todo: remove circular dependency
+#include "exif.hpp"                         // for MakerNote::writeMnTagInfo
+
 // + standard includes
 #include <string>
 #include <sstream>
 #include <iomanip>
-
 #if defined DEBUG_MAKERNOTE || defined DEBUG_REGISTRY
-#   include <iostream>
+# include <iostream>
 #endif
+#include <cassert>
 
 // *****************************************************************************
 // class member definitions
@@ -57,35 +60,6 @@ namespace Exiv2 {
     {
     }
 
-    std::string MakerNote::makeKey(uint16_t tag) const
-    {
-        return std::string(ExifTags::familyName())
-            + "." + std::string(ifdItem())
-            + "." + tagName(tag);
-    } // MakerNote::makeKey
-
-    uint16_t MakerNote::decomposeKey(const std::string& key) const
-    {
-        // Get the family, item and tag name parts of the key
-        std::string::size_type pos1 = key.find('.');
-        if (pos1 == std::string::npos) throw Error("Invalid key");
-        std::string familyName = key.substr(0, pos1);
-        std::string::size_type pos0 = pos1 + 1;
-        pos1 = key.find('.', pos0);
-        if (pos1 == std::string::npos) throw Error("Invalid key");
-        std::string ifdItem = key.substr(pos0, pos1 - pos0);
-        pos0 = pos1 + 1;
-        std::string tagName = key.substr(pos0);
-        if (tagName == "") throw Error("Invalid key");
-
-        if (familyName != ExifTags::familyName()) return 0xffff;
-        uint16_t tag = this->tag(tagName);
-        if (tag == 0xffff) return tag;
-        if (ifdItem != this->ifdItem()) return 0xffff;
-
-        return tag;
-    } // MakerNote::decomposeKey
-
     std::string MakerNote::tagName(uint16_t tag) const
     {
         std::string tagName;
@@ -149,12 +123,13 @@ namespace Exiv2 {
 
     std::ostream& MakerNote::writeMnTagInfo(std::ostream& os, uint16_t tag) const
     {
+        ExifKey exifKey(tag, ifdItem());
         return os << tagName(tag) << ", "
                   << std::dec << tag << ", "
                   << "0x" << std::setw(4) << std::setfill('0') 
                   << std::right << std::hex << tag << ", "
                   << ExifTags::ifdItem(makerIfdId) << ", "
-                  << makeKey(tag) << ", " 
+                  << exifKey.key() << ", " 
                   << tagDesc(tag);
     } // MakerNote::writeMnTagInfo
 
@@ -268,6 +243,21 @@ namespace Exiv2 {
         return *pInstance_;
     } // MakerNoteFactory::instance
 
+    void MakerNoteFactory::registerMakerNote(MakerNote* pMakerNote)
+    {
+        assert(pMakerNote);
+        ifdItemRegistry_[pMakerNote->ifdItem()] = pMakerNote;
+    } // MakerNoteFactory::registerMakerNote
+
+    MakerNote* MakerNoteFactory::create(const std::string& ifdItem,
+                                        bool alloc) const
+    {
+        IfdItemRegistry::const_iterator i = ifdItemRegistry_.find(ifdItem);
+        if (i == ifdItemRegistry_.end()) return 0;
+        assert(i->second);
+        return i->second->clone(alloc);
+    } // MakerNoteFactory::create
+
     void MakerNoteFactory::registerMakerNote(const std::string& make, 
                                              const std::string& model, 
                                              CreateFct createMakerNote)
diff --git a/src/makernote.hpp b/src/makernote.hpp
index aef5030..af81d9f 100644
--- a/src/makernote.hpp
+++ b/src/makernote.hpp
@@ -22,7 +22,7 @@
   @file    makernote.hpp
   @brief   Contains the Exif %MakerNote interface, IFD %MakerNote and a 
            MakerNote factory
-  @version $Name:  $ $Revision: 1.23 $
+  @version $Name:  $ $Revision: 1.24 $
   @author  Andreas Huggel (ahu)
            <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
   @date    18-Feb-04, ahu: created
@@ -40,6 +40,7 @@
 #include <iosfwd>
 #include <utility>
 #include <vector>
+#include <map>
 
 // *****************************************************************************
 // namespace extensions
@@ -73,7 +74,7 @@ namespace Exiv2 {
       - read the makernote from a character buffer
       - copy the makernote to a character buffer
       - maintain a list of makernote entries (similar to IFD entries) 
-      - provide makernote specific tag names and keys
+      - provide makernote specific tag names and tag information
       - interpret (print) the values of makernote tags
 
       Makernotes can be added to the system by subclassing %MakerNote and
@@ -164,10 +165,6 @@ namespace Exiv2 {
 
         //! @name Accessors
         //@{
-        //! Return the key for the tag.
-        std::string makeKey(uint16_t tag) const;
-        //! Return the associated tag for a makernote key.
-        uint16_t decomposeKey(const std::string& key) const;
         //! Return the byte order (little or big endian).
         ByteOrder byteOrder() const { return byteOrder_; }
         //! Return the offset of the makernote from the start of the TIFF header
@@ -180,23 +177,23 @@ namespace Exiv2 {
          */
         virtual std::string tagName(uint16_t tag) const;
         /*!
+          @brief Return the tag associated with a makernote tag name. The
+                 default implementation looks up the makernote info tag array
+                 if one is set, else it expects tag names in the form "0x01ff"
+                 and converts them to unsigned integer.
+         */
+        virtual uint16_t tag(const std::string& tagName) const;
+        /*!
           @brief Return the description of a makernote tag. The default
                  implementation looks up the makernote info tag array if one is
                  set, else it returns an empty string.
          */
-        virtual uint16_t tag(const std::string& tagName) const;
+        virtual std::string tagDesc(uint16_t tag) const;
         /*!
           @brief Print a list of all tags known by this MakerNote to the output 
                  stream os. The default implementation prints all tags in the 
                  makernote info tag array if one is set.
          */
-        virtual std::string tagDesc(uint16_t tag) const;
-        /*!
-          @brief Return the tag associated with a makernote tag name. The
-                 default implementation looks up the makernote info tag array
-                 if one is set, else it expects tag names in the form \"0x01ff\"
-                 and converts them to unsigned integer.
-         */
         virtual void taglist(std::ostream& os) const;
         /*!
           @brief Write the makernote tag info of tag to the output stream os.
@@ -395,6 +392,9 @@ namespace Exiv2 {
         void registerMakerNote(const std::string& make, 
                                const std::string& model, 
                                CreateFct createMakerNote);
+
+        //! Register a %MakerNote prototype in the IFD item registry.
+        void registerMakerNote(MakerNote* pMakerNote);
         //@}
 
         //! @name Accessors
@@ -449,6 +449,9 @@ namespace Exiv2 {
                           long len, 
                           ByteOrder byteOrder, 
                           long offset) const; 
+
+        //! Create a %MakerNote based on its IFD item string.
+        MakerNote* create(const std::string& ifdItem, bool alloc =true) const;
         //@}
 
         /*!
@@ -483,12 +486,16 @@ namespace Exiv2 {
         typedef std::vector<std::pair<std::string, CreateFct> > ModelRegistry;
         //! Type used to store a list of make labels and model registries
         typedef std::vector<std::pair<std::string, ModelRegistry*> > Registry;
+        //! Type used to store a list of IFD items and %MakerNote prototypes
+        typedef std::map<std::string, MakerNote*> IfdItemRegistry;
 
         // DATA
         //! Pointer to the one and only instance of this class.
         static MakerNoteFactory* pInstance_;
         //! List of makernote types and corresponding makernote create functions.
         Registry registry_;
+        //! List of makernote IfdItems and corresponding create functions.
+        IfdItemRegistry ifdItemRegistry_;
 
     }; // class MakerNoteFactory
    
diff --git a/src/nikonmn.cpp b/src/nikonmn.cpp
index cc081b5..1138cbd 100644
--- a/src/nikonmn.cpp
+++ b/src/nikonmn.cpp
@@ -20,14 +20,14 @@
  */
 /*
   File:      nikon1mn.cpp
-  Version:   $Name:  $ $Revision: 1.6 $
+  Version:   $Name:  $ $Revision: 1.7 $
   Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
   History:   17-May-04, ahu: created
              25-May-04, ahu: combined all Nikon formats in one component
  */
 // *****************************************************************************
 #include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.6 $ $RCSfile: nikonmn.cpp,v $");
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.7 $ $RCSfile: nikonmn.cpp,v $");
 
 // *****************************************************************************
 // included header files
@@ -183,6 +183,8 @@ namespace Exiv2 {
         return os;
     }
 
+    const Nikon2MakerNote::RegisterMakerNote Nikon2MakerNote::register_;
+
     // Nikon2 MakerNote Tag Info
     static const MakerNote::MnTagInfo nikon2MnTagInfo[] = {
         MakerNote::MnTagInfo(0x0003, "Quality", "Image quality setting"),
@@ -348,6 +350,8 @@ namespace Exiv2 {
         return os;
     }
 
+    const Nikon3MakerNote::RegisterMakerNote Nikon3MakerNote::register_;
+
     // Nikon3 MakerNote Tag Info
     static const MakerNote::MnTagInfo nikon3MnTagInfo[] = {
         MakerNote::MnTagInfo(0x0001, "Version", "Nikon Makernote version"),
diff --git a/src/nikonmn.hpp b/src/nikonmn.hpp
index 17f93b6..6b55a3b 100644
--- a/src/nikonmn.hpp
+++ b/src/nikonmn.hpp
@@ -28,7 +28,7 @@
            <a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
            Exif file format</a> by TsuruZoh Tachibanaya.<BR>
            Format 3: "EXIFutils Field Reference Guide".
-  @version $Name:  $ $Revision: 1.5 $
+  @version $Name:  $ $Revision: 1.6 $
   @author  Andreas Huggel (ahu)
            <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
   @date    17-May-04, ahu: created<BR>
@@ -132,6 +132,7 @@ namespace Exiv2 {
             {
                 MakerNoteFactory& mnf = MakerNoteFactory::instance();
                 mnf.registerMakerNote("NIKON*", "*", createNikonMakerNote); 
+                mnf.registerMakerNote(new Nikon1MakerNote);
             }
         };
         // DATA
@@ -206,6 +207,30 @@ namespace Exiv2 {
         //@}
 
     private:
+        //! Structure used to auto-register the MakerNote.
+        struct RegisterMakerNote {
+            //! Default constructor
+            RegisterMakerNote() 
+            {
+                MakerNoteFactory& mnf = MakerNoteFactory::instance();
+                mnf.registerMakerNote(new Nikon2MakerNote);
+            }
+        };
+        // DATA
+        /*!
+          The static member variable is initialized before main (see note) and
+          will in the process register the MakerNote class. (Remember the
+          definition of the variable in the implementation file!)
+
+          @note The standard says that, if no function is explicitly called ever
+                in a module, then that module's static data might be never
+                initialized. This clause was introduced to allow dynamic link
+                libraries. The idea is, with this clause the loader is not
+                forced to eagerly load all modules, but load them only on
+                demand.
+         */
+        static const RegisterMakerNote register_; 
+
         //! The item name (second part of the key) used for makernote tags
         std::string ifdItem_;
 
@@ -258,6 +283,30 @@ namespace Exiv2 {
         //@}
 
     private:
+        //! Structure used to auto-register the MakerNote.
+        struct RegisterMakerNote {
+            //! Default constructor
+            RegisterMakerNote() 
+            {
+                MakerNoteFactory& mnf = MakerNoteFactory::instance();
+                mnf.registerMakerNote(new Nikon3MakerNote);
+            }
+        };
+        // DATA
+        /*!
+          The static member variable is initialized before main (see note) and
+          will in the process register the MakerNote class. (Remember the
+          definition of the variable in the implementation file!)
+
+          @note The standard says that, if no function is explicitly called ever
+                in a module, then that module's static data might be never
+                initialized. This clause was introduced to allow dynamic link
+                libraries. The idea is, with this clause the loader is not
+                forced to eagerly load all modules, but load them only on
+                demand.
+         */
+        static const RegisterMakerNote register_; 
+
         //! The item name (second part of the key) used for makernote tags
         std::string ifdItem_;
 
diff --git a/src/sigmamn.hpp b/src/sigmamn.hpp
index c6ff088..afb7478 100644
--- a/src/sigmamn.hpp
+++ b/src/sigmamn.hpp
@@ -23,7 +23,7 @@
   @brief   Sigma and Foveon MakerNote implemented according to the specification
            <a href="http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html">
            SIGMA and FOVEON EXIF MakerNote Documentation</a> by Foveon.           
-  @version $Name:  $ $Revision: 1.8 $
+  @version $Name:  $ $Revision: 1.9 $
   @author  Andreas Huggel (ahu)
            <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
   @date    02-Apr-04, ahu: created
@@ -131,6 +131,7 @@ namespace Exiv2 {
                 MakerNoteFactory& mnf = MakerNoteFactory::instance();
                 mnf.registerMakerNote("SIGMA", "*", createSigmaMakerNote); 
                 mnf.registerMakerNote("FOVEON", "*", createSigmaMakerNote); 
+                mnf.registerMakerNote(new SigmaMakerNote);
             }
         };
         // DATA
diff --git a/src/taglist.cpp b/src/taglist.cpp
index d576afb..ab0d469 100644
--- a/src/taglist.cpp
+++ b/src/taglist.cpp
@@ -3,19 +3,15 @@
   Abstract:  Print a simple comma separated list of tags defined in Exiv2
 
   File:      taglist.cpp
-  Version:   $Name:  $ $Revision: 1.9 $
+  Version:   $Name:  $ $Revision: 1.10 $
   Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
   History:   07-Jan-04, ahu: created
  */
 // *****************************************************************************
 #include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.9 $ $RCSfile: taglist.cpp,v $");
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.10 $ $RCSfile: taglist.cpp,v $");
 
 #include "makernote.hpp"
-#include "nikonmn.hpp"
-#include "sigmamn.hpp"
-#include "fujimn.hpp"
-#include "canonmn.hpp"
 #include "tags.hpp"
 #include "datasets.hpp"
 #include "error.hpp"
@@ -38,26 +34,8 @@ try {
             IptcDataSets::dataSetList(std::cout);
             break;
         }
-
-        if (item == "Canon") {
-            pMakerNote = new CanonMakerNote;
-        }
-        else if (item == "Fujifilm") {
-            pMakerNote = new FujiMakerNote;
-        }
-        else if (item == "Sigma") {
-            pMakerNote = new SigmaMakerNote;
-        }
-        else if (item == "Nikon1") {
-            pMakerNote = new Nikon1MakerNote;
-        }
-        else if (item == "Nikon2") {
-            pMakerNote = new Nikon2MakerNote;
-        }
-        else if (item == "Nikon3") {
-            pMakerNote = new Nikon3MakerNote;
-        }
-
+        
+        pMakerNote = MakerNoteFactory::instance().create(item);
         if (pMakerNote) {
             pMakerNote->taglist(std::cout);
             delete pMakerNote;
diff --git a/src/tags.cpp b/src/tags.cpp
index fef2e22..4d75067 100644
--- a/src/tags.cpp
+++ b/src/tags.cpp
@@ -20,13 +20,13 @@
  */
 /*
   File:      tags.cpp
-  Version:   $Name:  $ $Revision: 1.35 $
+  Version:   $Name:  $ $Revision: 1.36 $
   Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
   History:   15-Jan-04, ahu: created
  */
 // *****************************************************************************
 #include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.35 $ $RCSfile: tags.cpp,v $");
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.36 $ $RCSfile: tags.cpp,v $");
 
 // *****************************************************************************
 // included header files
@@ -35,6 +35,9 @@ EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.35 $ $RCSfile: tags.cpp,v $");
 #include "types.hpp"
 #include "value.hpp"
 
+// Todo: remove circular dependency
+#include "exif.hpp"                             // for TagInfo operator<<
+
 #include <iostream>
 #include <iomanip>
 #include <sstream>
@@ -266,24 +269,26 @@ namespace Exiv2 {
         0
     };
 
-    const char* ExifTags::familyName_ = "Exif";
-
     int ExifTags::tagInfoIdx(uint16_t tag, IfdId ifdId)
     {
         const TagInfo* tagInfo = tagInfos_[ifdId];
         if (tagInfo == 0) return -1;
         int idx;
         for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) {
-            if (tagInfo[idx].tag_ == tag) break;
+            if (tagInfo[idx].tag_ == tag) return idx;
         }
-        return idx;
+        return -1;
     }
 
-    const char* ExifTags::tagName(uint16_t tag, IfdId ifdId)
+    std::string ExifTags::tagName(uint16_t tag, IfdId ifdId)
     {
         int idx = tagInfoIdx(tag, ifdId);
-        if (idx == -1) throw Error("No taginfo for IFD");
-        return tagInfos_[ifdId][idx].name_;
+        if (idx != -1) return tagInfos_[ifdId][idx].name_;
+
+        std::ostringstream os;
+        os << "0x" << std::setw(4) << std::setfill('0') << std::right
+           << std::hex << tag;
+        return os.str();
     }
 
     const char* ExifTags::tagDesc(uint16_t tag, IfdId ifdId)
@@ -311,13 +316,30 @@ namespace Exiv2 {
 
     uint16_t ExifTags::tag(const std::string& tagName, IfdId ifdId)
     {
+        uint16_t tag = 0xffff;
         const TagInfo* tagInfo = tagInfos_[ifdId];
-        if (tagInfo == 0) return 0xffff;
-        int idx;
-        for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) {
-            if (tagInfo[idx].name_ == tagName) break;
+        if (tagInfo) {
+            int idx;
+            for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) {
+                if (tagInfo[idx].name_ == tagName) break;
+            }
+            tag = tagInfo[idx].tag_;
+        }
+        if (tag == 0xffff) {
+            // Todo: Check format of tagName
+            std::istringstream is(tagName);
+            is >> std::hex >> tag;
+        }
+        return tag;
+    }
+
+    IfdId ExifTags::ifdIdByIfdItem(const std::string& ifdItem)
+    {
+        int i;
+        for (i = int(lastIfdId) - 1; i > 0; --i) {
+            if (ifdInfo_[i].item_ == ifdItem) break;
         }
-        return tagInfo[idx].tag_;
+        return IfdId(i);
     }
 
     const char* ExifTags::ifdName(IfdId ifdId)
@@ -344,44 +366,6 @@ namespace Exiv2 {
         return SectionId(i);
     }
 
-    std::string ExifTags::makeKey(uint16_t tag, IfdId ifdId)
-    {
-        return std::string(familyName()) 
-            + "." + std::string(ifdItem(ifdId)) 
-            + "." + std::string(tagName(tag, ifdId));
-    }
-
-    // This 'database lookup' function returns the first match that
-    // we find, it doesn't verify whether this is the only match.
-    std::pair<uint16_t, IfdId> ExifTags::decomposeKey(const std::string& key)
-    {
-        // Get the family name, IFD name and tag name parts of the key
-        std::string::size_type pos1 = key.find('.');
-        if (pos1 == std::string::npos) throw Error("Invalid key");
-        std::string familyName = key.substr(0, pos1);
-        if (familyName != std::string(ExifTags::familyName())) {
-            throw Error("Invalid key");
-        }
-        std::string::size_type pos0 = pos1 + 1;
-        pos1 = key.find('.', pos0);
-        if (pos1 == std::string::npos) throw Error("Invalid key");
-        std::string ifdItem = key.substr(pos0, pos1 - pos0);
-        pos0 = pos1 + 1;
-        std::string tagName = key.substr(pos0);
-        if (tagName == "") throw Error("Invalid key");
-
-        // Find IfdId
-        int i;
-        for (i = int(lastIfdId) - 1; i > 0; --i) {
-            if (ifdInfo_[i].item_ == ifdItem) break;
-        }
-        IfdId ifdId = IfdId(i);
-
-        if (ifdId == ifdIdNotSet) return std::make_pair(0xffff, ifdId);
-
-        return std::make_pair(tag(tagName, ifdId), ifdId);
-    } // ExifTags::decomposeKey
-
     std::ostream& ExifTags::printTag(std::ostream& os,
                                      uint16_t tag, 
                                      IfdId ifdId,
@@ -414,12 +398,13 @@ namespace Exiv2 {
 
     std::ostream& operator<<(std::ostream& os, const TagInfo& ti) 
     {
+        ExifKey exifKey(ti.tag_, ExifTags::ifdItem(ti.ifdId_));
         return os << ExifTags::tagName(ti.tag_, ti.ifdId_) << ", "
                   << std::dec << ti.tag_ << ", "
                   << "0x" << std::setw(4) << std::setfill('0') 
                   << std::right << std::hex << ti.tag_ << ", "
                   << ExifTags::ifdName(ti.ifdId_) << ", "
-                  << ExifTags::makeKey(ti.tag_, ti.ifdId_) << ", " 
+                  << exifKey.key() << ", " 
                   << ExifTags::tagDesc(ti.tag_, ti.ifdId_);
     }
 
diff --git a/src/tags.hpp b/src/tags.hpp
index 0a3a659..400f10b 100644
--- a/src/tags.hpp
+++ b/src/tags.hpp
@@ -21,7 +21,7 @@
 /*!
   @file    tags.hpp
   @brief   Exif tag and type information
-  @version $Name:  $ $Revision: 1.26 $
+  @version $Name:  $ $Revision: 1.27 $
   @author  Andreas Huggel (ahu)
            <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
   @date    15-Jan-04, ahu: created<BR>
@@ -114,19 +114,18 @@ namespace Exiv2 {
         ExifTags& operator=(const ExifTags& rhs);
 
     public:
-        //! Return an identifier for Exif metadata
-        static const char* familyName() { return familyName_; }
-
         /*!
-          @brief Return the name of the tag.
+          @brief Return the name of the tag or a string with the hexadecimal 
+                 value of the tag in the form "0x01ff", if the tag is not 
+                 a known Exif tag. 
+
           @param tag The tag
           @param ifdId IFD id
-          @return The name of the tag or a string indicating that the 
-                  tag is unknown. 
-          @throw Error ("No taginfo for IFD") if there is no tag info
-                 data for the given IFD id in the lookup tables.
+          @return The name of the tag or a string containing the hexadecimal
+                  value of the tag in the form "0x01ff", if this is an unknown 
+                  tag.
          */
-        static const char* tagName(uint16_t tag, IfdId ifdId);
+        static std::string tagName(uint16_t tag, IfdId ifdId);
         /*!
           @brief Return the description of the tag.
           @param tag The tag
@@ -137,8 +136,14 @@ namespace Exiv2 {
                  data for the given IFD id in the lookup tables.
          */
         static const char* tagDesc(uint16_t tag, IfdId ifdId);
-        //! Return the tag for one combination of IFD id and tagName
+        /*!
+          @brief Return the tag for one combination of IFD id and tagName. 
+                 If the tagName is not known, it expects tag names in the 
+                 form "0x01ff" and converts them to unsigned integer.
+         */
         static uint16_t tag(const std::string& tagName, IfdId ifdId);
+        //! Return the IFD id for an IFD item
+        static IfdId ifdIdByIfdItem(const std::string& ifdItem);
         //! Return the name of the IFD
         static const char* ifdName(IfdId ifdId);
         //! Return the related image item (image or thumbnail)
@@ -169,18 +174,6 @@ namespace Exiv2 {
         static const char* sectionDesc(uint16_t tag, IfdId ifdId);
         //! Return the section id for a section name
         static SectionId sectionId(const std::string& sectionName);
-        /*!
-          @brief Return the key for the tag and IFD id.  The key is of the form
-                 '<b>Exif</b>.ifdItem.tagName'.
-         */
-        static std::string makeKey(uint16_t tag, IfdId ifdId);
-        /*!
-          @brief Return tag and IFD id pair for the key.
-          @return A pair consisting of the tag and IFD id.
-          @throw Error ("Invalid key") if the key cannot be parsed into
-                 item item, section name and tag name parts.
-         */
-        static std::pair<uint16_t, IfdId> decomposeKey(const std::string& key);
         //! Interpret and print the value of an Exif tag
         static std::ostream& printTag(std::ostream& os,
                                       uint16_t tag, 
@@ -192,8 +185,6 @@ namespace Exiv2 {
     private:
         static int tagInfoIdx(uint16_t tag, IfdId ifdId);
 
-        static const char* familyName_;
-
         static const IfdInfo     ifdInfo_[];
         static const SectionInfo sectionInfo_[];
 

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list