diff --git a/src/makernote_int.cpp b/src/makernote_int.cpp index 4db41f46db..5ef722e770 100644 --- a/src/makernote_int.cpp +++ b/src/makernote_int.cpp @@ -130,6 +130,7 @@ namespace Exiv2 { { "Minolta", minoltaId, newIfdMn, newIfdMn2 }, { "NIKON", ifdIdNotSet, newNikonMn, 0 }, // mnGroup_ is not used { "OLYMPUS", ifdIdNotSet, newOlympusMn, 0 }, // mnGroup_ is not used + { "OM Digital", olympus2Id, newOMSystemMn, newOMSystemMn2 }, { "Panasonic", panasonicId, newPanasonicMn, newPanasonicMn2 }, { "PENTAX", ifdIdNotSet, newPentaxMn, 0 }, // mnGroup_ is not used { "RICOH", ifdIdNotSet, newPentaxMn, 0 }, // mnGroup_ is not used @@ -330,6 +331,60 @@ namespace Exiv2 { return sizeOfSignature(); } // Olympus2MnHeader::write + const byte OMSystemMnHeader::signature_[] = { + 'O', 'M', ' ', 'S', 'Y', 'S', 'T', 'E', 'M', 0x00, 0x00, 0x00, 'I', 'I', 0x04, 0x00 + }; + + uint32_t OMSystemMnHeader::sizeOfSignature() + { + return sizeof(signature_); + } + + OMSystemMnHeader::OMSystemMnHeader() + { + read(signature_, sizeOfSignature(), invalidByteOrder); + } + + OMSystemMnHeader::~OMSystemMnHeader() + { + } + + uint32_t OMSystemMnHeader::size() const + { + return header_.size_; + } + + uint32_t OMSystemMnHeader::ifdOffset() const + { + return sizeOfSignature(); + } + + uint32_t OMSystemMnHeader::baseOffset(uint32_t mnOffset) const + { + return mnOffset; + } + + bool OMSystemMnHeader::read(const byte* pData, + uint32_t size, + ByteOrder /*byteOrder*/) + { + if (!pData || size < sizeOfSignature()) return false; + header_.alloc(sizeOfSignature()); + std::memcpy(header_.pData_, pData, header_.size_); + if ( static_cast(header_.size_) < sizeOfSignature() + || 0 != memcmp(header_.pData_, signature_, sizeOfSignature() - 2)) { + return false; + } + return true; + } // OMSystemMnHeader::read + + uint32_t OMSystemMnHeader::write(IoWrapper& ioWrapper, + ByteOrder /*byteOrder*/) const + { + ioWrapper.write(signature_, sizeOfSignature()); + return sizeOfSignature(); + } // OMSystemMnHeader::write + const byte FujiMnHeader::signature_[] = { 'F', 'U', 'J', 'I', 'F', 'I', 'L', 'M', 0x0c, 0x00, 0x00, 0x00 }; @@ -900,6 +955,25 @@ namespace Exiv2 { return new TiffIfdMakernote(tag, group, mnGroup, new Olympus2MnHeader); } + TiffComponent* newOMSystemMn(uint16_t tag, + IfdId group, + IfdId mnGroup, + const byte* /*pData*/, + uint32_t size, + ByteOrder /*byteOrder*/) + { + // Require at least the header and an IFD with 1 entry + if (size < OMSystemMnHeader::sizeOfSignature() + 18) return 0; + return newOMSystemMn2(tag, group, mnGroup); + } + + TiffComponent* newOMSystemMn2(uint16_t tag, + IfdId group, + IfdId mnGroup) + { + return new TiffIfdMakernote(tag, group, mnGroup, new OMSystemMnHeader); + } + TiffComponent* newFujiMn(uint16_t tag, IfdId group, IfdId mnGroup, diff --git a/src/makernote_int.hpp b/src/makernote_int.hpp index d4282b7640..e4c8b43515 100644 --- a/src/makernote_int.hpp +++ b/src/makernote_int.hpp @@ -232,6 +232,38 @@ namespace Exiv2 { }; // class Olympus2MnHeader + //! Header of an OM Digital Solutions (ex Olympus) Makernote + class OMSystemMnHeader : public MnHeader { + public: + //! @name Creators + //@{ + //! Default constructor + OMSystemMnHeader(); + //! Virtual destructor. + virtual ~OMSystemMnHeader(); + //@} + //! @name Manipulators + //@{ + virtual bool read(const byte* pData, + uint32_t size, + ByteOrder byteOrder); + //@} + //! @name Accessors + //@{ + virtual uint32_t size() const; + virtual uint32_t write(IoWrapper& ioWrapper, ByteOrder byteOrder) const; + virtual uint32_t ifdOffset() const; + virtual uint32_t baseOffset(uint32_t mnOffset) const; + //@} + //! Return the size of the makernote header signature + static uint32_t sizeOfSignature(); + + private: + DataBuf header_; //!< Data buffer for the makernote header + static const byte signature_[]; //!< OM Digital Solutions makernote header signature + + }; // class OMSystemMnHeader + //! Header of a Fujifilm Makernote class FujiMnHeader : public MnHeader { public: @@ -587,6 +619,19 @@ namespace Exiv2 { IfdId group, IfdId mnGroup); + //! Function to create an OM Digital Solutions makernote + TiffComponent* newOMSystemMn(uint16_t tag, + IfdId group, + IfdId mnGroup, + const byte* pData, + uint32_t size, + ByteOrder byteOrder); + + //! Function to create a OM Digital Solutions makernote + TiffComponent* newOMSystemMn2(uint16_t tag, + IfdId group, + IfdId mnGroup); + //! Function to create a Fujifilm makernote TiffComponent* newFujiMn(uint16_t tag, IfdId group, diff --git a/test/data/test_issue_2126.exv b/test/data/test_issue_2126.exv new file mode 100644 index 0000000000..fca9b4967b Binary files /dev/null and b/test/data/test_issue_2126.exv differ diff --git a/tests/bugfixes/github/test_issue_2126.py b/tests/bugfixes/github/test_issue_2126.py new file mode 100644 index 0000000000..4832319139 --- /dev/null +++ b/tests/bugfixes/github/test_issue_2126.py @@ -0,0 +1,15 @@ +from system_tests import CaseMeta, path + +class OMSystemMakerNote(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/2126 + """ + url = "https://github.com/Exiv2/exiv2/issues/2126" + + filename = path("$data_path/test_issue_2126.exv") + commands = ["$exiv2 -q -K Exif.Olympus2.CameraID $filename"] + stdout = ["""Exif.Olympus2.CameraID Undefined 32 OM SYSTEM CAMERA +"""] + stderr = [""] + retval = [0]