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
|
# Brief Dot file for a graph showing the component dependencies
|
||||||
# of the Exiv2 library. Run the following command to get the image:
|
# of the Exiv2 library. Run the following command to get the image:
|
||||||
# $ dot -Tgif -oexiv2.gif exiv2.dot
|
# $ dot -Tgif -oexiv2.gif exiv2.dot
|
||||||
# Version $Name: $ $Revision: 1.4 $
|
# Version $Name: $ $Revision: 1.5 $
|
||||||
# Author Andreas Huggel (ahu)
|
# Author Andreas Huggel (ahu)
|
||||||
# <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
# <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||||
# Date 18-Feb-04, ahu: created
|
# Date 18-Feb-04, ahu: created
|
||||||
@ -15,8 +15,9 @@ L1 [shape=plaintext] ;
|
|||||||
L2 [shape=plaintext] ;
|
L2 [shape=plaintext] ;
|
||||||
L3 [shape=plaintext] ;
|
L3 [shape=plaintext] ;
|
||||||
L4 [shape=plaintext] ;
|
L4 [shape=plaintext] ;
|
||||||
|
L5 [shape=plaintext] ;
|
||||||
|
|
||||||
"L4" -> "L3" -> "L2" -> "L1" [style=invis] ;
|
"L5" -> "L4" -> "L3" -> "L2" -> "L1" [style=invis] ;
|
||||||
|
|
||||||
"exif" [shape=box] ;
|
"exif" [shape=box] ;
|
||||||
"iptc" [shape=box] ;
|
"iptc" [shape=box] ;
|
||||||
@ -30,11 +31,9 @@ L4 [shape=plaintext] ;
|
|||||||
"error" [shape=box] ;
|
"error" [shape=box] ;
|
||||||
"makernote" [shape=box] ;
|
"makernote" [shape=box] ;
|
||||||
|
|
||||||
"exif" -> "metadatum" ;
|
|
||||||
"exif" -> "tags" ;
|
"exif" -> "tags" ;
|
||||||
"exif" -> "makernote" ;
|
"exif" -> "makernote" ;
|
||||||
"exif" -> "image" ;
|
"exif" -> "image" ;
|
||||||
"iptc" -> "metadatum" ;
|
|
||||||
"iptc" -> "datasets" ;
|
"iptc" -> "datasets" ;
|
||||||
"iptc" -> "image" ;
|
"iptc" -> "image" ;
|
||||||
"metadatum" -> "value" ;
|
"metadatum" -> "value" ;
|
||||||
@ -44,10 +43,8 @@ L4 [shape=plaintext] ;
|
|||||||
"ifd" -> "error" ;
|
"ifd" -> "error" ;
|
||||||
"ifd" -> "types" ;
|
"ifd" -> "types" ;
|
||||||
"image" -> "types" ;
|
"image" -> "types" ;
|
||||||
"tags" -> "error" ;
|
"tags" -> "metadatum";
|
||||||
"tags" -> "value" ;
|
"datasets" -> "metadatum" ;
|
||||||
"datasets" -> "error" ;
|
|
||||||
"datasets" -> "value" ;
|
|
||||||
"value" -> "types" ;
|
"value" -> "types" ;
|
||||||
|
|
||||||
{ rank=same; L1 error 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>
|
<center>
|
||||||
<h3><a class="anchor">Exiv2 Components Diagram</a></h3>
|
<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>
|
</center>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
|
||||||
|
|||||||
@ -20,13 +20,13 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
File: datasets.cpp
|
File: datasets.cpp
|
||||||
Version: $Name: $ $Revision: 1.6 $
|
Version: $Name: $ $Revision: 1.7 $
|
||||||
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
||||||
History: 24-Jul-04, brad: created
|
History: 24-Jul-04, brad: created
|
||||||
*/
|
*/
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
#include "rcsid.hpp"
|
#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
|
// included header files
|
||||||
@ -34,14 +34,12 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.6 $ $RCSfile: datasets.cpp,v $");
|
|||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "value.hpp"
|
#include "value.hpp"
|
||||||
|
#include "metadatum.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
// Todo: remove circular dependency
|
|
||||||
#include "iptc.hpp" // for DataSet operator<<
|
|
||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// class member definitions
|
// class member definitions
|
||||||
namespace Exiv2 {
|
namespace Exiv2 {
|
||||||
@ -291,6 +289,77 @@ namespace Exiv2 {
|
|||||||
}
|
}
|
||||||
} // IptcDataSets::dataSetList
|
} // 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
|
// free functions
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
/*!
|
/*!
|
||||||
@file datasets.hpp
|
@file datasets.hpp
|
||||||
@brief Iptc dataSet and type information
|
@brief Iptc dataSet and type information
|
||||||
@version $Name: $ $Revision: 1.5 $
|
@version $Name: $ $Revision: 1.6 $
|
||||||
@author Brad Schick (brad) <schick@robotbattle.com>
|
@author Brad Schick (brad) <schick@robotbattle.com>
|
||||||
@date 24-Jul-04, brad: created
|
@date 24-Jul-04, brad: created
|
||||||
*/
|
*/
|
||||||
@ -31,6 +31,7 @@
|
|||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// included header files
|
// included header files
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
#include "metadatum.hpp"
|
||||||
|
|
||||||
// + standard includes
|
// + standard includes
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -256,6 +257,89 @@ namespace Exiv2 {
|
|||||||
|
|
||||||
}; // class IptcDataSets
|
}; // 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
|
// free functions
|
||||||
|
|
||||||
|
|||||||
156
src/exif.cpp
156
src/exif.cpp
@ -20,14 +20,14 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
File: exif.cpp
|
File: exif.cpp
|
||||||
Version: $Name: $ $Revision: 1.62 $
|
Version: $Name: $ $Revision: 1.63 $
|
||||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||||
History: 26-Jan-04, ahu: created
|
History: 26-Jan-04, ahu: created
|
||||||
11-Feb-04, ahu: isolated as a component
|
11-Feb-04, ahu: isolated as a component
|
||||||
*/
|
*/
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
#include "rcsid.hpp"
|
#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
|
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
|
||||||
#undef DEBUG_MAKERNOTE
|
#undef DEBUG_MAKERNOTE
|
||||||
@ -73,158 +73,6 @@ namespace {
|
|||||||
// class member definitions
|
// class member definitions
|
||||||
namespace Exiv2 {
|
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)
|
Exifdatum::Exifdatum(const Entry& e, ByteOrder byteOrder)
|
||||||
: pKey_(new ExifKey(e)), pValue_(0)
|
: pKey_(new ExifKey(e)), pValue_(0)
|
||||||
{
|
{
|
||||||
|
|||||||
97
src/exif.hpp
97
src/exif.hpp
@ -21,7 +21,7 @@
|
|||||||
/*!
|
/*!
|
||||||
@file exif.hpp
|
@file exif.hpp
|
||||||
@brief Encoding and decoding of Exif data
|
@brief Encoding and decoding of Exif data
|
||||||
@version $Name: $ $Revision: 1.54 $
|
@version $Name: $ $Revision: 1.55 $
|
||||||
@author Andreas Huggel (ahu)
|
@author Andreas Huggel (ahu)
|
||||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||||
@date 09-Jan-04, ahu: created
|
@date 09-Jan-04, ahu: created
|
||||||
@ -60,101 +60,6 @@ namespace Exiv2 {
|
|||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// class definitions
|
// 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.
|
@brief Information related to one Exif tag.
|
||||||
*/
|
*/
|
||||||
|
|||||||
75
src/iptc.cpp
75
src/iptc.cpp
@ -20,13 +20,13 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
File: iptc.cpp
|
File: iptc.cpp
|
||||||
Version: $Name: $ $Revision: 1.5 $
|
Version: $Name: $ $Revision: 1.6 $
|
||||||
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
||||||
History: 31-July-04, brad: created
|
History: 31-July-04, brad: created
|
||||||
*/
|
*/
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
#include "rcsid.hpp"
|
#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
|
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
|
||||||
#undef DEBUG_MAKERNOTE
|
#undef DEBUG_MAKERNOTE
|
||||||
@ -48,77 +48,6 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.5 $ $RCSfile: iptc.cpp,v $");
|
|||||||
// class member definitions
|
// class member definitions
|
||||||
namespace Exiv2 {
|
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,
|
Iptcdatum::Iptcdatum(const IptcKey& key,
|
||||||
const Value* value)
|
const Value* value)
|
||||||
: pKey_(key.clone()), pValue_(0), modified_(false)
|
: pKey_(key.clone()), pValue_(0), modified_(false)
|
||||||
|
|||||||
83
src/iptc.hpp
83
src/iptc.hpp
@ -21,7 +21,7 @@
|
|||||||
/*!
|
/*!
|
||||||
@file iptc.hpp
|
@file iptc.hpp
|
||||||
@brief Encoding and decoding of Iptc data
|
@brief Encoding and decoding of Iptc data
|
||||||
@version $Name: $ $Revision: 1.6 $
|
@version $Name: $ $Revision: 1.7 $
|
||||||
@author Brad Schick (brad)
|
@author Brad Schick (brad)
|
||||||
<a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a>
|
<a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a>
|
||||||
@date 31-Jul-04, brad: created
|
@date 31-Jul-04, brad: created
|
||||||
@ -48,87 +48,6 @@ namespace Exiv2 {
|
|||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// class definitions
|
// 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.
|
@brief Information related to one Iptc dataset.
|
||||||
*/
|
*/
|
||||||
|
|||||||
161
src/tags.cpp
161
src/tags.cpp
@ -20,23 +20,22 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
File: tags.cpp
|
File: tags.cpp
|
||||||
Version: $Name: $ $Revision: 1.36 $
|
Version: $Name: $ $Revision: 1.37 $
|
||||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||||
History: 15-Jan-04, ahu: created
|
History: 15-Jan-04, ahu: created
|
||||||
*/
|
*/
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
#include "rcsid.hpp"
|
#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
|
// included header files
|
||||||
#include "tags.hpp"
|
#include "tags.hpp"
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
#include "ifd.hpp"
|
||||||
#include "value.hpp"
|
#include "value.hpp"
|
||||||
|
#include "makernote.hpp"
|
||||||
// Todo: remove circular dependency
|
|
||||||
#include "exif.hpp" // for TagInfo operator<<
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@ -392,6 +391,158 @@ namespace Exiv2 {
|
|||||||
os << gpsTagInfo[i] << "\n";
|
os << gpsTagInfo[i] << "\n";
|
||||||
}
|
}
|
||||||
} // ExifTags::taglist
|
} // 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
|
// free functions
|
||||||
|
|||||||
102
src/tags.hpp
102
src/tags.hpp
@ -21,7 +21,7 @@
|
|||||||
/*!
|
/*!
|
||||||
@file tags.hpp
|
@file tags.hpp
|
||||||
@brief Exif tag and type information
|
@brief Exif tag and type information
|
||||||
@version $Name: $ $Revision: 1.27 $
|
@version $Name: $ $Revision: 1.28 $
|
||||||
@author Andreas Huggel (ahu)
|
@author Andreas Huggel (ahu)
|
||||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||||
@date 15-Jan-04, ahu: created<BR>
|
@date 15-Jan-04, ahu: created<BR>
|
||||||
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// included header files
|
// included header files
|
||||||
|
#include "metadatum.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
// + standard includes
|
// + standard includes
|
||||||
@ -46,6 +47,8 @@ namespace Exiv2 {
|
|||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// class declarations
|
// class declarations
|
||||||
class Value;
|
class Value;
|
||||||
|
class Entry;
|
||||||
|
class MakerNote;
|
||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// type definitions
|
// type definitions
|
||||||
@ -192,6 +195,103 @@ namespace Exiv2 {
|
|||||||
|
|
||||||
}; // class ExifTags
|
}; // 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
|
// free functions
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user