Move ExifKey to component tags, moved IptcKey to component datasets
This commit is contained in:
parent
6034d99950
commit
79721d04e0
@ -3,7 +3,7 @@
|
||||
# Brief Dot file for a graph showing the component dependencies
|
||||
# of the Exiv2 library. Run the following command to get the image:
|
||||
# $ dot -Tgif -oexiv2.gif exiv2.dot
|
||||
# Version $Name: $ $Revision: 1.4 $
|
||||
# Version $Name: $ $Revision: 1.5 $
|
||||
# Author Andreas Huggel (ahu)
|
||||
# <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
# Date 18-Feb-04, ahu: created
|
||||
@ -15,8 +15,9 @@ L1 [shape=plaintext] ;
|
||||
L2 [shape=plaintext] ;
|
||||
L3 [shape=plaintext] ;
|
||||
L4 [shape=plaintext] ;
|
||||
L5 [shape=plaintext] ;
|
||||
|
||||
"L4" -> "L3" -> "L2" -> "L1" [style=invis] ;
|
||||
"L5" -> "L4" -> "L3" -> "L2" -> "L1" [style=invis] ;
|
||||
|
||||
"exif" [shape=box] ;
|
||||
"iptc" [shape=box] ;
|
||||
@ -30,11 +31,9 @@ L4 [shape=plaintext] ;
|
||||
"error" [shape=box] ;
|
||||
"makernote" [shape=box] ;
|
||||
|
||||
"exif" -> "metadatum" ;
|
||||
"exif" -> "tags" ;
|
||||
"exif" -> "makernote" ;
|
||||
"exif" -> "image" ;
|
||||
"iptc" -> "metadatum" ;
|
||||
"iptc" -> "datasets" ;
|
||||
"iptc" -> "image" ;
|
||||
"metadatum" -> "value" ;
|
||||
@ -44,10 +43,8 @@ L4 [shape=plaintext] ;
|
||||
"ifd" -> "error" ;
|
||||
"ifd" -> "types" ;
|
||||
"image" -> "types" ;
|
||||
"tags" -> "error" ;
|
||||
"tags" -> "value" ;
|
||||
"datasets" -> "error" ;
|
||||
"datasets" -> "value" ;
|
||||
"tags" -> "metadatum";
|
||||
"datasets" -> "metadatum" ;
|
||||
"value" -> "types" ;
|
||||
|
||||
{ rank=same; L1 error types }
|
||||
|
||||
BIN
doc/exiv2.gif
BIN
doc/exiv2.gif
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
@ -86,7 +86,7 @@ own header and source files.</p>
|
||||
|
||||
<center>
|
||||
<h3><a class="anchor">Exiv2 Components Diagram</a></h3>
|
||||
<p><img src="exiv2.gif" width="620" height="369" alt="Exiv2 components diagram"></p>
|
||||
<p><img src="exiv2.gif" width="470" height="465" alt="Exiv2 components diagram"></p>
|
||||
</center>
|
||||
<p> </p>
|
||||
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: datasets.cpp
|
||||
Version: $Name: $ $Revision: 1.6 $
|
||||
Version: $Name: $ $Revision: 1.7 $
|
||||
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
||||
History: 24-Jul-04, brad: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.6 $ $RCSfile: datasets.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.7 $ $RCSfile: datasets.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -34,14 +34,12 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.6 $ $RCSfile: datasets.cpp,v $");
|
||||
#include "error.hpp"
|
||||
#include "types.hpp"
|
||||
#include "value.hpp"
|
||||
#include "metadatum.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
// Todo: remove circular dependency
|
||||
#include "iptc.hpp" // for DataSet operator<<
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
@ -291,6 +289,77 @@ namespace Exiv2 {
|
||||
}
|
||||
} // IptcDataSets::dataSetList
|
||||
|
||||
const char* IptcKey::familyName_ = "Iptc";
|
||||
|
||||
IptcKey::IptcKey(const std::string& key)
|
||||
: key_(key)
|
||||
{
|
||||
decomposeKey();
|
||||
}
|
||||
|
||||
IptcKey::IptcKey(uint16_t tag, uint16_t record)
|
||||
: tag_(tag), record_(record)
|
||||
{
|
||||
makeKey();
|
||||
}
|
||||
|
||||
IptcKey::IptcKey(const IptcKey& rhs)
|
||||
: tag_(rhs.tag_), record_(rhs.record_), key_(rhs.key_)
|
||||
{
|
||||
}
|
||||
|
||||
IptcKey& IptcKey::operator=(const IptcKey& rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
Key::operator=(rhs);
|
||||
tag_ = rhs.tag_;
|
||||
record_ = rhs.record_;
|
||||
key_ = rhs.key_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IptcKey* IptcKey::clone() const
|
||||
{
|
||||
return new IptcKey(*this);
|
||||
}
|
||||
|
||||
void IptcKey::decomposeKey()
|
||||
{
|
||||
// Get the family name, record name and dataSet 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 recordName = key_.substr(pos0, pos1 - pos0);
|
||||
if (recordName == "") throw Error("Invalid key");
|
||||
std::string dataSetName = key_.substr(pos1 + 1);
|
||||
if (dataSetName == "") throw Error("Invalid key");
|
||||
|
||||
// Use the parts of the key to find dataSet and recordId
|
||||
uint16_t recId = IptcDataSets::recordId(recordName);
|
||||
uint16_t dataSet = IptcDataSets::dataSet(dataSetName, recId);
|
||||
|
||||
// Possibly translate hex name parts (0xabcd) to real names
|
||||
recordName = IptcDataSets::recordName(recId);
|
||||
dataSetName = IptcDataSets::dataSetName(dataSet, recId);
|
||||
|
||||
tag_ = dataSet;
|
||||
record_ = recId;
|
||||
key_ = familyName + "." + recordName + "." + dataSetName;
|
||||
} // IptcKey::decomposeKey
|
||||
|
||||
void IptcKey::makeKey()
|
||||
{
|
||||
key_ = std::string(familyName_)
|
||||
+ "." + IptcDataSets::recordName(record_)
|
||||
+ "." + IptcDataSets::dataSetName(tag_, record_);
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file datasets.hpp
|
||||
@brief Iptc dataSet and type information
|
||||
@version $Name: $ $Revision: 1.5 $
|
||||
@version $Name: $ $Revision: 1.6 $
|
||||
@author Brad Schick (brad) <schick@robotbattle.com>
|
||||
@date 24-Jul-04, brad: created
|
||||
*/
|
||||
@ -31,6 +31,7 @@
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "types.hpp"
|
||||
#include "metadatum.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
@ -256,6 +257,89 @@ namespace Exiv2 {
|
||||
|
||||
}; // class IptcDataSets
|
||||
|
||||
/*!
|
||||
@brief Concrete keys for Iptc metadata.
|
||||
*/
|
||||
class IptcKey : public Key {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to create an Iptc key from a key string.
|
||||
|
||||
@param key The key string.
|
||||
@throw Error ("Invalid key") if the first part of the key is not
|
||||
'Iptc' or the remaining parts of the key cannot be parsed and
|
||||
converted to a record name and a dataset name.
|
||||
*/
|
||||
explicit IptcKey(const std::string& key);
|
||||
/*!
|
||||
@brief Constructor to create an Iptc key from dataset and record ids.
|
||||
@param tag Dataset id
|
||||
@param record Record id
|
||||
*/
|
||||
IptcKey(uint16_t tag, uint16_t record);
|
||||
//! Copy constructor
|
||||
IptcKey(const IptcKey& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Assignment operator.
|
||||
*/
|
||||
IptcKey& operator=(const IptcKey& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual std::string key() const { return key_; }
|
||||
virtual const char* familyName() const { return familyName_; }
|
||||
/*!
|
||||
@brief Return the name of the group (the second part of the key).
|
||||
For Iptc keys, the group name is the record name.
|
||||
*/
|
||||
virtual std::string groupName() const { return recordName(); }
|
||||
virtual std::string tagName() const
|
||||
{ return IptcDataSets::dataSetName(tag_, record_); }
|
||||
virtual uint16_t tag() const { return tag_; }
|
||||
virtual IptcKey* clone() const;
|
||||
|
||||
//! Return the name of the record
|
||||
std::string recordName() const
|
||||
{ return IptcDataSets::recordName(record_); }
|
||||
//! Return the record id
|
||||
uint16_t record() const { return record_; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Set the key corresponding to the dataset and record id.
|
||||
The key is of the form '<b>Iptc</b>.recordName.dataSetName'.
|
||||
*/
|
||||
void makeKey();
|
||||
/*!
|
||||
@brief Parse and convert the key string into dataset and record id.
|
||||
Updates data members if the string can be decomposed, or throws
|
||||
Error ("Invalid key").
|
||||
|
||||
@throw Error ("Invalid key") if the key cannot be decomposed.
|
||||
*/
|
||||
void decomposeKey();
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
static const char* familyName_;
|
||||
|
||||
uint16_t tag_; //!< Tag value
|
||||
uint16_t record_; //!< Record value
|
||||
std::string key_; //!< Key
|
||||
|
||||
}; // class IptcKey
|
||||
|
||||
// *****************************************************************************
|
||||
// free functions
|
||||
|
||||
|
||||
156
src/exif.cpp
156
src/exif.cpp
@ -20,14 +20,14 @@
|
||||
*/
|
||||
/*
|
||||
File: exif.cpp
|
||||
Version: $Name: $ $Revision: 1.62 $
|
||||
Version: $Name: $ $Revision: 1.63 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 26-Jan-04, ahu: created
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.62 $ $RCSfile: exif.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.63 $ $RCSfile: exif.cpp,v $");
|
||||
|
||||
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
|
||||
#undef DEBUG_MAKERNOTE
|
||||
@ -73,158 +73,6 @@ namespace {
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
const char* ExifKey::familyName_ = "Exif";
|
||||
|
||||
ExifKey::ExifKey(const std::string& 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()), 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_), 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)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
Key::operator=(rhs);
|
||||
tag_ = rhs.tag_;
|
||||
ifdId_ = rhs.ifdId_;
|
||||
ifdItem_ = rhs.ifdItem_;
|
||||
idx_ = rhs.idx_;
|
||||
pMakerNote_ = rhs.pMakerNote_ ? rhs.pMakerNote_->clone() : 0;
|
||||
key_ = rhs.key_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string ExifKey::tagName() const
|
||||
{
|
||||
if (ifdId_ == makerIfdId) {
|
||||
assert(pMakerNote_);
|
||||
return pMakerNote_->tagName(tag_);
|
||||
}
|
||||
return ExifTags::tagName(tag_, ifdId_);
|
||||
}
|
||||
|
||||
ExifKey* ExifKey::clone() const
|
||||
{
|
||||
return new ExifKey(*this);
|
||||
}
|
||||
|
||||
std::string ExifKey::sectionName() const
|
||||
{
|
||||
if (ifdId_ == makerIfdId) {
|
||||
assert(pMakerNote_);
|
||||
return pMakerNote_->ifdItem();
|
||||
}
|
||||
return ExifTags::sectionName(tag(), ifdId());
|
||||
}
|
||||
|
||||
void ExifKey::decomposeKey()
|
||||
{
|
||||
// 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);
|
||||
if (ifdItem == "") throw Error("Invalid key");
|
||||
std::string tagName = key_.substr(pos1 + 1);
|
||||
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) {
|
||||
assert(pMakerNote_);
|
||||
return pMakerNote_->printTag(os, tag(), value);
|
||||
}
|
||||
return ExifTags::printTag(os, tag(), ifdId(), value);
|
||||
}
|
||||
|
||||
Exifdatum::Exifdatum(const Entry& e, ByteOrder byteOrder)
|
||||
: pKey_(new ExifKey(e)), pValue_(0)
|
||||
{
|
||||
|
||||
97
src/exif.hpp
97
src/exif.hpp
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file exif.hpp
|
||||
@brief Encoding and decoding of Exif data
|
||||
@version $Name: $ $Revision: 1.54 $
|
||||
@version $Name: $ $Revision: 1.55 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 09-Jan-04, ahu: created
|
||||
@ -60,101 +60,6 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Concrete keys for Exif metadata.
|
||||
class ExifKey : public Key {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to create an Exif key from a key string.
|
||||
|
||||
@param key The key string.
|
||||
@throw Error ("Invalid key") if the key cannot be parsed into three
|
||||
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);
|
||||
virtual ~ExifKey();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Assignment operator.
|
||||
*/
|
||||
ExifKey& operator=(const ExifKey& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual std::string key() const { return key_; }
|
||||
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 item.
|
||||
*/
|
||||
virtual std::string groupName() const { return ifdItem(); }
|
||||
virtual std::string tagName() 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;
|
||||
//! 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
|
||||
std::string ifdItem() const { return ifdItem_; }
|
||||
//! Return the name of the Exif section (deprecated)
|
||||
std::string sectionName() const;
|
||||
//! Return the index (unique id of this key within the original IFD)
|
||||
int idx() const { return idx_; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@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 members if the string can be decomposed,
|
||||
or throws Error ("Invalid key").
|
||||
|
||||
@throw Error ("Invalid key") if the key cannot be decomposed.
|
||||
*/
|
||||
void decomposeKey();
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
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
|
||||
}; // class ExifKey
|
||||
|
||||
/*!
|
||||
@brief Information related to one Exif tag.
|
||||
*/
|
||||
|
||||
75
src/iptc.cpp
75
src/iptc.cpp
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: iptc.cpp
|
||||
Version: $Name: $ $Revision: 1.5 $
|
||||
Version: $Name: $ $Revision: 1.6 $
|
||||
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
||||
History: 31-July-04, brad: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.5 $ $RCSfile: iptc.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.6 $ $RCSfile: iptc.cpp,v $");
|
||||
|
||||
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
|
||||
#undef DEBUG_MAKERNOTE
|
||||
@ -48,77 +48,6 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.5 $ $RCSfile: iptc.cpp,v $");
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
const char* IptcKey::familyName_ = "Iptc";
|
||||
|
||||
IptcKey::IptcKey(const std::string& key)
|
||||
: key_(key)
|
||||
{
|
||||
decomposeKey();
|
||||
}
|
||||
|
||||
IptcKey::IptcKey(uint16_t tag, uint16_t record)
|
||||
: tag_(tag), record_(record)
|
||||
{
|
||||
makeKey();
|
||||
}
|
||||
|
||||
IptcKey::IptcKey(const IptcKey& rhs)
|
||||
: tag_(rhs.tag_), record_(rhs.record_), key_(rhs.key_)
|
||||
{
|
||||
}
|
||||
|
||||
IptcKey& IptcKey::operator=(const IptcKey& rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
Key::operator=(rhs);
|
||||
tag_ = rhs.tag_;
|
||||
record_ = rhs.record_;
|
||||
key_ = rhs.key_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IptcKey* IptcKey::clone() const
|
||||
{
|
||||
return new IptcKey(*this);
|
||||
}
|
||||
|
||||
void IptcKey::decomposeKey()
|
||||
{
|
||||
// Get the family name, record name and dataSet 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 recordName = key_.substr(pos0, pos1 - pos0);
|
||||
if (recordName == "") throw Error("Invalid key");
|
||||
std::string dataSetName = key_.substr(pos1 + 1);
|
||||
if (dataSetName == "") throw Error("Invalid key");
|
||||
|
||||
// Use the parts of the key to find dataSet and recordId
|
||||
uint16_t recId = IptcDataSets::recordId(recordName);
|
||||
uint16_t dataSet = IptcDataSets::dataSet(dataSetName, recId);
|
||||
|
||||
// Possibly translate hex name parts (0xabcd) to real names
|
||||
recordName = IptcDataSets::recordName(recId);
|
||||
dataSetName = IptcDataSets::dataSetName(dataSet, recId);
|
||||
|
||||
tag_ = dataSet;
|
||||
record_ = recId;
|
||||
key_ = familyName + "." + recordName + "." + dataSetName;
|
||||
} // IptcKey::decomposeKey
|
||||
|
||||
void IptcKey::makeKey()
|
||||
{
|
||||
key_ = std::string(familyName_)
|
||||
+ "." + IptcDataSets::recordName(record_)
|
||||
+ "." + IptcDataSets::dataSetName(tag_, record_);
|
||||
}
|
||||
|
||||
Iptcdatum::Iptcdatum(const IptcKey& key,
|
||||
const Value* value)
|
||||
: pKey_(key.clone()), pValue_(0), modified_(false)
|
||||
|
||||
83
src/iptc.hpp
83
src/iptc.hpp
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file iptc.hpp
|
||||
@brief Encoding and decoding of Iptc data
|
||||
@version $Name: $ $Revision: 1.6 $
|
||||
@version $Name: $ $Revision: 1.7 $
|
||||
@author Brad Schick (brad)
|
||||
<a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a>
|
||||
@date 31-Jul-04, brad: created
|
||||
@ -48,87 +48,6 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Concrete keys for Iptc metadata.
|
||||
class IptcKey : public Key {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to create an Iptc key from a key string.
|
||||
|
||||
@param key The key string.
|
||||
@throw Error ("Invalid key") if the first part of the key is not
|
||||
'Iptc' or the remaining parts of the key cannot be parsed and
|
||||
converted to a record name and a dataset name.
|
||||
*/
|
||||
explicit IptcKey(const std::string& key);
|
||||
/*!
|
||||
@brief Constructor to create an Iptc key from dataset and record ids.
|
||||
@param tag Dataset id
|
||||
@param record Record id
|
||||
*/
|
||||
IptcKey(uint16_t tag, uint16_t record);
|
||||
//! Copy constructor
|
||||
IptcKey(const IptcKey& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Assignment operator.
|
||||
*/
|
||||
IptcKey& operator=(const IptcKey& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual std::string key() const { return key_; }
|
||||
virtual const char* familyName() const { return familyName_; }
|
||||
/*!
|
||||
@brief Return the name of the group (the second part of the key).
|
||||
For Iptc keys, the group name is the record name.
|
||||
*/
|
||||
virtual std::string groupName() const { return recordName(); }
|
||||
virtual std::string tagName() const
|
||||
{ return IptcDataSets::dataSetName(tag_, record_); }
|
||||
virtual uint16_t tag() const { return tag_; }
|
||||
virtual IptcKey* clone() const;
|
||||
|
||||
//! Return the name of the record
|
||||
std::string recordName() const
|
||||
{ return IptcDataSets::recordName(record_); }
|
||||
//! Return the record id
|
||||
uint16_t record() const { return record_; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Set the key corresponding to the dataset and record id.
|
||||
The key is of the form '<b>Iptc</b>.recordName.dataSetName'.
|
||||
*/
|
||||
void makeKey();
|
||||
/*!
|
||||
@brief Parse and convert the key string into dataset and record id.
|
||||
Updates data members if the string can be decomposed, or throws
|
||||
Error ("Invalid key").
|
||||
|
||||
@throw Error ("Invalid key") if the key cannot be decomposed.
|
||||
*/
|
||||
void decomposeKey();
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
static const char* familyName_;
|
||||
|
||||
uint16_t tag_; //!< Tag value
|
||||
uint16_t record_; //!< Record value
|
||||
std::string key_; //!< Key
|
||||
|
||||
}; // class IptcKey
|
||||
|
||||
/*!
|
||||
@brief Information related to one Iptc dataset.
|
||||
*/
|
||||
|
||||
161
src/tags.cpp
161
src/tags.cpp
@ -20,23 +20,22 @@
|
||||
*/
|
||||
/*
|
||||
File: tags.cpp
|
||||
Version: $Name: $ $Revision: 1.36 $
|
||||
Version: $Name: $ $Revision: 1.37 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 15-Jan-04, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.36 $ $RCSfile: tags.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.37 $ $RCSfile: tags.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "tags.hpp"
|
||||
#include "error.hpp"
|
||||
#include "types.hpp"
|
||||
#include "ifd.hpp"
|
||||
#include "value.hpp"
|
||||
|
||||
// Todo: remove circular dependency
|
||||
#include "exif.hpp" // for TagInfo operator<<
|
||||
#include "makernote.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
@ -393,6 +392,158 @@ namespace Exiv2 {
|
||||
}
|
||||
} // ExifTags::taglist
|
||||
|
||||
const char* ExifKey::familyName_ = "Exif";
|
||||
|
||||
ExifKey::ExifKey(const std::string& 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()), 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_), 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)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
Key::operator=(rhs);
|
||||
tag_ = rhs.tag_;
|
||||
ifdId_ = rhs.ifdId_;
|
||||
ifdItem_ = rhs.ifdItem_;
|
||||
idx_ = rhs.idx_;
|
||||
pMakerNote_ = rhs.pMakerNote_ ? rhs.pMakerNote_->clone() : 0;
|
||||
key_ = rhs.key_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string ExifKey::tagName() const
|
||||
{
|
||||
if (ifdId_ == makerIfdId) {
|
||||
assert(pMakerNote_);
|
||||
return pMakerNote_->tagName(tag_);
|
||||
}
|
||||
return ExifTags::tagName(tag_, ifdId_);
|
||||
}
|
||||
|
||||
ExifKey* ExifKey::clone() const
|
||||
{
|
||||
return new ExifKey(*this);
|
||||
}
|
||||
|
||||
std::string ExifKey::sectionName() const
|
||||
{
|
||||
if (ifdId_ == makerIfdId) {
|
||||
assert(pMakerNote_);
|
||||
return pMakerNote_->ifdItem();
|
||||
}
|
||||
return ExifTags::sectionName(tag(), ifdId());
|
||||
}
|
||||
|
||||
void ExifKey::decomposeKey()
|
||||
{
|
||||
// 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);
|
||||
if (ifdItem == "") throw Error("Invalid key");
|
||||
std::string tagName = key_.substr(pos1 + 1);
|
||||
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) {
|
||||
assert(pMakerNote_);
|
||||
return pMakerNote_->printTag(os, tag(), value);
|
||||
}
|
||||
return ExifTags::printTag(os, tag(), ifdId(), value);
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
|
||||
|
||||
102
src/tags.hpp
102
src/tags.hpp
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file tags.hpp
|
||||
@brief Exif tag and type information
|
||||
@version $Name: $ $Revision: 1.27 $
|
||||
@version $Name: $ $Revision: 1.28 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 15-Jan-04, ahu: created<BR>
|
||||
@ -32,6 +32,7 @@
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "metadatum.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
@ -46,6 +47,8 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class declarations
|
||||
class Value;
|
||||
class Entry;
|
||||
class MakerNote;
|
||||
|
||||
// *****************************************************************************
|
||||
// type definitions
|
||||
@ -192,6 +195,103 @@ namespace Exiv2 {
|
||||
|
||||
}; // class ExifTags
|
||||
|
||||
/*!
|
||||
@brief Concrete keys for Exif metadata.
|
||||
*/
|
||||
class ExifKey : public Key {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to create an Exif key from a key string.
|
||||
|
||||
@param key The key string.
|
||||
@throw Error ("Invalid key") if the key cannot be parsed into three
|
||||
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);
|
||||
virtual ~ExifKey();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Assignment operator.
|
||||
*/
|
||||
ExifKey& operator=(const ExifKey& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual std::string key() const { return key_; }
|
||||
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 item.
|
||||
*/
|
||||
virtual std::string groupName() const { return ifdItem(); }
|
||||
virtual std::string tagName() 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;
|
||||
//! 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
|
||||
std::string ifdItem() const { return ifdItem_; }
|
||||
//! Return the name of the Exif section (deprecated)
|
||||
std::string sectionName() const;
|
||||
//! Return the index (unique id of this key within the original IFD)
|
||||
int idx() const { return idx_; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@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 members if the string can be decomposed,
|
||||
or throws Error ("Invalid key").
|
||||
|
||||
@throw Error ("Invalid key") if the key cannot be decomposed.
|
||||
*/
|
||||
void decomposeKey();
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
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
|
||||
}; // class ExifKey
|
||||
|
||||
// *****************************************************************************
|
||||
// free functions
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user