[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