27 #include "io/stream.hpp" 28 #include "ifdfilecontainer.hpp" 30 #include "makernotedir.hpp" 32 using namespace Debug;
38 bool IfdDir::isPrimary()
const 40 auto result = getValue<uint32_t>(IFD::EXIF_TAG_NEW_SUBFILE_TYPE);
41 return result.ok() && (result.unwrap() == 0);
44 bool IfdDir::isThumbnail()
const 46 auto result = getValue<uint32_t>(IFD::EXIF_TAG_NEW_SUBFILE_TYPE);
47 return result.ok() && (result.unwrap() == 1);
50 IfdDir::IfdDir(off_t _offset, IfdFileContainer &_container)
51 : m_offset(_offset), m_container(_container), m_entries()
61 LOGDBG1(
"IfdDir::load() m_offset =%ld\n", m_offset);
63 auto file = m_container.file();
65 file->seek(m_offset, SEEK_SET);
67 int16_t numEntries = m_container.readInt16(file).unwrap_or(0);
68 LOGDBG1(
"num entries %d\n", numEntries);
70 for (int16_t i = 0; i < numEntries; i++) {
72 auto id = m_container.readUInt16(file);
73 auto type = m_container.readInt16(file);
74 auto count = m_container.readInt32(file);
75 size_t sz = file->read(&data, 4);
76 if (
id.empty() || type.empty() || count.empty() || sz != 4) {
77 LOGERR(
"Failed to read entry %d\n", i);
80 uint16_t n_id =
id.unwrap();
82 std::make_shared<IfdEntry>(n_id, type.unwrap(),
83 count.unwrap(), data, m_container);
84 m_entries[n_id] = entry;
92 std::map<uint16_t, IfdEntry::Ref>::const_iterator iter;
93 iter = m_entries.find(
id);
94 if (iter != m_entries.end()) {
112 int16_t numEntries = 0;
113 auto file = m_container.file();
115 if (m_entries.size() == 0) {
116 file->seek(m_offset, SEEK_SET);
117 numEntries = m_container.readInt16(file).unwrap_or(0);
118 LOGDBG1(
"numEntries =%d shifting %d bytes\n", numEntries, (numEntries * 12) + 2);
120 numEntries = m_entries.size();
123 file->seek(m_offset + (numEntries * 12) + 2, SEEK_SET);
125 return m_container.readInt32(file).unwrap_or(0);
136 auto result = e->getArray<uint32_t>();
138 std::vector<uint32_t> offsets = result.unwrap();
139 if (idx >= offsets.size()) {
140 Ref ref = std::make_shared<IfdDir>(offsets[idx], m_container);
145 LOGERR(
"Can't get SubIFD offsets\n");
153 std::vector<IfdDir::Ref> ifds;
156 auto result = e->getArray<uint32_t>();
158 std::vector<uint32_t> offsets = result.unwrap();
159 for (
auto offset : offsets) {
160 Ref ifd = std::make_shared<IfdDir>(offset, m_container);
175 auto result = getValue<uint32_t>(IFD::EXIF_TAG_EXIF_IFD_POINTER);
176 if (result.empty()) {
177 LOGDBG1(
"Exif IFD offset not found.\n");
181 uint32_t val_offset = result.unwrap();
182 LOGDBG1(
"Exif IFD offset (uncorrected) = %u\n", val_offset);
183 val_offset += m_container.exifOffsetCorrection();
184 LOGDBG1(
"Exif IFD offset = %u\n", val_offset);
186 Ref ref = std::make_shared<IfdDir>(val_offset, m_container);
193 uint32_t val_offset = 0;
196 LOGDBG1(
"MakerNote IFD offset not found.\n");
197 return MakerNoteDir::Ref();
199 val_offset = e->offset();
200 LOGDBG1(
"MakerNote IFD offset (uncorrected) = %u\n", val_offset);
201 val_offset += m_container.exifOffsetCorrection();
202 LOGDBG1(
"MakerNote IFD offset = %u\n", val_offset);
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
static Ref createMakerNote(off_t offset, IfdFileContainer &container)
Option< std::vector< IfdDir::Ref > > getSubIFDs()
Option< uint32_t > getIntegerValue(uint16_t id)
std::shared_ptr< IfdEntry > Ref
Ref getSubIFD(uint32_t idx=0) const