Skip to content

Commit

Permalink
Merge pull request #2172 from Exiv2/mergify/bp/main/pr-2167
Browse files Browse the repository at this point in the history
Initial support for OM System MakerNote (backport #2167)
  • Loading branch information
piponazo committed Mar 31, 2022
2 parents fafe999 + 44c3aab commit 790fc46
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/makernote_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const TiffMnRegistry TiffMnCreator::registry_[] = {
{"Minolta", minoltaId, newIfdMn, newIfdMn2},
{"NIKON", ifdIdNotSet, newNikonMn, nullptr}, // mnGroup_ is not used
{"OLYMPUS", ifdIdNotSet, newOlympusMn, nullptr}, // mnGroup_ is not used
{"OM Digital", olympus2Id, newOMSystemMn, newOMSystemMn2},
{"Panasonic", panasonicId, newPanasonicMn, newPanasonicMn2},
{"PENTAX", ifdIdNotSet, newPentaxMn, nullptr}, // mnGroup_ is not used
{"RICOH", ifdIdNotSet, newPentaxMn, nullptr}, // mnGroup_ is not used
Expand Down Expand Up @@ -232,6 +233,42 @@ size_t Olympus2MnHeader::write(IoWrapper& ioWrapper, ByteOrder /*byteOrder*/) co
return sizeOfSignature();
} // Olympus2MnHeader::write

const byte OMSystemMnHeader::signature_[] = {'O', 'M', ' ', 'S', 'Y', 'S', 'T', 'E',
'M', 0x00, 0x00, 0x00, 'I', 'I', 0x04, 0x00};

size_t OMSystemMnHeader::sizeOfSignature() {
return sizeof(signature_);
}

OMSystemMnHeader::OMSystemMnHeader() {
read(signature_, sizeOfSignature(), invalidByteOrder);
}

size_t OMSystemMnHeader::size() const {
return header_.size();
}

size_t OMSystemMnHeader::ifdOffset() const {
return sizeOfSignature();
}

uint32_t OMSystemMnHeader::baseOffset(uint32_t mnOffset) const {
return mnOffset;
}

bool OMSystemMnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder*/) {
if (!pData || size < sizeOfSignature())
return false;
header_.alloc(sizeOfSignature());
std::copy_n(pData, header_.size(), header_.data());
return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, sizeOfSignature() - 2));
}

size_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};
const ByteOrder FujiMnHeader::byteOrder_ = littleEndian;

Expand Down Expand Up @@ -630,6 +667,18 @@ TiffComponent* newOlympus2Mn2(uint16_t tag, IfdId group, IfdId mnGroup) {
return new TiffIfdMakernote(tag, group, mnGroup, new Olympus2MnHeader);
}

TiffComponent* newOMSystemMn(uint16_t tag, IfdId group, IfdId mnGroup, const byte* /*pData*/, size_t size,
ByteOrder /*byteOrder*/) {
// Require at least the header and an IFD with 1 entry
if (size < OMSystemMnHeader::sizeOfSignature() + 18)
return nullptr;
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, const byte* /*pData*/, size_t size,
ByteOrder /*byteOrder*/) {
// Require at least the header and an IFD with 1 entry
Expand Down
37 changes: 37 additions & 0 deletions src/makernote_int.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,36 @@ class Olympus2MnHeader : public MnHeader {

}; // class Olympus2MnHeader

//! Header of an OM Digital Solutions (ex Olympus) Makernote
class OMSystemMnHeader : public MnHeader {
public:
//! @name Creators
//@{
//! Default constructor
OMSystemMnHeader();
//! Virtual destructor.
~OMSystemMnHeader() override = default;
//@}
//! @name Manipulators
//@{
bool read(const byte* pData, size_t size, ByteOrder byteOrder) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] size_t size() const override;
size_t write(IoWrapper& ioWrapper, ByteOrder byteOrder) const override;
[[nodiscard]] size_t ifdOffset() const override;
[[nodiscard]] uint32_t baseOffset(uint32_t mnOffset) const override;
//@}
//! Return the size of the makernote header signature
static size_t sizeOfSignature();

private:
DataBuf header_; //!< Data buffer for the makernote header
static const byte signature_[]; //!< Olympus makernote header signature

}; // class OMSystemMnHeader

//! Header of a Fujifilm Makernote
class FujiMnHeader : public MnHeader {
public:
Expand Down Expand Up @@ -510,6 +540,13 @@ TiffComponent* newOlympusMn2(uint16_t tag, IfdId group, IfdId mnGroup);
//! Function to create an Olympus II makernote
TiffComponent* newOlympus2Mn2(uint16_t tag, IfdId group, IfdId mnGroup);

//! Function to create an OM Digital Solutions makernote
TiffComponent* newOMSystemMn(uint16_t tag, IfdId group, IfdId mnGroup, const byte* pData, size_t size,
ByteOrder byteOrder);

//! Function to create an 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, IfdId mnGroup, const byte* pData, size_t size, ByteOrder byteOrder);

Expand Down
Binary file added test/data/test_issue_2126.exv
Binary file not shown.
198 changes: 198 additions & 0 deletions test/data/test_reference_files/test_issue_2126.exv.out

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions tests/bugfixes/github/test_issue_2126.py
Original file line number Diff line number Diff line change
@@ -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]

0 comments on commit 790fc46

Please sign in to comment.