From 54a42fc1f7944a1af2c4ac12579a508bd64f4a0f Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Sun, 13 Mar 2005 12:52:56 +0000 Subject: [PATCH] Generalized and cleaned-up makernote handling --- src/canonmn.cpp | 42 +--- src/canonmn.hpp | 16 +- src/exif.cpp | 24 +- src/fujimn.cpp | 66 ++---- src/fujimn.hpp | 16 +- src/ifd.cpp | 6 +- src/ifd.hpp | 7 - src/makernote.cpp | 108 +-------- src/makernote.hpp | 106 +++------ src/nikonmn.cpp | 242 +++++++-------------- src/nikonmn.hpp | 56 +++-- src/sigmamn.cpp | 78 +++---- src/sigmamn.hpp | 16 +- src/taglist.cpp | 8 +- src/tags.cpp | 282 ++++++++++++++++-------- src/tags.hpp | 39 +++- src/types.hpp | 7 +- test/data/exifdata-test.out | 421 ++++++++++++++++++++++++++++++++++++ test/exifdata-test.sh | 2 + 19 files changed, 884 insertions(+), 658 deletions(-) diff --git a/src/canonmn.cpp b/src/canonmn.cpp index 8874e90e..46cd2cf8 100644 --- a/src/canonmn.cpp +++ b/src/canonmn.cpp @@ -54,26 +54,26 @@ namespace Exiv2 { const CanonMakerNote::RegisterMakerNote CanonMakerNote::register_; // Canon MakerNote Tag Info - static const MakerNote::MnTagInfo canonMnTagInfo[] = { - MakerNote::MnTagInfo(0x0001, "CameraSettings1", "Various camera settings (1)"), - MakerNote::MnTagInfo(0x0004, "CameraSettings2", "Various camera settings (2)"), - MakerNote::MnTagInfo(0x0006, "ImageType", "Image type"), - MakerNote::MnTagInfo(0x0007, "FirmwareVersion", "Firmware version"), - MakerNote::MnTagInfo(0x0008, "ImageNumber", "Image number"), - MakerNote::MnTagInfo(0x0009, "OwnerName", "Owner Name"), - MakerNote::MnTagInfo(0x000c, "SerialNumber", "Camera serial number"), - MakerNote::MnTagInfo(0x000f, "EosD30Functions", "EOS D30 Custom Functions"), + const TagInfo CanonMakerNote::tagInfo_[] = { + TagInfo(0x0001, "CameraSettings1", "Various camera settings (1)", canonIfdId, makerTags, print0x0001), + TagInfo(0x0004, "CameraSettings2", "Various camera settings (2)", canonIfdId, makerTags, print0x0004), + TagInfo(0x0006, "ImageType", "Image type", canonIfdId, makerTags, printValue), + TagInfo(0x0007, "FirmwareVersion", "Firmware version", canonIfdId, makerTags, printValue), + TagInfo(0x0008, "ImageNumber", "Image number", canonIfdId, makerTags, print0x0008), + TagInfo(0x0009, "OwnerName", "Owner Name", canonIfdId, makerTags, printValue), + TagInfo(0x000c, "SerialNumber", "Camera serial number", canonIfdId, makerTags, print0x000c), + TagInfo(0x000f, "EosD30Functions", "EOS D30 Custom Functions", canonIfdId, makerTags, print0x000f), // End of list marker - MakerNote::MnTagInfo(0xffff, "(UnknownCanonMakerNoteTag)", "Unknown CanonMakerNote tag") + TagInfo(0xffff, "(UnknownCanonMakerNoteTag)", "Unknown CanonMakerNote tag", canonIfdId, makerTags, printValue) }; CanonMakerNote::CanonMakerNote(bool alloc) - : IfdMakerNote(canonMnTagInfo, alloc), ifdItem_("Canon") + : IfdMakerNote(canonIfdId, alloc) { } CanonMakerNote::CanonMakerNote(const CanonMakerNote& rhs) - : IfdMakerNote(rhs), ifdItem_(rhs.ifdItem_) + : IfdMakerNote(rhs) { } @@ -97,24 +97,6 @@ namespace Exiv2 { return new CanonMakerNote(*this); } - std::ostream& CanonMakerNote::printTag(std::ostream& os, - uint16_t tag, - const Value& value) const - { - switch (tag) { - case 0x0001: print0x0001(os, value); break; - case 0x0004: print0x0004(os, value); break; - case 0x0008: print0x0008(os, value); break; - case 0x000c: print0x000c(os, value); break; - case 0x000f: print0x000f(os, value); break; - default: - // All other tags (known or unknown) go here - os << value; - break; - } - return os; - } - std::ostream& CanonMakerNote::print0x0001(std::ostream& os, const Value& value) { diff --git a/src/canonmn.hpp b/src/canonmn.hpp index 447731a8..f4de1ad7 100644 --- a/src/canonmn.hpp +++ b/src/canonmn.hpp @@ -36,6 +36,7 @@ // included header files #include "types.hpp" #include "makernote.hpp" +#include "tags.hpp" // + standard includes #include @@ -107,11 +108,6 @@ namespace Exiv2 { //@{ AutoPtr create(bool alloc =true) const; AutoPtr clone() const; - //! Return the name of the makernote item ("Canon") - std::string ifdItem() const { return ifdItem_; } - std::ostream& printTag(std::ostream& os, - uint16_t tag, - const Value& value) const; //@} //! @name Print functions for Canon %MakerNote tags @@ -184,6 +180,9 @@ namespace Exiv2 { //! Internal virtual copy constructor. CanonMakerNote* clone_() const; + //! Tag information + static const TagInfo tagInfo_[]; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor @@ -191,7 +190,9 @@ namespace Exiv2 { { MakerNoteFactory& mnf = MakerNoteFactory::instance(); mnf.registerMakerNote("Canon", "*", createCanonMakerNote); - mnf.registerMakerNote(MakerNote::AutoPtr(new CanonMakerNote)); + mnf.registerMakerNote(canonIfdId, + MakerNote::AutoPtr(new CanonMakerNote)); + ExifTags::registerMakerTagInfo(canonIfdId, tagInfo_); } }; /*! @@ -208,9 +209,6 @@ namespace Exiv2 { */ static const RegisterMakerNote register_; - //! The item name (second part of the key) used for makernote tags - std::string ifdItem_; - }; // class CanonMakerNote } // namespace Exiv2 diff --git a/src/exif.cpp b/src/exif.cpp index 80d0f69c..04a01073 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -475,10 +475,8 @@ namespace Exiv2 { pExifIfd_->offset() + pos->offset()); if (rc) { // Todo: How to handle debug output like this - std::cerr << "Warning: Failed to read " - << makerNote_->ifdItem() - << " Makernote, rc = " << rc << "\n"; - + std::cerr << "Warning: Failed to read Makernote, rc = " + << rc << "\n"; makerNote_.reset(); } } @@ -710,14 +708,10 @@ namespace Exiv2 { void ExifData::add(const Exifdatum& exifdatum) { - if (exifdatum.ifdId() == makerIfdId) { - if ( makerNote_.get() != 0 - && makerNote_->ifdItem() != exifdatum.groupName()) { - throw Error("Inconsistent MakerNote"); - } + if (ExifTags::isMakerIfd(exifdatum.ifdId())) { if (makerNote_.get() == 0) { MakerNoteFactory& mnf = MakerNoteFactory::instance(); - makerNote_ = mnf.create(exifdatum.groupName()); + makerNote_ = mnf.create(exifdatum.ifdId()); } } // allow duplicates @@ -1033,7 +1027,7 @@ namespace Exiv2 { Entries::const_iterator entry; std::pair rc(false, entry); - if (ifdId == makerIfdId && makerNote_.get() != 0) { + if (ExifTags::isMakerIfd(ifdId) && makerNote_.get() != 0) { entry = makerNote_->findIdx(idx); if (entry != makerNote_->end()) { rc.first = true; @@ -1042,7 +1036,7 @@ namespace Exiv2 { return rc; } const Ifd* ifd = getIfd(ifdId); - if (ifd && ifdId != makerIfdId) { + if (ifd && isExifIfd(ifdId)) { entry = ifd->findIdx(idx); if (entry != ifd->end()) { rc.first = true; @@ -1166,8 +1160,7 @@ namespace Exiv2 { ByteOrder byteOrder) { for (ExifMetadata::const_iterator i = begin; i != end; ++i) { - // add only metadata with IFD id 'makerIfd' - if (i->ifdId() == makerIfdId) { + if (ExifTags::isMakerIfd(i->ifdId())) { addToMakerNote(makerNote, *i, byteOrder); } } @@ -1196,8 +1189,7 @@ namespace Exiv2 { std::ostream& operator<<(std::ostream& os, const Exifdatum& md) { - assert(md.key_.get() != 0); - return md.key_->printTag(os, md.value()); + return ExifTags::printTag(os, md.tag(), md.ifdId(), md.value()); } } // namespace Exiv2 diff --git a/src/fujimn.cpp b/src/fujimn.cpp index a8429d56..3364b193 100644 --- a/src/fujimn.cpp +++ b/src/fujimn.cpp @@ -56,29 +56,29 @@ namespace Exiv2 { const FujiMakerNote::RegisterMakerNote FujiMakerNote::register_; // Fujifilm MakerNote Tag Info - static const MakerNote::MnTagInfo fujiMnTagInfo[] = { - MakerNote::MnTagInfo(0x0000, "Version", "Fujifilm Makernote version"), - MakerNote::MnTagInfo(0x1000, "Quality", "Image quality setting"), - MakerNote::MnTagInfo(0x1001, "Sharpness", "Sharpness setting"), - MakerNote::MnTagInfo(0x1002, "WhiteBalance", "White balance setting"), - MakerNote::MnTagInfo(0x1003, "Color", "Chroma saturation setting"), - MakerNote::MnTagInfo(0x1004, "Tone", "Contrast setting"), - MakerNote::MnTagInfo(0x1010, "FlashMode", "Flash firing mode setting"), - MakerNote::MnTagInfo(0x1011, "FlashStrength", "Flash firing strength compensation setting"), - MakerNote::MnTagInfo(0x1020, "Macro", "Macro mode setting"), - MakerNote::MnTagInfo(0x1021, "FocusMode", "Focusing mode setting"), - MakerNote::MnTagInfo(0x1030, "SlowSync", "Slow synchro mode setting"), - MakerNote::MnTagInfo(0x1031, "PictureMode", "Picture mode setting"), - MakerNote::MnTagInfo(0x1100, "Continuous", "Continuous shooting or auto bracketing setting"), - MakerNote::MnTagInfo(0x1300, "BlurWarning", "Blur warning status"), - MakerNote::MnTagInfo(0x1301, "FocusWarning", "Auto Focus warning status"), - MakerNote::MnTagInfo(0x1302, "AeWarning", "Auto Exposure warning status"), + const TagInfo FujiMakerNote::tagInfo_[] = { + TagInfo(0x0000, "Version", "Fujifilm Makernote version", fujiIfdId, makerTags, printValue), + TagInfo(0x1000, "Quality", "Image quality setting", fujiIfdId, makerTags, printValue), + TagInfo(0x1001, "Sharpness", "Sharpness setting", fujiIfdId, makerTags, print0x1001), + TagInfo(0x1002, "WhiteBalance", "White balance setting", fujiIfdId, makerTags, print0x1002), + TagInfo(0x1003, "Color", "Chroma saturation setting", fujiIfdId, makerTags, print0x1003), + TagInfo(0x1004, "Tone", "Contrast setting", fujiIfdId, makerTags, print0x1004), + TagInfo(0x1010, "FlashMode", "Flash firing mode setting", fujiIfdId, makerTags, print0x1010), + TagInfo(0x1011, "FlashStrength", "Flash firing strength compensation setting", fujiIfdId, makerTags, printValue), + TagInfo(0x1020, "Macro", "Macro mode setting", fujiIfdId, makerTags, printOffOn), + TagInfo(0x1021, "FocusMode", "Focusing mode setting", fujiIfdId, makerTags, print0x1021), + TagInfo(0x1030, "SlowSync", "Slow synchro mode setting", fujiIfdId, makerTags, printOffOn), + TagInfo(0x1031, "PictureMode", "Picture mode setting", fujiIfdId, makerTags, print0x1031), + TagInfo(0x1100, "Continuous", "Continuous shooting or auto bracketing setting", fujiIfdId, makerTags, printOffOn), + TagInfo(0x1300, "BlurWarning", "Blur warning status", fujiIfdId, makerTags, printOffOn), + TagInfo(0x1301, "FocusWarning", "Auto Focus warning status", fujiIfdId, makerTags, printOffOn), + TagInfo(0x1302, "AeWarning", "Auto Exposure warning status", fujiIfdId, makerTags, printOffOn), // End of list marker - MakerNote::MnTagInfo(0xffff, "(UnknownFujiMakerNoteTag)", "Unknown FujiMakerNote tag") + TagInfo(0xffff, "(UnknownFujiMakerNoteTag)", "Unknown FujiMakerNote tag", fujiIfdId, makerTags, printValue) }; FujiMakerNote::FujiMakerNote(bool alloc) - : IfdMakerNote(fujiMnTagInfo, alloc), ifdItem_("Fujifilm") + : IfdMakerNote(fujiIfdId, alloc) { byteOrder_ = littleEndian; absOffset_ = false; @@ -89,7 +89,7 @@ namespace Exiv2 { } FujiMakerNote::FujiMakerNote(const FujiMakerNote& rhs) - : IfdMakerNote(rhs), ifdItem_(rhs.ifdItem_) + : IfdMakerNote(rhs) { } @@ -142,32 +142,6 @@ namespace Exiv2 { return new FujiMakerNote(*this); } - std::ostream& FujiMakerNote::printTag(std::ostream& os, - uint16_t tag, - const Value& value) const - { - switch (tag) { - case 0x1020: // fallthrough - case 0x1030: // fallthrough - case 0x1100: // fallthrough - case 0x1300: // fallthrough - case 0x1301: // fallthrough - case 0x1302: printOffOn(os, value); break; - case 0x1001: print0x1001(os, value); break; - case 0x1002: print0x1002(os, value); break; - case 0x1003: print0x1003(os, value); break; - case 0x1004: print0x1004(os, value); break; - case 0x1010: print0x1010(os, value); break; - case 0x1021: print0x1021(os, value); break; - case 0x1031: print0x1031(os, value); break; - default: - // All other tags (known or unknown) go here - os << value; - break; - } - return os; - } - std::ostream& FujiMakerNote::printOffOn(std::ostream& os, const Value& value) { diff --git a/src/fujimn.hpp b/src/fujimn.hpp index e9701be2..6be13ec2 100644 --- a/src/fujimn.hpp +++ b/src/fujimn.hpp @@ -36,6 +36,7 @@ // included header files #include "types.hpp" #include "makernote.hpp" +#include "tags.hpp" // + standard includes #include @@ -115,11 +116,6 @@ namespace Exiv2 { int checkHeader() const; AutoPtr create(bool alloc =true) const; AutoPtr clone() const; - //! Return the name of the makernote item ("Fujifilm") - std::string ifdItem() const { return ifdItem_; } - std::ostream& printTag(std::ostream& os, - uint16_t tag, - const Value& value) const; //@} //! @name Print functions for Fujifilm %MakerNote tags @@ -148,6 +144,9 @@ namespace Exiv2 { //! Internal virtual copy constructor. FujiMakerNote* clone_() const; + //! Tag information + static const TagInfo tagInfo_[]; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor @@ -155,7 +154,9 @@ namespace Exiv2 { { MakerNoteFactory& mnf = MakerNoteFactory::instance(); mnf.registerMakerNote("FUJIFILM", "*", createFujiMakerNote); - mnf.registerMakerNote(MakerNote::AutoPtr(new FujiMakerNote)); + mnf.registerMakerNote(fujiIfdId, + MakerNote::AutoPtr(new FujiMakerNote)); + ExifTags::registerMakerTagInfo(fujiIfdId, tagInfo_); } }; /*! @@ -172,9 +173,6 @@ namespace Exiv2 { */ static const RegisterMakerNote register_; - //! The item name (second part of the key) used for makernote tags - std::string ifdItem_; - }; // class FujiMakerNote } // namespace Exiv2 diff --git a/src/ifd.cpp b/src/ifd.cpp index 39e613d2..5108e7cb 100644 --- a/src/ifd.cpp +++ b/src/ifd.cpp @@ -50,7 +50,7 @@ EXIV2_RCSID("@(#) $Id$"); namespace Exiv2 { Entry::Entry(bool alloc) - : alloc_(alloc), ifdId_(ifdIdNotSet), idx_(0), pMakerNote_(0), + : alloc_(alloc), ifdId_(ifdIdNotSet), idx_(0), tag_(0), type_(0), count_(0), offset_(0), size_(0), pData_(0), sizeDataArea_(0), pDataArea_(0) { @@ -62,12 +62,11 @@ namespace Exiv2 { delete[] pData_; delete[] pDataArea_; } - // do *not* delete the MakerNote } Entry::Entry(const Entry& rhs) : alloc_(rhs.alloc_), ifdId_(rhs.ifdId_), idx_(rhs.idx_), - pMakerNote_(rhs.pMakerNote_), tag_(rhs.tag_), type_(rhs.type_), + tag_(rhs.tag_), type_(rhs.type_), count_(rhs.count_), offset_(rhs.offset_), size_(rhs.size_), pData_(0), sizeDataArea_(rhs.sizeDataArea_), pDataArea_(0) { @@ -93,7 +92,6 @@ namespace Exiv2 { alloc_ = rhs.alloc_; ifdId_ = rhs.ifdId_; idx_ = rhs.idx_; - pMakerNote_ = rhs.pMakerNote_; tag_ = rhs.tag_; type_ = rhs.type_; count_ = rhs.count_; diff --git a/src/ifd.hpp b/src/ifd.hpp index e35e9651..cce2a166 100644 --- a/src/ifd.hpp +++ b/src/ifd.hpp @@ -45,7 +45,6 @@ namespace Exiv2 { // ***************************************************************************** // class declarations - class MakerNote; class Ifd; // ***************************************************************************** @@ -84,8 +83,6 @@ namespace Exiv2 { void setIfdId(IfdId ifdId) { ifdId_ = ifdId; } //! Set the index (unique id of an entry within one IFD) void setIdx(int idx) { idx_ = idx; } - //! Set the pointer to the MakerNote - void setMakerNote(MakerNote* makerNote) { pMakerNote_ = makerNote; } //! Set the offset. The offset is relative to the start of the IFD. void setOffset(long offset) { offset_ = offset; } /*! @@ -177,8 +174,6 @@ namespace Exiv2 { IfdId ifdId() const { return ifdId_; } //! Return the index (unique id >0 of an entry within an IFD, 0 if not set) int idx() const { return idx_; } - //! Return the pointer to the associated MakerNote - MakerNote* makerNote() const { return pMakerNote_; } //! Return the number of components in the value uint32_t count() const { return count_; } /*! @@ -232,8 +227,6 @@ namespace Exiv2 { IfdId ifdId_; //! Unique id of an entry within an IFD (0 if not set) int idx_; - //! Pointer to the associated MakerNote - MakerNote* pMakerNote_; //! Tag uint16_t tag_; //! Type diff --git a/src/makernote.cpp b/src/makernote.cpp index 1c795630..c26178c8 100644 --- a/src/makernote.cpp +++ b/src/makernote.cpp @@ -35,7 +35,6 @@ EXIV2_RCSID("@(#) $Id$"); // ***************************************************************************** // included header files #include "makernote.hpp" -#include "tags.hpp" // for ExifTags::ifdItem #include "error.hpp" // + standard includes @@ -51,9 +50,8 @@ EXIV2_RCSID("@(#) $Id$"); // class member definitions namespace Exiv2 { - MakerNote::MakerNote(const MnTagInfo* pMnTagInfo, bool alloc) - : pMnTagInfo_(pMnTagInfo), alloc_(alloc), - offset_(0), byteOrder_(invalidByteOrder) + MakerNote::MakerNote(bool alloc) + : alloc_(alloc), offset_(0), byteOrder_(invalidByteOrder) { } @@ -67,83 +65,9 @@ namespace Exiv2 { return AutoPtr(clone_()); } - std::string MakerNote::tagName(uint16_t tag) const - { - std::string tagName; - if (pMnTagInfo_) { - for (int i = 0; pMnTagInfo_[i].tag_ != 0xffff; ++i) { - if (pMnTagInfo_[i].tag_ == tag) { - tagName = pMnTagInfo_[i].name_; - break; - } - } - } - if (tagName.empty()) { - std::ostringstream os; - os << "0x" << std::setw(4) << std::setfill('0') << std::right - << std::hex << tag; - tagName = os.str(); - } - return tagName; - } // MakerNote::tagName - - uint16_t MakerNote::tag(const std::string& tagName) const - { - uint16_t tag = 0xffff; - if (pMnTagInfo_) { - for (int i = 0; pMnTagInfo_[i].tag_ != 0xffff; ++i) { - if (pMnTagInfo_[i].name_ == tagName) { - tag = pMnTagInfo_[i].tag_; - break; - } - } - } - if (tag == 0xffff) { - std::istringstream is(tagName); - is >> std::hex >> tag; - } - return tag; - } // MakerNote::tag - - std::string MakerNote::tagDesc(uint16_t tag) const - { - std::string tagDesc; - if (pMnTagInfo_) { - for (int i = 0; pMnTagInfo_[i].tag_ != 0xffff; ++i) { - if (pMnTagInfo_[i].tag_ == tag) { - tagDesc = pMnTagInfo_[i].desc_; - break; - } - } - } - return tagDesc; - } // MakerNote::tagDesc - - void MakerNote::taglist(std::ostream& os) const - { - if (pMnTagInfo_) { - for (int i = 0; pMnTagInfo_[i].tag_ != 0xffff; ++i) { - writeMnTagInfo(os, pMnTagInfo_[i].tag_) << std::endl; - } - } - } // MakerNote::taglist - - std::ostream& MakerNote::writeMnTagInfo(std::ostream& os, uint16_t tag) const - { - ExifKey exifKey(tag, ifdItem()); - return os << tagName(tag) << ", " - << std::dec << tag << ", " - << "0x" << std::setw(4) << std::setfill('0') - << std::right << std::hex << tag << ", " - << ExifTags::ifdItem(makerIfdId) << ", " - << exifKey.key() << ", " - << tagDesc(tag); - } // MakerNote::writeMnTagInfo - - IfdMakerNote::IfdMakerNote(const MakerNote::MnTagInfo* pMnTagInfo, - bool alloc) - : MakerNote(pMnTagInfo, alloc), - absOffset_(true), adjOffset_(0), ifd_(makerIfdId, 0, alloc) + IfdMakerNote::IfdMakerNote(IfdId ifdId, bool alloc) + : MakerNote(alloc), + absOffset_(true), adjOffset_(0), ifd_(ifdId, 0, alloc) { } @@ -181,12 +105,6 @@ namespace Exiv2 { // IfdMakerNote currently does not support multiple IFDs if (ifd_.next() != 0) rc = 3; } - if (rc == 0) { - Entries::iterator end = ifd_.end(); - for (Entries::iterator i = ifd_.begin(); i != end; ++i) { - i->setMakerNote(this); - } - } #ifdef DEBUG_MAKERNOTE hexdump(std::cerr, buf, len, offset); if (rc == 0) ifd_.print(std::cerr); @@ -224,10 +142,6 @@ namespace Exiv2 { if (absOffset_) { ifd_.updateBase(pNewBase); } - Entries::iterator end = ifd_.end(); - for (Entries::iterator i = ifd_.begin(); i != end; ++i) { - i->setMakerNote(this); - } } int IfdMakerNote::checkHeader() const @@ -277,18 +191,18 @@ namespace Exiv2 { return *pInstance_; } // MakerNoteFactory::instance - void MakerNoteFactory::registerMakerNote(MakerNote::AutoPtr makerNote) + void MakerNoteFactory::registerMakerNote(IfdId ifdId, + MakerNote::AutoPtr makerNote) { MakerNote* pMakerNote = makerNote.release(); assert(pMakerNote); - ifdItemRegistry_[pMakerNote->ifdItem()] = pMakerNote; + ifdIdRegistry_[ifdId] = pMakerNote; } // MakerNoteFactory::registerMakerNote - MakerNote::AutoPtr MakerNoteFactory::create(const std::string& ifdItem, - bool alloc) const + MakerNote::AutoPtr MakerNoteFactory::create(IfdId ifdId, bool alloc) const { - IfdItemRegistry::const_iterator i = ifdItemRegistry_.find(ifdItem); - if (i == ifdItemRegistry_.end()) return MakerNote::AutoPtr(0); + IfdIdRegistry::const_iterator i = ifdIdRegistry_.find(ifdId); + if (i == ifdIdRegistry_.end()) return MakerNote::AutoPtr(0); assert(i->second); return i->second->create(alloc); } // MakerNoteFactory::create diff --git a/src/makernote.hpp b/src/makernote.hpp index 4696f177..6dd0b897 100644 --- a/src/makernote.hpp +++ b/src/makernote.hpp @@ -69,7 +69,6 @@ namespace Exiv2 { - read the makernote from a character buffer - copy the makernote to a character buffer - maintain a list of makernote entries (similar to IFD entries) - - provide makernote specific tag names and tag information - interpret (print) the values of makernote tags Makernotes can be added to the system by subclassing %MakerNote and @@ -104,25 +103,13 @@ namespace Exiv2 { //! Shortcut for a %MakerNote auto pointer. typedef std::auto_ptr AutoPtr; - //! MakerNote Tag information - struct MnTagInfo { - //! Constructor - MnTagInfo(uint16_t tag, const char* name, const char* desc) - : tag_(tag), name_(name), desc_(desc) {} - - uint16_t tag_; //!< Tag - const char* name_; //!< One word tag label - const char* desc_; //!< Short tag description - }; // struct MnTagInfo - //! @name Creators //@{ /*! - @brief Constructor. Takes an optional makernote info tag array and - allows to choose whether or not memory management is required - for the Entries. + @brief Constructor. Allows to choose whether or not memory management + is required for the Entries. */ - explicit MakerNote(const MnTagInfo* pMnTagInfo =0, bool alloc =true); + explicit MakerNote(bool alloc =true); //! Virtual destructor. virtual ~MakerNote() {} //@} @@ -197,36 +184,6 @@ namespace Exiv2 { Use updateBase(byte* pNewBase) to adjust them. */ AutoPtr clone() const; - /*! - @brief Return the name of a makernote tag. The default implementation - looks up the makernote info tag array if one is set, else - it translates the tag to a string with the hexadecimal value of - the tag. - */ - virtual std::string tagName(uint16_t tag) const; - /*! - @brief Return the tag associated with a makernote tag name. The - default implementation looks up the makernote info tag array - if one is set, else it expects tag names in the form "0x01ff" - and converts them to unsigned integer. - */ - virtual uint16_t tag(const std::string& tagName) const; - /*! - @brief Return the description of a makernote tag. The default - implementation looks up the makernote info tag array if one is - set, else it returns an empty string. - */ - virtual std::string tagDesc(uint16_t tag) const; - /*! - @brief Print a list of all tags known by this MakerNote to the output - stream os. The default implementation prints all tags in the - makernote info tag array if one is set. - */ - virtual void taglist(std::ostream& os) const; - /*! - @brief Write the makernote tag info of tag to the output stream os. - */ - virtual std::ostream& writeMnTagInfo(std::ostream& os, uint16_t tag) const; //! The first makernote entry virtual Entries::const_iterator begin() const =0; //! End of the makernote entries @@ -235,18 +192,10 @@ namespace Exiv2 { virtual Entries::const_iterator findIdx(int idx) const =0; //! Return the size of the makernote in bytes virtual long size() const =0; - //! Return the name of the makernote item - virtual std::string ifdItem() const =0; - //! Interpret and print the value of a makernote tag - virtual std::ostream& printTag(std::ostream& os, - uint16_t tag, - const Value& value) const =0; //@} protected: // DATA - //! Pointer to an array of makernote tag infos - const MnTagInfo* pMnTagInfo_; /*! @brief Flag to control the memory management:
True: requires memory allocation and deallocation,
@@ -274,6 +223,7 @@ namespace Exiv2 { //! 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. */ @@ -291,12 +241,10 @@ namespace Exiv2 { //! @name Creators //@{ /*! - @brief Constructor. Takes an optional makernote info tag array and - allows to choose whether or not memory management is required - for the Entries. - */ - explicit IfdMakerNote(const MakerNote::MnTagInfo* pMnTagInfo =0, - bool alloc =true); + @brief Constructor. Requires an %Ifd id and allows to choose whether + or not memory management is needed for the Entries. + */ + explicit IfdMakerNote(IfdId ifdId, bool alloc =true); //! Copy constructor IfdMakerNote(const IfdMakerNote& rhs); //! Virtual destructor @@ -321,18 +269,18 @@ namespace Exiv2 { long len, ByteOrder byteOrder); virtual long copy(byte* buf, ByteOrder byteOrder, long offset); - void add(const Entry& entry) { ifd_.add(entry); } - Entries::iterator begin() { return ifd_.begin(); } - Entries::iterator end() { return ifd_.end(); } + virtual void add(const Entry& entry) { ifd_.add(entry); } + virtual Entries::iterator begin() { return ifd_.begin(); } + virtual Entries::iterator end() { return ifd_.end(); } virtual void updateBase(byte* pNewBase); //@} //! @name Accessors //@{ - Entries::const_iterator begin() const { return ifd_.begin(); } - Entries::const_iterator end() const { return ifd_.end(); } - Entries::const_iterator findIdx(int idx) const; - long size() const; + virtual Entries::const_iterator begin() const { return ifd_.begin(); } + virtual Entries::const_iterator end() const { return ifd_.end(); } + virtual Entries::const_iterator findIdx(int idx) const; + virtual long size() const; AutoPtr create(bool alloc =true) const; AutoPtr clone() const; /*! @@ -355,10 +303,6 @@ namespace Exiv2 { buffer. */ virtual long headerSize() const; - virtual std::string ifdItem() const =0; - virtual std::ostream& printTag(std::ostream& os, - uint16_t tag, - const Value& value) const =0; //@} protected: @@ -409,7 +353,8 @@ namespace Exiv2 { //! @name Manipulators //@{ /*! - @brief Register a %MakerNote create function for a camera make and model. + @brief Register a %MakerNote create function for a camera make and + model. Registers a create function for a %MakerNote for a given make and model combination with the factory. Both the make and model strings @@ -429,8 +374,8 @@ namespace Exiv2 { const std::string& model, CreateFct createMakerNote); - //! Register a %MakerNote prototype in the IFD item registry. - void registerMakerNote(MakerNote::AutoPtr makerNote); + //! Register a %MakerNote prototype in the IFD id registry. + void registerMakerNote(IfdId ifdId, MakerNote::AutoPtr makerNote); //@} //! @name Accessors @@ -486,9 +431,8 @@ namespace Exiv2 { ByteOrder byteOrder, long offset) const; - //! Create a %MakerNote based on its IFD item string. - MakerNote::AutoPtr create(const std::string& ifdItem, - bool alloc =true) const; + //! Create a %MakerNote for an IFD id. + MakerNote::AutoPtr create(IfdId ifdId, bool alloc =true) const; //@} /*! @@ -523,16 +467,16 @@ namespace Exiv2 { typedef std::vector > ModelRegistry; //! Type used to store a list of make labels and model registries typedef std::vector > Registry; - //! Type used to store a list of IFD items and %MakerNote prototypes - typedef std::map IfdItemRegistry; + //! Type used to store a list of IFD ids and %MakerNote prototypes + typedef std::map IfdIdRegistry; // DATA //! Pointer to the one and only instance of this class. static MakerNoteFactory* pInstance_; //! List of makernote types and corresponding makernote create functions. Registry registry_; - //! List of makernote IfdItems and corresponding create functions. - IfdItemRegistry ifdItemRegistry_; + //! List of makernote IFD ids and corresponding create functions. + IfdIdRegistry ifdIdRegistry_; }; // class MakerNoteFactory diff --git a/src/nikonmn.cpp b/src/nikonmn.cpp index 99f0218d..af6c98a3 100644 --- a/src/nikonmn.cpp +++ b/src/nikonmn.cpp @@ -36,6 +36,8 @@ EXIV2_RCSID("@(#) $Id$"); #include "makernote.hpp" #include "value.hpp" #include "image.hpp" +#include "tags.hpp" +#include "error.hpp" // + standard includes #include @@ -53,32 +55,32 @@ namespace Exiv2 { const Nikon1MakerNote::RegisterMakerNote Nikon1MakerNote::register_; // Nikon1 MakerNote Tag Info - static const MakerNote::MnTagInfo nikon1MnTagInfo[] = { - MakerNote::MnTagInfo(0x0001, "Version", "Nikon Makernote version"), - MakerNote::MnTagInfo(0x0002, "ISOSpeed", "ISO speed setting"), - MakerNote::MnTagInfo(0x0003, "ColorMode", "Color mode"), - MakerNote::MnTagInfo(0x0004, "Quality", "Image quality setting"), - MakerNote::MnTagInfo(0x0005, "WhiteBalance", "White balance"), - MakerNote::MnTagInfo(0x0006, "Sharpening", "Image sharpening setting"), - MakerNote::MnTagInfo(0x0007, "Focus", "Focus mode"), - MakerNote::MnTagInfo(0x0008, "Flash", "Flash mode"), - MakerNote::MnTagInfo(0x000f, "ISOSelection", "ISO selection"), - MakerNote::MnTagInfo(0x0080, "ImageAdjustment", "Image adjustment setting"), - MakerNote::MnTagInfo(0x0082, "Adapter", "Adapter used"), - MakerNote::MnTagInfo(0x0085, "FocusDistance", "Manual focus distance"), - MakerNote::MnTagInfo(0x0086, "DigitalZoom", "Digital zoom setting"), - MakerNote::MnTagInfo(0x0088, "AFFocusPos", "AF focus position"), + const TagInfo Nikon1MakerNote::tagInfo_[] = { + TagInfo(0x0001, "Version", "Nikon Makernote version", nikon1IfdId, makerTags, printValue), + TagInfo(0x0002, "ISOSpeed", "ISO speed setting", nikon1IfdId, makerTags, print0x0002), + TagInfo(0x0003, "ColorMode", "Color mode", nikon1IfdId, makerTags, printValue), + TagInfo(0x0004, "Quality", "Image quality setting", nikon1IfdId, makerTags, printValue), + TagInfo(0x0005, "WhiteBalance", "White balance", nikon1IfdId, makerTags, printValue), + TagInfo(0x0006, "Sharpening", "Image sharpening setting", nikon1IfdId, makerTags, printValue), + TagInfo(0x0007, "Focus", "Focus mode", nikon1IfdId, makerTags, print0x0007), + TagInfo(0x0008, "Flash", "Flash mode", nikon1IfdId, makerTags, printValue), + TagInfo(0x000f, "ISOSelection", "ISO selection", nikon1IfdId, makerTags, printValue), + TagInfo(0x0080, "ImageAdjustment", "Image adjustment setting", nikon1IfdId, makerTags, printValue), + TagInfo(0x0082, "Adapter", "Adapter used", nikon1IfdId, makerTags, printValue), + TagInfo(0x0085, "FocusDistance", "Manual focus distance", nikon1IfdId, makerTags, print0x0085), + TagInfo(0x0086, "DigitalZoom", "Digital zoom setting", nikon1IfdId, makerTags, print0x0086), + TagInfo(0x0088, "AFFocusPos", "AF focus position", nikon1IfdId, makerTags, print0x0088), // End of list marker - MakerNote::MnTagInfo(0xffff, "(UnknownNikon1MnTag)", "Unknown Nikon1MakerNote tag") + TagInfo(0xffff, "(UnknownNikon1MnTag)", "Unknown Nikon1MakerNote tag", nikon1IfdId, makerTags, printValue) }; Nikon1MakerNote::Nikon1MakerNote(bool alloc) - : IfdMakerNote(nikon1MnTagInfo, alloc), ifdItem_("Nikon1") + : IfdMakerNote(nikon1IfdId, alloc) { } Nikon1MakerNote::Nikon1MakerNote(const Nikon1MakerNote& rhs) - : IfdMakerNote(rhs), ifdItem_(rhs.ifdItem_) + : IfdMakerNote(rhs) { } @@ -102,24 +104,6 @@ namespace Exiv2 { return new Nikon1MakerNote(*this); } - std::ostream& Nikon1MakerNote::printTag(std::ostream& os, - uint16_t tag, - const Value& value) const - { - switch (tag) { - case 0x0002: print0x0002(os, value); break; - case 0x0007: print0x0007(os, value); break; - case 0x0085: print0x0085(os, value); break; - case 0x0086: print0x0086(os, value); break; - case 0x0088: print0x0088(os, value); break; - default: - // All other tags (known or unknown) go here - os << value; - break; - } - return os; - } - std::ostream& Nikon1MakerNote::print0x0002(std::ostream& os, const Value& value) { @@ -206,21 +190,21 @@ namespace Exiv2 { const Nikon2MakerNote::RegisterMakerNote Nikon2MakerNote::register_; // Nikon2 MakerNote Tag Info - static const MakerNote::MnTagInfo nikon2MnTagInfo[] = { - MakerNote::MnTagInfo(0x0003, "Quality", "Image quality setting"), - MakerNote::MnTagInfo(0x0004, "ColorMode", "Color mode"), - MakerNote::MnTagInfo(0x0005, "ImageAdjustment", "Image adjustment setting"), - MakerNote::MnTagInfo(0x0006, "ISOSpeed", "ISO speed setting"), - MakerNote::MnTagInfo(0x0007, "WhiteBalance", "White balance"), - MakerNote::MnTagInfo(0x0008, "Focus", "Focus mode"), - MakerNote::MnTagInfo(0x000a, "DigitalZoom", "Digital zoom setting"), - MakerNote::MnTagInfo(0x000b, "Adapter", "Adapter used"), + const TagInfo Nikon2MakerNote::tagInfo_[] = { + TagInfo(0x0003, "Quality", "Image quality setting", nikon2IfdId, makerTags, print0x0003), + TagInfo(0x0004, "ColorMode", "Color mode", nikon2IfdId, makerTags, print0x0004), + TagInfo(0x0005, "ImageAdjustment", "Image adjustment setting", nikon2IfdId, makerTags, print0x0005), + TagInfo(0x0006, "ISOSpeed", "ISO speed setting", nikon2IfdId, makerTags, print0x0006), + TagInfo(0x0007, "WhiteBalance", "White balance", nikon2IfdId, makerTags, print0x0007), + TagInfo(0x0008, "Focus", "Focus mode", nikon2IfdId, makerTags, printValue), + TagInfo(0x000a, "DigitalZoom", "Digital zoom setting", nikon2IfdId, makerTags, print0x000a), + TagInfo(0x000b, "Adapter", "Adapter used", nikon2IfdId, makerTags, printValue), // End of list marker - MakerNote::MnTagInfo(0xffff, "(UnknownNikon2MnTag)", "Unknown Nikon2MakerNote tag") + TagInfo(0xffff, "(UnknownNikon2MnTag)", "Unknown Nikon2MakerNote tag", nikon2IfdId, makerTags, printValue) }; Nikon2MakerNote::Nikon2MakerNote(bool alloc) - : IfdMakerNote(nikon2MnTagInfo, alloc), ifdItem_("Nikon2") + : IfdMakerNote(nikon2IfdId, alloc) { byte buf[] = { 'N', 'i', 'k', 'o', 'n', '\0', 0x00, 0x01 @@ -229,7 +213,7 @@ namespace Exiv2 { } Nikon2MakerNote::Nikon2MakerNote(const Nikon2MakerNote& rhs) - : IfdMakerNote(rhs), ifdItem_(rhs.ifdItem_) + : IfdMakerNote(rhs) { } @@ -280,25 +264,6 @@ namespace Exiv2 { return new Nikon2MakerNote(*this); } - std::ostream& Nikon2MakerNote::printTag(std::ostream& os, - uint16_t tag, - const Value& value) const - { - switch (tag) { - case 0x0003: print0x0003(os, value); break; - case 0x0004: print0x0004(os, value); break; - case 0x0005: print0x0005(os, value); break; - case 0x0006: print0x0006(os, value); break; - case 0x0007: print0x0007(os, value); break; - case 0x000a: print0x000a(os, value); break; - default: - // All other tags (known or unknown) go here - os << value; - break; - } - return os; - } - std::ostream& Nikon2MakerNote::print0x0003(std::ostream& os, const Value& value) { @@ -397,59 +362,59 @@ namespace Exiv2 { const Nikon3MakerNote::RegisterMakerNote Nikon3MakerNote::register_; // Nikon3 MakerNote Tag Info - static const MakerNote::MnTagInfo nikon3MnTagInfo[] = { - MakerNote::MnTagInfo(0x0001, "Version", "Nikon Makernote version"), - MakerNote::MnTagInfo(0x0002, "ISOSpeed", "ISO speed used"), - MakerNote::MnTagInfo(0x0003, "ColorMode", "Color mode"), - MakerNote::MnTagInfo(0x0004, "Quality", "Image quality setting"), - MakerNote::MnTagInfo(0x0005, "WhiteBalance", "White balance"), - MakerNote::MnTagInfo(0x0006, "Sharpening", "Image sharpening setting"), - MakerNote::MnTagInfo(0x0007, "Focus", "Focus mode"), - MakerNote::MnTagInfo(0x0008, "FlashSetting", "Flash setting"), - MakerNote::MnTagInfo(0x0009, "FlashMode", "Flash mode"), - MakerNote::MnTagInfo(0x000b, "WhiteBalanceBias", "White balance bias"), - MakerNote::MnTagInfo(0x000c, "ColorBalance1", "Color balance 1"), - MakerNote::MnTagInfo(0x000e, "ExposureDiff", "Exposure difference"), - MakerNote::MnTagInfo(0x000f, "ISOSelection", "ISO selection"), - MakerNote::MnTagInfo(0x000b, "DataDump", "Data dump"), - MakerNote::MnTagInfo(0x0011, "ThumbOffset", "Thumbnail IFD offset"), - MakerNote::MnTagInfo(0x0012, "FlashComp", "Flash compensation setting"), - MakerNote::MnTagInfo(0x0013, "ISOSetting", "ISO speed setting"), - MakerNote::MnTagInfo(0x0016, "ImageBoundry", "Image boundry"), - MakerNote::MnTagInfo(0x0018, "FlashBracketComp", "Flash bracket compensation applied"), - MakerNote::MnTagInfo(0x0019, "ExposureBracketComp", "AE bracket compensation applied"), - MakerNote::MnTagInfo(0x0080, "ImageAdjustment", "Image adjustment setting"), - MakerNote::MnTagInfo(0x0081, "ToneComp", "Tone compensation setting (contrast)"), - MakerNote::MnTagInfo(0x0082, "AuxiliaryLens", "Auxiliary lens (adapter)"), - MakerNote::MnTagInfo(0x0083, "LensType", "Lens type"), - MakerNote::MnTagInfo(0x0084, "Lens", "Lens"), - MakerNote::MnTagInfo(0x0085, "FocusDistance", "Manual focus distance"), - MakerNote::MnTagInfo(0x0086, "DigitalZoom", "Digital zoom setting"), - MakerNote::MnTagInfo(0x0087, "FlashType", "Type of flash used"), - MakerNote::MnTagInfo(0x0088, "AFFocusPos", "AF focus position"), - MakerNote::MnTagInfo(0x0089, "Bracketing", "Bracketing"), - MakerNote::MnTagInfo(0x008c, "NEFCurve1", "NEF curve 1"), - MakerNote::MnTagInfo(0x008d, "ColorMode", "Color mode"), - MakerNote::MnTagInfo(0x008f, "SceneMode", "Scene mode"), - MakerNote::MnTagInfo(0x0090, "LightingType", "Lighting type"), - MakerNote::MnTagInfo(0x0092, "HueAdjustment", "Hue adjustment"), - MakerNote::MnTagInfo(0x0094, "Saturation", "Saturation adjustment"), - MakerNote::MnTagInfo(0x0095, "NoiseReduction", "Noise reduction"), - MakerNote::MnTagInfo(0x0096, "NEFCurve2", "NEF curve 2"), - MakerNote::MnTagInfo(0x0097, "ColorBalance2", "Color balance 2"), - MakerNote::MnTagInfo(0x0099, "NEFThumbnailSize", "NEF thumbnail size"), - MakerNote::MnTagInfo(0x00a0, "SerialNumber", "Camera serial number"), - MakerNote::MnTagInfo(0x00a7, "ShutterCount", "Number of shots taken by camera"), - MakerNote::MnTagInfo(0x00a9, "ImageOptimization", "Image optimization"), - MakerNote::MnTagInfo(0x00aa, "Saturation", "Saturation"), - MakerNote::MnTagInfo(0x00ab, "VariProgram", "Vari program"), - MakerNote::MnTagInfo(0x0e00, "PrintIM", "Print image matching"), + const TagInfo Nikon3MakerNote::tagInfo_[] = { + TagInfo(0x0001, "Version", "Nikon Makernote version", nikon3IfdId, makerTags, printValue), + TagInfo(0x0002, "ISOSpeed", "ISO speed used", nikon3IfdId, makerTags, print0x0002), + TagInfo(0x0003, "ColorMode", "Color mode", nikon3IfdId, makerTags, printValue), + TagInfo(0x0004, "Quality", "Image quality setting", nikon3IfdId, makerTags, printValue), + TagInfo(0x0005, "WhiteBalance", "White balance", nikon3IfdId, makerTags, printValue), + TagInfo(0x0006, "Sharpening", "Image sharpening setting", nikon3IfdId, makerTags, printValue), + TagInfo(0x0007, "Focus", "Focus mode", nikon3IfdId, makerTags, printValue), + TagInfo(0x0008, "FlashSetting", "Flash setting", nikon3IfdId, makerTags, printValue), + TagInfo(0x0009, "FlashMode", "Flash mode", nikon3IfdId, makerTags, printValue), + TagInfo(0x000b, "WhiteBalanceBias", "White balance bias", nikon3IfdId, makerTags, printValue), + TagInfo(0x000c, "ColorBalance1", "Color balance 1", nikon3IfdId, makerTags, printValue), + TagInfo(0x000e, "ExposureDiff", "Exposure difference", nikon3IfdId, makerTags, printValue), + TagInfo(0x000f, "ISOSelection", "ISO selection", nikon3IfdId, makerTags, printValue), + TagInfo(0x000b, "DataDump", "Data dump", nikon3IfdId, makerTags, printValue), + TagInfo(0x0011, "ThumbOffset", "Thumbnail IFD offset", nikon3IfdId, makerTags, printValue), + TagInfo(0x0012, "FlashComp", "Flash compensation setting", nikon3IfdId, makerTags, print0x0012), + TagInfo(0x0013, "ISOSetting", "ISO speed setting", nikon3IfdId, makerTags, print0x0002), // use 0x0002 print fct + TagInfo(0x0016, "ImageBoundry", "Image boundry", nikon3IfdId, makerTags, printValue), + TagInfo(0x0018, "FlashBracketComp", "Flash bracket compensation applied", nikon3IfdId, makerTags, print0x0012), // use 0x0012 print fct + TagInfo(0x0019, "ExposureBracketComp", "AE bracket compensation applied", nikon3IfdId, makerTags, printValue), + TagInfo(0x0080, "ImageAdjustment", "Image adjustment setting", nikon3IfdId, makerTags, printValue), + TagInfo(0x0081, "ToneComp", "Tone compensation setting (contrast)", nikon3IfdId, makerTags, printValue), + TagInfo(0x0082, "AuxiliaryLens", "Auxiliary lens (adapter)", nikon3IfdId, makerTags, printValue), + TagInfo(0x0083, "LensType", "Lens type", nikon3IfdId, makerTags, printValue), + TagInfo(0x0084, "Lens", "Lens", nikon3IfdId, makerTags, print0x0084), + TagInfo(0x0085, "FocusDistance", "Manual focus distance", nikon3IfdId, makerTags, printValue), + TagInfo(0x0086, "DigitalZoom", "Digital zoom setting", nikon3IfdId, makerTags, printValue), + TagInfo(0x0087, "FlashType", "Type of flash used", nikon3IfdId, makerTags, print0x0087), + TagInfo(0x0088, "AFFocusPos", "AF focus position", nikon3IfdId, makerTags, print0x0088), + TagInfo(0x0089, "Bracketing", "Bracketing", nikon3IfdId, makerTags, print0x0089), + TagInfo(0x008c, "NEFCurve1", "NEF curve 1", nikon3IfdId, makerTags, printValue), + TagInfo(0x008d, "ColorMode", "Color mode", nikon3IfdId, makerTags, printValue), + TagInfo(0x008f, "SceneMode", "Scene mode", nikon3IfdId, makerTags, printValue), + TagInfo(0x0090, "LightingType", "Lighting type", nikon3IfdId, makerTags, printValue), + TagInfo(0x0092, "HueAdjustment", "Hue adjustment", nikon3IfdId, makerTags, printValue), + TagInfo(0x0094, "Saturation", "Saturation adjustment", nikon3IfdId, makerTags, printValue), + TagInfo(0x0095, "NoiseReduction", "Noise reduction", nikon3IfdId, makerTags, printValue), + TagInfo(0x0096, "NEFCurve2", "NEF curve 2", nikon3IfdId, makerTags, printValue), + TagInfo(0x0097, "ColorBalance2", "Color balance 2", nikon3IfdId, makerTags, printValue), + TagInfo(0x0099, "NEFThumbnailSize", "NEF thumbnail size", nikon3IfdId, makerTags, printValue), + TagInfo(0x00a0, "SerialNumber", "Camera serial number", nikon3IfdId, makerTags, printValue), + TagInfo(0x00a7, "ShutterCount", "Number of shots taken by camera", nikon3IfdId, makerTags, printValue), + TagInfo(0x00a9, "ImageOptimization", "Image optimization", nikon3IfdId, makerTags, printValue), + TagInfo(0x00aa, "Saturation", "Saturation", nikon3IfdId, makerTags, printValue), + TagInfo(0x00ab, "VariProgram", "Vari program", nikon3IfdId, makerTags, printValue), + TagInfo(0x0e00, "PrintIM", "Print image matching", nikon3IfdId, makerTags, printValue), // End of list marker - MakerNote::MnTagInfo(0xffff, "(UnknownNikon3MnTag)", "Unknown Nikon3MakerNote tag") + TagInfo(0xffff, "(UnknownNikon3MnTag)", "Unknown Nikon3MakerNote tag", nikon3IfdId, makerTags, printValue) }; Nikon3MakerNote::Nikon3MakerNote(bool alloc) - : IfdMakerNote(nikon3MnTagInfo, alloc), ifdItem_("Nikon3") + : IfdMakerNote(nikon3IfdId, alloc) { absOffset_ = false; byte buf[] = { @@ -460,32 +425,10 @@ namespace Exiv2 { } Nikon3MakerNote::Nikon3MakerNote(const Nikon3MakerNote& rhs) - : IfdMakerNote(rhs), ifdItem_(rhs.ifdItem_) + : IfdMakerNote(rhs) { } - int Nikon3MakerNote::read(const byte* buf, - long len, - ByteOrder byteOrder, - long offset) - { - int rc = IfdMakerNote::read(buf, len, byteOrder, offset); - if (rc) return rc; - - // Todo: Add the tags and thumbnail from the embedded thumbnail IFD - // Accessing them is easy, but we need support for more than - // one IfdId in makernotes to get it working. -// Ifd thumbIfd(makerIfdId, 0, false); -// rc = ifd_.readSubIfd(thumbIfd, buf+10, len-10, byteOrder, 0x0011); -// if (rc) { -// std::cerr << "Didn't work :(\n"; -// } -// else { -// thumbIfd.print(std::cout); -// } - return 0; - } - int Nikon3MakerNote::readHeader(const byte* buf, long len, ByteOrder byteOrder) @@ -536,27 +479,6 @@ namespace Exiv2 { return new Nikon3MakerNote(*this); } - std::ostream& Nikon3MakerNote::printTag(std::ostream& os, - uint16_t tag, - const Value& value) const - { - switch (tag) { - case 0x0002: print0x0002(os, value); break; - case 0x0012: print0x0012(os, value); break; - case 0x0013: print0x0002(os, value); break; // use 0x0002 print fct - case 0x0018: print0x0012(os, value); break; // use 0x0012 print fct - case 0x0084: print0x0084(os, value); break; - case 0x0087: print0x0087(os, value); break; - case 0x0088: print0x0088(os, value); break; - case 0x0089: print0x0089(os, value); break; - default: - // All other tags (known or unknown) go here - os << value; - break; - } - return os; - } - std::ostream& Nikon3MakerNote::print0x0002(std::ostream& os, const Value& value) { diff --git a/src/nikonmn.hpp b/src/nikonmn.hpp index 4e92857e..6ac8a62d 100644 --- a/src/nikonmn.hpp +++ b/src/nikonmn.hpp @@ -48,6 +48,7 @@ // included header files #include "types.hpp" #include "makernote.hpp" +#include "tags.hpp" // + standard includes #include @@ -119,11 +120,6 @@ namespace Exiv2 { //@{ AutoPtr create(bool alloc =true) const; AutoPtr clone() const; - //! Return the name of the makernote item ("Nikon1") - std::string ifdItem() const { return ifdItem_; } - std::ostream& printTag(std::ostream& os, - uint16_t tag, - const Value& value) const; //@} //! @name Print functions for Nikon1 %MakerNote tags @@ -146,6 +142,9 @@ namespace Exiv2 { //! Internal virtual copy constructor. Nikon1MakerNote* clone_() const; + //! Tag information + static const TagInfo tagInfo_[]; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor @@ -153,7 +152,9 @@ namespace Exiv2 { { MakerNoteFactory& mnf = MakerNoteFactory::instance(); mnf.registerMakerNote("NIKON*", "*", createNikonMakerNote); - mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon1MakerNote)); + mnf.registerMakerNote(nikon1IfdId, + MakerNote::AutoPtr(new Nikon1MakerNote)); + ExifTags::registerMakerTagInfo(nikon1IfdId, tagInfo_); } }; // DATA @@ -170,8 +171,6 @@ namespace Exiv2 { demand. */ static const RegisterMakerNote register_; - //! The item name (second part of the key) used for makernote tags - std::string ifdItem_; }; // class Nikon1MakerNote @@ -209,11 +208,6 @@ namespace Exiv2 { int checkHeader() const; AutoPtr create(bool alloc =true) const; AutoPtr clone() const; - //! Return the name of the makernote item ("Nikon2") - std::string ifdItem() const { return ifdItem_; } - std::ostream& printTag(std::ostream& os, - uint16_t tag, - const Value& value) const; //@} //! @name Print functions for Nikon2 %MakerNote tags @@ -238,13 +232,18 @@ namespace Exiv2 { //! Internal virtual copy constructor. Nikon2MakerNote* clone_() const; + //! Tag information + static const TagInfo tagInfo_[]; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor RegisterMakerNote() { MakerNoteFactory& mnf = MakerNoteFactory::instance(); - mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon2MakerNote)); + mnf.registerMakerNote(nikon2IfdId, + MakerNote::AutoPtr(new Nikon2MakerNote)); + ExifTags::registerMakerTagInfo(nikon2IfdId, tagInfo_); } }; // DATA @@ -262,9 +261,6 @@ namespace Exiv2 { */ static const RegisterMakerNote register_; - //! The item name (second part of the key) used for makernote tags - std::string ifdItem_; - }; // class Nikon2MakerNote //! A third MakerNote format used by Nikon cameras, e.g., E5400, SQ, D2H, D70 @@ -288,10 +284,6 @@ namespace Exiv2 { //! @name Manipulators //@{ - int read(const byte* buf, - long len, - ByteOrder byteOrder, - long offset); int readHeader(const byte* buf, long len, ByteOrder byteOrder); @@ -302,11 +294,6 @@ namespace Exiv2 { int checkHeader() const; AutoPtr create(bool alloc =true) const; AutoPtr clone() const; - //! Return the name of the makernote item ("Nikon3") - std::string ifdItem() const { return ifdItem_; } - std::ostream& printTag(std::ostream& os, - uint16_t tag, - const Value& value) const; //@} //! @name Print functions for Nikon3 %MakerNote tags @@ -331,15 +318,24 @@ namespace Exiv2 { //! Internal virtual copy constructor. Nikon3MakerNote* clone_() const; - //! Structure used to auto-register the MakerNote. + //! Tag information + static const TagInfo tagInfo_[]; + + //! Structure used to auto-register the MakerNote and %TagInfos struct RegisterMakerNote { //! Default constructor RegisterMakerNote() { MakerNoteFactory& mnf = MakerNoteFactory::instance(); - mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon3MakerNote)); + mnf.registerMakerNote(nikon3IfdId, + MakerNote::AutoPtr(new Nikon3MakerNote)); + mnf.registerMakerNote(nikon3ThumbIfdId, + MakerNote::AutoPtr(new Nikon3MakerNote)); + ExifTags::registerMakerTagInfo(nikon3IfdId, tagInfo_); + ExifTags::registerBaseTagInfo(nikon3ThumbIfdId); } }; + // DATA /*! The static member variable is initialized before main (see note) and @@ -355,8 +351,8 @@ namespace Exiv2 { */ static const RegisterMakerNote register_; - //! The item name (second part of the key) used for makernote tags - std::string ifdItem_; + //! All makernote entries + Entries entries_; }; // class Nikon3MakerNote diff --git a/src/sigmamn.cpp b/src/sigmamn.cpp index 4ec4c38a..0b0264fe 100644 --- a/src/sigmamn.cpp +++ b/src/sigmamn.cpp @@ -54,36 +54,36 @@ namespace Exiv2 { const SigmaMakerNote::RegisterMakerNote SigmaMakerNote::register_; // Sigma (Foveon) MakerNote Tag Info - static const MakerNote::MnTagInfo sigmaMnTagInfo[] = { - MakerNote::MnTagInfo(0x0002, "SerialNumber", "Camera serial number"), - MakerNote::MnTagInfo(0x0003, "DriveMode", "Drive Mode"), - MakerNote::MnTagInfo(0x0004, "ResolutionMode", "Resolution Mode"), - MakerNote::MnTagInfo(0x0005, "AutofocusMode", "Autofocus mode"), - MakerNote::MnTagInfo(0x0006, "FocusSetting", "Focus setting"), - MakerNote::MnTagInfo(0x0007, "WhiteBalance", "White balance"), - MakerNote::MnTagInfo(0x0008, "ExposureMode", "Exposure mode"), - MakerNote::MnTagInfo(0x0009, "MeteringMode", "Metering mode"), - MakerNote::MnTagInfo(0x000a, "LensRange", "Lens focal length range"), - MakerNote::MnTagInfo(0x000b, "ColorSpace", "Color space"), - MakerNote::MnTagInfo(0x000c, "Exposure", "Exposure"), - MakerNote::MnTagInfo(0x000d, "Contrast", "Contrast"), - MakerNote::MnTagInfo(0x000e, "Shadow", "Shadow"), - MakerNote::MnTagInfo(0x000f, "Highlight", "Highlight"), - MakerNote::MnTagInfo(0x0010, "Saturation", "Saturation"), - MakerNote::MnTagInfo(0x0011, "Sharpness", "Sharpness"), - MakerNote::MnTagInfo(0x0012, "FillLight", "X3 Fill light"), - MakerNote::MnTagInfo(0x0014, "ColorAdjustment", "Color adjustment"), - MakerNote::MnTagInfo(0x0015, "AdjustmentMode", "Adjustment mode"), - MakerNote::MnTagInfo(0x0016, "Quality", "Quality"), - MakerNote::MnTagInfo(0x0017, "Firmware", "Firmware"), - MakerNote::MnTagInfo(0x0018, "Software", "Software"), - MakerNote::MnTagInfo(0x0019, "AutoBracket", "Auto bracket"), + const TagInfo SigmaMakerNote::tagInfo_[] = { + TagInfo(0x0002, "SerialNumber", "Camera serial number", sigmaIfdId, makerTags, printValue), + TagInfo(0x0003, "DriveMode", "Drive Mode", sigmaIfdId, makerTags, printValue), + TagInfo(0x0004, "ResolutionMode", "Resolution Mode", sigmaIfdId, makerTags, printValue), + TagInfo(0x0005, "AutofocusMode", "Autofocus mode", sigmaIfdId, makerTags, printValue), + TagInfo(0x0006, "FocusSetting", "Focus setting", sigmaIfdId, makerTags, printValue), + TagInfo(0x0007, "WhiteBalance", "White balance", sigmaIfdId, makerTags, printValue), + TagInfo(0x0008, "ExposureMode", "Exposure mode", sigmaIfdId, makerTags, print0x0008), + TagInfo(0x0009, "MeteringMode", "Metering mode", sigmaIfdId, makerTags, print0x0009), + TagInfo(0x000a, "LensRange", "Lens focal length range", sigmaIfdId, makerTags, printValue), + TagInfo(0x000b, "ColorSpace", "Color space", sigmaIfdId, makerTags, printValue), + TagInfo(0x000c, "Exposure", "Exposure", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x000d, "Contrast", "Contrast", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x000e, "Shadow", "Shadow", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x000f, "Highlight", "Highlight", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x0010, "Saturation", "Saturation", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x0011, "Sharpness", "Sharpness", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x0012, "FillLight", "X3 Fill light", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x0014, "ColorAdjustment", "Color adjustment", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x0015, "AdjustmentMode", "Adjustment mode", sigmaIfdId, makerTags, printValue), + TagInfo(0x0016, "Quality", "Quality", sigmaIfdId, makerTags, printStripLabel), + TagInfo(0x0017, "Firmware", "Firmware", sigmaIfdId, makerTags, printValue), + TagInfo(0x0018, "Software", "Software", sigmaIfdId, makerTags, printValue), + TagInfo(0x0019, "AutoBracket", "Auto bracket", sigmaIfdId, makerTags, printValue), // End of list marker - MakerNote::MnTagInfo(0xffff, "(UnknownSigmaMakerNoteTag)", "Unknown SigmaMakerNote tag") + TagInfo(0xffff, "(UnknownSigmaMakerNoteTag)", "Unknown SigmaMakerNote tag", sigmaIfdId, makerTags, printValue) }; SigmaMakerNote::SigmaMakerNote(bool alloc) - : IfdMakerNote(sigmaMnTagInfo, alloc), ifdItem_("Sigma") + : IfdMakerNote(sigmaIfdId, alloc) { byte buf[] = { 'S', 'I', 'G', 'M', 'A', '\0', '\0', '\0', 0x01, 0x00 @@ -92,7 +92,7 @@ namespace Exiv2 { } SigmaMakerNote::SigmaMakerNote(const SigmaMakerNote& rhs) - : IfdMakerNote(rhs), ifdItem_(rhs.ifdItem_) + : IfdMakerNote(rhs) { } @@ -149,30 +149,6 @@ namespace Exiv2 { return new SigmaMakerNote(*this); } - std::ostream& SigmaMakerNote::printTag(std::ostream& os, - uint16_t tag, - const Value& value) const - { - switch (tag) { - case 0x000c: // fallthrough - case 0x000d: // fallthrough - case 0x000e: // fallthrough - case 0x000f: // fallthrough - case 0x0010: // fallthrough - case 0x0011: // fallthrough - case 0x0012: // fallthrough - case 0x0014: // fallthrough - case 0x0016: printStripLabel(os, value); break; - case 0x0008: print0x0008(os, value); break; - case 0x0009: print0x0009(os, value); break; - default: - // All other tags (known or unknown) go here - os << value; - break; - } - return os; - } - std::ostream& SigmaMakerNote::printStripLabel(std::ostream& os, const Value& value) { diff --git a/src/sigmamn.hpp b/src/sigmamn.hpp index 1926f395..e304f8d8 100644 --- a/src/sigmamn.hpp +++ b/src/sigmamn.hpp @@ -35,6 +35,7 @@ // included header files #include "types.hpp" #include "makernote.hpp" +#include "tags.hpp" // + standard includes #include @@ -114,11 +115,6 @@ namespace Exiv2 { int checkHeader() const; AutoPtr create(bool alloc =true) const; AutoPtr clone() const; - //! Return the name of the makernote item ("Sigma") - std::string ifdItem() const { return ifdItem_; } - std::ostream& printTag(std::ostream& os, - uint16_t tag, - const Value& value) const; //@} //! @name Print functions for Sigma (Foveon) %MakerNote tags @@ -137,6 +133,9 @@ namespace Exiv2 { //! Internal virtual copy constructor. SigmaMakerNote* clone_() const; + //! Tag information + static const TagInfo tagInfo_[]; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor @@ -145,7 +144,9 @@ namespace Exiv2 { MakerNoteFactory& mnf = MakerNoteFactory::instance(); mnf.registerMakerNote("SIGMA", "*", createSigmaMakerNote); mnf.registerMakerNote("FOVEON", "*", createSigmaMakerNote); - mnf.registerMakerNote(MakerNote::AutoPtr(new SigmaMakerNote)); + mnf.registerMakerNote(sigmaIfdId, + MakerNote::AutoPtr(new SigmaMakerNote)); + ExifTags::registerMakerTagInfo(sigmaIfdId, tagInfo_); } }; // DATA @@ -163,9 +164,6 @@ namespace Exiv2 { */ static const RegisterMakerNote register_; - //! The item name (second part of the key) used for makernote tags - std::string ifdItem_; - }; // class SigmaMakerNote } // namespace Exiv2 diff --git a/src/taglist.cpp b/src/taglist.cpp index 665fdf8f..5f4d6d12 100644 --- a/src/taglist.cpp +++ b/src/taglist.cpp @@ -33,10 +33,10 @@ try { IptcDataSets::dataSetList(std::cout); break; } - - MakerNote::AutoPtr makerNote = MakerNoteFactory::instance().create(item); - if (makerNote.get() != 0) { - makerNote->taglist(std::cout); + + IfdId ifdId = ExifTags::ifdIdByIfdItem(item); + if (ExifTags::isMakerIfd(ifdId)) { + ExifTags::makerTaglist(std::cout, ifdId); } else { rc = 2; diff --git a/src/tags.cpp b/src/tags.cpp index f95e7a3a..b9371e78 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -23,6 +23,7 @@ Version: $Rev$ Author(s): Andreas Huggel (ahu) History: 15-Jan-04, ahu: created + 21-Jan-05, ahu: added MakerNote TagInfo registry and related code */ // ***************************************************************************** #include "rcsid.hpp" @@ -59,9 +60,15 @@ namespace Exiv2 { IfdInfo(ifd0Id, "IFD0", "Image"), IfdInfo(exifIfdId, "Exif", "Photo"), // just to avoid 'Exif.Exif.*' keys IfdInfo(gpsIfdId, "GPSInfo", "GPSInfo"), - IfdInfo(makerIfdId, "Makernote", "Makernote"), IfdInfo(iopIfdId, "Iop", "Iop"), IfdInfo(ifd1Id, "IFD1", "Thumbnail"), + IfdInfo(canonIfdId, "Makernote", "Canon"), + IfdInfo(fujiIfdId, "Makernote", "Fujifilm"), + IfdInfo(nikon1IfdId, "Makernote", "Nikon1"), + IfdInfo(nikon2IfdId, "Makernote", "Nikon2"), + IfdInfo(nikon3IfdId, "Makernote", "Nikon3"), + IfdInfo(nikon3ThumbIfdId, "Makernote", "Nikon3Thumb"), + IfdInfo(sigmaIfdId, "Makernote", "Sigma"), IfdInfo(lastIfdId, "(Last IFD info)", "(Last IFD item)") }; @@ -89,6 +96,7 @@ namespace Exiv2 { SectionInfo(captureCond, "CaptureConditions", "Picture taking conditions"), SectionInfo(gpsTags, "GPS", "GPS information"), SectionInfo(iopTags, "Interoperability", "Interoperability information"), + SectionInfo(makerTags, "Makernote", "Vendor specific information"), SectionInfo(lastSectionId, "(LastSection)", "Last section") }; @@ -254,12 +262,6 @@ namespace Exiv2 { TagInfo(0xffff, "(UnknownIopTag)", "Unknown Exif Interoperability tag", ifdIdNotSet, sectionIdNotSet, printValue) }; - // MakerNote Tags - static const TagInfo makerNoteTagInfo[] = { - // End of list marker - TagInfo(0xffff, "(UnknownMakerNoteTag)", "Unknown MakerNote tag", ifdIdNotSet, sectionIdNotSet, printValue) - }; - // Unknown Tag static const TagInfo unknownTag(0xffff, "Unknown tag", "Unknown tag", ifdIdNotSet, sectionIdNotSet, printValue); @@ -268,10 +270,34 @@ namespace Exiv2 { // index into the array. const TagInfo* ExifTags::tagInfos_[] = { 0, - ifdTagInfo, exifTagInfo, gpsTagInfo, makerNoteTagInfo, iopTagInfo, ifdTagInfo, + ifdTagInfo, exifTagInfo, gpsTagInfo, iopTagInfo, ifdTagInfo, 0 }; + // Lookup list for registered makernote tag info tables + const TagInfo* ExifTags::makerTagInfos_[]; + + // All makernote ifd ids, in the same order as the tag infos in makerTagInfos_ + IfdId ExifTags::makerIfdIds_[]; + + void ExifTags::registerBaseTagInfo(IfdId ifdId) + { + registerMakerTagInfo(ifdId, ifdTagInfo); + } + + void ExifTags::registerMakerTagInfo(IfdId ifdId, const TagInfo* tagInfo) + { + int i = 0; + for (; i < MAX_MAKER_TAG_INFOS; ++i) { + if (makerIfdIds_[i] == 0) { + makerIfdIds_[i] = ifdId; + makerTagInfos_[i] = tagInfo; + break; + } + } + if (i == MAX_MAKER_TAG_INFOS) throw Error("MakerTagInfo registry full"); + } // ExifTags::registerMakerTagInfo + int ExifTags::tagInfoIdx(uint16_t tag, IfdId ifdId) { const TagInfo* tagInfo = tagInfos_[ifdId]; @@ -281,60 +307,133 @@ namespace Exiv2 { if (tagInfo[idx].tag_ == tag) return idx; } return -1; + } // ExifTags::tagInfoIdx + + const TagInfo* ExifTags::makerTagInfo(uint16_t tag, IfdId ifdId) + { + int i = 0; + for (; i < MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != ifdId; ++i); + if (i == MAX_MAKER_TAG_INFOS) return 0; + + for (int k = 0; makerTagInfos_[i][k].tag_ != 0xffff; ++k) { + if (makerTagInfos_[i][k].tag_ == tag) return &makerTagInfos_[i][k]; + } + + return 0; + } // ExifTags::makerTagInfo + + const TagInfo* ExifTags::makerTagInfo(const std::string& tagName, + IfdId ifdId) + { + int i = 0; + for (; i < MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != ifdId; ++i); + if (i == MAX_MAKER_TAG_INFOS) return 0; + + for (int k = 0; makerTagInfos_[i][k].tag_ != 0xffff; ++k) { + if (makerTagInfos_[i][k].name_ == tagName) { + return &makerTagInfos_[i][k]; + } + } + + return 0; + } // ExifTags::makerTagInfo + + bool ExifTags::isMakerIfd(IfdId ifdId) + { + int i = 0; + for (; i < MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != ifdId; ++i); + return i != MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != IfdId(0); } std::string ExifTags::tagName(uint16_t tag, IfdId ifdId) { - int idx = tagInfoIdx(tag, ifdId); - if (idx != -1) return tagInfos_[ifdId][idx].name_; - + if (isExifIfd(ifdId)) { + int idx = tagInfoIdx(tag, ifdId); + if (idx != -1) return tagInfos_[ifdId][idx].name_; + } + if (isMakerIfd(ifdId)) { + const TagInfo* tagInfo = makerTagInfo(tag, ifdId); + if (tagInfo != 0) return tagInfo->name_; + } std::ostringstream os; os << "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << tag; return os.str(); - } + } // ExifTags::tagName const char* ExifTags::tagDesc(uint16_t tag, IfdId ifdId) { - int idx = tagInfoIdx(tag, ifdId); - if (idx == -1) return unknownTag.desc_; - return tagInfos_[ifdId][idx].desc_; - } + if (isExifIfd(ifdId)) { + int idx = tagInfoIdx(tag, ifdId); + if (idx == -1) return unknownTag.desc_; + return tagInfos_[ifdId][idx].desc_; + } + if (isMakerIfd(ifdId)) { + const TagInfo* tagInfo = makerTagInfo(tag, ifdId); + if (tagInfo != 0) return tagInfo->desc_; + } + return ""; + } // ExifTags::tagDesc const char* ExifTags::sectionName(uint16_t tag, IfdId ifdId) { - int idx = tagInfoIdx(tag, ifdId); - if (idx == -1) return sectionInfo_[unknownTag.sectionId_].name_; - const TagInfo* tagInfo = tagInfos_[ifdId]; - return sectionInfo_[tagInfo[idx].sectionId_].name_; - } + if (isExifIfd(ifdId)) { + int idx = tagInfoIdx(tag, ifdId); + if (idx == -1) return sectionInfo_[unknownTag.sectionId_].name_; + const TagInfo* tagInfo = tagInfos_[ifdId]; + return sectionInfo_[tagInfo[idx].sectionId_].name_; + } + if (isMakerIfd(ifdId)) { + const TagInfo* tagInfo = makerTagInfo(tag, ifdId); + if (tagInfo != 0) return sectionInfo_[tagInfo->sectionId_].name_; + } + return ""; + } // ExifTags::sectionName const char* ExifTags::sectionDesc(uint16_t tag, IfdId ifdId) { - int idx = tagInfoIdx(tag, ifdId); - if (idx == -1) return sectionInfo_[unknownTag.sectionId_].desc_; - const TagInfo* tagInfo = tagInfos_[ifdId]; - return sectionInfo_[tagInfo[idx].sectionId_].desc_; - } + if (isExifIfd(ifdId)) { + int idx = tagInfoIdx(tag, ifdId); + if (idx == -1) return sectionInfo_[unknownTag.sectionId_].desc_; + const TagInfo* tagInfo = tagInfos_[ifdId]; + return sectionInfo_[tagInfo[idx].sectionId_].desc_; + } + if (isMakerIfd(ifdId)) { + const TagInfo* tagInfo = makerTagInfo(tag, ifdId); + if (tagInfo != 0) return sectionInfo_[tagInfo->sectionId_].desc_; + } + return ""; + } // ExifTags::sectionDesc uint16_t ExifTags::tag(const std::string& tagName, IfdId ifdId) { uint16_t tag = 0xffff; - const TagInfo* tagInfo = tagInfos_[ifdId]; - if (tagInfo) { - int idx; - for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) { - if (tagInfo[idx].name_ == tagName) break; + if (isExifIfd(ifdId)) { + const TagInfo* tagInfo = tagInfos_[ifdId]; + if (tagInfo) { + int idx; + for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) { + if (tagInfo[idx].name_ == tagName) break; + } + tag = tagInfo[idx].tag_; } - tag = tagInfo[idx].tag_; + } + if (isMakerIfd(ifdId)) { + + + + const TagInfo* tagInfo = makerTagInfo(tagName, ifdId); + if (tagInfo != 0) tag = tagInfo->tag_; } if (tag == 0xffff) { - if (!isHex(tagName, 4, "0x")) throw Error("Invalid tag name"); + if (!isHex(tagName, 4, "0x")) { + throw Error("Invalid tag name " + tagName + ", " + toString(ifdId)); + } std::istringstream is(tagName); is >> std::hex >> tag; } return tag; - } + } // ExifTags::tag IfdId ExifTags::ifdIdByIfdItem(const std::string& ifdItem) { @@ -375,12 +474,18 @@ namespace Exiv2 { const Value& value) { PrintFct fct = printValue; - int idx = tagInfoIdx(tag, ifdId); - if (idx != -1) { - fct = tagInfos_[ifdId][idx].printFct_; + if (isExifIfd(ifdId)) { + int idx = tagInfoIdx(tag, ifdId); + if (idx != -1) { + fct = tagInfos_[ifdId][idx].printFct_; + } + } + if (isMakerIfd(ifdId)) { + const TagInfo* tagInfo = makerTagInfo(tag, ifdId); + if (tagInfo != 0) fct = tagInfo->printFct_; } return fct(os, value); - } + } // ExifTags::printTag void ExifTags::taglist(std::ostream& os) { @@ -398,6 +503,18 @@ namespace Exiv2 { } } // ExifTags::taglist + void ExifTags::makerTaglist(std::ostream& os, IfdId ifdId) + { + int i = 0; + for (; i < MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != ifdId; ++i); + if (i != MAX_MAKER_TAG_INFOS) { + const TagInfo* mnTagInfo = makerTagInfos_[i]; + for (int k=0; mnTagInfo[k].tag_ != 0xffff; ++k) { + os << mnTagInfo[k] << "\n"; + } + } + } // ExifTags::makerTaglist + const char* ExifKey::familyName_ = "Exif"; ExifKey::ExifKey(const std::string& key) @@ -412,43 +529,28 @@ namespace Exiv2 { idx_(0), key_("") { IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); - if (ifdId == makerIfdId) throw Error("Invalid key"); - MakerNote::AutoPtr makerNote; - if (ifdId == ifdIdNotSet) { - makerNote = MakerNoteFactory::instance().create(ifdItem); - if (makerNote.get() != 0) ifdId = makerIfdId; - else throw Error("Invalid key"); + if (ExifTags::isMakerIfd(ifdId)) { + MakerNote::AutoPtr makerNote + = MakerNoteFactory::instance().create(ifdId); + if (makerNote.get() == 0) throw Error("Invalid key"); } tag_ = tag; ifdId_ = ifdId; ifdItem_ = ifdItem; - makerNote_ = makerNote; makeKey(); } ExifKey::ExifKey(const Entry& e) - : tag_(e.tag()), ifdId_(e.ifdId()), ifdItem_(""), + : tag_(e.tag()), ifdId_(e.ifdId()), + ifdItem_(ExifTags::ifdItem(e.ifdId())), idx_(e.idx()), key_("") { - if (ifdId_ == makerIfdId) { - if (e.makerNote()) { - ifdItem_ = e.makerNote()->ifdItem(); - makerNote_ = e.makerNote()->create(); - } - 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_), - makerNote_(rhs.makerNote_.get() != 0 ? rhs.makerNote_->create() - : MakerNote::AutoPtr(0)), - key_(rhs.key_) + idx_(rhs.idx_), key_(rhs.key_) { } @@ -464,18 +566,12 @@ namespace Exiv2 { ifdId_ = rhs.ifdId_; ifdItem_ = rhs.ifdItem_; idx_ = rhs.idx_; - makerNote_ = rhs.makerNote_.get() != 0 ? rhs.makerNote_->create() - : MakerNote::AutoPtr(0); key_ = rhs.key_; return *this; } std::string ExifKey::tagName() const { - if (ifdId_ == makerIfdId) { - assert(makerNote_.get() != 0); - return makerNote_->tagName(tag_); - } return ExifTags::tagName(tag_, ifdId_); } @@ -491,10 +587,6 @@ namespace Exiv2 { std::string ExifKey::sectionName() const { - if (ifdId_ == makerIfdId) { - assert(makerNote_.get() != 0); - return makerNote_->ifdItem(); - } return ExifTags::sectionName(tag(), ifdId()); } @@ -517,47 +609,47 @@ namespace Exiv2 { // Find IfdId IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); - if (ifdId == makerIfdId) throw Error("Invalid key"); - MakerNote::AutoPtr makerNote; - if (ifdId == ifdIdNotSet) { - makerNote = MakerNoteFactory::instance().create(ifdItem); - if (makerNote.get() != 0) ifdId = makerIfdId; - else throw Error("Invalid key"); + if (ExifTags::isMakerIfd(ifdId)) { + MakerNote::AutoPtr makerNote + = MakerNoteFactory::instance().create(ifdId); + if (makerNote.get() == 0) throw Error("Invalid key"); } - // Convert tag - uint16_t tag = makerNote.get() != 0 ? makerNote->tag(tagName) - : ExifTags::tag(tagName, ifdId); + uint16_t tag = ExifTags::tag(tagName, ifdId); + // Translate hex tag name (0xabcd) to a real tag name if there is one - tagName = makerNote.get() != 0 ? makerNote->tagName(tag) - : ExifTags::tagName(tag, ifdId); + tagName = ExifTags::tagName(tag, ifdId); + tag_ = tag; ifdId_ = ifdId; ifdItem_ = ifdItem; - makerNote_ = makerNote; key_ = familyName + "." + ifdItem + "." + tagName; } void ExifKey::makeKey() { - key_ = std::string(familyName_) - + "." + ifdItem_ - + "." + (makerNote_.get() != 0 ? makerNote_->tagName(tag_) - : ExifTags::tagName(tag_, ifdId_)); - } - - std::ostream& ExifKey::printTag(std::ostream& os, const Value& value) const - { - if (ifdId_ == makerIfdId) { - assert(makerNote_.get() != 0); - return makerNote_->printTag(os, tag(), value); - } - return ExifTags::printTag(os, tag(), ifdId(), value); + key_ = std::string(familyName_) + + "." + ifdItem_ + + "." + ExifTags::tagName(tag_, ifdId_); } // ************************************************************************* // free functions + bool isExifIfd(IfdId ifdId) + { + bool rc; + switch (ifdId) { + case ifd0Id: rc = true; break; + case exifIfdId: rc = true; break; + case gpsIfdId: rc = true; break; + case iopIfdId: rc = true; break; + case ifd1Id: rc = true; break; + default: rc = false; break; + } + return rc; + } // isExifIfd + std::ostream& operator<<(std::ostream& os, const TagInfo& ti) { ExifKey exifKey(ti.tag_, ExifTags::ifdItem(ti.ifdId_)); diff --git a/src/tags.hpp b/src/tags.hpp index 28181da9..703d0527 100644 --- a/src/tags.hpp +++ b/src/tags.hpp @@ -49,7 +49,6 @@ namespace Exiv2 { // class declarations class Value; class Entry; - class MakerNote; // ***************************************************************************** // type definitions @@ -64,7 +63,7 @@ namespace Exiv2 { enum SectionId { sectionIdNotSet, imgStruct, recOffset, imgCharacter, otherTags, exifFormat, exifVersion, imgConfig, userInfo, relatedFile, dateTime, - captureCond, gpsTags, iopTags, + captureCond, gpsTags, iopTags, makerTags, lastSectionId }; // ***************************************************************************** @@ -100,7 +99,7 @@ namespace Exiv2 { SectionId sectionId, PrintFct printFct ); - uint16_t tag_; //!< Tag + uint16_t tag_; //!< Tag const char* name_; //!< One word tag label const char* desc_; //!< Short tag description IfdId ifdId_; //!< Link to the (prefered) IFD @@ -183,17 +182,37 @@ namespace Exiv2 { uint16_t tag, IfdId ifdId, const Value& value); - //! Print a list of all tags to output stream + //! Print a list of all standard Exif tags to output stream static void taglist(std::ostream& os); + //! Print a list of all tags related to one makernote %IfdId + static void makerTaglist(std::ostream& os, IfdId ifdId); + //! Register an %IfdId with the base IFD %TagInfo list for a makernote + static void registerBaseTagInfo(IfdId ifdId); + //! Register an %IfdId and %TagInfo list for a makernote + static void registerMakerTagInfo(IfdId ifdId, const TagInfo* tagInfo); + + /*! + @brief Return true if \em ifdId is an %Ifd Id which is registered + as a makernote %Ifd id. Note: Calling this function with + makerIfd returns false. + */ + static bool isMakerIfd(IfdId ifdId); private: static int tagInfoIdx(uint16_t tag, IfdId ifdId); + static const TagInfo* makerTagInfo(uint16_t tag, IfdId ifdId); + static const TagInfo* makerTagInfo(const std::string& tagName, + IfdId ifdId); static const IfdInfo ifdInfo_[]; static const SectionInfo sectionInfo_[]; static const TagInfo* tagInfos_[]; + static const int MAX_MAKER_TAG_INFOS = 64; + static const TagInfo* makerTagInfos_[MAX_MAKER_TAG_INFOS]; + static IfdId makerIfdIds_[MAX_MAKER_TAG_INFOS]; + }; // class ExifTags /*! @@ -252,8 +271,6 @@ namespace Exiv2 { virtual uint16_t tag() const { return tag_; } AutoPtr 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 @@ -295,14 +312,20 @@ namespace Exiv2 { IfdId ifdId_; //!< The IFD associated with this tag std::string ifdItem_; //!< The IFD item int idx_; //!< Unique id of an entry within one IFD - //! Auto-pointer to the associated MakerNote - std::auto_ptr makerNote_; std::string key_; //!< Key }; // class ExifKey // ***************************************************************************** // free functions + /*! + @brief Return true if \em ifdId is an Exif %Ifd Id, i.e., one of + ifd0Id, exifIfdId, gpsIfdId, iopIfdId or ifd1Id, else false. + This is used to differentiate between standard Exif %Ifds + and %Ifds associated with the makernote. + */ + bool isExifIfd(IfdId ifdId); + //! Output operator for TagInfo std::ostream& operator<<(std::ostream& os, const TagInfo& ti); diff --git a/src/types.hpp b/src/types.hpp index 41951298..bf8ec5cf 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -84,9 +84,12 @@ namespace Exiv2 { comment, lastTypeId }; + // Todo: decentralize IfdId, so that new ids can be defined elsewhere //! Type to specify the IFD to which a metadata belongs enum IfdId { ifdIdNotSet, - ifd0Id, exifIfdId, gpsIfdId, makerIfdId, iopIfdId, ifd1Id, + ifd0Id, exifIfdId, gpsIfdId, iopIfdId, ifd1Id, + canonIfdId, fujiIfdId, nikon1IfdId, nikon2IfdId, nikon3IfdId, + nikon3ThumbIfdId, sigmaIfdId, lastIfdId }; // ***************************************************************************** @@ -285,7 +288,7 @@ namespace Exiv2 { bool isHex(const std::string& str, size_t size =0, const std::string& prefix =""); - + // ***************************************************************************** // template and inline definitions diff --git a/test/data/exifdata-test.out b/test/data/exifdata-test.out index cc00c0fe..c2897541 100644 --- a/test/data/exifdata-test.out +++ b/test/data/exifdata-test.out @@ -418,3 +418,424 @@ Exif.Thumbnail.YResolution 0x011b IFD1 Rational 1 Exif.Thumbnail.ResolutionUnit 0x0128 IFD1 Short 1 2 Exif.Thumbnail.JPEGInterchangeFormat 0x0201 IFD1 Long 1 0 Exif.Thumbnail.JPEGInterchangeFormatLength 0x0202 IFD1 Long 1 5448 +Copy construction, non-intrusive changes +Exif.Image.Make 0x010f IFD0 Ascii 18 NIKON CORPORATION +Exif.Image.Model 0x0110 IFD0 Ascii 10 NIKON D70 +Exif.Image.Orientation 0x0112 IFD0 Short 1 2 +Exif.Image.XResolution 0x011a IFD0 Rational 1 300/1 +Exif.Image.YResolution 0x011b IFD0 Rational 1 300/1 +Exif.Image.ResolutionUnit 0x0128 IFD0 Short 1 2 +Exif.Image.Software 0x0131 IFD0 Ascii 10 Ver.1.01 +Exif.Image.DateTime 0x0132 IFD0 Ascii 20 Sunday, 11am +Exif.Image.WhitePoint 0x013e IFD0 Rational 2 313/1000 329/1000 +Exif.Image.PrimaryChromaticities 0x013f IFD0 Rational 6 64/100 33/100 21/100 71/100 15/100 6/100 +Exif.Image.YCbCrCoefficients 0x0211 IFD0 Rational 3 299/1000 587/1000 114/1000 +Exif.Image.YCbCrPositioning 0x0213 IFD0 Short 1 2 +Exif.Image.ExifTag 0x8769 IFD0 Long 1 340 +Exif.Photo.ExposureTime 0x829a Exif Rational 1 10/2500 +Exif.Photo.FNumber 0x829d Exif Rational 1 90/10 +Exif.Photo.ExposureProgram 0x8822 Exif Short 1 2 +Exif.Photo.ExifVersion 0x9000 Exif Undefined 4 48 50 50 49 +Exif.Photo.DateTimeOriginal 0x9003 Exif Ascii 20 Sunday, 11am +Exif.Photo.DateTimeDigitized 0x9004 Exif Ascii 20 2004:03:30 10:43:46 +Exif.Photo.ComponentsConfiguration 0x9101 Exif Undefined 4 1 2 3 0 +Exif.Photo.CompressedBitsPerPixel 0x9102 Exif Rational 1 4/1 +Exif.Photo.ExposureBiasValue 0x9204 Exif SRational 1 0/6 +Exif.Photo.MaxApertureValue 0x9205 Exif Rational 1 43/10 +Exif.Photo.MeteringMode 0x9207 Exif Short 1 1 +Exif.Photo.LightSource 0x9208 Exif Short 1 0 +Exif.Photo.Flash 0x9209 Exif Short 1 0 +Exif.Photo.FocalLength 0x920a Exif Rational 1 500/10 +Exif.Photo.UserComment 0x9286 Exif Undefined 44 65 83 67 73 73 0 0 0 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 +Exif.Photo.SubSecTime 0x9290 Exif Ascii 3 00 +Exif.Photo.SubSecTimeOriginal 0x9291 Exif Ascii 3 00 +Exif.Photo.SubSecTimeDigitized 0x9292 Exif Ascii 3 00 +Exif.Photo.FlashpixVersion 0xa000 Exif Undefined 4 48 49 48 48 +Exif.Photo.ColorSpace 0xa001 Exif Short 1 65535 +Exif.Photo.PixelXDimension 0xa002 Exif Short 1 3008 +Exif.Photo.PixelYDimension 0xa003 Exif Short 1 2000 +Exif.Photo.InteroperabilityTag 0xa005 Exif Long 1 30306 +Exif.Photo.SensingMethod 0xa217 Exif Short 1 2 +Exif.Photo.FileSource 0xa300 Exif Undefined 1 3 +Exif.Photo.SceneType 0xa301 Exif Undefined 1 1 +Exif.Photo.CFAPattern 0xa302 Exif Undefined 8 0 2 0 2 2 1 1 0 +Exif.Photo.CustomRendered 0xa401 Exif Short 1 0 +Exif.Photo.ExposureMode 0xa402 Exif Short 1 0 +Exif.Photo.WhiteBalance 0xa403 Exif Short 1 0 +Exif.Photo.DigitalZoomRatio 0xa404 Exif Rational 1 1/1 +Exif.Photo.FocalLengthIn35mmFilm 0xa405 Exif Short 1 75 +Exif.Photo.SceneCaptureType 0xa406 Exif Short 1 0 +Exif.Photo.GainControl 0xa407 Exif Short 1 0 +Exif.Photo.Contrast 0xa408 Exif Short 1 0 +Exif.Photo.Saturation 0xa409 Exif Short 1 0 +Exif.Photo.Sharpness 0xa40a Exif Short 1 0 +Exif.Photo.SubjectDistanceRange 0xa40c Exif Short 1 0 +Exif.Photo.0xa500 0xa500 Exif Rational 1 22/10 +Exif.Nikon3.Version 0x0001 Makernote Undefined 4 48 50 49 48 +Exif.Nikon3.ISOSpeed 0x0002 Makernote Short 2 0 200 +Exif.Nikon3.Quality 0x0004 Makernote Ascii 8 FINE +Exif.Nikon3.WhiteBalance 0x0005 Makernote Ascii 13 AUTO +Exif.Nikon3.Sharpening 0x0006 Makernote Ascii 7 AUTO +Exif.Nikon3.Focus 0x0007 Makernote Ascii 7 AF-S +Exif.Nikon3.FlashSetting 0x0008 Makernote Ascii 13 NORMAL +Exif.Nikon3.FlashMode 0x0009 Makernote Ascii 13 +Exif.Nikon3.WhiteBalanceBias 0x000b Makernote SShort 1 0 +Exif.Nikon3.0x000d 0x000d Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ExposureDiff 0x000e Makernote Undefined 4 0 1 12 0 +Exif.Nikon3.ThumbOffset 0x0011 Makernote Long 1 1430 +Exif.Nikon3.FlashComp 0x0012 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ISOSetting 0x0013 Makernote Short 2 0 200 +Exif.Nikon3.ImageBoundry 0x0016 Makernote Short 4 0 0 3008 2000 +Exif.Nikon3.0x0017 0x0017 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.FlashBracketComp 0x0018 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ExposureBracketComp 0x0019 Makernote SRational 1 0/1 +Exif.Nikon3.ToneComp 0x0081 Makernote Ascii 9 AUTO +Exif.Nikon3.LensType 0x0083 Makernote Byte 1 6 +Exif.Nikon3.Lens 0x0084 Makernote Rational 4 180/10 700/10 35/10 45/10 +Exif.Nikon3.FlashType 0x0087 Makernote Byte 1 0 +Exif.Nikon3.AFFocusPos 0x0088 Makernote Undefined 4 0 0 0 1 +Exif.Nikon3.Bracketing 0x0089 Makernote Short 1 0 +Exif.Nikon3.0x008a 0x008a Makernote Short 1 0 +Exif.Nikon3.0x008b 0x008b Makernote Undefined 4 64 1 12 0 +Exif.Nikon3.ColorMode 0x008d Makernote Ascii 9 MODE1a +Exif.Nikon3.LightingType 0x0090 Makernote Ascii 12 NATURAL +Exif.Nikon3.0x0091 0x0091 Makernote Undefined 465 48 49 48 51 0 0 0 124 0 0 5 13 113 0 0 0 0 1 0 0 11 0 0 0 0 0 20 0 0 31 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 31 0 0 0 0 0 0 248 0 0 248 0 0 0 0 0 0 248 0 0 248 0 0 0 0 0 0 0 0 0 0 0 0 0 45 0 0 0 0 0 1 0 0 0 0 89 1 2 205 51 206 179 54 56 53 54 48 51 0 218 0 214 0 167 0 171 0 50 0 51 0 5 0 0 0 0 0 0 0 0 0 1 0 5 0 0 3 194 0 0 0 100 30 161 200 95 222 59 231 63 201 147 36 178 108 51 110 51 142 15 205 20 205 255 24 187 172 35 200 39 84 41 220 51 68 39 136 59 158 49 239 176 221 55 206 242 77 6 206 51 212 169 76 179 220 17 174 50 140 159 228 51 220 49 78 186 201 119 196 225 223 50 196 178 204 146 204 17 54 56 53 54 48 49 0 101 0 161 0 172 172 169 163 163 168 169 169 168 168 170 171 164 152 149 5 249 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48 38 72 0 8 1 78 226 1 0 72 49 38 48 0 0 0 3 7 252 11 226 0 4 169 1 72 0 128 16 0 0 3 151 96 196 12 145 80 60 0 0 4 190 3 111 0 0 9 186 0 0 4 197 0 0 4 190 3 111 0 0 0 0 3 0 0 0 0 200 0 60 52 62 143 63 0 0 4 176 0 0 4 162 0 0 4 177 0 0 4 126 255 127 255 127 255 127 255 127 8 128 3 111 3 28 2 157 18 17 1 0 0 0 0 72 240 23 52 7 0 161 109 80 127 64 45 92 44 52 132 52 23 100 32 99 0 0 0 21 5 0 2 2 64 0 0 0 0 64 +Exif.Nikon3.HueAdjustment 0x0092 Makernote SShort 1 0 +Exif.Nikon3.NoiseReduction 0x0095 Makernote Ascii 5 OFF +Exif.Nikon3.ColorBalance2 0x0097 Makernote Undefined 140 48 49 48 51 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 2 4 1 0 1 163 1 0 0 0 1 8 1 0 0 0 0 0 0 112 0 12 0 24 0 3 1 140 255 109 0 7 255 216 1 90 255 206 255 251 255 222 1 39 255 255 255 255 255 255 128 0 0 0 0 0 0 0 0 0 10 0 0 0 2 128 0 0 3 0 0 0 2 128 0 0 0 0 16 16 0 255 0 255 0 77 0 150 0 29 255 204 255 186 0 122 0 127 255 150 255 235 0 0 5 0 0 8 108 18 223 51 5 89 1 63 240 240 0 26 +Exif.Nikon3.0x0098 0x0098 Makernote Undefined 31 48 49 48 49 23 52 7 0 161 109 80 127 64 45 92 44 52 132 52 23 100 32 99 0 0 0 21 5 0 2 2 +Exif.Nikon3.0x009a 0x009a Makernote Rational 2 78/10 78/10 +Exif.Nikon3.SerialNumber 0x00a0 Makernote Ascii 21 NO= 100005e5 +Exif.Nikon3.0x00a2 0x00a2 Makernote Long 1 2929656 +Exif.Nikon3.0x00a3 0x00a3 Makernote Byte 1 0 +Exif.Nikon3.ShutterCount 0x00a7 Makernote Long 1 1193 +Exif.Nikon3.0x00a8 0x00a8 Makernote Undefined 20 48 49 48 48 0 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Exif.Nikon3.ImageOptimization 0x00a9 Makernote Ascii 16 NORMAL +Exif.Nikon3.Saturation 0x00aa Makernote Ascii 16 NORMAL +Exif.Nikon3.VariProgram 0x00ab Makernote Ascii 16 +Exif.Iop.InteroperabilityIndex 0x0001 Iop Ascii 4 123 +Exif.Iop.InteroperabilityVersion 0x0002 Iop Undefined 4 48 49 48 48 +Exif.Thumbnail.Compression 0x0103 IFD1 Short 1 6 +Exif.Thumbnail.XResolution 0x011a IFD1 Rational 1 300/1 +Exif.Thumbnail.YResolution 0x011b IFD1 Rational 1 300/1 +Exif.Thumbnail.ResolutionUnit 0x0128 IFD1 Short 1 2 +Exif.Thumbnail.JPEGInterchangeFormat 0x0201 IFD1 Long 1 0 +Exif.Thumbnail.JPEGInterchangeFormatLength 0x0202 IFD1 Long 1 8930 +Exif.Thumbnail.YCbCrPositioning 0x0213 IFD1 Short 1 2 +---------------------------------------------- +Copy construction, intrusive changes +Exif.Image.Make 0x010f IFD0 Ascii 18 NIKON CORPORATION +Exif.Image.Model 0x0110 IFD0 Ascii 10 NIKON D70 +Exif.Image.Orientation 0x0112 IFD0 Short 4 2 3 4 5 +Exif.Image.XResolution 0x011a IFD0 Rational 1 300/1 +Exif.Image.YResolution 0x011b IFD0 Rational 1 300/1 +Exif.Image.ResolutionUnit 0x0128 IFD0 Short 1 2 +Exif.Image.Software 0x0131 IFD0 Ascii 10 Ver.1.01 +Exif.Image.DateTime 0x0132 IFD0 Ascii 29 Sunday, 11am and ten minutes +Exif.Image.WhitePoint 0x013e IFD0 Rational 2 313/1000 329/1000 +Exif.Image.PrimaryChromaticities 0x013f IFD0 Rational 6 64/100 33/100 21/100 71/100 15/100 6/100 +Exif.Image.YCbCrCoefficients 0x0211 IFD0 Rational 3 299/1000 587/1000 114/1000 +Exif.Image.YCbCrPositioning 0x0213 IFD0 Short 1 2 +Exif.Image.ExifTag 0x8769 IFD0 Long 1 349 +Exif.Photo.ExposureTime 0x829a Exif Rational 1 10/2500 +Exif.Photo.FNumber 0x829d Exif Rational 1 90/10 +Exif.Photo.ExposureProgram 0x8822 Exif Short 1 2 +Exif.Photo.ExifVersion 0x9000 Exif Undefined 4 48 50 50 49 +Exif.Photo.DateTimeOriginal 0x9003 Exif Ascii 29 Sunday, 11am and ten minutes +Exif.Photo.DateTimeDigitized 0x9004 Exif Ascii 20 2004:03:30 10:43:46 +Exif.Photo.ComponentsConfiguration 0x9101 Exif Undefined 4 1 2 3 0 +Exif.Photo.CompressedBitsPerPixel 0x9102 Exif Rational 1 4/1 +Exif.Photo.ExposureBiasValue 0x9204 Exif SRational 1 0/6 +Exif.Photo.MaxApertureValue 0x9205 Exif Rational 1 43/10 +Exif.Photo.MeteringMode 0x9207 Exif Short 6 1 2 3 4 5 6 +Exif.Photo.LightSource 0x9208 Exif Short 1 0 +Exif.Photo.Flash 0x9209 Exif Short 1 0 +Exif.Photo.FocalLength 0x920a Exif Rational 1 500/10 +Exif.Photo.UserComment 0x9286 Exif Undefined 44 65 83 67 73 73 0 0 0 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 +Exif.Photo.SubSecTime 0x9290 Exif Ascii 3 00 +Exif.Photo.SubSecTimeOriginal 0x9291 Exif Ascii 3 00 +Exif.Photo.SubSecTimeDigitized 0x9292 Exif Ascii 3 00 +Exif.Photo.FlashpixVersion 0xa000 Exif Undefined 4 48 49 48 48 +Exif.Photo.ColorSpace 0xa001 Exif Short 1 65535 +Exif.Photo.PixelXDimension 0xa002 Exif Short 1 3008 +Exif.Photo.PixelYDimension 0xa003 Exif Short 1 2000 +Exif.Photo.InteroperabilityTag 0xa005 Exif Long 1 2425 +Exif.Photo.SensingMethod 0xa217 Exif Short 1 2 +Exif.Photo.FileSource 0xa300 Exif Undefined 1 3 +Exif.Photo.SceneType 0xa301 Exif Undefined 1 1 +Exif.Photo.CFAPattern 0xa302 Exif Undefined 8 0 2 0 2 2 1 1 0 +Exif.Photo.CustomRendered 0xa401 Exif Short 1 0 +Exif.Photo.ExposureMode 0xa402 Exif Short 1 0 +Exif.Photo.WhiteBalance 0xa403 Exif Short 1 0 +Exif.Photo.DigitalZoomRatio 0xa404 Exif Rational 1 1/1 +Exif.Photo.FocalLengthIn35mmFilm 0xa405 Exif Short 1 75 +Exif.Photo.SceneCaptureType 0xa406 Exif Short 1 0 +Exif.Photo.GainControl 0xa407 Exif Short 1 0 +Exif.Photo.Contrast 0xa408 Exif Short 1 0 +Exif.Photo.Saturation 0xa409 Exif Short 1 0 +Exif.Photo.Sharpness 0xa40a Exif Short 1 0 +Exif.Photo.SubjectDistanceRange 0xa40c Exif Short 1 0 +Exif.Photo.0xa500 0xa500 Exif Rational 1 22/10 +Exif.Nikon3.Version 0x0001 Makernote Undefined 4 48 50 49 48 +Exif.Nikon3.ISOSpeed 0x0002 Makernote Short 2 0 200 +Exif.Nikon3.Quality 0x0004 Makernote Ascii 8 FINE +Exif.Nikon3.WhiteBalance 0x0005 Makernote Ascii 13 AUTO +Exif.Nikon3.Sharpening 0x0006 Makernote Ascii 7 AUTO +Exif.Nikon3.Focus 0x0007 Makernote Ascii 7 AF-S +Exif.Nikon3.FlashSetting 0x0008 Makernote Ascii 13 NORMAL +Exif.Nikon3.FlashMode 0x0009 Makernote Ascii 13 +Exif.Nikon3.WhiteBalanceBias 0x000b Makernote SShort 1 0 +Exif.Nikon3.0x000d 0x000d Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ExposureDiff 0x000e Makernote Undefined 4 0 1 12 0 +Exif.Nikon3.ThumbOffset 0x0011 Makernote Long 1 1430 +Exif.Nikon3.FlashComp 0x0012 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ISOSetting 0x0013 Makernote Short 2 0 200 +Exif.Nikon3.ImageBoundry 0x0016 Makernote Short 4 0 0 3008 2000 +Exif.Nikon3.0x0017 0x0017 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.FlashBracketComp 0x0018 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ExposureBracketComp 0x0019 Makernote SRational 1 0/1 +Exif.Nikon3.ToneComp 0x0081 Makernote Ascii 9 AUTO +Exif.Nikon3.LensType 0x0083 Makernote Byte 1 6 +Exif.Nikon3.Lens 0x0084 Makernote Rational 4 180/10 700/10 35/10 45/10 +Exif.Nikon3.FlashType 0x0087 Makernote Byte 1 0 +Exif.Nikon3.AFFocusPos 0x0088 Makernote Undefined 4 0 0 0 1 +Exif.Nikon3.Bracketing 0x0089 Makernote Short 1 0 +Exif.Nikon3.0x008a 0x008a Makernote Short 1 0 +Exif.Nikon3.0x008b 0x008b Makernote Undefined 4 64 1 12 0 +Exif.Nikon3.ColorMode 0x008d Makernote Ascii 9 MODE1a +Exif.Nikon3.LightingType 0x0090 Makernote Ascii 12 NATURAL +Exif.Nikon3.0x0091 0x0091 Makernote Undefined 465 48 49 48 51 0 0 0 124 0 0 5 13 113 0 0 0 0 1 0 0 11 0 0 0 0 0 20 0 0 31 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 31 0 0 0 0 0 0 248 0 0 248 0 0 0 0 0 0 248 0 0 248 0 0 0 0 0 0 0 0 0 0 0 0 0 45 0 0 0 0 0 1 0 0 0 0 89 1 2 205 51 206 179 54 56 53 54 48 51 0 218 0 214 0 167 0 171 0 50 0 51 0 5 0 0 0 0 0 0 0 0 0 1 0 5 0 0 3 194 0 0 0 100 30 161 200 95 222 59 231 63 201 147 36 178 108 51 110 51 142 15 205 20 205 255 24 187 172 35 200 39 84 41 220 51 68 39 136 59 158 49 239 176 221 55 206 242 77 6 206 51 212 169 76 179 220 17 174 50 140 159 228 51 220 49 78 186 201 119 196 225 223 50 196 178 204 146 204 17 54 56 53 54 48 49 0 101 0 161 0 172 172 169 163 163 168 169 169 168 168 170 171 164 152 149 5 249 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48 38 72 0 8 1 78 226 1 0 72 49 38 48 0 0 0 3 7 252 11 226 0 4 169 1 72 0 128 16 0 0 3 151 96 196 12 145 80 60 0 0 4 190 3 111 0 0 9 186 0 0 4 197 0 0 4 190 3 111 0 0 0 0 3 0 0 0 0 200 0 60 52 62 143 63 0 0 4 176 0 0 4 162 0 0 4 177 0 0 4 126 255 127 255 127 255 127 255 127 8 128 3 111 3 28 2 157 18 17 1 0 0 0 0 72 240 23 52 7 0 161 109 80 127 64 45 92 44 52 132 52 23 100 32 99 0 0 0 21 5 0 2 2 64 0 0 0 0 64 +Exif.Nikon3.HueAdjustment 0x0092 Makernote SShort 1 0 +Exif.Nikon3.NoiseReduction 0x0095 Makernote Ascii 5 OFF +Exif.Nikon3.ColorBalance2 0x0097 Makernote Undefined 140 48 49 48 51 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 2 4 1 0 1 163 1 0 0 0 1 8 1 0 0 0 0 0 0 112 0 12 0 24 0 3 1 140 255 109 0 7 255 216 1 90 255 206 255 251 255 222 1 39 255 255 255 255 255 255 128 0 0 0 0 0 0 0 0 0 10 0 0 0 2 128 0 0 3 0 0 0 2 128 0 0 0 0 16 16 0 255 0 255 0 77 0 150 0 29 255 204 255 186 0 122 0 127 255 150 255 235 0 0 5 0 0 8 108 18 223 51 5 89 1 63 240 240 0 26 +Exif.Nikon3.0x0098 0x0098 Makernote Undefined 31 48 49 48 49 23 52 7 0 161 109 80 127 64 45 92 44 52 132 52 23 100 32 99 0 0 0 21 5 0 2 2 +Exif.Nikon3.0x009a 0x009a Makernote Rational 2 78/10 78/10 +Exif.Nikon3.SerialNumber 0x00a0 Makernote Ascii 21 NO= 100005e5 +Exif.Nikon3.0x00a2 0x00a2 Makernote Long 1 2929656 +Exif.Nikon3.0x00a3 0x00a3 Makernote Byte 1 0 +Exif.Nikon3.ShutterCount 0x00a7 Makernote Long 1 1193 +Exif.Nikon3.0x00a8 0x00a8 Makernote Undefined 20 48 49 48 48 0 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Exif.Nikon3.ImageOptimization 0x00a9 Makernote Ascii 16 NORMAL +Exif.Nikon3.Saturation 0x00aa Makernote Ascii 16 NORMAL +Exif.Nikon3.VariProgram 0x00ab Makernote Ascii 16 +Exif.Iop.InteroperabilityIndex 0x0001 Iop Ascii 5 1234 +Exif.Iop.InteroperabilityVersion 0x0002 Iop Undefined 4 48 49 48 48 +Exif.Thumbnail.Compression 0x0103 IFD1 Short 1 6 +Exif.Thumbnail.Orientation 0x0112 IFD1 Ascii 10 2 3 4 5 6 +Exif.Thumbnail.XResolution 0x011a IFD1 Rational 1 300/1 +Exif.Thumbnail.YResolution 0x011b IFD1 Rational 1 300/1 +Exif.Thumbnail.ResolutionUnit 0x0128 IFD1 Short 1 2 +Exif.Thumbnail.JPEGInterchangeFormat 0x0201 IFD1 Long 1 0 +Exif.Thumbnail.JPEGInterchangeFormatLength 0x0202 IFD1 Long 1 8930 +Exif.Thumbnail.YCbCrPositioning 0x0213 IFD1 Short 1 2 +---------------------------------------------- +Assignment, non-intrusive changes +Exif.Image.Make 0x010f IFD0 Ascii 18 NIKON CORPORATION +Exif.Image.Model 0x0110 IFD0 Ascii 10 NIKON D70 +Exif.Image.Orientation 0x0112 IFD0 Short 1 2 +Exif.Image.XResolution 0x011a IFD0 Rational 1 300/1 +Exif.Image.YResolution 0x011b IFD0 Rational 1 300/1 +Exif.Image.ResolutionUnit 0x0128 IFD0 Short 1 2 +Exif.Image.Software 0x0131 IFD0 Ascii 10 Ver.1.01 +Exif.Image.DateTime 0x0132 IFD0 Ascii 20 Sunday, 11am +Exif.Image.WhitePoint 0x013e IFD0 Rational 2 313/1000 329/1000 +Exif.Image.PrimaryChromaticities 0x013f IFD0 Rational 6 64/100 33/100 21/100 71/100 15/100 6/100 +Exif.Image.YCbCrCoefficients 0x0211 IFD0 Rational 3 299/1000 587/1000 114/1000 +Exif.Image.YCbCrPositioning 0x0213 IFD0 Short 1 2 +Exif.Image.ExifTag 0x8769 IFD0 Long 1 340 +Exif.Photo.ExposureTime 0x829a Exif Rational 1 10/2500 +Exif.Photo.FNumber 0x829d Exif Rational 1 90/10 +Exif.Photo.ExposureProgram 0x8822 Exif Short 1 2 +Exif.Photo.ExifVersion 0x9000 Exif Undefined 4 48 50 50 49 +Exif.Photo.DateTimeOriginal 0x9003 Exif Ascii 20 Sunday, 11am +Exif.Photo.DateTimeDigitized 0x9004 Exif Ascii 20 2004:03:30 10:43:46 +Exif.Photo.ComponentsConfiguration 0x9101 Exif Undefined 4 1 2 3 0 +Exif.Photo.CompressedBitsPerPixel 0x9102 Exif Rational 1 4/1 +Exif.Photo.ExposureBiasValue 0x9204 Exif SRational 1 0/6 +Exif.Photo.MaxApertureValue 0x9205 Exif Rational 1 43/10 +Exif.Photo.MeteringMode 0x9207 Exif Short 1 1 +Exif.Photo.LightSource 0x9208 Exif Short 1 0 +Exif.Photo.Flash 0x9209 Exif Short 1 0 +Exif.Photo.FocalLength 0x920a Exif Rational 1 500/10 +Exif.Photo.UserComment 0x9286 Exif Undefined 44 65 83 67 73 73 0 0 0 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 +Exif.Photo.SubSecTime 0x9290 Exif Ascii 3 00 +Exif.Photo.SubSecTimeOriginal 0x9291 Exif Ascii 3 00 +Exif.Photo.SubSecTimeDigitized 0x9292 Exif Ascii 3 00 +Exif.Photo.FlashpixVersion 0xa000 Exif Undefined 4 48 49 48 48 +Exif.Photo.ColorSpace 0xa001 Exif Short 1 65535 +Exif.Photo.PixelXDimension 0xa002 Exif Short 1 3008 +Exif.Photo.PixelYDimension 0xa003 Exif Short 1 2000 +Exif.Photo.InteroperabilityTag 0xa005 Exif Long 1 30306 +Exif.Photo.SensingMethod 0xa217 Exif Short 1 2 +Exif.Photo.FileSource 0xa300 Exif Undefined 1 3 +Exif.Photo.SceneType 0xa301 Exif Undefined 1 1 +Exif.Photo.CFAPattern 0xa302 Exif Undefined 8 0 2 0 2 2 1 1 0 +Exif.Photo.CustomRendered 0xa401 Exif Short 1 0 +Exif.Photo.ExposureMode 0xa402 Exif Short 1 0 +Exif.Photo.WhiteBalance 0xa403 Exif Short 1 0 +Exif.Photo.DigitalZoomRatio 0xa404 Exif Rational 1 1/1 +Exif.Photo.FocalLengthIn35mmFilm 0xa405 Exif Short 1 75 +Exif.Photo.SceneCaptureType 0xa406 Exif Short 1 0 +Exif.Photo.GainControl 0xa407 Exif Short 1 0 +Exif.Photo.Contrast 0xa408 Exif Short 1 0 +Exif.Photo.Saturation 0xa409 Exif Short 1 0 +Exif.Photo.Sharpness 0xa40a Exif Short 1 0 +Exif.Photo.SubjectDistanceRange 0xa40c Exif Short 1 0 +Exif.Photo.0xa500 0xa500 Exif Rational 1 22/10 +Exif.Nikon3.Version 0x0001 Makernote Undefined 4 48 50 49 48 +Exif.Nikon3.ISOSpeed 0x0002 Makernote Short 2 0 200 +Exif.Nikon3.Quality 0x0004 Makernote Ascii 8 FINE +Exif.Nikon3.WhiteBalance 0x0005 Makernote Ascii 13 AUTO +Exif.Nikon3.Sharpening 0x0006 Makernote Ascii 7 AUTO +Exif.Nikon3.Focus 0x0007 Makernote Ascii 7 AF-S +Exif.Nikon3.FlashSetting 0x0008 Makernote Ascii 13 NORMAL +Exif.Nikon3.FlashMode 0x0009 Makernote Ascii 13 +Exif.Nikon3.WhiteBalanceBias 0x000b Makernote SShort 1 0 +Exif.Nikon3.0x000d 0x000d Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ExposureDiff 0x000e Makernote Undefined 4 0 1 12 0 +Exif.Nikon3.ThumbOffset 0x0011 Makernote Long 1 1430 +Exif.Nikon3.FlashComp 0x0012 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ISOSetting 0x0013 Makernote Short 2 0 200 +Exif.Nikon3.ImageBoundry 0x0016 Makernote Short 4 0 0 3008 2000 +Exif.Nikon3.0x0017 0x0017 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.FlashBracketComp 0x0018 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ExposureBracketComp 0x0019 Makernote SRational 1 0/1 +Exif.Nikon3.ToneComp 0x0081 Makernote Ascii 9 AUTO +Exif.Nikon3.LensType 0x0083 Makernote Byte 1 6 +Exif.Nikon3.Lens 0x0084 Makernote Rational 4 180/10 700/10 35/10 45/10 +Exif.Nikon3.FlashType 0x0087 Makernote Byte 1 0 +Exif.Nikon3.AFFocusPos 0x0088 Makernote Undefined 4 0 0 0 1 +Exif.Nikon3.Bracketing 0x0089 Makernote Short 1 0 +Exif.Nikon3.0x008a 0x008a Makernote Short 1 0 +Exif.Nikon3.0x008b 0x008b Makernote Undefined 4 64 1 12 0 +Exif.Nikon3.ColorMode 0x008d Makernote Ascii 9 MODE1a +Exif.Nikon3.LightingType 0x0090 Makernote Ascii 12 NATURAL +Exif.Nikon3.0x0091 0x0091 Makernote Undefined 465 48 49 48 51 0 0 0 124 0 0 5 13 113 0 0 0 0 1 0 0 11 0 0 0 0 0 20 0 0 31 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 31 0 0 0 0 0 0 248 0 0 248 0 0 0 0 0 0 248 0 0 248 0 0 0 0 0 0 0 0 0 0 0 0 0 45 0 0 0 0 0 1 0 0 0 0 89 1 2 205 51 206 179 54 56 53 54 48 51 0 218 0 214 0 167 0 171 0 50 0 51 0 5 0 0 0 0 0 0 0 0 0 1 0 5 0 0 3 194 0 0 0 100 30 161 200 95 222 59 231 63 201 147 36 178 108 51 110 51 142 15 205 20 205 255 24 187 172 35 200 39 84 41 220 51 68 39 136 59 158 49 239 176 221 55 206 242 77 6 206 51 212 169 76 179 220 17 174 50 140 159 228 51 220 49 78 186 201 119 196 225 223 50 196 178 204 146 204 17 54 56 53 54 48 49 0 101 0 161 0 172 172 169 163 163 168 169 169 168 168 170 171 164 152 149 5 249 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48 38 72 0 8 1 78 226 1 0 72 49 38 48 0 0 0 3 7 252 11 226 0 4 169 1 72 0 128 16 0 0 3 151 96 196 12 145 80 60 0 0 4 190 3 111 0 0 9 186 0 0 4 197 0 0 4 190 3 111 0 0 0 0 3 0 0 0 0 200 0 60 52 62 143 63 0 0 4 176 0 0 4 162 0 0 4 177 0 0 4 126 255 127 255 127 255 127 255 127 8 128 3 111 3 28 2 157 18 17 1 0 0 0 0 72 240 23 52 7 0 161 109 80 127 64 45 92 44 52 132 52 23 100 32 99 0 0 0 21 5 0 2 2 64 0 0 0 0 64 +Exif.Nikon3.HueAdjustment 0x0092 Makernote SShort 1 0 +Exif.Nikon3.NoiseReduction 0x0095 Makernote Ascii 5 OFF +Exif.Nikon3.ColorBalance2 0x0097 Makernote Undefined 140 48 49 48 51 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 2 4 1 0 1 163 1 0 0 0 1 8 1 0 0 0 0 0 0 112 0 12 0 24 0 3 1 140 255 109 0 7 255 216 1 90 255 206 255 251 255 222 1 39 255 255 255 255 255 255 128 0 0 0 0 0 0 0 0 0 10 0 0 0 2 128 0 0 3 0 0 0 2 128 0 0 0 0 16 16 0 255 0 255 0 77 0 150 0 29 255 204 255 186 0 122 0 127 255 150 255 235 0 0 5 0 0 8 108 18 223 51 5 89 1 63 240 240 0 26 +Exif.Nikon3.0x0098 0x0098 Makernote Undefined 31 48 49 48 49 23 52 7 0 161 109 80 127 64 45 92 44 52 132 52 23 100 32 99 0 0 0 21 5 0 2 2 +Exif.Nikon3.0x009a 0x009a Makernote Rational 2 78/10 78/10 +Exif.Nikon3.SerialNumber 0x00a0 Makernote Ascii 21 NO= 100005e5 +Exif.Nikon3.0x00a2 0x00a2 Makernote Long 1 2929656 +Exif.Nikon3.0x00a3 0x00a3 Makernote Byte 1 0 +Exif.Nikon3.ShutterCount 0x00a7 Makernote Long 1 1193 +Exif.Nikon3.0x00a8 0x00a8 Makernote Undefined 20 48 49 48 48 0 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Exif.Nikon3.ImageOptimization 0x00a9 Makernote Ascii 16 NORMAL +Exif.Nikon3.Saturation 0x00aa Makernote Ascii 16 NORMAL +Exif.Nikon3.VariProgram 0x00ab Makernote Ascii 16 +Exif.Iop.InteroperabilityIndex 0x0001 Iop Ascii 4 123 +Exif.Iop.InteroperabilityVersion 0x0002 Iop Undefined 4 48 49 48 48 +Exif.Thumbnail.Compression 0x0103 IFD1 Short 1 6 +Exif.Thumbnail.XResolution 0x011a IFD1 Rational 1 300/1 +Exif.Thumbnail.YResolution 0x011b IFD1 Rational 1 300/1 +Exif.Thumbnail.ResolutionUnit 0x0128 IFD1 Short 1 2 +Exif.Thumbnail.JPEGInterchangeFormat 0x0201 IFD1 Long 1 0 +Exif.Thumbnail.JPEGInterchangeFormatLength 0x0202 IFD1 Long 1 8930 +Exif.Thumbnail.YCbCrPositioning 0x0213 IFD1 Short 1 2 +---------------------------------------------- +Assignment, intrusive changes +Exif.Image.Make 0x010f IFD0 Ascii 18 NIKON CORPORATION +Exif.Image.Model 0x0110 IFD0 Ascii 10 NIKON D70 +Exif.Image.Orientation 0x0112 IFD0 Short 4 2 3 4 5 +Exif.Image.XResolution 0x011a IFD0 Rational 1 300/1 +Exif.Image.YResolution 0x011b IFD0 Rational 1 300/1 +Exif.Image.ResolutionUnit 0x0128 IFD0 Short 1 2 +Exif.Image.Software 0x0131 IFD0 Ascii 10 Ver.1.01 +Exif.Image.DateTime 0x0132 IFD0 Ascii 29 Sunday, 11am and ten minutes +Exif.Image.WhitePoint 0x013e IFD0 Rational 2 313/1000 329/1000 +Exif.Image.PrimaryChromaticities 0x013f IFD0 Rational 6 64/100 33/100 21/100 71/100 15/100 6/100 +Exif.Image.YCbCrCoefficients 0x0211 IFD0 Rational 3 299/1000 587/1000 114/1000 +Exif.Image.YCbCrPositioning 0x0213 IFD0 Short 1 2 +Exif.Image.ExifTag 0x8769 IFD0 Long 1 349 +Exif.Photo.ExposureTime 0x829a Exif Rational 1 10/2500 +Exif.Photo.FNumber 0x829d Exif Rational 1 90/10 +Exif.Photo.ExposureProgram 0x8822 Exif Short 1 2 +Exif.Photo.ExifVersion 0x9000 Exif Undefined 4 48 50 50 49 +Exif.Photo.DateTimeOriginal 0x9003 Exif Ascii 29 Sunday, 11am and ten minutes +Exif.Photo.DateTimeDigitized 0x9004 Exif Ascii 20 2004:03:30 10:43:46 +Exif.Photo.ComponentsConfiguration 0x9101 Exif Undefined 4 1 2 3 0 +Exif.Photo.CompressedBitsPerPixel 0x9102 Exif Rational 1 4/1 +Exif.Photo.ExposureBiasValue 0x9204 Exif SRational 1 0/6 +Exif.Photo.MaxApertureValue 0x9205 Exif Rational 1 43/10 +Exif.Photo.MeteringMode 0x9207 Exif Short 1 1 +Exif.Photo.LightSource 0x9208 Exif Short 1 0 +Exif.Photo.Flash 0x9209 Exif Short 1 0 +Exif.Photo.FocalLength 0x920a Exif Rational 1 500/10 +Exif.Photo.UserComment 0x9286 Exif Undefined 44 65 83 67 73 73 0 0 0 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 +Exif.Photo.SubSecTime 0x9290 Exif Ascii 3 00 +Exif.Photo.SubSecTimeOriginal 0x9291 Exif Ascii 3 00 +Exif.Photo.SubSecTimeDigitized 0x9292 Exif Ascii 3 00 +Exif.Photo.FlashpixVersion 0xa000 Exif Undefined 4 48 49 48 48 +Exif.Photo.ColorSpace 0xa001 Exif Short 1 65535 +Exif.Photo.PixelXDimension 0xa002 Exif Short 1 3008 +Exif.Photo.PixelYDimension 0xa003 Exif Short 1 2000 +Exif.Photo.InteroperabilityTag 0xa005 Exif Long 1 2413 +Exif.Photo.SensingMethod 0xa217 Exif Short 1 2 +Exif.Photo.FileSource 0xa300 Exif Undefined 1 3 +Exif.Photo.SceneType 0xa301 Exif Undefined 1 1 +Exif.Photo.CFAPattern 0xa302 Exif Undefined 8 0 2 0 2 2 1 1 0 +Exif.Photo.CustomRendered 0xa401 Exif Short 1 0 +Exif.Photo.ExposureMode 0xa402 Exif Short 1 0 +Exif.Photo.WhiteBalance 0xa403 Exif Short 1 0 +Exif.Photo.DigitalZoomRatio 0xa404 Exif Rational 1 1/1 +Exif.Photo.FocalLengthIn35mmFilm 0xa405 Exif Short 1 75 +Exif.Photo.SceneCaptureType 0xa406 Exif Short 1 0 +Exif.Photo.GainControl 0xa407 Exif Short 1 0 +Exif.Photo.Contrast 0xa408 Exif Short 1 0 +Exif.Photo.Saturation 0xa409 Exif Short 1 0 +Exif.Photo.Sharpness 0xa40a Exif Short 1 0 +Exif.Photo.SubjectDistanceRange 0xa40c Exif Short 1 0 +Exif.Photo.0xa500 0xa500 Exif Rational 1 22/10 +Exif.Nikon3.Version 0x0001 Makernote Undefined 4 48 50 49 48 +Exif.Nikon3.ISOSpeed 0x0002 Makernote Short 2 0 200 +Exif.Nikon3.Quality 0x0004 Makernote Ascii 8 FINE +Exif.Nikon3.WhiteBalance 0x0005 Makernote Ascii 13 AUTO +Exif.Nikon3.Sharpening 0x0006 Makernote Ascii 7 AUTO +Exif.Nikon3.Focus 0x0007 Makernote Ascii 7 AF-S +Exif.Nikon3.FlashSetting 0x0008 Makernote Ascii 13 NORMAL +Exif.Nikon3.FlashMode 0x0009 Makernote Ascii 13 +Exif.Nikon3.WhiteBalanceBias 0x000b Makernote SShort 1 0 +Exif.Nikon3.0x000d 0x000d Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ExposureDiff 0x000e Makernote Undefined 4 0 1 12 0 +Exif.Nikon3.ThumbOffset 0x0011 Makernote Long 1 1430 +Exif.Nikon3.FlashComp 0x0012 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ISOSetting 0x0013 Makernote Short 2 0 200 +Exif.Nikon3.ImageBoundry 0x0016 Makernote Short 4 0 0 3008 2000 +Exif.Nikon3.0x0017 0x0017 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.FlashBracketComp 0x0018 Makernote Undefined 4 0 1 6 0 +Exif.Nikon3.ExposureBracketComp 0x0019 Makernote SRational 1 0/1 +Exif.Nikon3.ToneComp 0x0081 Makernote Ascii 9 AUTO +Exif.Nikon3.LensType 0x0083 Makernote Byte 1 6 +Exif.Nikon3.Lens 0x0084 Makernote Rational 4 180/10 700/10 35/10 45/10 +Exif.Nikon3.FlashType 0x0087 Makernote Byte 1 0 +Exif.Nikon3.AFFocusPos 0x0088 Makernote Undefined 4 0 0 0 1 +Exif.Nikon3.Bracketing 0x0089 Makernote Short 1 0 +Exif.Nikon3.0x008a 0x008a Makernote Short 1 0 +Exif.Nikon3.0x008b 0x008b Makernote Undefined 4 64 1 12 0 +Exif.Nikon3.ColorMode 0x008d Makernote Ascii 9 MODE1a +Exif.Nikon3.LightingType 0x0090 Makernote Ascii 12 NATURAL +Exif.Nikon3.0x0091 0x0091 Makernote Undefined 465 48 49 48 51 0 0 0 124 0 0 5 13 113 0 0 0 0 1 0 0 11 0 0 0 0 0 20 0 0 31 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 31 0 0 0 0 0 0 248 0 0 248 0 0 0 0 0 0 248 0 0 248 0 0 0 0 0 0 0 0 0 0 0 0 0 45 0 0 0 0 0 1 0 0 0 0 89 1 2 205 51 206 179 54 56 53 54 48 51 0 218 0 214 0 167 0 171 0 50 0 51 0 5 0 0 0 0 0 0 0 0 0 1 0 5 0 0 3 194 0 0 0 100 30 161 200 95 222 59 231 63 201 147 36 178 108 51 110 51 142 15 205 20 205 255 24 187 172 35 200 39 84 41 220 51 68 39 136 59 158 49 239 176 221 55 206 242 77 6 206 51 212 169 76 179 220 17 174 50 140 159 228 51 220 49 78 186 201 119 196 225 223 50 196 178 204 146 204 17 54 56 53 54 48 49 0 101 0 161 0 172 172 169 163 163 168 169 169 168 168 170 171 164 152 149 5 249 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48 38 72 0 8 1 78 226 1 0 72 49 38 48 0 0 0 3 7 252 11 226 0 4 169 1 72 0 128 16 0 0 3 151 96 196 12 145 80 60 0 0 4 190 3 111 0 0 9 186 0 0 4 197 0 0 4 190 3 111 0 0 0 0 3 0 0 0 0 200 0 60 52 62 143 63 0 0 4 176 0 0 4 162 0 0 4 177 0 0 4 126 255 127 255 127 255 127 255 127 8 128 3 111 3 28 2 157 18 17 1 0 0 0 0 72 240 23 52 7 0 161 109 80 127 64 45 92 44 52 132 52 23 100 32 99 0 0 0 21 5 0 2 2 64 0 0 0 0 64 +Exif.Nikon3.HueAdjustment 0x0092 Makernote SShort 1 0 +Exif.Nikon3.NoiseReduction 0x0095 Makernote Ascii 5 OFF +Exif.Nikon3.ColorBalance2 0x0097 Makernote Undefined 140 48 49 48 51 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 2 4 1 0 1 163 1 0 0 0 1 8 1 0 0 0 0 0 0 112 0 12 0 24 0 3 1 140 255 109 0 7 255 216 1 90 255 206 255 251 255 222 1 39 255 255 255 255 255 255 128 0 0 0 0 0 0 0 0 0 10 0 0 0 2 128 0 0 3 0 0 0 2 128 0 0 0 0 16 16 0 255 0 255 0 77 0 150 0 29 255 204 255 186 0 122 0 127 255 150 255 235 0 0 5 0 0 8 108 18 223 51 5 89 1 63 240 240 0 26 +Exif.Nikon3.0x0098 0x0098 Makernote Undefined 31 48 49 48 49 23 52 7 0 161 109 80 127 64 45 92 44 52 132 52 23 100 32 99 0 0 0 21 5 0 2 2 +Exif.Nikon3.0x009a 0x009a Makernote Rational 2 78/10 78/10 +Exif.Nikon3.SerialNumber 0x00a0 Makernote Ascii 21 NO= 100005e5 +Exif.Nikon3.0x00a2 0x00a2 Makernote Long 1 2929656 +Exif.Nikon3.0x00a3 0x00a3 Makernote Byte 1 0 +Exif.Nikon3.ShutterCount 0x00a7 Makernote Long 1 1193 +Exif.Nikon3.0x00a8 0x00a8 Makernote Undefined 20 48 49 48 48 0 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Exif.Nikon3.ImageOptimization 0x00a9 Makernote Ascii 16 NORMAL +Exif.Nikon3.Saturation 0x00aa Makernote Ascii 16 NORMAL +Exif.Nikon3.VariProgram 0x00ab Makernote Ascii 16 +Exif.Iop.InteroperabilityIndex 0x0001 Iop Ascii 4 123 +Exif.Iop.InteroperabilityVersion 0x0002 Iop Undefined 4 48 49 48 48 +Exif.Thumbnail.Compression 0x0103 IFD1 Short 1 6 +Exif.Thumbnail.Orientation 0x0112 IFD1 Short 1 2 +Exif.Thumbnail.XResolution 0x011a IFD1 Rational 1 300/1 +Exif.Thumbnail.YResolution 0x011b IFD1 Rational 1 300/1 +Exif.Thumbnail.ResolutionUnit 0x0128 IFD1 Short 1 2 +Exif.Thumbnail.JPEGInterchangeFormat 0x0201 IFD1 Long 1 0 +Exif.Thumbnail.JPEGInterchangeFormatLength 0x0202 IFD1 Long 1 8930 +Exif.Thumbnail.YCbCrPositioning 0x0213 IFD1 Short 1 2 diff --git a/test/exifdata-test.sh b/test/exifdata-test.sh index 0d27ef81..601f8922 100755 --- a/test/exifdata-test.sh +++ b/test/exifdata-test.sh @@ -15,9 +15,11 @@ export LD_LIBRARY_PATH binpath="../../src" cp -f ./data/exiv2-gc.jpg ./tmp cp -f ./data/exiv2-canon-powershot-s40.jpg ./tmp +cp -f ./data/exiv2-nikon-d70.jpg ./tmp cd ./tmp $binpath/exifdata-test exiv2-gc.jpg $binpath/exifdata-test exiv2-canon-powershot-s40.jpg +$binpath/exifdata-test exiv2-nikon-d70.jpg ) > $results diff -q $diffargs $results $good