Changed MakerNote class hierarchy to use std::auto_ptr where appropriate

v0.27.3
Andreas Huggel 21 years ago
parent b2b9cfd599
commit 8551c935f8

@ -20,7 +20,7 @@
*/ */
/* /*
File: canonmn.cpp File: canonmn.cpp
Version: $Name: $ $Revision: 1.14 $ Version: $Name: $ $Revision: 1.15 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 18-Feb-04, ahu: created History: 18-Feb-04, ahu: created
07-Mar-04, ahu: isolated as a separate component 07-Mar-04, ahu: isolated as a separate component
@ -30,7 +30,7 @@
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.14 $ $RCSfile: canonmn.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.15 $ $RCSfile: canonmn.cpp,v $");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
@ -72,7 +72,12 @@ namespace Exiv2 {
{ {
} }
CanonMakerNote* CanonMakerNote::clone(bool alloc) const CanonMakerNote::AutoPtr CanonMakerNote::clone(bool alloc) const
{
return AutoPtr(clone_(alloc));
}
CanonMakerNote* CanonMakerNote::clone_(bool alloc) const
{ {
return new CanonMakerNote(alloc); return new CanonMakerNote(alloc);
} }
@ -656,13 +661,13 @@ namespace Exiv2 {
// ***************************************************************************** // *****************************************************************************
// free functions // free functions
MakerNote* createCanonMakerNote(bool alloc, MakerNote::AutoPtr createCanonMakerNote(bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
long offset) long offset)
{ {
return new CanonMakerNote(alloc); return MakerNote::AutoPtr(new CanonMakerNote(alloc));
} }
} // namespace Exiv2 } // namespace Exiv2

@ -23,7 +23,7 @@
@brief Canon MakerNote implemented according to the specification @brief Canon MakerNote implemented according to the specification
<a href="http://www.burren.cx/david/canon.html"> <a href="http://www.burren.cx/david/canon.html">
EXIF MakerNote of Canon</a> by David Burren EXIF MakerNote of Canon</a> by David Burren
@version $Name: $ $Revision: 1.12 $ @version $Name: $ $Revision: 1.13 $
@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<BR> @date 18-Feb-04, ahu: created<BR>
@ -40,6 +40,7 @@
// + standard includes // + standard includes
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
@ -53,9 +54,10 @@ namespace Exiv2 {
// free functions // free functions
/*! /*!
@brief Return a pointer to a newly created empty MakerNote initialized to @brief Return an auto-pointer to a newly created empty MakerNote
operate in the memory management model indicated. The caller owns initialized to operate in the memory management model indicated.
this copy and is responsible to delete it! The caller owns this copy and the auto-pointer ensures that it
will be deleted.
@param alloc Memory management model for the new MakerNote. Determines if @param alloc Memory management model for the new MakerNote. Determines if
memory required to store data should be allocated and deallocated memory required to store data should be allocated and deallocated
@ -69,10 +71,11 @@ namespace Exiv2 {
@param offset Offset from the start of the TIFF header of the makernote @param offset Offset from the start of the TIFF header of the makernote
buffer (not used). buffer (not used).
@return A pointer to a newly created empty MakerNote. The caller owns @return An auto-pointer to a newly created empty MakerNote. The caller
this copy and is responsible to delete it! owns this copy and the auto-pointer ensures that it will be
deleted.
*/ */
MakerNote* createCanonMakerNote(bool alloc, MakerNote::AutoPtr createCanonMakerNote(bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
@ -84,6 +87,9 @@ namespace Exiv2 {
//! MakerNote for Canon cameras //! MakerNote for Canon cameras
class CanonMakerNote : public IfdMakerNote { class CanonMakerNote : public IfdMakerNote {
public: public:
//! Shortcut for a %CanonMakerNote auto pointer.
typedef std::auto_ptr<CanonMakerNote> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
/*! /*!
@ -97,7 +103,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
CanonMakerNote* clone(bool alloc =true) const; CanonMakerNote::AutoPtr clone(bool alloc =true) const;
//! Return the name of the makernote item ("Canon") //! Return the name of the makernote item ("Canon")
std::string ifdItem() const { return ifdItem_; } std::string ifdItem() const { return ifdItem_; }
std::ostream& printTag(std::ostream& os, std::ostream& printTag(std::ostream& os,
@ -170,6 +176,9 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
CanonMakerNote* clone_(bool alloc =true) const;
//! Structure used to auto-register the MakerNote. //! Structure used to auto-register the MakerNote.
struct RegisterMakerNote { struct RegisterMakerNote {
//! Default constructor //! Default constructor
@ -177,7 +186,7 @@ namespace Exiv2 {
{ {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); MakerNoteFactory& mnf = MakerNoteFactory::instance();
mnf.registerMakerNote("Canon", "*", createCanonMakerNote); mnf.registerMakerNote("Canon", "*", createCanonMakerNote);
mnf.registerMakerNote(new CanonMakerNote); mnf.registerMakerNote(MakerNote::AutoPtr(new CanonMakerNote));
} }
}; };
/*! /*!

@ -20,14 +20,14 @@
*/ */
/* /*
File: exif.cpp File: exif.cpp
Version: $Name: $ $Revision: 1.64 $ Version: $Name: $ $Revision: 1.65 $
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.64 $ $RCSfile: exif.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.65 $ $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
@ -494,7 +494,7 @@ namespace Exiv2 {
} }
ExifData::ExifData() ExifData::ExifData()
: pThumbnail_(0), pMakerNote_(0), ifd0_(ifd0Id, 0, false), : pThumbnail_(0), ifd0_(ifd0Id, 0, false),
exifIfd_(exifIfdId, 0, false), iopIfd_(iopIfdId, 0, false), exifIfd_(exifIfdId, 0, false), iopIfd_(iopIfdId, 0, false),
gpsIfd_(gpsIfdId, 0, false), ifd1_(ifd1Id, 0, false), gpsIfd_(gpsIfdId, 0, false), ifd1_(ifd1Id, 0, false),
size_(0), pData_(0), compatible_(true) size_(0), pData_(0), compatible_(true)
@ -503,7 +503,6 @@ namespace Exiv2 {
ExifData::~ExifData() ExifData::~ExifData()
{ {
delete pMakerNote_;
delete pThumbnail_; delete pThumbnail_;
delete[] pData_; delete[] pData_;
} }
@ -559,7 +558,7 @@ namespace Exiv2 {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); MakerNoteFactory& mnf = MakerNoteFactory::instance();
// Todo: The conversion to string assumes that there is a \0 at the end // Todo: The conversion to string assumes that there is a \0 at the end
// Todo: How to avoid the cast (is that a MSVC thing?) // Todo: How to avoid the cast (is that a MSVC thing?)
pMakerNote_ = mnf.create(reinterpret_cast<const char*>(make->data()), makerNote_ = mnf.create(reinterpret_cast<const char*>(make->data()),
reinterpret_cast<const char*>(model->data()), reinterpret_cast<const char*>(model->data()),
false, false,
pos->data(), pos->data(),
@ -568,24 +567,23 @@ namespace Exiv2 {
exifIfd_.offset() + pos->offset()); exifIfd_.offset() + pos->offset());
} }
// Read the MakerNote // Read the MakerNote
if (pMakerNote_) { if (makerNote_.get() != 0) {
rc = pMakerNote_->read(pos->data(), rc = makerNote_->read(pos->data(),
pos->size(), pos->size(),
byteOrder(), byteOrder(),
exifIfd_.offset() + pos->offset()); exifIfd_.offset() + pos->offset());
if (rc) { if (rc) {
// Todo: How to handle debug output like this // Todo: How to handle debug output like this
std::cerr << "Warning: Failed to read " std::cerr << "Warning: Failed to read "
<< pMakerNote_->ifdItem() << makerNote_->ifdItem()
<< " Makernote, rc = " << rc << "\n"; << " Makernote, rc = " << rc << "\n";
delete pMakerNote_; makerNote_.reset();
pMakerNote_ = 0;
} }
} }
// If we successfully parsed the MakerNote, delete the raw MakerNote, // If we successfully parsed the MakerNote, delete the raw MakerNote,
// the parsed MakerNote is the primary MakerNote from now on // the parsed MakerNote is the primary MakerNote from now on
if (pMakerNote_) { if (makerNote_.get() != 0) {
exifIfd_.erase(pos); exifIfd_.erase(pos);
} }
// Find and read Interoperability IFD in ExifIFD // Find and read Interoperability IFD in ExifIFD
@ -618,8 +616,8 @@ namespace Exiv2 {
exifMetadata_.clear(); exifMetadata_.clear();
add(ifd0_.begin(), ifd0_.end(), byteOrder()); add(ifd0_.begin(), ifd0_.end(), byteOrder());
add(exifIfd_.begin(), exifIfd_.end(), byteOrder()); add(exifIfd_.begin(), exifIfd_.end(), byteOrder());
if (pMakerNote_) { if (makerNote_.get() != 0) {
add(pMakerNote_->begin(), pMakerNote_->end(), pMakerNote_->byteOrder()); add(makerNote_->begin(), makerNote_->end(), makerNote_->byteOrder());
} }
add(iopIfd_.begin(), iopIfd_.end(), byteOrder()); add(iopIfd_.begin(), iopIfd_.end(), byteOrder());
add(gpsIfd_.begin(), gpsIfd_.end(), byteOrder()); add(gpsIfd_.begin(), gpsIfd_.end(), byteOrder());
@ -699,17 +697,19 @@ namespace Exiv2 {
// Build Exif IFD from metadata // Build Exif IFD from metadata
Ifd exifIfd(exifIfdId); Ifd exifIfd(exifIfdId);
addToIfd(exifIfd, begin(), end(), byteOrder()); addToIfd(exifIfd, begin(), end(), byteOrder());
MakerNote* pMakerNote = 0; MakerNote::AutoPtr makerNote;
if (pMakerNote_) { if (makerNote_.get() != 0) {
// Build MakerNote from metadata // Build MakerNote from metadata
pMakerNote = pMakerNote_->clone(); makerNote = makerNote_->clone();
addToMakerNote(pMakerNote, begin(), end(), pMakerNote_->byteOrder()); addToMakerNote(makerNote.get(),
begin(), end(),
makerNote_->byteOrder());
// Create a placeholder MakerNote entry of the correct size and // Create a placeholder MakerNote entry of the correct size and
// add it to the Exif IFD (because we don't know the offset yet) // add it to the Exif IFD (because we don't know the offset yet)
Entry e; Entry e;
e.setIfdId(exifIfd.ifdId()); e.setIfdId(exifIfd.ifdId());
e.setTag(0x927c); e.setTag(0x927c);
DataBuf buf(pMakerNote->size()); DataBuf buf(makerNote->size());
memset(buf.pData_, 0x0, buf.size_); memset(buf.pData_, 0x0, buf.size_);
e.setValue(undefined, buf.size_, buf.pData_, buf.size_); e.setValue(undefined, buf.size_, buf.pData_, buf.size_);
exifIfd.erase(0x927c); exifIfd.erase(0x927c);
@ -787,17 +787,15 @@ namespace Exiv2 {
ifd0.copy(buf + ifd0Offset, byteOrder(), ifd0Offset); ifd0.copy(buf + ifd0Offset, byteOrder(), ifd0Offset);
exifIfd.sortByTag(); exifIfd.sortByTag();
exifIfd.copy(buf + exifIfdOffset, byteOrder(), exifIfdOffset); exifIfd.copy(buf + exifIfdOffset, byteOrder(), exifIfdOffset);
if (pMakerNote) { if (makerNote.get() != 0) {
// Copy the MakerNote over the placeholder data // Copy the MakerNote over the placeholder data
Entries::iterator mn = exifIfd.findTag(0x927c); Entries::iterator mn = exifIfd.findTag(0x927c);
// Do _not_ sort the makernote; vendors (at least Canon), don't seem // Do _not_ sort the makernote; vendors (at least Canon), don't seem
// to bother about this TIFF standard requirement, so writing the // to bother about this TIFF standard requirement, so writing the
// makernote as is might result in fewer deviations from the original // makernote as is might result in fewer deviations from the original
pMakerNote->copy(buf + exifIfdOffset + mn->offset(), makerNote->copy(buf + exifIfdOffset + mn->offset(),
byteOrder(), byteOrder(),
exifIfdOffset + mn->offset()); exifIfdOffset + mn->offset());
delete pMakerNote;
pMakerNote = 0;
} }
iopIfd.sortByTag(); iopIfd.sortByTag();
iopIfd.copy(buf + iopIfdOffset, byteOrder(), iopIfdOffset); iopIfd.copy(buf + iopIfdOffset, byteOrder(), iopIfdOffset);
@ -878,13 +876,13 @@ namespace Exiv2 {
void ExifData::add(const Exifdatum& exifdatum) void ExifData::add(const Exifdatum& exifdatum)
{ {
if (exifdatum.ifdId() == makerIfdId) { if (exifdatum.ifdId() == makerIfdId) {
if ( pMakerNote_ if ( makerNote_.get() != 0
&& pMakerNote_->ifdItem() != exifdatum.groupName()) { && makerNote_->ifdItem() != exifdatum.groupName()) {
throw Error("Inconsistent MakerNote"); throw Error("Inconsistent MakerNote");
} }
if (!pMakerNote_) { if (makerNote_.get() == 0) {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); MakerNoteFactory& mnf = MakerNoteFactory::instance();
pMakerNote_ = mnf.create(exifdatum.groupName()); makerNote_ = mnf.create(exifdatum.groupName());
} }
} }
// allow duplicates // allow duplicates
@ -980,9 +978,9 @@ namespace Exiv2 {
maxOffset = std::max(maxOffset, exifIfd_.offset()); maxOffset = std::max(maxOffset, exifIfd_.offset());
maxOffset = std::max(maxOffset, exifIfd_.dataOffset() maxOffset = std::max(maxOffset, exifIfd_.dataOffset()
+ exifIfd_.dataSize()); + exifIfd_.dataSize());
if (pMakerNote_) { if (makerNote_.get() != 0) {
maxOffset = std::max(maxOffset, pMakerNote_->offset() maxOffset = std::max(maxOffset, makerNote_->offset()
+ pMakerNote_->size()); + makerNote_->size());
} }
maxOffset = std::max(maxOffset, iopIfd_.offset()); maxOffset = std::max(maxOffset, iopIfd_.offset());
maxOffset = std::max(maxOffset, iopIfd_.dataOffset() maxOffset = std::max(maxOffset, iopIfd_.dataOffset()
@ -1030,10 +1028,10 @@ namespace Exiv2 {
bool compatible = true; bool compatible = true;
compatible &= updateRange(ifd0_.begin(), ifd0_.end(), byteOrder()); compatible &= updateRange(ifd0_.begin(), ifd0_.end(), byteOrder());
compatible &= updateRange(exifIfd_.begin(), exifIfd_.end(), byteOrder()); compatible &= updateRange(exifIfd_.begin(), exifIfd_.end(), byteOrder());
if (pMakerNote_) { if (makerNote_.get() != 0) {
compatible &= updateRange(pMakerNote_->begin(), compatible &= updateRange(makerNote_->begin(),
pMakerNote_->end(), makerNote_->end(),
pMakerNote_->byteOrder()); makerNote_->byteOrder());
} }
compatible &= updateRange(iopIfd_.begin(), iopIfd_.end(), byteOrder()); compatible &= updateRange(iopIfd_.begin(), iopIfd_.end(), byteOrder());
compatible &= updateRange(gpsIfd_.begin(), gpsIfd_.end(), byteOrder()); compatible &= updateRange(gpsIfd_.begin(), gpsIfd_.end(), byteOrder());
@ -1105,9 +1103,9 @@ namespace Exiv2 {
Entries::const_iterator entry; Entries::const_iterator entry;
std::pair<bool, Entries::const_iterator> rc(false, entry); std::pair<bool, Entries::const_iterator> rc(false, entry);
if (ifdId == makerIfdId && pMakerNote_) { if (ifdId == makerIfdId && makerNote_.get() != 0) {
entry = pMakerNote_->findIdx(idx); entry = makerNote_->findIdx(idx);
if (entry != pMakerNote_->end()) { if (entry != makerNote_->end()) {
rc.first = true; rc.first = true;
rc.second = entry; rc.second = entry;
} }

@ -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.55 $ @version $Name: $ $Revision: 1.56 $
@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
@ -42,6 +42,7 @@
// + standard includes // + standard includes
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
@ -799,10 +800,10 @@ namespace Exiv2 {
// DATA // DATA
TiffHeader tiffHeader_; TiffHeader tiffHeader_;
ExifMetadata exifMetadata_; ExifMetadata exifMetadata_;
Thumbnail* pThumbnail_; //!< Pointer to the Exif thumbnail image //! Pointer to the Exif thumbnail image
MakerNote* pMakerNote_; //!< Pointer to the MakerNote Thumbnail* pThumbnail_;
// Todo: implement reference counting instead //! Pointer to the MakerNote
// of making ExifData own this pointer std::auto_ptr<MakerNote> makerNote_;
Ifd ifd0_; Ifd ifd0_;
Ifd exifIfd_; Ifd exifIfd_;

@ -20,7 +20,7 @@
*/ */
/* /*
File: fujimn.cpp File: fujimn.cpp
Version: $Name: $ $Revision: 1.12 $ Version: $Name: $ $Revision: 1.13 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 18-Feb-04, ahu: created History: 18-Feb-04, ahu: created
07-Mar-04, ahu: isolated as a separate component 07-Mar-04, ahu: isolated as a separate component
@ -31,7 +31,7 @@
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.12 $ $RCSfile: fujimn.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.13 $ $RCSfile: fujimn.cpp,v $");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
@ -114,12 +114,17 @@ namespace Exiv2 {
return rc; return rc;
} }
FujiMakerNote* FujiMakerNote::clone(bool alloc) const FujiMakerNote::AutoPtr FujiMakerNote::clone(bool alloc) const
{ {
FujiMakerNote* pMakerNote = new FujiMakerNote(alloc); return AutoPtr(clone_(alloc));
assert(pMakerNote); }
pMakerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
return pMakerNote; FujiMakerNote* FujiMakerNote::clone_(bool alloc) const
{
AutoPtr makerNote = AutoPtr(new FujiMakerNote(alloc));
assert(makerNote.get() != 0);
makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
return makerNote.release();
} }
std::ostream& FujiMakerNote::printTag(std::ostream& os, std::ostream& FujiMakerNote::printTag(std::ostream& os,
@ -259,13 +264,13 @@ namespace Exiv2 {
// ***************************************************************************** // *****************************************************************************
// free functions // free functions
MakerNote* createFujiMakerNote(bool alloc, MakerNote::AutoPtr createFujiMakerNote(bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
long offset) long offset)
{ {
return new FujiMakerNote(alloc); return MakerNote::AutoPtr(new FujiMakerNote(alloc));
} }
} // namespace Exiv2 } // namespace Exiv2

@ -24,7 +24,7 @@
in Appendix 4: Makernote of Fujifilm of the document in Appendix 4: Makernote of Fujifilm of the document
<a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html"> <a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
Exif file format</a> by TsuruZoh Tachibanaya Exif file format</a> by TsuruZoh Tachibanaya
@version $Name: $ $Revision: 1.9 $ @version $Name: $ $Revision: 1.10 $
@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 11-Feb-04, ahu: created @date 11-Feb-04, ahu: created
@ -40,6 +40,7 @@
// + standard includes // + standard includes
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
@ -53,9 +54,10 @@ namespace Exiv2 {
// free functions // free functions
/*! /*!
@brief Return a pointer to a newly created empty MakerNote initialized to @brief Return an auto-pointer to a newly created empty MakerNote
operate in the memory management model indicated. The caller owns initialized to operate in the memory management model indicated.
this copy and is responsible to delete it! The caller owns this copy and the auto-pointer ensures that it
will be deleted.
@param alloc Memory management model for the new MakerNote. Determines if @param alloc Memory management model for the new MakerNote. Determines if
memory required to store data should be allocated and deallocated memory required to store data should be allocated and deallocated
@ -69,10 +71,11 @@ namespace Exiv2 {
@param offset Offset from the start of the TIFF header of the makernote @param offset Offset from the start of the TIFF header of the makernote
buffer (not used). buffer (not used).
@return A pointer to a newly created empty MakerNote. The caller owns @return An auto-pointer to a newly created empty MakerNote. The caller
this copy and is responsible to delete it! owns this copy and the auto-pointer ensures that it will be
deleted.
*/ */
MakerNote* createFujiMakerNote(bool alloc, MakerNote::AutoPtr createFujiMakerNote(bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
@ -84,6 +87,9 @@ namespace Exiv2 {
//! MakerNote for Fujifilm cameras //! MakerNote for Fujifilm cameras
class FujiMakerNote : public IfdMakerNote { class FujiMakerNote : public IfdMakerNote {
public: public:
//! Shortcut for a %FujiMakerNote auto pointer.
typedef std::auto_ptr<FujiMakerNote> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
/*! /*!
@ -105,7 +111,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
int checkHeader() const; int checkHeader() const;
FujiMakerNote* clone(bool alloc =true) const; FujiMakerNote::AutoPtr clone(bool alloc =true) const;
//! Return the name of the makernote item ("Fujifilm") //! Return the name of the makernote item ("Fujifilm")
std::string ifdItem() const { return ifdItem_; } std::string ifdItem() const { return ifdItem_; }
std::ostream& printTag(std::ostream& os, std::ostream& printTag(std::ostream& os,
@ -134,6 +140,9 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
FujiMakerNote* clone_(bool alloc =true) const;
//! Structure used to auto-register the MakerNote. //! Structure used to auto-register the MakerNote.
struct RegisterMakerNote { struct RegisterMakerNote {
//! Default constructor //! Default constructor
@ -141,7 +150,7 @@ namespace Exiv2 {
{ {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); MakerNoteFactory& mnf = MakerNoteFactory::instance();
mnf.registerMakerNote("FUJIFILM", "*", createFujiMakerNote); mnf.registerMakerNote("FUJIFILM", "*", createFujiMakerNote);
mnf.registerMakerNote(new FujiMakerNote); mnf.registerMakerNote(MakerNote::AutoPtr(new FujiMakerNote));
} }
}; };
/*! /*!

@ -20,13 +20,13 @@
*/ */
/* /*
File: makernote.cpp File: makernote.cpp
Version: $Name: $ $Revision: 1.28 $ Version: $Name: $ $Revision: 1.29 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 18-Feb-04, ahu: created History: 18-Feb-04, ahu: created
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.28 $ $RCSfile: makernote.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.29 $ $RCSfile: makernote.cpp,v $");
// Define DEBUG_* to output debug information to std::cerr // Define DEBUG_* to output debug information to std::cerr
#undef DEBUG_MAKERNOTE #undef DEBUG_MAKERNOTE
@ -60,6 +60,11 @@ namespace Exiv2 {
{ {
} }
MakerNote::AutoPtr MakerNote::clone(bool alloc) const
{
return AutoPtr(clone_(alloc));
}
std::string MakerNote::tagName(uint16_t tag) const std::string MakerNote::tagName(uint16_t tag) const
{ {
std::string tagName; std::string tagName;
@ -133,7 +138,6 @@ namespace Exiv2 {
<< tagDesc(tag); << tagDesc(tag);
} // MakerNote::writeMnTagInfo } // MakerNote::writeMnTagInfo
IfdMakerNote::IfdMakerNote(const MakerNote::MnTagInfo* pMnTagInfo, IfdMakerNote::IfdMakerNote(const MakerNote::MnTagInfo* pMnTagInfo,
bool alloc) bool alloc)
: MakerNote(pMnTagInfo, alloc), : MakerNote(pMnTagInfo, alloc),
@ -233,6 +237,11 @@ namespace Exiv2 {
return headerSize() + ifd_.size() + ifd_.dataSize(); return headerSize() + ifd_.size() + ifd_.dataSize();
} }
IfdMakerNote::AutoPtr IfdMakerNote::clone(bool alloc) const
{
return AutoPtr(clone_(alloc));
}
MakerNoteFactory* MakerNoteFactory::pInstance_ = 0; MakerNoteFactory* MakerNoteFactory::pInstance_ = 0;
MakerNoteFactory& MakerNoteFactory::instance() MakerNoteFactory& MakerNoteFactory::instance()
@ -243,17 +252,18 @@ namespace Exiv2 {
return *pInstance_; return *pInstance_;
} // MakerNoteFactory::instance } // MakerNoteFactory::instance
void MakerNoteFactory::registerMakerNote(MakerNote* pMakerNote) void MakerNoteFactory::registerMakerNote(MakerNote::AutoPtr makerNote)
{ {
MakerNote* pMakerNote = makerNote.release();
assert(pMakerNote); assert(pMakerNote);
ifdItemRegistry_[pMakerNote->ifdItem()] = pMakerNote; ifdItemRegistry_[pMakerNote->ifdItem()] = pMakerNote;
} // MakerNoteFactory::registerMakerNote } // MakerNoteFactory::registerMakerNote
MakerNote* MakerNoteFactory::create(const std::string& ifdItem, MakerNote::AutoPtr MakerNoteFactory::create(const std::string& ifdItem,
bool alloc) const bool alloc) const
{ {
IfdItemRegistry::const_iterator i = ifdItemRegistry_.find(ifdItem); IfdItemRegistry::const_iterator i = ifdItemRegistry_.find(ifdItem);
if (i == ifdItemRegistry_.end()) return 0; if (i == ifdItemRegistry_.end()) return MakerNote::AutoPtr(0);
assert(i->second); assert(i->second);
return i->second->clone(alloc); return i->second->clone(alloc);
} // MakerNoteFactory::create } // MakerNoteFactory::create
@ -270,34 +280,34 @@ namespace Exiv2 {
// Todo: use case insensitive make and model comparisons // Todo: use case insensitive make and model comparisons
// Find or create a registry entry for make // Find or create a registry entry for make
ModelRegistry* modelRegistry = 0; ModelRegistry* pModelRegistry = 0;
Registry::const_iterator end1 = registry_.end(); Registry::const_iterator end1 = registry_.end();
Registry::const_iterator pos1; Registry::const_iterator pos1;
for (pos1 = registry_.begin(); pos1 != end1; ++pos1) { for (pos1 = registry_.begin(); pos1 != end1; ++pos1) {
if (pos1->first == make) break; if (pos1->first == make) break;
} }
if (pos1 != end1) { if (pos1 != end1) {
modelRegistry = pos1->second; pModelRegistry = pos1->second;
} }
else { else {
modelRegistry = new ModelRegistry; pModelRegistry = new ModelRegistry;
registry_.push_back(std::make_pair(make, modelRegistry)); registry_.push_back(std::make_pair(make, pModelRegistry));
} }
// Find or create a registry entry for model // Find or create a registry entry for model
ModelRegistry::iterator end2 = modelRegistry->end(); ModelRegistry::iterator end2 = pModelRegistry->end();
ModelRegistry::iterator pos2; ModelRegistry::iterator pos2;
for (pos2 = modelRegistry->begin(); pos2 != end2; ++pos2) { for (pos2 = pModelRegistry->begin(); pos2 != end2; ++pos2) {
if (pos2->first == model) break; if (pos2->first == model) break;
} }
if (pos2 != end2) { if (pos2 != end2) {
pos2->second = createMakerNote; pos2->second = createMakerNote;
} }
else { else {
modelRegistry->push_back(std::make_pair(model, createMakerNote)); pModelRegistry->push_back(std::make_pair(model, createMakerNote));
} }
} // MakerNoteFactory::registerMakerNote } // MakerNoteFactory::registerMakerNote
MakerNote* MakerNoteFactory::create(const std::string& make, MakerNote::AutoPtr MakerNoteFactory::create(const std::string& make,
const std::string& model, const std::string& model,
bool alloc, bool alloc,
const byte* buf, const byte* buf,
@ -312,7 +322,7 @@ namespace Exiv2 {
#endif #endif
// loop through each make of the registry to find the best matching make // loop through each make of the registry to find the best matching make
int score = 0; int score = 0;
ModelRegistry* modelRegistry = 0; ModelRegistry* pModelRegistry = 0;
#ifdef DEBUG_REGISTRY #ifdef DEBUG_REGISTRY
std::string makeMatch; std::string makeMatch;
std::cerr << "Searching make registry...\n"; std::cerr << "Searching make registry...\n";
@ -326,10 +336,10 @@ namespace Exiv2 {
#ifdef DEBUG_REGISTRY #ifdef DEBUG_REGISTRY
makeMatch = pos1->first; makeMatch = pos1->first;
#endif #endif
modelRegistry = pos1->second; pModelRegistry = pos1->second;
} }
} }
if (modelRegistry == 0) return 0; if (pModelRegistry == 0) return MakerNote::AutoPtr(0);
#ifdef DEBUG_REGISTRY #ifdef DEBUG_REGISTRY
std::cerr << "Best match is \"" << makeMatch << "\".\n"; std::cerr << "Best match is \"" << makeMatch << "\".\n";
#endif #endif
@ -341,9 +351,9 @@ namespace Exiv2 {
std::string modelMatch; std::string modelMatch;
std::cerr << "Searching model registry...\n"; std::cerr << "Searching model registry...\n";
#endif #endif
ModelRegistry::const_iterator end2 = modelRegistry->end(); ModelRegistry::const_iterator end2 = pModelRegistry->end();
ModelRegistry::const_iterator pos2; ModelRegistry::const_iterator pos2;
for (pos2 = modelRegistry->begin(); pos2 != end2; ++pos2) { for (pos2 = pModelRegistry->begin(); pos2 != end2; ++pos2) {
int rc = match(pos2->first, model); int rc = match(pos2->first, model);
if (rc > score) { if (rc > score) {
score = rc; score = rc;
@ -353,7 +363,7 @@ namespace Exiv2 {
createMakerNote = pos2->second; createMakerNote = pos2->second;
} }
} }
if (createMakerNote == 0) return 0; if (createMakerNote == 0) return MakerNote::AutoPtr(0);
#ifdef DEBUG_REGISTRY #ifdef DEBUG_REGISTRY
std::cerr << "Best match is \"" << modelMatch << "\".\n"; std::cerr << "Best match is \"" << modelMatch << "\".\n";
#endif #endif

@ -22,7 +22,7 @@
@file makernote.hpp @file makernote.hpp
@brief Contains the Exif %MakerNote interface, IFD %MakerNote and a @brief Contains the Exif %MakerNote interface, IFD %MakerNote and a
MakerNote factory MakerNote factory
@version $Name: $ $Revision: 1.24 $ @version $Name: $ $Revision: 1.25 $
@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
@ -41,6 +41,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <map> #include <map>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
@ -50,12 +51,6 @@ namespace Exiv2 {
// class declarations // class declarations
class Value; class Value;
// *****************************************************************************
// type definitions
//! Type for a pointer to a function creating a makernote
typedef MakerNote* (*CreateFct)(bool, const byte*, long, ByteOrder, long);
// ***************************************************************************** // *****************************************************************************
// class definitions // class definitions
@ -106,6 +101,8 @@ namespace Exiv2 {
//@} //@}
public: public:
//! Shortcut for a %MakerNote auto pointer.
typedef std::auto_ptr<MakerNote> AutoPtr;
//! MakerNote Tag information //! MakerNote Tag information
struct MnTagInfo { struct MnTagInfo {
@ -169,6 +166,18 @@ namespace Exiv2 {
ByteOrder byteOrder() const { return byteOrder_; } ByteOrder byteOrder() const { return byteOrder_; }
//! Return the offset of the makernote from the start of the TIFF header //! Return the offset of the makernote from the start of the TIFF header
long offset() const { return offset_; } long offset() const { return offset_; }
/*!
@brief Return a pointer to an newly created, empty instance of the
same type as this. The makernote entries are <B>not</B> copied.
The caller owns the new object and is responsible to delete it!
@param alloc Memory management model for the clone. Indicates if
memory required to store data should be allocated and deallocated
(true) or not (false). If false, only pointers to the buffer
provided to read() will be kept. See Ifd for more background on
this concept.
*/
MakerNote::AutoPtr clone(bool alloc =true) const;
/*! /*!
@brief Return the name of a makernote tag. The default implementation @brief Return the name of a makernote tag. The default implementation
looks up the makernote info tag array if one is set, else looks up the makernote info tag array if one is set, else
@ -199,18 +208,6 @@ namespace Exiv2 {
@brief Write the makernote tag info of tag to the output stream os. @brief Write the makernote tag info of tag to the output stream os.
*/ */
virtual std::ostream& writeMnTagInfo(std::ostream& os, uint16_t tag) const; virtual std::ostream& writeMnTagInfo(std::ostream& os, uint16_t tag) const;
/*!
@brief Return a pointer to an newly created, empty instance of the
same type as this. The makernote entries are <B>not</B> copied.
The caller owns the new object and is responsible to delete it!
@param alloc Memory management model for the clone. Indicates if
memory required to store data should be allocated and deallocated
(true) or not (false). If false, only pointers to the buffer
provided to read() will be kept. See Ifd for more background on
this concept.
*/
virtual MakerNote* clone(bool alloc =true) const =0;
//! The first makernote entry //! The first makernote entry
virtual Entries::const_iterator begin() const =0; virtual Entries::const_iterator begin() const =0;
//! End of the makernote entries //! End of the makernote entries
@ -248,8 +245,14 @@ namespace Exiv2 {
*/ */
ByteOrder byteOrder_; ByteOrder byteOrder_;
private:
//! Internal virtual copy constructor.
virtual MakerNote* clone_(bool alloc =true) const =0;
}; // class MakerNote }; // class MakerNote
//! Type for a pointer to a function creating a makernote
typedef MakerNote::AutoPtr (*CreateFct)(bool, const byte*, long, ByteOrder, long);
/*! /*!
@brief Interface for MakerNotes in IFD format. See MakerNote. @brief Interface for MakerNotes in IFD format. See MakerNote.
*/ */
@ -261,6 +264,9 @@ namespace Exiv2 {
//@} //@}
public: public:
//! Shortcut for an %IfdMakerNote auto pointer.
typedef std::auto_ptr<IfdMakerNote> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
/*! /*!
@ -303,6 +309,7 @@ namespace Exiv2 {
Entries::const_iterator end() const { return ifd_.end(); } Entries::const_iterator end() const { return ifd_.end(); }
Entries::const_iterator findIdx(int idx) const; Entries::const_iterator findIdx(int idx) const;
long size() const; long size() const;
IfdMakerNote::AutoPtr clone(bool alloc =true) const;
/*! /*!
@brief Check the makernote header. This will typically check if a @brief Check the makernote header. This will typically check if a
required prefix string is present in the header. Return 0 if required prefix string is present in the header. Return 0 if
@ -323,7 +330,6 @@ namespace Exiv2 {
buffer. buffer.
*/ */
virtual long headerSize() const; virtual long headerSize() const;
virtual IfdMakerNote* clone(bool alloc =true) const =0;
virtual std::string ifdItem() const =0; virtual std::string ifdItem() const =0;
virtual std::ostream& printTag(std::ostream& os, virtual std::ostream& printTag(std::ostream& os,
uint16_t tag, uint16_t tag,
@ -351,6 +357,9 @@ namespace Exiv2 {
//! The makernote IFD //! The makernote IFD
Ifd ifd_; Ifd ifd_;
private:
virtual IfdMakerNote* clone_(bool alloc =true) const =0;
}; // class IfdMakerNote }; // class IfdMakerNote
/*! /*!
@ -394,7 +403,7 @@ namespace Exiv2 {
CreateFct createMakerNote); CreateFct createMakerNote);
//! Register a %MakerNote prototype in the IFD item registry. //! Register a %MakerNote prototype in the IFD item registry.
void registerMakerNote(MakerNote* pMakerNote); void registerMakerNote(MakerNote::AutoPtr makerNote);
//@} //@}
//! @name Accessors //! @name Accessors
@ -402,8 +411,8 @@ namespace Exiv2 {
/*! /*!
@brief Create the appropriate %MakerNote based on camera make and @brief Create the appropriate %MakerNote based on camera make and
model and possibly the contents of the makernote itself, return model and possibly the contents of the makernote itself, return
a pointer to the newly created MakerNote instance. Return 0 if an auto-pointer to the newly created MakerNote instance. Return
no %MakerNote is defined for the camera model. 0 if no %MakerNote is defined for the camera model.
The method searches the make-model tree for a make and model The method searches the make-model tree for a make and model
combination in the registry that matches the search key. The search is combination in the registry that matches the search key. The search is
@ -413,15 +422,15 @@ namespace Exiv2 {
is searched. If there is no matching make or no matching model within is searched. If there is no matching make or no matching model within
the models registered for the best matching make, then no makernote the models registered for the best matching make, then no makernote
is created and the function returns 0. If a match is found, the is created and the function returns 0. If a match is found, the
function invokes the registered create function and returns a pointer function invokes the registered create function and returns an
to the newly created MakerNote. The makernote pointed to is owned by auto-pointer to the newly created MakerNote. The makernote pointed to
the caller of the function, i.e., the caller is responsible to delete is owned by the caller of the function and the auto-pointer ensures
the returned makernote when it is no longer needed. The best match is that it is deleted. The best match is an exact match, then a match is
an exact match, then a match is rated according to the number of rated according to the number of matching characters. The makernote
matching characters. The makernote buffer is passed on to the create buffer is passed on to the create function, which can based on its
function, which can based on its content, automatically determine the content, automatically determine the correct version or flavour of the
correct version or flavour of the makernote required. This is used, makernote required. This is used, e.g., to determine which of the
e.g., to determine which of the three Nikon makernotes to create. three Nikon makernotes to create.
@param make Camera manufacturer. (Typically the string from the Exif @param make Camera manufacturer. (Typically the string from the Exif
make tag.) make tag.)
@ -439,10 +448,10 @@ namespace Exiv2 {
@param offset Offset from the start of the TIFF header of the makernote @param offset Offset from the start of the TIFF header of the makernote
buffer. buffer.
@return A pointer that owns a %MakerNote for the camera model. If the @return An auto-pointer that owns a %MakerNote for the camera model.
camera is not supported, the pointer is 0. If the camera is not supported, the pointer is 0.
*/ */
MakerNote* create(const std::string& make, MakerNote::AutoPtr create(const std::string& make,
const std::string& model, const std::string& model,
bool alloc, bool alloc,
const byte* buf, const byte* buf,
@ -451,7 +460,8 @@ namespace Exiv2 {
long offset) const; long offset) const;
//! Create a %MakerNote based on its IFD item string. //! Create a %MakerNote based on its IFD item string.
MakerNote* create(const std::string& ifdItem, bool alloc =true) const; MakerNote::AutoPtr create(const std::string& ifdItem,
bool alloc =true) const;
//@} //@}
/*! /*!

@ -20,14 +20,14 @@
*/ */
/* /*
File: nikonmn.cpp File: nikonmn.cpp
Version: $Name: $ $Revision: 1.9 $ Version: $Name: $ $Revision: 1.10 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 17-May-04, ahu: created History: 17-May-04, ahu: created
25-May-04, ahu: combined all Nikon formats in one component 25-May-04, ahu: combined all Nikon formats in one component
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.9 $ $RCSfile: nikonmn.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.10 $ $RCSfile: nikonmn.cpp,v $");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
@ -77,7 +77,12 @@ namespace Exiv2 {
{ {
} }
Nikon1MakerNote* Nikon1MakerNote::clone(bool alloc) const Nikon1MakerNote::AutoPtr Nikon1MakerNote::clone(bool alloc) const
{
return AutoPtr(clone_(alloc));
}
Nikon1MakerNote* Nikon1MakerNote::clone_(bool alloc) const
{ {
return new Nikon1MakerNote(alloc); return new Nikon1MakerNote(alloc);
} }
@ -232,12 +237,17 @@ namespace Exiv2 {
return rc; return rc;
} }
Nikon2MakerNote* Nikon2MakerNote::clone(bool alloc) const Nikon2MakerNote::AutoPtr Nikon2MakerNote::clone(bool alloc) const
{
return AutoPtr(clone_(alloc));
}
Nikon2MakerNote* Nikon2MakerNote::clone_(bool alloc) const
{ {
Nikon2MakerNote* pMakerNote = new Nikon2MakerNote(alloc); AutoPtr makerNote = AutoPtr(new Nikon2MakerNote(alloc));
assert(pMakerNote); assert(makerNote.get() != 0);
pMakerNote->readHeader(header_.pData_, header_.size_, byteOrder_); makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
return pMakerNote; return makerNote.release();
} }
std::ostream& Nikon2MakerNote::printTag(std::ostream& os, std::ostream& Nikon2MakerNote::printTag(std::ostream& os,
@ -428,12 +438,17 @@ namespace Exiv2 {
return rc; return rc;
} }
Nikon3MakerNote* Nikon3MakerNote::clone(bool alloc) const Nikon3MakerNote::AutoPtr Nikon3MakerNote::clone(bool alloc) const
{ {
Nikon3MakerNote* pMakerNote = new Nikon3MakerNote(alloc); return AutoPtr(clone_(alloc));
assert(pMakerNote); }
pMakerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
return pMakerNote; Nikon3MakerNote* Nikon3MakerNote::clone_(bool alloc) const
{
AutoPtr makerNote = AutoPtr(new Nikon3MakerNote(alloc));
assert(makerNote.get() != 0);
makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
return makerNote.release();
} }
std::ostream& Nikon3MakerNote::printTag(std::ostream& os, std::ostream& Nikon3MakerNote::printTag(std::ostream& os,
@ -535,7 +550,7 @@ namespace Exiv2 {
// ***************************************************************************** // *****************************************************************************
// free functions // free functions
MakerNote* createNikonMakerNote(bool alloc, MakerNote::AutoPtr createNikonMakerNote(bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
@ -544,17 +559,17 @@ namespace Exiv2 {
// If there is no "Nikon" string it must be Nikon1 format // If there is no "Nikon" string it must be Nikon1 format
if (len < 6 || std::string(reinterpret_cast<const char*>(buf), 6) if (len < 6 || std::string(reinterpret_cast<const char*>(buf), 6)
!= std::string("Nikon\0", 6)) { != std::string("Nikon\0", 6)) {
return new Nikon1MakerNote(alloc); return MakerNote::AutoPtr(new Nikon1MakerNote(alloc));
} }
// If the "Nikon" string is not followed by a TIFF header, we assume // If the "Nikon" string is not followed by a TIFF header, we assume
// Nikon2 format // Nikon2 format
TiffHeader tiffHeader; TiffHeader tiffHeader;
if ( len < 18 if ( len < 18
|| tiffHeader.read(buf + 10) != 0 || tiffHeader.tag() != 0x002a) { || tiffHeader.read(buf + 10) != 0 || tiffHeader.tag() != 0x002a) {
return new Nikon2MakerNote(alloc); return MakerNote::AutoPtr(new Nikon2MakerNote(alloc));
} }
// Else we have a Nikon3 makernote // Else we have a Nikon3 makernote
return new Nikon3MakerNote(alloc); return MakerNote::AutoPtr(new Nikon3MakerNote(alloc));
} }
} // namespace Exiv2 } // namespace Exiv2

@ -28,7 +28,7 @@
<a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html"> <a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
Exif file format</a> by TsuruZoh Tachibanaya.<BR> Exif file format</a> by TsuruZoh Tachibanaya.<BR>
Format 3: "EXIFutils Field Reference Guide". Format 3: "EXIFutils Field Reference Guide".
@version $Name: $ $Revision: 1.6 $ @version $Name: $ $Revision: 1.7 $
@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 17-May-04, ahu: created<BR> @date 17-May-04, ahu: created<BR>
@ -45,6 +45,7 @@
// + standard includes // + standard includes
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
@ -58,9 +59,10 @@ namespace Exiv2 {
// free functions // free functions
/*! /*!
@brief Return a pointer to a newly created empty MakerNote initialized to @brief Return an auto-pointer to a newly created empty MakerNote
operate in the memory management model indicated. The caller owns initialized to operate in the memory management model indicated.
this copy and is responsible to delete it! The caller owns this copy and the auto-pointer ensures that it
will be deleted.
@param alloc Memory management model for the new MakerNote. Determines if @param alloc Memory management model for the new MakerNote. Determines if
memory required to store data should be allocated and deallocated memory required to store data should be allocated and deallocated
@ -74,10 +76,11 @@ namespace Exiv2 {
@param offset Offset from the start of the TIFF header of the makernote @param offset Offset from the start of the TIFF header of the makernote
buffer (not used). buffer (not used).
@return A pointer to a newly created empty MakerNote. The caller owns @return An auto-pointer to a newly created empty MakerNote. The caller
this copy and is responsible to delete it! owns this copy and the auto-pointer ensures that it will be
deleted.
*/ */
MakerNote* createNikonMakerNote(bool alloc, MakerNote::AutoPtr createNikonMakerNote(bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
@ -89,6 +92,9 @@ namespace Exiv2 {
//! A MakerNote format used by Nikon cameras, such as the E990 and D1. //! A MakerNote format used by Nikon cameras, such as the E990 and D1.
class Nikon1MakerNote : public IfdMakerNote { class Nikon1MakerNote : public IfdMakerNote {
public: public:
//! Shortcut for a %Nikon1MakerNote auto pointer.
typedef std::auto_ptr<Nikon1MakerNote> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
/*! /*!
@ -102,7 +108,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
Nikon1MakerNote* clone(bool alloc =true) const; Nikon1MakerNote::AutoPtr clone(bool alloc =true) const;
//! Return the name of the makernote item ("Nikon1") //! Return the name of the makernote item ("Nikon1")
std::string ifdItem() const { return ifdItem_; } std::string ifdItem() const { return ifdItem_; }
std::ostream& printTag(std::ostream& os, std::ostream& printTag(std::ostream& os,
@ -125,6 +131,9 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
Nikon1MakerNote* clone_(bool alloc =true) const;
//! Structure used to auto-register the MakerNote. //! Structure used to auto-register the MakerNote.
struct RegisterMakerNote { struct RegisterMakerNote {
//! Default constructor //! Default constructor
@ -132,7 +141,7 @@ namespace Exiv2 {
{ {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); MakerNoteFactory& mnf = MakerNoteFactory::instance();
mnf.registerMakerNote("NIKON*", "*", createNikonMakerNote); mnf.registerMakerNote("NIKON*", "*", createNikonMakerNote);
mnf.registerMakerNote(new Nikon1MakerNote); mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon1MakerNote));
} }
}; };
// DATA // DATA
@ -161,6 +170,9 @@ namespace Exiv2 {
*/ */
class Nikon2MakerNote : public IfdMakerNote { class Nikon2MakerNote : public IfdMakerNote {
public: public:
//! Shortcut for a %Nikon2MakerNote auto pointer.
typedef std::auto_ptr<Nikon2MakerNote> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
/*! /*!
@ -182,7 +194,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
int checkHeader() const; int checkHeader() const;
Nikon2MakerNote* clone(bool alloc =true) const; Nikon2MakerNote::AutoPtr clone(bool alloc =true) const;
//! Return the name of the makernote item ("Nikon2") //! Return the name of the makernote item ("Nikon2")
std::string ifdItem() const { return ifdItem_; } std::string ifdItem() const { return ifdItem_; }
std::ostream& printTag(std::ostream& os, std::ostream& printTag(std::ostream& os,
@ -207,13 +219,16 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
Nikon2MakerNote* clone_(bool alloc =true) const;
//! Structure used to auto-register the MakerNote. //! Structure used to auto-register the MakerNote.
struct RegisterMakerNote { struct RegisterMakerNote {
//! Default constructor //! Default constructor
RegisterMakerNote() RegisterMakerNote()
{ {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); MakerNoteFactory& mnf = MakerNoteFactory::instance();
mnf.registerMakerNote(new Nikon2MakerNote); mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon2MakerNote));
} }
}; };
// DATA // DATA
@ -239,6 +254,9 @@ namespace Exiv2 {
//! A third MakerNote format used by Nikon cameras, e.g., E5400, SQ, D2H, D70 //! A third MakerNote format used by Nikon cameras, e.g., E5400, SQ, D2H, D70
class Nikon3MakerNote : public IfdMakerNote { class Nikon3MakerNote : public IfdMakerNote {
public: public:
//! Shortcut for a %Nikon3MakerNote auto pointer.
typedef std::auto_ptr<Nikon3MakerNote> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
/*! /*!
@ -260,7 +278,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
int checkHeader() const; int checkHeader() const;
Nikon3MakerNote* clone(bool alloc =true) const; Nikon3MakerNote::AutoPtr clone(bool alloc =true) const;
//! Return the name of the makernote item ("Nikon3") //! Return the name of the makernote item ("Nikon3")
std::string ifdItem() const { return ifdItem_; } std::string ifdItem() const { return ifdItem_; }
std::ostream& printTag(std::ostream& os, std::ostream& printTag(std::ostream& os,
@ -283,13 +301,16 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
Nikon3MakerNote* clone_(bool alloc =true) const;
//! Structure used to auto-register the MakerNote. //! Structure used to auto-register the MakerNote.
struct RegisterMakerNote { struct RegisterMakerNote {
//! Default constructor //! Default constructor
RegisterMakerNote() RegisterMakerNote()
{ {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); MakerNoteFactory& mnf = MakerNoteFactory::instance();
mnf.registerMakerNote(new Nikon3MakerNote); mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon3MakerNote));
} }
}; };
// DATA // DATA

@ -20,7 +20,7 @@
*/ */
/* /*
File: sigmamn.cpp File: sigmamn.cpp
Version: $Name: $ $Revision: 1.11 $ Version: $Name: $ $Revision: 1.12 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 02-Apr-04, ahu: created History: 02-Apr-04, ahu: created
Credits: Sigma and Foveon MakerNote implemented according to the specification Credits: Sigma and Foveon MakerNote implemented according to the specification
@ -29,7 +29,7 @@
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.11 $ $RCSfile: sigmamn.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.12 $ $RCSfile: sigmamn.cpp,v $");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
@ -121,12 +121,17 @@ namespace Exiv2 {
return rc; return rc;
} }
SigmaMakerNote* SigmaMakerNote::clone(bool alloc) const SigmaMakerNote::AutoPtr SigmaMakerNote::clone(bool alloc) const
{ {
SigmaMakerNote* pMakerNote = new SigmaMakerNote(alloc); return AutoPtr(clone_(alloc));
assert(pMakerNote); }
pMakerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
return pMakerNote; SigmaMakerNote* SigmaMakerNote::clone_(bool alloc) const
{
AutoPtr makerNote = AutoPtr(new SigmaMakerNote(alloc));
assert(makerNote.get() != 0);
makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
return makerNote.release();
} }
std::ostream& SigmaMakerNote::printTag(std::ostream& os, std::ostream& SigmaMakerNote::printTag(std::ostream& os,
@ -193,13 +198,13 @@ namespace Exiv2 {
// ***************************************************************************** // *****************************************************************************
// free functions // free functions
MakerNote* createSigmaMakerNote(bool alloc, MakerNote::AutoPtr createSigmaMakerNote(bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
long offset) long offset)
{ {
return new SigmaMakerNote(alloc); return MakerNote::AutoPtr(new SigmaMakerNote(alloc));
} }
} // namespace Exiv2 } // namespace Exiv2

@ -23,7 +23,7 @@
@brief Sigma and Foveon MakerNote implemented according to the specification @brief Sigma and Foveon MakerNote implemented according to the specification
<a href="http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html"> <a href="http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html">
SIGMA and FOVEON EXIF MakerNote Documentation</a> by Foveon. SIGMA and FOVEON EXIF MakerNote Documentation</a> by Foveon.
@version $Name: $ $Revision: 1.9 $ @version $Name: $ $Revision: 1.10 $
@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 02-Apr-04, ahu: created @date 02-Apr-04, ahu: created
@ -39,6 +39,7 @@
// + standard includes // + standard includes
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
@ -52,9 +53,10 @@ namespace Exiv2 {
// free functions // free functions
/*! /*!
@brief Return a pointer to a newly created empty MakerNote initialized to @brief Return an auto-pointer to a newly created empty MakerNote
operate in the memory management model indicated. The caller owns initialized to operate in the memory management model indicated.
this copy and is responsible to delete it! The caller owns this copy and the auto-pointer ensures that it
will be deleted.
@param alloc Memory management model for the new MakerNote. Determines if @param alloc Memory management model for the new MakerNote. Determines if
memory required to store data should be allocated and deallocated memory required to store data should be allocated and deallocated
@ -68,10 +70,11 @@ namespace Exiv2 {
@param offset Offset from the start of the TIFF header of the makernote @param offset Offset from the start of the TIFF header of the makernote
buffer (not used). buffer (not used).
@return A pointer to a newly created empty MakerNote. The caller owns @return An auto-pointer to a newly created empty MakerNote. The caller
this copy and is responsible to delete it! owns this copy and the auto-pointer ensures that it will be
deleted.
*/ */
MakerNote* createSigmaMakerNote(bool alloc, MakerNote::AutoPtr createSigmaMakerNote(bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
@ -83,6 +86,9 @@ namespace Exiv2 {
//! MakerNote for Sigma (Foveon) cameras //! MakerNote for Sigma (Foveon) cameras
class SigmaMakerNote : public IfdMakerNote { class SigmaMakerNote : public IfdMakerNote {
public: public:
//! Shortcut for a %SigmaMakerNote auto pointer.
typedef std::auto_ptr<SigmaMakerNote> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
/*! /*!
@ -104,7 +110,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
int checkHeader() const; int checkHeader() const;
SigmaMakerNote* clone(bool alloc =true) const; SigmaMakerNote::AutoPtr clone(bool alloc =true) const;
//! Return the name of the makernote item ("Sigma") //! Return the name of the makernote item ("Sigma")
std::string ifdItem() const { return ifdItem_; } std::string ifdItem() const { return ifdItem_; }
std::ostream& printTag(std::ostream& os, std::ostream& printTag(std::ostream& os,
@ -123,6 +129,9 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
SigmaMakerNote* clone_(bool alloc =true) const;
//! Structure used to auto-register the MakerNote. //! Structure used to auto-register the MakerNote.
struct RegisterMakerNote { struct RegisterMakerNote {
//! Default constructor //! Default constructor
@ -131,7 +140,7 @@ namespace Exiv2 {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); MakerNoteFactory& mnf = MakerNoteFactory::instance();
mnf.registerMakerNote("SIGMA", "*", createSigmaMakerNote); mnf.registerMakerNote("SIGMA", "*", createSigmaMakerNote);
mnf.registerMakerNote("FOVEON", "*", createSigmaMakerNote); mnf.registerMakerNote("FOVEON", "*", createSigmaMakerNote);
mnf.registerMakerNote(new SigmaMakerNote); mnf.registerMakerNote(MakerNote::AutoPtr(new SigmaMakerNote));
} }
}; };
// DATA // DATA

@ -3,13 +3,13 @@
Abstract: Print a simple comma separated list of tags defined in Exiv2 Abstract: Print a simple comma separated list of tags defined in Exiv2
File: taglist.cpp File: taglist.cpp
Version: $Name: $ $Revision: 1.10 $ Version: $Name: $ $Revision: 1.11 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 07-Jan-04, ahu: created History: 07-Jan-04, ahu: created
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.10 $ $RCSfile: taglist.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.11 $ $RCSfile: taglist.cpp,v $");
#include "makernote.hpp" #include "makernote.hpp"
#include "tags.hpp" #include "tags.hpp"
@ -28,18 +28,15 @@ try {
switch (argc) { switch (argc) {
case 2: case 2:
{ {
MakerNote* pMakerNote = 0;
std::string item(argv[1]); std::string item(argv[1]);
if (item == "Iptc") { if (item == "Iptc") {
IptcDataSets::dataSetList(std::cout); IptcDataSets::dataSetList(std::cout);
break; break;
} }
pMakerNote = MakerNoteFactory::instance().create(item); MakerNote::AutoPtr makerNote = MakerNoteFactory::instance().create(item);
if (pMakerNote) { if (makerNote.get() != 0) {
pMakerNote->taglist(std::cout); makerNote->taglist(std::cout);
delete pMakerNote;
pMakerNote = 0;
} }
else { else {
rc = 2; rc = 2;

@ -20,13 +20,13 @@
*/ */
/* /*
File: tags.cpp File: tags.cpp
Version: $Name: $ $Revision: 1.37 $ Version: $Name: $ $Revision: 1.38 $
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.37 $ $RCSfile: tags.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.38 $ $RCSfile: tags.cpp,v $");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
@ -396,38 +396,38 @@ namespace Exiv2 {
ExifKey::ExifKey(const std::string& key) ExifKey::ExifKey(const std::string& key)
: tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""), : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""),
idx_(0), pMakerNote_(0), key_(key) idx_(0), key_(key)
{ {
decomposeKey(); decomposeKey();
} }
ExifKey::ExifKey(uint16_t tag, const std::string& ifdItem) ExifKey::ExifKey(uint16_t tag, const std::string& ifdItem)
: tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""), : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""),
idx_(0), pMakerNote_(0), key_("") idx_(0), key_("")
{ {
IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
if (ifdId == makerIfdId) throw Error("Invalid key"); if (ifdId == makerIfdId) throw Error("Invalid key");
MakerNote* pMakerNote = 0; MakerNote::AutoPtr makerNote;
if (ifdId == ifdIdNotSet) { if (ifdId == ifdIdNotSet) {
pMakerNote = MakerNoteFactory::instance().create(ifdItem); makerNote = MakerNoteFactory::instance().create(ifdItem);
if (pMakerNote) ifdId = makerIfdId; if (makerNote.get() != 0) ifdId = makerIfdId;
else throw Error("Invalid key"); else throw Error("Invalid key");
} }
tag_ = tag; tag_ = tag;
ifdId_ = ifdId; ifdId_ = ifdId;
ifdItem_ = ifdItem; ifdItem_ = ifdItem;
pMakerNote_ = pMakerNote; makerNote_ = makerNote;
makeKey(); makeKey();
} }
ExifKey::ExifKey(const Entry& e) ExifKey::ExifKey(const Entry& e)
: tag_(e.tag()), ifdId_(e.ifdId()), ifdItem_(""), : tag_(e.tag()), ifdId_(e.ifdId()), ifdItem_(""),
idx_(e.idx()), pMakerNote_(0), key_("") idx_(e.idx()), key_("")
{ {
if (ifdId_ == makerIfdId) { if (ifdId_ == makerIfdId) {
if (e.makerNote()) { if (e.makerNote()) {
ifdItem_ = e.makerNote()->ifdItem(); ifdItem_ = e.makerNote()->ifdItem();
pMakerNote_ = e.makerNote()->clone(); makerNote_ = e.makerNote()->clone();
} }
else throw Error("Invalid Key"); else throw Error("Invalid Key");
} }
@ -440,14 +440,14 @@ namespace Exiv2 {
ExifKey::ExifKey(const ExifKey& rhs) ExifKey::ExifKey(const ExifKey& rhs)
: tag_(rhs.tag_), ifdId_(rhs.ifdId_), ifdItem_(rhs.ifdItem_), : tag_(rhs.tag_), ifdId_(rhs.ifdId_), ifdItem_(rhs.ifdItem_),
idx_(rhs.idx_), idx_(rhs.idx_),
pMakerNote_(rhs.pMakerNote_ ? rhs.pMakerNote_->clone() : 0), makerNote_(rhs.makerNote_.get() != 0 ? rhs.makerNote_->clone()
: MakerNote::AutoPtr(0)),
key_(rhs.key_) key_(rhs.key_)
{ {
} }
ExifKey::~ExifKey() ExifKey::~ExifKey()
{ {
delete pMakerNote_;
} }
ExifKey& ExifKey::operator=(const ExifKey& rhs) ExifKey& ExifKey::operator=(const ExifKey& rhs)
@ -458,7 +458,8 @@ namespace Exiv2 {
ifdId_ = rhs.ifdId_; ifdId_ = rhs.ifdId_;
ifdItem_ = rhs.ifdItem_; ifdItem_ = rhs.ifdItem_;
idx_ = rhs.idx_; idx_ = rhs.idx_;
pMakerNote_ = rhs.pMakerNote_ ? rhs.pMakerNote_->clone() : 0; makerNote_ = rhs.makerNote_.get() != 0 ? rhs.makerNote_->clone()
: MakerNote::AutoPtr(0);
key_ = rhs.key_; key_ = rhs.key_;
return *this; return *this;
} }
@ -466,8 +467,8 @@ namespace Exiv2 {
std::string ExifKey::tagName() const std::string ExifKey::tagName() const
{ {
if (ifdId_ == makerIfdId) { if (ifdId_ == makerIfdId) {
assert(pMakerNote_); assert(makerNote_.get() != 0);
return pMakerNote_->tagName(tag_); return makerNote_->tagName(tag_);
} }
return ExifTags::tagName(tag_, ifdId_); return ExifTags::tagName(tag_, ifdId_);
} }
@ -480,8 +481,8 @@ namespace Exiv2 {
std::string ExifKey::sectionName() const std::string ExifKey::sectionName() const
{ {
if (ifdId_ == makerIfdId) { if (ifdId_ == makerIfdId) {
assert(pMakerNote_); assert(makerNote_.get() != 0);
return pMakerNote_->ifdItem(); return makerNote_->ifdItem();
} }
return ExifTags::sectionName(tag(), ifdId()); return ExifTags::sectionName(tag(), ifdId());
} }
@ -506,24 +507,23 @@ namespace Exiv2 {
// Find IfdId // Find IfdId
IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
if (ifdId == makerIfdId) throw Error("Invalid key"); if (ifdId == makerIfdId) throw Error("Invalid key");
MakerNote* pMakerNote = 0; MakerNote::AutoPtr makerNote;
if (ifdId == ifdIdNotSet) { if (ifdId == ifdIdNotSet) {
pMakerNote = MakerNoteFactory::instance().create(ifdItem); makerNote = MakerNoteFactory::instance().create(ifdItem);
if (pMakerNote) ifdId = makerIfdId; if (makerNote.get() != 0) ifdId = makerIfdId;
else throw Error("Invalid key"); else throw Error("Invalid key");
} }
// Convert tag // Convert tag
uint16_t tag = pMakerNote ? uint16_t tag = makerNote.get() != 0 ? makerNote->tag(tagName)
pMakerNote->tag(tagName) : ExifTags::tag(tagName, ifdId); : ExifTags::tag(tagName, ifdId);
// Translate hex tag name (0xabcd) to a real tag name if there is one // Translate hex tag name (0xabcd) to a real tag name if there is one
tagName = pMakerNote ? tagName = makerNote.get() != 0 ? makerNote->tagName(tag)
pMakerNote->tagName(tag) : ExifTags::tagName(tag, ifdId); : ExifTags::tagName(tag, ifdId);
tag_ = tag; tag_ = tag;
ifdId_ = ifdId; ifdId_ = ifdId;
ifdItem_ = ifdItem; ifdItem_ = ifdItem;
pMakerNote_ = pMakerNote; makerNote_ = makerNote;
key_ = familyName + "." + ifdItem + "." + tagName; key_ = familyName + "." + ifdItem + "." + tagName;
} }
@ -531,15 +531,15 @@ namespace Exiv2 {
{ {
key_ = std::string(familyName_) key_ = std::string(familyName_)
+ "." + ifdItem_ + "." + ifdItem_
+ "." + (pMakerNote_ ? + "." + (makerNote_.get() != 0 ? makerNote_->tagName(tag_)
pMakerNote_->tagName(tag_) : ExifTags::tagName(tag_, ifdId_)); : ExifTags::tagName(tag_, ifdId_));
} }
std::ostream& ExifKey::printTag(std::ostream& os, const Value& value) const std::ostream& ExifKey::printTag(std::ostream& os, const Value& value) const
{ {
if (ifdId_ == makerIfdId) { if (ifdId_ == makerIfdId) {
assert(pMakerNote_); assert(makerNote_.get() != 0);
return pMakerNote_->printTag(os, tag(), value); return makerNote_->printTag(os, tag(), value);
} }
return ExifTags::printTag(os, tag(), ifdId(), value); return ExifTags::printTag(os, tag(), ifdId(), value);
} }

@ -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.28 $ @version $Name: $ $Revision: 1.29 $
@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>
@ -39,6 +39,7 @@
#include <string> #include <string>
#include <utility> // for std::pair #include <utility> // for std::pair
#include <iosfwd> #include <iosfwd>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
@ -288,7 +289,8 @@ namespace Exiv2 {
IfdId ifdId_; //!< The IFD associated with this tag IfdId ifdId_; //!< The IFD associated with this tag
std::string ifdItem_; //!< The IFD item std::string ifdItem_; //!< The IFD item
int idx_; //!< Unique id of an entry within one IFD int idx_; //!< Unique id of an entry within one IFD
MakerNote* pMakerNote_; //!< Pointer to the associated MakerNote //! Auto-pointer to the associated MakerNote
std::auto_ptr<MakerNote> makerNote_;
std::string key_; //!< Key std::string key_; //!< Key
}; // class ExifKey }; // class ExifKey

Loading…
Cancel
Save