[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:22 UTC 2017
Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=29f2e78
The following commit has been merged in the master branch:
commit 29f2e78ce32342f9b7ef374f5b8b4a9266185fbb
Author: Andreas Huggel <ahuggel at gmx.net>
Date: Mon May 24 02:18:47 2004 +0000
* Replaced too simple prefix with a more general concept of a makernote header.
* Fixed match() to prefer an exact match over a wildcard match with the same
number of matching characters (Key "Nikon" now prefers registry entry "Nikon"
over "Nikon*"), simplified the return value of match() to an int score value.
* Added DEBUG_REGISTRY debug output.
* Code and documentation cleanup.
---
src/makernote.cpp | 169 +++++++++++++++++++++++++++++++++++++++---------------
src/makernote.hpp | 114 +++++++++++++++++++++++++-----------
2 files changed, 206 insertions(+), 77 deletions(-)
diff --git a/src/makernote.cpp b/src/makernote.cpp
index acadd35..0d478b1 100644
--- a/src/makernote.cpp
+++ b/src/makernote.cpp
@@ -20,16 +20,17 @@
*/
/*
File: makernote.cpp
- Version: $Name: $ $Revision: 1.18 $
+ Version: $Name: $ $Revision: 1.19 $
Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
History: 18-Feb-04, ahu: created
*/
// *****************************************************************************
#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name: $ $Revision: 1.18 $ $RCSfile: makernote.cpp,v $")
+EXIV2_RCSID("@(#) $Name: $ $Revision: 1.19 $ $RCSfile: makernote.cpp,v $")
-// Define DEBUG_MAKERNOTE to output debug information to std::cerr
+// Define DEBUG_* to output debug information to std::cerr
#undef DEBUG_MAKERNOTE
+#define DEBUG_REGISTRY
// *****************************************************************************
// included header files
@@ -42,7 +43,7 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.18 $ $RCSfile: makernote.cpp,v $")
#include <sstream>
#include <iomanip>
-#ifdef DEBUG_MAKERNOTE
+#if defined DEBUG_MAKERNOTE || defined DEBUG_REGISTRY
# include <iostream>
#endif
@@ -50,6 +51,12 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.18 $ $RCSfile: makernote.cpp,v $")
// class member definitions
namespace Exiv2 {
+ MakerNote::MakerNote(const MnTagInfo* pMnTagInfo, bool alloc)
+ : pMnTagInfo_(pMnTagInfo), alloc_(alloc),
+ offset_(0), byteOrder_(invalidByteOrder)
+ {
+ }
+
std::string MakerNote::makeKey(uint16 tag) const
{
return std::string(ExifTags::ifdItem(makerIfd))
@@ -150,6 +157,14 @@ namespace Exiv2 {
<< tagDesc(tag);
} // MakerNote::writeMnTagInfo
+
+ IfdMakerNote::IfdMakerNote(const MakerNote::MnTagInfo* pMnTagInfo,
+ bool alloc)
+ : MakerNote(pMnTagInfo, alloc),
+ absOffset_(true), adjOffset_(0), ifd_(makerIfd, 0, alloc)
+ {
+ }
+
int IfdMakerNote::read(const char* buf,
long len,
ByteOrder byteOrder,
@@ -159,24 +174,22 @@ namespace Exiv2 {
offset_ = offset;
// Set byte order if none is set yet
if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
- int rc = 0;
- if (!prefix_.empty()) {
- // Check if makernote is long enough and starts with prefix
- if ( len < static_cast<long>(prefix_.size())
- || prefix_ != std::string(buf, prefix_.size())) rc = 2;
- }
- if (!absOffset_) {
- // Use offsets relative to the start of the Makernote field
- offset = 0;
+ // Read and check the header (and set offset adjustment)
+ int rc = readHeader(buf, len, byteOrder);
+ if (rc == 0) {
+ rc = checkHeader();
}
+ // Adjust the offset
+ offset = absOffset_ ? offset + adjOffset_ : adjOffset_;
+ // Read the makernote IFD
if (rc == 0) {
- rc = ifd_.read(buf + prefix_.size(),
- len - prefix_.size(),
- byteOrder_,
- offset + prefix_.size());
+ rc = ifd_.read(buf + headerSize(),
+ len - headerSize(),
+ byteOrder_,
+ offset);
}
if (rc == 0) {
- // IfdMakerNote does not support multiple IFDs
+ // IfdMakerNote currently does not support multiple IFDs
if (ifd_.next() != 0) rc = 3;
}
if (rc == 0) {
@@ -188,8 +201,8 @@ namespace Exiv2 {
#ifdef DEBUG_MAKERNOTE
hexdump(std::cerr, buf, len, offset);
if (rc == 0) ifd_.print(std::cerr);
- else std::cerr << "IfdMakerNote::read() failed, rc = " << rc << "
";
#endif
+
return rc;
} // IfdMakerNote::read
@@ -199,20 +212,39 @@ namespace Exiv2 {
offset_ = offset;
// Set byte order if none is set yet
if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
+
long len = 0;
- if (!prefix_.empty()) {
- // Write the prefix string to the Makernote buffer
- memcpy(buf, prefix_.data(), prefix_.size());
- len += prefix_.size();
- }
- if (!absOffset_) {
- // Use offsets relative to the start of the Makernote field
- offset = 0;
- }
- len += ifd_.copy(buf + len, byteOrder_, offset + len);
+ len += copyHeader(buf);
+ len += ifd_.copy(buf + len, byteOrder_, offset_);
+
return len;
} // IfdMakerNote::copy
+ int IfdMakerNote::readHeader(const char* buf,
+ long len,
+ ByteOrder byteOrder)
+ {
+ // Default implementation does nothing, assuming there is no header
+ return 0;
+ }
+
+ int IfdMakerNote::checkHeader() const
+ {
+ // Default implementation does nothing, assuming there is no header
+ return 0;
+ }
+
+ long IfdMakerNote::copyHeader(char* buf) const
+ {
+ if (header_.size_ != 0) memcpy(buf, header_.pData_, header_.size_);
+ return header_.size_;
+ }
+
+ long IfdMakerNote::headerSize() const
+ {
+ return header_.size_;
+ }
+
Entries::const_iterator IfdMakerNote::findIdx(int idx) const
{
return ifd_.findIdx(idx);
@@ -220,7 +252,7 @@ namespace Exiv2 {
long IfdMakerNote::size() const
{
- return prefix_.size() + ifd_.size() + ifd_.dataSize();
+ return headerSize() + ifd_.size() + ifd_.dataSize();
}
MakerNoteFactory* MakerNoteFactory::pInstance_ = 0;
@@ -237,7 +269,7 @@ namespace Exiv2 {
const std::string& model,
CreateFct createMakerNote)
{
-#ifdef DEBUG_MAKERNOTE
+#ifdef DEBUG_REGISTRY
std::cerr << "Registering MakerNote create function for \""
<< make << "\" and \"" << model << "\".
";
#endif
@@ -276,42 +308,80 @@ namespace Exiv2 {
const std::string& model,
bool alloc) const
{
+#ifdef DEBUG_REGISTRY
+ std::cerr << "Entering MakerNoteFactory::create(\""
+ << make << "\", \"" << model << "\", "
+ << (alloc == true ? "true" : "false") << ")
";
+#endif
// loop through each make of the registry to find the best matching make
- int matchCount = -1;
+ int score = 0;
ModelRegistry* modelRegistry = 0;
+#ifdef DEBUG_REGISTRY
+ std::string makeMatch;
+ std::cerr << "Searching make registry...
";
+#endif
Registry::const_iterator end1 = registry_.end();
Registry::const_iterator pos1;
for (pos1 = registry_.begin(); pos1 != end1; ++pos1) {
- std::pair<bool, int> rc = match(pos1->first, make);
- if (rc.first && rc.second > matchCount) {
- matchCount = rc.second;
+ int rc = match(pos1->first, make);
+ if (rc > score) {
+ score = rc;
+#ifdef DEBUG_REGISTRY
+ makeMatch = pos1->first;
+#endif
modelRegistry = pos1->second;
}
}
if (modelRegistry == 0) return 0;
+#ifdef DEBUG_REGISTRY
+ std::cerr << "Best match is \"" << makeMatch << "\".
";
+#endif
// loop through each model of the model registry to find the best match
- matchCount = -1;
+ score = 0;
CreateFct createMakerNote = 0;
+#ifdef DEBUG_REGISTRY
+ std::string modelMatch;
+ std::cerr << "Searching model registry...
";
+#endif
ModelRegistry::const_iterator end2 = modelRegistry->end();
ModelRegistry::const_iterator pos2;
for (pos2 = modelRegistry->begin(); pos2 != end2; ++pos2) {
- std::pair<bool, int> rc = match(pos2->first, model);
- if (rc.first && rc.second > matchCount) {
- matchCount = rc.second;
+ int rc = match(pos2->first, model);
+ if (rc > score) {
+ score = rc;
+#ifdef DEBUG_REGISTRY
+ modelMatch = pos2->first;
+#endif
createMakerNote = pos2->second;
}
}
if (createMakerNote == 0) return 0;
+#ifdef DEBUG_REGISTRY
+ std::cerr << "Best match is \"" << modelMatch << "\".
";
+#endif
return createMakerNote(alloc);
} // MakerNoteFactory::create
- std::pair<bool, int> MakerNoteFactory::match(const std::string& regEntry,
- const std::string& key)
+ int MakerNoteFactory::match(const std::string& regEntry,
+ const std::string& key)
{
+#ifdef DEBUG_REGISTRY
+ std::cerr << " Matching registry entry \"" << regEntry << "\" ("
+ << regEntry.size() << ") with key \"" << key << "\" ("
+ << key.size() << "): ";
+#endif
// Todo: make the comparisons case insensitive
+ // Handle exact match (this is only necessary because of the different
+ // return value - the following algorithm also finds exact matches)
+ if (regEntry == key) {
+#ifdef DEBUG_REGISTRY
+ std::cerr << "Exact match (score: " << key.size() + 2 << ")
";
+#endif
+ return key.size() + 2;
+ }
std::string uKey = key;
std::string uReg = regEntry;
@@ -327,7 +397,10 @@ namespace Exiv2 {
uReg.substr(ei) : uReg.substr(ei, pos - ei);
if (ki == std::string::npos) {
- return std::make_pair(false, 0);
+#ifdef DEBUG_REGISTRY
+ std::cerr << "Not a match.
";
+#endif
+ return 0;
}
bool found = false;
@@ -372,15 +445,21 @@ namespace Exiv2 {
count += ss.size();
}
else {
- return std::make_pair(false, 0);
+#ifdef DEBUG_REGISTRY
+ std::cerr << "Not a match.
";
+#endif
+ return 0;
}
} // if the substr is not empty
ei = pos == std::string::npos ? std::string::npos : pos + 1;
} // while ei doesn't point to the end of the registry entry
-
- return std::make_pair(true, count);
+
+#ifdef DEBUG_REGISTRY
+ std::cerr << "Match (score: " << count + 1 << ")
";
+#endif
+ return count + 1;
} // MakerNoteFactory::match
diff --git a/src/makernote.hpp b/src/makernote.hpp
index 1b7edb5..a9da013 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.17 $
+ @version $Name: $ $Revision: 1.18 $
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
@date 18-Feb-04, ahu: created
@@ -85,11 +85,17 @@ namespace Exiv2 {
To implement a new IFD makernote, all that you need to do is
- subclass %IfdMakerNote,
- - implement the create function,
+ - implement methods to read and check the header (if any) as well as
+ clone and create functions,
- add a list of tag descriptions and appropriate print functions and
- register the camera make/model and create function in the makernote factory.
.
- See CanonMakerNote for an example.
+ See existing makernote implementations for examples, e.g., CanonMakerNote
+ or FujiMakerNote.
+
+ Finally, the implementation files should be named *mn.[ch]pp, so that the
+ magic, which ensures that the makernote is automatically registered
+ in the factory, will pick it up (see mn.sh for details).
*/
class MakerNote {
public:
@@ -112,21 +118,18 @@ namespace Exiv2 {
allows to choose whether or not memory management is required
for the Entries.
*/
- MakerNote(const MnTagInfo* pMnTagInfo =0, bool alloc =true)
- : pMnTagInfo_(pMnTagInfo), alloc_(alloc),
- byteOrder_(invalidByteOrder), offset_(0) {}
+ explicit MakerNote(const MnTagInfo* pMnTagInfo =0, bool alloc =true);
//! Virtual destructor.
virtual ~MakerNote() {}
//@}
//! @name Manipulators
//@{
- //! Set the byte order (little or big endian).
- void setByteOrder(ByteOrder byteOrder) { byteOrder_ = byteOrder; }
/*!
- @brief Read the makernote from character buffer buf of length len at
- position offset (from the start of the TIFF header) and encoded
- in byte order byteOrder.
+ @brief Read the makernote, including the makernote header, from
+ character buffer buf of length len at position offset (from the
+ start of the TIFF header) and encoded in byte order byteOrder.
+ Return 0 if successful.
*/
virtual int read(const char* buf,
long len,
@@ -231,13 +234,16 @@ namespace Exiv2 {
False: no memory management needed.
*/
const bool alloc_;
- /*!
+ /*!
+ @brief Offset of the makernote from the start of the TIFF header
+ (for offset()).
+ */
+ long offset_;
+ /*!
@brief Alternative byte order to use, invalid if the byte order of the
Exif block can be used
*/
ByteOrder byteOrder_;
- //! Offset of the makernote from the start of the TIFF header
- long offset_;
}; // class MakerNote
@@ -253,9 +259,8 @@ namespace Exiv2 {
allows to choose whether or not memory management is required
for the Entries.
*/
- IfdMakerNote(const MakerNote::MnTagInfo* pMnTagInfo =0, bool alloc =true)
- : MakerNote(pMnTagInfo, alloc),
- absOffset_(true), ifd_(makerIfd, 0, alloc) {}
+ explicit IfdMakerNote(const MakerNote::MnTagInfo* pMnTagInfo =0,
+ bool alloc =true);
//! Virtual destructor
virtual ~IfdMakerNote() {}
//@}
@@ -266,6 +271,17 @@ namespace Exiv2 {
long len,
ByteOrder byteOrder,
long offset);
+ /*!
+ @brief Read the makernote header from the makernote databuffer. This
+ method must set the offset adjustment (adjOffset_), if needed
+ (assuming that the required information is in the header).
+ Return 0 if successful.
+ @note The default implementation does nothing, assuming there is no
+ header
+ */
+ virtual int readHeader(const char* buf,
+ long len,
+ ByteOrder byteOrder);
virtual long copy(char* buf, ByteOrder byteOrder, long offset);
void add(const Entry& entry) { ifd_.add(entry); }
Entries::iterator begin() { return ifd_.begin(); }
@@ -278,7 +294,27 @@ namespace Exiv2 {
Entries::const_iterator end() const { return ifd_.end(); }
Entries::const_iterator findIdx(int idx) const;
long size() const;
- virtual MakerNote* clone(bool alloc =true) const =0;
+ /*!
+ @brief Check the makernote header. This will typically check if a
+ required prefix string is present in the header. Return 0 if
+ successful.
+ @note The default implementation does nothing, assuming there is no
+ header
+ */
+ virtual int checkHeader() const;
+ /*!
+ @brief Write the makernote header to a character buffer, return the
+ number of characters written.
+ @note The default implementation copies the header_ buffer.
+ */
+ virtual long copyHeader(char* buf) const;
+ /*!
+ @brief Return the size of the makernote header in bytes.
+ @note The default implementation returns the size of the header_
+ buffer.
+ */
+ virtual long headerSize() const;
+ virtual IfdMakerNote* clone(bool alloc =true) const =0;
virtual std::string sectionName(uint16 tag) const =0;
virtual std::ostream& printTag(std::ostream& os,
uint16 tag,
@@ -287,14 +323,23 @@ namespace Exiv2 {
protected:
// DATA
- //! String prefix at the beginning of the makernote, before the IFD
- std::string prefix_;
/*!
- @brief True: Offsets are from start of the TIFF header,
- False: Offsets are from start of the makernote
+ @brief True: Adjustment of the IFD offsets is to be added to the
+ offset from the start of the TIFF header,
+ False: Adjustment of the IFD offsets is a suitable absolute
+ value. Ignore the offset from the start of the TIFF
+ header.
+ */
+ bool absOffset_;
+ /*!
+ @brief Adjustment of the IFD offsets relative to the start of the
+ TIFF header or to the start of the makernote, depending on
+ the setting of absOffset_.
*/
- bool absOffset_;
- //! MakerNote IFD
+ long adjOffset_;
+ //! Data buffer for the makernote header
+ DataBuf header_;
+ //! The makernote IFD
Ifd ifd_;
}; // class IfdMakerNote
@@ -383,15 +428,20 @@ namespace Exiv2 {
@brief Match a registry entry with a key (used for make and model).
The matching algorithm is case insensitive and wildcards ('*') in the
- registry entry are supported. The best match is the match with the
- most matching characters.
-
- @return A pair of which the first component indicates whether or not
- the key matches and the second component contains the number
- of matching characters.
+ registry entry are supported. The best match is an exact match, then
+ a match is rated according to the number of matching characters.
+
+ @return A score value indicating how good the key and registry entry
+ match. 0 means no match, values greater than 0 indicate a
+ match, larger values are better matches:<BR>
+ 0: key and registry entry do not match<BR>
+ 1: a pure wildcard match, i.e., the registry entry is just
+ a wildcard.<BR>
+ Score values greater than 1 are computed by adding 1 to the
+ number of matching characters, except for an exact match,
+ which scores 2 plus the number of matching characters.
*/
- static std::pair<bool, int> match(const std::string& regEntry,
- const std::string& key);
+ static int match(const std::string& regEntry, const std::string& key);
private:
//! @name Creators
--
exiv2 packaging
More information about the pkg-kde-commits
mailing list