24#include "rawspeedconfig.h"
61 t = std::make_unique<TiffEntry>(
this, bs);
90 for (
uint32_t j = 0; j < t->count; j++)
91 add(std::make_unique<TiffIFD>(
this, ifds, bs, t->getU32(j)));
116 if (offset == UINT32_MAX)
125 auto numEntries = bs.
getU16();
130 const auto IFDFullSize = 2 + 4 + (12 * numEntries);
133 ThrowTPE(
"Two IFD's overlap. Raw corrupt!");
135 for (
uint32_t i = 0; i < numEntries; i++)
151 while (p && !makeEntry) {
166 auto setup = [&bs](
bool rebase,
uint32_t newPosition,
168 const char* context =
nullptr) {
176 if (bs.
hasPrefix(std::string_view(
"AOC\0", 4))) {
177 setup(
false, 6, 4,
"Pentax makernote");
179 setup(
true, 10, 8,
"Pentax makernote");
180 }
else if (bs.
hasPrefix(std::string_view(
"FUJIFILM\x0c\x00\x00\x00", 12))) {
183 }
else if (bs.
hasPrefix(std::string_view(
"Nikon\x00\x02", 7))) {
188 setup(
true, 8, 0,
"Nikon makernote");
198 setup(
true, 14, 12,
"Apple makernote");
204 setup(
false, 20, 12,
"Panosonic makernote");
205 }
else if (make ==
"SAMSUNG") {
223 return std::make_unique<TiffRootIFD>(
this, ifds, bs, bs.
getPosition());
227 vector<const TiffIFD*> matchingIFDs;
229 matchingIFDs.push_back(
this);
231 for (
const auto& i :
subIFDs) {
232 vector<const TiffIFD*> t = i->getIFDsWithTag(tag);
233 matchingIFDs.insert(matchingIFDs.end(), t.begin(), t.end());
240 if (index >= ifds.size())
241 ThrowTPE(
"failed to find %u ifd with tag 0x%04x", index + 1,
242 static_cast<unsigned>(tag));
248 return i->second.get();
250 for (
const auto& j :
subIFDs) {
251 TiffEntry* entry = j->getEntryRecursive(tag);
265 for (; p !=
nullptr; p = p->parent)
266 p->subIFDCountRecursive++;
274 ThrowTPE(
"TIFF IFD has %d SubIFDs", count);
280 ThrowTPE(
"TIFF IFD file has %d SubIFDs (recursively)", count);
285 for (
const TiffIFD* p =
this; p !=
nullptr;) {
289 ThrowTPE(
"TiffIFD cascading overflow, found %d level IFD", depth);
291 p->checkSubIFDs(headroom);
300 assert(subIFD->parent ==
this);
303 subIFD->recursivelyCheckSubIFDs(0);
305 subIFDs.push_back(std::move(subIFD));
309 entry->parent =
this;
310 entries[entry->tag] = std::move(entry);
316 ThrowTPE(
"Entry 0x%x not found.",
static_cast<unsigned>(tag));
317 return i->second.get();
331 ThrowTPE(
"Failed to find MAKE entry.");
333 ThrowTPE(
"Failed to find MODEL entry.");
assert(dim.area() >=area)
Buffer getSubView(size_type offset, size_type size_) const
size_type RAWSPEED_READONLY getRemainSize() const
void setPosition(size_type newPos)
ByteStream getSubStream(size_type offset, size_type size_) const
bool hasPrefix(std::string_view prefix) const
void skipBytes(size_type nbytes)
bool skipPrefix(std::string_view prefix)
size_type getPosition() const
bool hasPatternAt(std::string_view pattern, size_type relPos) const
Endianness setByteOrder(Endianness endianness_)
bool insert(const T &newElt)
ByteStream getData() const
std::string getString() const
std::vector< TiffIFDOwner > subIFDs
TiffEntry *RAWSPEED_READONLY getEntryRecursive(TiffTag tag) const
virtual void anchor() const
const TiffIFD * getIFDWithTag(TiffTag tag, uint32_t index=0) const
std::vector< const TiffIFD * > getIFDsWithTag(TiffTag tag) const
std::map< TiffTag, TiffEntryOwner > entries
void recursivelyCheckSubIFDs(int headroom) const
TiffEntry * getEntry(TiffTag tag) const
void checkSubIFDs(int headroom) const
TiffRootIFDOwner parseMakerNote(NORangesSet< Buffer > *ifds, const TiffEntry *t)
void add(TiffIFDOwner subIFD)
void parseIFDEntry(NORangesSet< Buffer > *ifds, ByteStream &bs)
void recursivelyIncrementSubIFDCount()
void anchor() const override
std::unique_ptr< TiffIFD > TiffIFDOwner
std::string trimSpaces(std::string_view str)
std::unique_ptr< TiffRootIFD > TiffRootIFDOwner
Endianness getTiffByteOrder(ByteStream bs, uint32_t pos, const char *context="")
std::unique_ptr< TiffEntry > TiffEntryOwner
static constexpr int RecursiveSubIFDCount
static constexpr int SubIFDCount
static constexpr int Depth