RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
TiffParser.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5 Copyright (C) 2014 Pedro CĂ´rte-Real
6 Copyright (C) 2017 Axel Waggershauser
7 Copyright (C) 2017 Roman Lebedev
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22*/
23
24#include "parsers/TiffParser.h"
25#include "adt/NORangesSet.h"
26#include "decoders/ArwDecoder.h"
27#include "decoders/Cr2Decoder.h"
28#include "decoders/DcrDecoder.h"
29#include "decoders/DcsDecoder.h"
30#include "decoders/DngDecoder.h"
31#include "decoders/ErfDecoder.h"
32#include "decoders/IiqDecoder.h"
33#include "decoders/KdcDecoder.h"
34#include "decoders/MefDecoder.h"
35#include "decoders/MosDecoder.h"
36#include "decoders/NefDecoder.h"
37#include "decoders/OrfDecoder.h"
38#include "decoders/PefDecoder.h"
39#include "decoders/Rw2Decoder.h"
40#include "decoders/SrwDecoder.h"
41#include "decoders/StiDecoder.h"
43#include "io/Buffer.h"
44#include "io/ByteStream.h"
45#include "io/Endianness.h"
46#include "parsers/RawParser.h"
48#include "tiff/TiffIFD.h"
49#include <array>
50#include <cassert>
51#include <cstdint>
52#include <memory>
53#include <tuple>
54#include <utility>
55#include <vector>
56
57namespace rawspeed {
58class RawDecoder;
59
61
62std::unique_ptr<RawDecoder> TiffParser::getDecoder(const CameraMetaData* meta) {
64}
65
68 bs.setByteOrder(getTiffByteOrder(bs, 0, "TIFF header"));
69 bs.skipBytes(2);
70
71 if (uint16_t magic = bs.getU16();
72 magic != 42 && magic != 0x4f52 && magic != 0x5352 &&
73 magic != 0x55) // ORF has 0x4f52/0x5352, RW2 0x55 - Brilliant!
74 ThrowTPE("Not a TIFF file (magic 42)");
75
76 auto root = std::make_unique<TiffRootIFD>(
77 parent, nullptr, bs,
78 UINT32_MAX); // tell TiffIFD constructor not to parse bs as IFD
79
81
82 for (uint32_t IFDOffset = bs.getU32(); IFDOffset;
83 IFDOffset = root->getSubIFDs().back()->getNextIFD()) {
84 std::unique_ptr<TiffIFD> subIFD;
85 try {
86 subIFD = std::make_unique<TiffIFD>(root.get(), &ifds, bs, IFDOffset);
87 } catch (const TiffParserException&) {
88 // This IFD may fail to parse, in which case exit the loop,
89 // because the offset to the next IFD is last 4 bytes of an IFD,
90 // and we didn't get them because the IFD failed to parse.
91 // BUT: don't discard the IFD's that did succeed to parse!
92 break;
93 }
94 assert(subIFD.get());
95 root->add(std::move(subIFD));
96 }
97
98 return root;
99}
100
101std::unique_ptr<RawDecoder> TiffParser::makeDecoder(TiffRootIFDOwner root,
102 Buffer data) {
103 if (!root)
104 ThrowTPE("TiffIFD is null.");
105
106 for (const auto& decoder : Map) {
107 checker_t dChecker = nullptr;
108 constructor_t dConstructor = nullptr;
109
110 std::tie(dChecker, dConstructor) = decoder;
111
112 assert(dChecker);
113 assert(dConstructor);
114
115 if (!dChecker(root.get(), data))
116 continue;
117
118 return dConstructor(std::move(root), data);
119 }
120
121 ThrowTPE("No decoder found. Sorry.");
122}
123
124template <class Decoder>
125std::unique_ptr<RawDecoder> TiffParser::constructor(TiffRootIFDOwner&& root,
126 Buffer data) {
127 return std::make_unique<Decoder>(std::move(root), data);
128}
129
130#define DECODER(name) \
131 {std::make_pair( \
132 static_cast<TiffParser::checker_t>(&name::isAppropriateDecoder), \
133 &constructor<name>)}
134
135const std::array<std::pair<TiffParser::checker_t, TiffParser::constructor_t>,
136 17>
137 TiffParser::Map = {{
138 DECODER(DngDecoder),
139 DECODER(MosDecoder),
140 DECODER(IiqDecoder),
141 DECODER(Cr2Decoder),
142 DECODER(NefDecoder),
143 DECODER(OrfDecoder),
144 DECODER(ArwDecoder),
145 DECODER(PefDecoder),
146 DECODER(Rw2Decoder),
147 DECODER(SrwDecoder),
148 DECODER(MefDecoder),
149 DECODER(DcrDecoder),
150 DECODER(DcsDecoder),
151 DECODER(KdcDecoder),
152 DECODER(ErfDecoder),
153 DECODER(StiDecoder),
154 DECODER(ThreefrDecoder),
155
156 }};
157
158} // namespace rawspeed
#define DECODER(name)
#define ThrowTPE(...)
assert(dim.area() >=area)
void skipBytes(size_type nbytes)
Definition ByteStream.h:130
Endianness setByteOrder(Endianness endianness_)
Definition Buffer.h:156
RawParser(Buffer inputData)
Definition RawParser.h:33
std::unique_ptr< RawDecoder >(*)(TiffRootIFDOwner &&root, Buffer data) constructor_t
Definition TiffParser.h:56
static TiffRootIFDOwner parse(TiffIFD *parent, Buffer data)
static const std::array< std::pair< checker_t, constructor_t >, 17 > Map
Definition TiffParser.h:58
std::unique_ptr< RawDecoder > getDecoder(const CameraMetaData *meta=nullptr) override
TiffParser(Buffer file)
static std::unique_ptr< RawDecoder > makeDecoder(TiffRootIFDOwner root, Buffer data)
static std::unique_ptr< RawDecoder > constructor(TiffRootIFDOwner &&root, Buffer data)
bool(*)(const TiffRootIFD *root, Buffer data) checker_t
Definition TiffParser.h:55
std::unique_ptr< TiffRootIFD > TiffRootIFDOwner
Definition TiffIFD.h:46
Endianness getTiffByteOrder(ByteStream bs, uint32_t pos, const char *context="")
Definition TiffIFD.h:153