26 #include "io/stream.hpp" 27 #include "ifdfilecontainer.hpp" 29 #include "makernotedir.hpp" 31 using namespace Debug;
37 bool IfdDir::isPrimary()
const 40 return getValue(IFD::EXIF_TAG_NEW_SUBFILE_TYPE, subtype) && (subtype == 0);
43 bool IfdDir::isThumbnail()
const 46 return getValue(IFD::EXIF_TAG_NEW_SUBFILE_TYPE, subtype) && (subtype == 1);
49 IfdDir::IfdDir(off_t _offset, IfdFileContainer &_container)
50 : m_offset(_offset), m_container(_container), m_entries()
60 Trace(DEBUG1) <<
"IfdDir::load() m_offset =" << m_offset <<
"\n";
61 int16_t numEntries = 0;
62 auto file = m_container.file();
64 file->seek(m_offset, SEEK_SET);
65 m_container.readInt16(file, numEntries);
66 Trace(DEBUG1) <<
"num entries " << numEntries <<
"\n";
67 for (int16_t i = 0; i < numEntries; i++) {
72 m_container.readUInt16(file,
id);
73 m_container.readInt16(file, type);
74 m_container.readInt32(file, count);
77 std::make_shared<IfdEntry>(
id, type, count, data, m_container));
78 m_entries[id] = entry;
86 std::map<uint16_t, IfdEntry::Ref>::const_iterator iter;
87 iter = m_entries.find(
id);
88 if (iter != m_entries.end()) {
99 v = e->getIntegerArrayItem(0);
108 auto file = m_container.file();
110 if (m_entries.size() == 0) {
111 file->seek(m_offset, SEEK_SET);
112 m_container.readInt16(file, numEntries);
113 Trace(DEBUG1) <<
"numEntries =" << numEntries <<
" shifting " 114 << (numEntries * 12) + 2 <<
"bytes\n";
116 numEntries = m_entries.size();
119 file->seek(m_offset + (numEntries * 12) + 2, SEEK_SET);
121 m_container.readInt32(file, next);
130 std::vector<uint32_t> offsets;
134 e->getArray(offsets);
135 if (idx >= offsets.size()) {
136 Ref ref(std::make_shared<IfdDir>(offsets[idx], m_container));
141 catch (
const std::exception &ex) {
142 Trace(ERROR) <<
"Exception " << ex.what() <<
"\n";
150 bool success =
false;
151 std::vector<uint32_t> offsets;
155 e->getArray(offsets);
156 for (
auto iter : offsets) {
157 Ref ifd(std::make_shared<IfdDir>(iter, m_container));
163 catch (
const std::exception &ex) {
164 Trace(ERROR) <<
"Exception " << ex.what() <<
"\n";
175 bool success =
false;
176 uint32_t val_offset = 0;
177 success = getValue(IFD::EXIF_TAG_EXIF_IFD_POINTER, val_offset);
179 Trace(DEBUG1) <<
"Exif IFD offset (uncorrected) = " << val_offset
181 val_offset += m_container.exifOffsetCorrection();
182 Trace(DEBUG1) <<
"Exif IFD offset = " << val_offset <<
"\n";
183 Ref ref(std::make_shared<IfdDir>(val_offset, m_container));
187 Trace(DEBUG1) <<
"Exif IFD offset not found.\n";
194 uint32_t val_offset = 0;
197 Trace(DEBUG1) <<
"MakerNote IFD offset not found.\n";
198 return MakerNoteDir::Ref();
200 val_offset = e->offset();
201 Trace(DEBUG1) <<
"MakerNote IFD offset (uncorrected) = " << val_offset
203 val_offset += m_container.exifOffsetCorrection();
204 Trace(DEBUG1) <<
"MakerNote IFD offset = " << val_offset <<
"\n";
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
bool getSubIFDs(std::vector< IfdDir::Ref > &ifds)
bool getIntegerValue(uint16_t id, uint32_t &v)
static Ref createMakerNote(off_t offset, IfdFileContainer &container)
std::shared_ptr< IfdEntry > Ref
Ref getSubIFD(uint32_t idx=0) const