RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
TiffIFD.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5 Copyright (C) 2017 Axel Waggershauser
6 Copyright (C) 2018 Roman Lebedev
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21*/
22
23#pragma once
24
25#include "rawspeedconfig.h"
26#include "adt/NORangesSet.h"
27#include "io/Buffer.h"
28#include "io/ByteStream.h"
29#include "io/Endianness.h"
31#include "tiff/TiffEntry.h"
32#include "tiff/TiffTag.h"
33#include <cstdint>
34#include <map>
35#include <memory>
36#include <string>
37#include <vector>
38
39namespace rawspeed {
40
41class TiffIFD;
42class TiffRootIFD;
43template <typename T> class NORangesSet;
44
45using TiffIFDOwner = std::unique_ptr<TiffIFD>;
46using TiffRootIFDOwner = std::unique_ptr<TiffRootIFD>;
47using TiffEntryOwner = std::unique_ptr<TiffEntry>;
48
49class TiffIFD {
51
53
54 std::vector<TiffIFDOwner> subIFDs;
55
56 int subIFDCount = 0;
58
59 std::map<TiffTag, TiffEntryOwner> entries;
60
61 virtual void anchor() const;
62
63 friend class TiffEntry;
64 friend class FiffParser;
65 friend class TiffParser;
66
68 void checkSubIFDs(int headroom) const;
69 void recursivelyCheckSubIFDs(int headroom) const;
70
71 void add(TiffIFDOwner subIFD);
72 void add(TiffEntryOwner entry);
74 const TiffEntry* t);
76
77 // TIFF IFD are tree-like structure, with branches.
78 // A branch (IFD) can have branches (IFDs) of it's own.
79 // We must be careful to weed-out all the degenerative cases that
80 // can be produced e.g. via fuzzing, or other means.
81 struct Limits final {
82 // How many layers of IFD's can there be?
83 // All RPU samples (as of 2018-02-11) are ok with 4.
84 // However, let's be on the safe side, and pad it by one.
85 static constexpr int Depth = 4 + 1;
86
87 // How many sub-IFD's can this IFD have?
88 // NOTE: only for the given IFD, *NOT* recursively including all sub-IFD's!
89 // All RPU samples (as of 2018-02-11) are ok with 5.
90 // However, let's be on the safe side, and double it.
91 static constexpr int SubIFDCount = 5 * 2;
92
93 // How many sub-IFD's can this IFD have, recursively?
94 // All RPU samples (as of 2018-02-11) are ok with 14.
95 // However, let's be on the safe side, and double it.
96 static constexpr int RecursiveSubIFDCount = 14 * 2;
97 };
98
99public:
100 explicit TiffIFD(TiffIFD* parent);
101
103 uint32_t offset);
104
105 virtual ~TiffIFD() = default;
106
107 // make sure we never copy-constuct/assign a TiffIFD to keep the owning
108 // subcontainers contents save
109 TiffIFD(const TiffIFD&) = delete;
110 TiffIFD& operator=(const TiffIFD&) = delete;
111
112 [[nodiscard]] uint32_t getNextIFD() const { return nextIFD; }
113 [[nodiscard]] std::vector<const TiffIFD*> getIFDsWithTag(TiffTag tag) const;
114 [[nodiscard]] const TiffIFD* getIFDWithTag(TiffTag tag,
115 uint32_t index = 0) const;
116 [[nodiscard]] TiffEntry* getEntry(TiffTag tag) const;
117 [[nodiscard]] TiffEntry* RAWSPEED_READONLY
118 getEntryRecursive(TiffTag tag) const;
119 [[nodiscard]] bool RAWSPEED_READONLY hasEntry(TiffTag tag) const {
120 return entries.contains(tag);
121 }
122 [[nodiscard]] bool hasEntryRecursive(TiffTag tag) const {
123 return getEntryRecursive(tag) != nullptr;
124 }
125
126 [[nodiscard]] const std::vector<TiffIFDOwner>& getSubIFDs() const {
127 return subIFDs;
128 }
129 // const std::map<TiffTag, TiffEntry*>& getEntries() const { return entries;
130 // }
131};
132
133struct TiffID final {
134 std::string make;
135 std::string model;
136};
137
138class TiffRootIFD final : public TiffIFD {
139 void anchor() const override;
140
141public:
143
145 uint32_t offset)
146 : TiffIFD(parent_, ifds, data, offset), rootBuffer(data) {}
147
148 // find the MAKE and MODEL tags identifying the camera
149 // note: the returned strings are trimmed automatically
150 [[nodiscard]] TiffID getID() const;
151};
152
154 const char* context = "") {
155 if (bs.hasPatternAt("II", pos))
156 return Endianness::little;
157 if (bs.hasPatternAt("MM", pos))
158 return Endianness::big;
159
160 ThrowTPE("Failed to parse TIFF endianness information in %s.", context);
161}
162
163} // namespace rawspeed
#define ThrowTPE(...)
bool hasPatternAt(std::string_view pattern, size_type relPos) const
Definition ByteStream.h:135
Definition TiffEntry.h:62
friend class FiffParser
Definition TiffIFD.h:64
TiffIFD(TiffIFD *parent)
Definition TiffIFD.cpp:103
std::vector< TiffIFDOwner > subIFDs
Definition TiffIFD.h:54
TiffEntry *RAWSPEED_READONLY getEntryRecursive(TiffTag tag) const
Definition TiffIFD.cpp:246
virtual void anchor() const
Definition TiffIFD.cpp:48
const TiffIFD * getIFDWithTag(TiffTag tag, uint32_t index=0) const
Definition TiffIFD.cpp:238
TiffIFD & operator=(const TiffIFD &)=delete
uint32_t getNextIFD() const
Definition TiffIFD.h:112
std::vector< const TiffIFD * > getIFDsWithTag(TiffTag tag) const
Definition TiffIFD.cpp:226
std::map< TiffTag, TiffEntryOwner > entries
Definition TiffIFD.h:59
bool RAWSPEED_READONLY hasEntry(TiffTag tag) const
Definition TiffIFD.h:119
void recursivelyCheckSubIFDs(int headroom) const
Definition TiffIFD.cpp:283
const std::vector< TiffIFDOwner > & getSubIFDs() const
Definition TiffIFD.h:126
uint32_t nextIFD
Definition TiffIFD.h:50
TiffEntry * getEntry(TiffTag tag) const
Definition TiffIFD.cpp:313
int subIFDCountRecursive
Definition TiffIFD.h:57
friend class TiffParser
Definition TiffIFD.h:65
void checkSubIFDs(int headroom) const
Definition TiffIFD.cpp:269
TiffRootIFDOwner parseMakerNote(NORangesSet< Buffer > *ifds, const TiffEntry *t)
Definition TiffIFD.cpp:142
friend class TiffEntry
Definition TiffIFD.h:63
void add(TiffIFDOwner subIFD)
Definition TiffIFD.cpp:299
TiffIFD(const TiffIFD &)=delete
bool hasEntryRecursive(TiffTag tag) const
Definition TiffIFD.h:122
TiffIFD *const parent
Definition TiffIFD.h:52
void parseIFDEntry(NORangesSet< Buffer > *ifds, ByteStream &bs)
Definition TiffIFD.cpp:53
virtual ~TiffIFD()=default
void recursivelyIncrementSubIFDCount()
Definition TiffIFD.cpp:258
const DataBuffer rootBuffer
Definition TiffIFD.h:142
TiffRootIFD(TiffIFD *parent_, NORangesSet< Buffer > *ifds, DataBuffer data, uint32_t offset)
Definition TiffIFD.h:144
void anchor() const override
Definition TiffIFD.cpp:320
TiffID getID() const
Definition TiffIFD.cpp:325
std::unique_ptr< TiffIFD > TiffIFDOwner
Definition TiffIFD.h:45
std::unique_ptr< TiffRootIFD > TiffRootIFDOwner
Definition TiffIFD.h:46
Endianness getTiffByteOrder(ByteStream bs, uint32_t pos, const char *context="")
Definition TiffIFD.h:153
std::unique_ptr< TiffEntry > TiffEntryOwner
Definition TiffIFD.h:47
std::string model
Definition TiffIFD.h:135
std::string make
Definition TiffIFD.h:134
static constexpr int RecursiveSubIFDCount
Definition TiffIFD.h:96
static constexpr int SubIFDCount
Definition TiffIFD.h:91
static constexpr int Depth
Definition TiffIFD.h:85