diff --git a/src/Makefile b/src/Makefile index 8d944380..b49e5453 100644 --- a/src/Makefile +++ b/src/Makefile @@ -73,6 +73,7 @@ CCSRC = basicio.cpp \ metadatum.cpp \ mnreg.cpp \ nikonmn.cpp \ + nikonmn2.cpp \ olympusmn.cpp \ olympusmn2.cpp \ panasonicmn.cpp \ diff --git a/src/fujimn2.cpp b/src/fujimn2.cpp index 02055e22..3d299238 100644 --- a/src/fujimn2.cpp +++ b/src/fujimn2.cpp @@ -53,13 +53,15 @@ EXIV2_RCSID("@(#) $Id$"); // class member definitions namespace Exiv2 { - const char* FujiMnHeader::signature_ = "FUJIFILM\12\0\0\0"; + const byte FujiMnHeader::signature_[] = { + 'F', 'U', 'J', 'I', 'F', 'I', 'L', 'M', 0x0c, 0x00, 0x00, 0x00 + }; const uint32_t FujiMnHeader::size_ = 12; const ByteOrder FujiMnHeader::byteOrder_ = littleEndian; FujiMnHeader::FujiMnHeader() { - read(reinterpret_cast(signature_), size_, byteOrder_); + read(signature_, size_, byteOrder_); } bool FujiMnHeader::read(const byte* pData, @@ -101,11 +103,9 @@ namespace Exiv2 { { // Byteorder: from the header (little endian) // Offsets : relative to the start of the makernote - // Creator : standard TIFF component factory + // Creator : no change return TiffRwState::AutoPtr( - new TiffRwState(header_.byteOrder(), - mnOffset, - TiffCreator::create)); + new TiffRwState(header_.byteOrder(), mnOffset, 0)); } // ************************************************************************* diff --git a/src/fujimn2.hpp b/src/fujimn2.hpp index 1d83ca8e..d4ccd8f6 100644 --- a/src/fujimn2.hpp +++ b/src/fujimn2.hpp @@ -73,11 +73,11 @@ namespace Exiv2 { //@} private: - DataBuf header_; //!< Data buffer for the makernote header - static const char* signature_; //!< Fujifilm makernote header signature - static const uint32_t size_; //!< Size of the signature + DataBuf header_; //!< Data buffer for the makernote header + static const byte signature_[]; //!< Fujifilm makernote header signature + static const uint32_t size_; //!< Size of the signature static const ByteOrder byteOrder_; //!< Byteorder for makernote (II) - uint32_t start_; //!< Start of the mn IFD rel. to mn start + uint32_t start_; //!< Start of the mn IFD rel. to mn start }; // class FujiMnHeader diff --git a/src/mnreg.cpp b/src/mnreg.cpp index 0f8d57d5..6f501553 100644 --- a/src/mnreg.cpp +++ b/src/mnreg.cpp @@ -34,6 +34,7 @@ EXIV2_RCSID("@(#) $Id$"); #include "makernote2.hpp" #include "canonmn2.hpp" #include "fujimn2.hpp" +#include "nikonmn2.hpp" #include "olympusmn2.hpp" // + standard includes @@ -45,6 +46,7 @@ namespace Exiv2 { const TiffMnRegistry TiffMnCreator::registry_[] = { { "Canon", newCanonMn, Group::canonmn }, { "FUJIFILM", newFujiMn, Group::fujimn }, + { "NIKON", newNikonMn, Group::nikon3mn }, { "OLYMPUS", newOlympusMn, Group::olympmn } }; diff --git a/src/nikonmn2.cpp b/src/nikonmn2.cpp new file mode 100644 index 00000000..315f3ca6 --- /dev/null +++ b/src/nikonmn2.cpp @@ -0,0 +1,115 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2006 Andreas Huggel + * + * This program is part of the Exiv2 distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/* + File: nikonmn2.cpp + Version: $Rev$ + Author(s): Andreas Huggel (ahu) + History: 18-Apr-06, ahu: created + */ +// ***************************************************************************** +#include "rcsid.hpp" +EXIV2_RCSID("@(#) $Id$"); + +// ***************************************************************************** +// included header files +#ifdef _MSC_VER +# include "exv_msvc.h" +#else +# include "exv_conf.h" +#endif + +#include "nikonmn2.hpp" +#include "tiffcomposite.hpp" +#include "types.hpp" + +// + standard includes + +// ***************************************************************************** +// class member definitions +namespace Exiv2 { + + const byte Nikon3MnHeader::signature_[] = { + 'N', 'i', 'k', 'o', 'n', '\0', + 0x02, 0x10, 0x00, 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08 + }; + const uint32_t Nikon3MnHeader::size_ = 18; + + Nikon3MnHeader::Nikon3MnHeader() + { + read(signature_, size_, invalidByteOrder); + } + + bool Nikon3MnHeader::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_); + TiffHeade2 th; + if (!th.read(buf_.pData_ + 10, 8)) return false; + byteOrder_ = th.byteOrder(); + start_ = 10 + th.ifdOffset(); + return true; + + } // Nikon3MnHeader::read + + bool TiffNikon3Mn::doReadHeader(const byte* pData, + uint32_t size, + ByteOrder byteOrder) + { + return header_.read(pData, size, byteOrder); + } + + uint32_t TiffNikon3Mn::doIfdOffset() const + { + return header_.ifdOffset(); + } + + TiffRwState::AutoPtr TiffNikon3Mn::doGetState(uint32_t mnOffset, + ByteOrder byteOrder) const + { + // Byteorder: From header + // Offsets : From header + // Creator : No change + return TiffRwState::AutoPtr( + new TiffRwState(header_.byteOrder(), + mnOffset + header_.baseOffset(), + 0)); + } + + // ************************************************************************* + // free functions + + TiffComponent* newNikonMn(uint16_t tag, + uint16_t group, + uint16_t mnGroup, + const byte* /*pData*/, + uint32_t /*size*/, + ByteOrder /*byteOrder*/) + { + return new TiffNikon3Mn(tag, group, mnGroup); + } + +} // namespace Exiv2 diff --git a/src/nikonmn2.hpp b/src/nikonmn2.hpp new file mode 100644 index 00000000..26025442 --- /dev/null +++ b/src/nikonmn2.hpp @@ -0,0 +1,144 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2006 Andreas Huggel + * + * This program is part of the Exiv2 distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/*! + @file nikonmn2.hpp + @brief TIFF Nikon makernote + @version $Rev$ + @author Andreas Huggel (ahu) + ahuggel@gmx.net + @date 18-Apr-06, ahu: created + */ +#ifndef NIKONMN2_HPP_ +#define NIKONMN2_HPP_ + +// ***************************************************************************** +// included header files +#include "makernote2.hpp" +#include "tiffcomposite.hpp" +#include "types.hpp" +#include "tiffimage.hpp" // for TiffHeade2 + +// + standard includes + +// ***************************************************************************** +// namespace extensions +namespace Exiv2 { + +// ***************************************************************************** +// class definitions + + namespace Group { + const uint16_t nikonmn = 263; //!< Any Nikon makernote + const uint16_t nikon1mn = 264; //!< Nikon1 makernote + const uint16_t nikon2mn = 265; //!< Nikon2 makernote + const uint16_t nikon3mn = 266; //!< Nikon3 makernote + } + + //! Header of a Nikon 3 Makernote + class Nikon3MnHeader : public MnHeader { + public: + //! @name Creators + //@{ + //! Default constructor + Nikon3MnHeader(); + //! Virtual destructor. + virtual ~Nikon3MnHeader() {} + //@} + //! @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 size_; } + //! Return the byte order for the header + ByteOrder byteOrder() const { return byteOrder_; } + /*! + @brief Return the base offset for the makernote IFD entries relative + to the start of the makernote. + */ + uint32_t baseOffset() const { return 10; } + //@} + + private: + DataBuf buf_; //!< Raw header data + ByteOrder byteOrder_; //!< Byteorder for makernote + uint32_t start_; //!< Start of the mn IFD rel. to mn start + static const byte signature_[]; //!< Nikon 3 makernote header signature + static const uint32_t size_; //!< Size of the signature + + }; // class Nikon3MnHeader + + /*! + @brief Nikon 3 Makernote + */ + class TiffNikon3Mn : public TiffIfdMakernote { + public: + //! @name Creators + //@{ + //! Default constructor + TiffNikon3Mn(uint16_t tag, uint16_t group, uint16_t mnGroup) + : TiffIfdMakernote(tag, group, mnGroup) {} + //! Virtual destructor + virtual ~TiffNikon3Mn() {} + //@} + + private: + //! @name Manipulators + //@{ + virtual bool doReadHeader(const byte* pData, + uint32_t size, + ByteOrder byteOrder); + //@} + + //! @name Accessors + //@{ + virtual uint32_t doIfdOffset() const; + virtual TiffRwState::AutoPtr doGetState(uint32_t mnOffset, + ByteOrder byteOrder) const; + //@} + + private: + // DATA + Nikon3MnHeader header_; //!< Makernote header + + }; // class TiffNikon3Mn + +// ***************************************************************************** +// template, inline and free functions + + /*! + @brief Function to create a Nikon makernote. This will create the + appropriate Nikon 1, 2 or 3 makernote, based on the arguments. + */ + TiffComponent* newNikonMn(uint16_t tag, + uint16_t group, + uint16_t mnGroup, + const byte* pData, + uint32_t size, + ByteOrder byteOrder); + +} // namespace Exiv2 + +#endif // #ifndef NIKONMN2_HPP_ diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp index 3be23d74..2dc1cc53 100644 --- a/src/tiffcomposite.cpp +++ b/src/tiffcomposite.cpp @@ -105,6 +105,9 @@ namespace Exiv2 { case 260: group = "CanonCs1"; break; case 261: group = "CanonCs2"; break; case 262: group = "CanonCf"; break; + case 264: group = "Nikon1"; break; + case 265: group = "Nikon2"; break; + case 266: group = "Nikon3"; break; default: group = "Unknown"; break; } return group; diff --git a/src/tiffimage.hpp b/src/tiffimage.hpp index 926d82a1..7e2a03f1 100644 --- a/src/tiffimage.hpp +++ b/src/tiffimage.hpp @@ -208,7 +208,9 @@ namespace Exiv2 { //! Return the byte order (little or big endian). ByteOrder byteOrder() const { return byteOrder_; } //! Return the offset to the start of the root directory - uint32_t offset() const { return offset_; } + uint32_t ifdOffset() const { return offset_; } + //! Return the size (in bytes) of the TIFF header + uint32_t size() const { return 8; } //@} private: diff --git a/src/tiffparse.cpp b/src/tiffparse.cpp index 973e722f..25d67eeb 100644 --- a/src/tiffparse.cpp +++ b/src/tiffparse.cpp @@ -47,7 +47,7 @@ try { if (0 == rootDir.get()) { throw Error(1, "No root element defined in TIFF structure"); } - rootDir->setStart(buf.pData_ + tiffHeader.offset()); + rootDir->setStart(buf.pData_ + tiffHeader.ifdOffset()); TiffRwState::AutoPtr state( new TiffRwState(tiffHeader.byteOrder(), 0, createFct)); diff --git a/src/tiffparser.cpp b/src/tiffparser.cpp index 9c0bf239..e3fe9c74 100644 --- a/src/tiffparser.cpp +++ b/src/tiffparser.cpp @@ -125,12 +125,12 @@ namespace Exiv2 { assert(pData != 0); TiffHeade2 tiffHeader; - if (!tiffHeader.read(pData, size) || tiffHeader.offset() >= size) { + if (!tiffHeader.read(pData, size) || tiffHeader.ifdOffset() >= size) { throw Error(3, "TIFF"); } TiffComponent::AutoPtr rootDir = createFct(Tag::root, Group::none); if (0 == rootDir.get()) return; - rootDir->setStart(pData + tiffHeader.offset()); + rootDir->setStart(pData + tiffHeader.ifdOffset()); TiffRwState::AutoPtr state( new TiffRwState(tiffHeader.byteOrder(), 0, createFct)); diff --git a/src/tiffvisitor.cpp b/src/tiffvisitor.cpp index a2f2379e..4aa5232f 100644 --- a/src/tiffvisitor.cpp +++ b/src/tiffvisitor.cpp @@ -348,6 +348,8 @@ namespace Exiv2 { { if (state.get() != 0) { if (pOrigState_ != pState_) delete pState_; + // 0 for create function indicates 'no change' + if (state->createFct_ == 0) state->createFct_ = pState_->createFct_; pState_ = state.release(); } }