From 4a304e9265fef4e468342aa831f5671fdc7a6083 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Mon, 24 Apr 2006 17:49:49 +0000 Subject: [PATCH] New TIFF parser: Added Nikon 1 and Nikon 2 Makernotes --- src/mnreg.cpp | 2 +- src/nikonmn2.cpp | 57 ++++++++++++++++++++++++++++++++-- src/nikonmn2.hpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++- src/tiffimage.hpp | 2 ++ 4 files changed, 135 insertions(+), 5 deletions(-) diff --git a/src/mnreg.cpp b/src/mnreg.cpp index 6f501553..6c315b5f 100644 --- a/src/mnreg.cpp +++ b/src/mnreg.cpp @@ -46,7 +46,7 @@ namespace Exiv2 { const TiffMnRegistry TiffMnCreator::registry_[] = { { "Canon", newCanonMn, Group::canonmn }, { "FUJIFILM", newFujiMn, Group::fujimn }, - { "NIKON", newNikonMn, Group::nikon3mn }, + { "NIKON", newNikonMn, Group::nikonmn }, { "OLYMPUS", newOlympusMn, Group::olympmn } }; diff --git a/src/nikonmn2.cpp b/src/nikonmn2.cpp index 315f3ca6..fa8955ce 100644 --- a/src/nikonmn2.cpp +++ b/src/nikonmn2.cpp @@ -46,6 +46,43 @@ EXIV2_RCSID("@(#) $Id$"); // class member definitions namespace Exiv2 { + const byte Nikon2MnHeader::signature_[] = { + 'N', 'i', 'k', 'o', 'n', '\0', 0x00, 0x01 + }; + const uint32_t Nikon2MnHeader::size_ = 8; + + Nikon2MnHeader::Nikon2MnHeader() + { + read(signature_, size_, invalidByteOrder); + } + + bool Nikon2MnHeader::read(const byte* pData, + uint32_t size, + ByteOrder /*byteOrder*/) + { + assert (pData != 0); + + if (size < size_) return false; + if (0 != memcmp(pData, signature_, 6)) return false; + buf_.alloc(size_); + memcpy(buf_.pData_, pData, buf_.size_); + start_ = size_; + return true; + + } // Nikon2MnHeader::read + + bool TiffNikon2Mn::doReadHeader(const byte* pData, + uint32_t size, + ByteOrder byteOrder) + { + return header_.read(pData, size, byteOrder); + } + + uint32_t TiffNikon2Mn::doIfdOffset() const + { + return header_.ifdOffset(); + } + const byte Nikon3MnHeader::signature_[] = { 'N', 'i', 'k', 'o', 'n', '\0', 0x02, 0x10, 0x00, 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08 @@ -105,11 +142,25 @@ namespace Exiv2 { TiffComponent* newNikonMn(uint16_t tag, uint16_t group, uint16_t mnGroup, - const byte* /*pData*/, - uint32_t /*size*/, + const byte* pData, + uint32_t size, ByteOrder /*byteOrder*/) { - return new TiffNikon3Mn(tag, group, mnGroup); + // If there is no "Nikon" string it must be Nikon1 format + if (size < 6 || std::string(reinterpret_cast(pData), 6) + != std::string("Nikon\0", 6)) { + return new TiffNikon1Mn(tag, group, Group::nikon1mn); + } + // If the "Nikon" string is not followed by a TIFF header, we assume + // Nikon2 format + TiffHeade2 tiffHeader; + if ( size < 18 + || !tiffHeader.read(pData + 10, size - 10) + || tiffHeader.tag() != 0x002a) { + return new TiffNikon2Mn(tag, group, Group::nikon2mn); + } + // Else we have a Nikon3 makernote + return new TiffNikon3Mn(tag, group, Group::nikon3mn); } } // namespace Exiv2 diff --git a/src/nikonmn2.hpp b/src/nikonmn2.hpp index 26025442..5f227c76 100644 --- a/src/nikonmn2.hpp +++ b/src/nikonmn2.hpp @@ -52,6 +52,83 @@ namespace Exiv2 { const uint16_t nikon3mn = 266; //!< Nikon3 makernote } + //! Nikon 1 Makernote + class TiffNikon1Mn : public TiffIfdMakernote { + public: + //! @name Creators + //@{ + //! Default constructor + TiffNikon1Mn(uint16_t tag, uint16_t group, uint16_t mnGroup) + : TiffIfdMakernote(tag, group, mnGroup) {} + //! Virtual destructor + virtual ~TiffNikon1Mn() {} + //@} + + }; // class TiffNikon1Mn + + //! Header of a Nikon 2 Makernote + class Nikon2MnHeader : public MnHeader { + public: + //! @name Creators + //@{ + //! Default constructor + Nikon2MnHeader(); + //! Virtual destructor. + virtual ~Nikon2MnHeader() {} + //@} + //! @name Manipulators + //@{ + virtual bool read(const byte* pData, + uint32_t size, + ByteOrder byteOrder); + //@} + //! @name Accessors + //@{ + virtual uint32_t size() const { return size_; } + virtual uint32_t ifdOffset() const { return start_; } + //@} + + private: + DataBuf buf_; //!< Raw header data + uint32_t start_; //!< Start of the mn IFD rel. to mn start + static const byte signature_[]; //!< Nikon 2 makernote header signature + static const uint32_t size_; //!< Size of the signature + + }; // class Nikon2MnHeader + + /*! + @brief Nikon 2 Makernote + */ + class TiffNikon2Mn : public TiffIfdMakernote { + public: + //! @name Creators + //@{ + //! Default constructor + TiffNikon2Mn(uint16_t tag, uint16_t group, uint16_t mnGroup) + : TiffIfdMakernote(tag, group, mnGroup) {} + //! Virtual destructor + virtual ~TiffNikon2Mn() {} + //@} + + private: + //! @name Manipulators + //@{ + virtual bool doReadHeader(const byte* pData, + uint32_t size, + ByteOrder byteOrder); + //@} + + //! @name Accessors + //@{ + virtual uint32_t doIfdOffset() const; + //@} + + private: + // DATA + Nikon2MnHeader header_; //!< Makernote header + + }; // class TiffNikon2Mn + //! Header of a Nikon 3 Makernote class Nikon3MnHeader : public MnHeader { public: @@ -71,7 +148,7 @@ namespace Exiv2 { //! @name Accessors //@{ virtual uint32_t size() const { return size_; } - virtual uint32_t ifdOffset() const { return size_; } + virtual uint32_t ifdOffset() const { return start_; } //! Return the byte order for the header ByteOrder byteOrder() const { return byteOrder_; } /*! diff --git a/src/tiffimage.hpp b/src/tiffimage.hpp index 7e2a03f1..625d9a8e 100644 --- a/src/tiffimage.hpp +++ b/src/tiffimage.hpp @@ -211,6 +211,8 @@ namespace Exiv2 { uint32_t ifdOffset() const { return offset_; } //! Return the size (in bytes) of the TIFF header uint32_t size() const { return 8; } + //! Return the tag value (magic number) which identifies the buffer as TIFF data + uint16_t tag() const { return tag_; } //@} private: