1 /*
2     RawSpeed - RAW file decoder.
3 
4     Copyright (C) 2009-2014 Klaus Post
5     Copyright (C) 2017 Axel Waggershauser
6     Copyright (C) 2017-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 #include "parsers/FiffParser.h"
24 #include "decoders/RafDecoder.h"         // for RafDecoder
25 #include "decoders/RawDecoder.h"         // for RawDecoder
26 #include "io/Buffer.h"                   // for Buffer, DataBuffer
27 #include "io/ByteStream.h"               // for ByteStream
28 #include "io/Endianness.h"               // for Endianness, Endianness::big
29 #include "parsers/FiffParserException.h" // for ThrowFPE
30 #include "parsers/RawParser.h"           // for RawParser
31 #include "parsers/TiffParser.h"          // for TiffParser
32 #include "parsers/TiffParserException.h" // for TiffParserException
33 #include "tiff/TiffEntry.h" // for TiffEntry, TiffDataType::SHORT, TIFF...
34 #include "tiff/TiffIFD.h"                // for TiffIFD, TiffRootIFDOwner
35 #include "tiff/TiffTag.h"                // for FUJIOLDWB, FUJI_STRIPBYTECO...
36 #include <cstdint>                       // for uint32_t, uint16_t
37 #include <limits>                        // for numeric_limits
38 #include <memory>                        // for make_unique, unique_ptr
39 #include <utility>                       // for move
40 
41 using std::numeric_limits;
42 
43 namespace rawspeed {
44 
FiffParser(const Buffer & inputData)45 FiffParser::FiffParser(const Buffer& inputData) : RawParser(inputData) {}
46 
parseData()47 void FiffParser::parseData() {
48   ByteStream bs(DataBuffer(mInput, Endianness::big));
49   bs.skipBytes(0x54);
50 
51   uint32_t first_ifd = bs.getU32();
52   if (first_ifd >= numeric_limits<uint32_t>::max() - 12)
53     ThrowFPE("Not Fiff. First IFD too far away");
54 
55   first_ifd += 12;
56 
57   bs.skipBytes(4);
58   const uint32_t third_ifd = bs.getU32();
59   bs.skipBytes(4);
60   const uint32_t second_ifd = bs.getU32();
61 
62   rootIFD = TiffParser::parse(nullptr, mInput.getSubView(first_ifd));
63   auto subIFD = std::make_unique<TiffIFD>(rootIFD.get());
64 
65   if (mInput.isValid(second_ifd)) {
66     // RAW Tiff on newer models, pointer to raw data on older models
67     // -> so we try parsing as Tiff first and add it as data if parsing fails
68     try {
69       rootIFD->add(
70           TiffParser::parse(rootIFD.get(), mInput.getSubView(second_ifd)));
71     } catch (const TiffParserException&) {
72       // the offset will be interpreted relative to the rootIFD where this
73       // subIFD gets inserted
74 
75       if (second_ifd <= first_ifd)
76         ThrowFPE("Fiff is corrupted: second IFD is not after the first IFD");
77 
78       uint32_t rawOffset = second_ifd - first_ifd;
79       subIFD->add(std::make_unique<TiffEntry>(
80           subIFD.get(), TiffTag::FUJI_STRIPOFFSETS, TiffDataType::OFFSET, 1,
81           ByteStream::createCopy(&rawOffset, 4)));
82       uint32_t max_size = mInput.getSize() - second_ifd;
83       subIFD->add(std::make_unique<TiffEntry>(
84           subIFD.get(), TiffTag::FUJI_STRIPBYTECOUNTS, TiffDataType::LONG, 1,
85           ByteStream::createCopy(&max_size, 4)));
86     }
87   }
88 
89   if (mInput.isValid(third_ifd)) {
90     // RAW information IFD on older
91 
92     // This Fuji directory structure is similar to a Tiff IFD but with two
93     // differences:
94     //   a) no type info and b) data is always stored in place.
95     // 4b: # of entries, for each entry: 2b tag, 2b len, xb data
96     ByteStream bytes(DataBuffer(mInput.getSubView(third_ifd), Endianness::big));
97     uint32_t entries = bytes.getU32();
98 
99     if (entries > 255)
100       ThrowFPE("Too many entries");
101 
102     for (uint32_t i = 0; i < entries; i++) {
103       auto tag = static_cast<TiffTag>(bytes.getU16());
104       uint16_t length = bytes.getU16();
105       TiffDataType type = TiffDataType::UNDEFINED;
106 
107       if (tag == TiffTag::IMAGEWIDTH ||
108           tag == TiffTag::FUJIOLDWB) // also 0x121?
109         type = TiffDataType::SHORT;
110 
111       uint32_t count = type == TiffDataType::SHORT ? length / 2 : length;
112       subIFD->add(std::make_unique<TiffEntry>(
113           subIFD.get(), tag, type, count,
114           bytes.getSubStream(bytes.getPosition(), length)));
115 
116       bytes.skipBytes(length);
117     }
118   }
119 
120   rootIFD->add(move(subIFD));
121 }
122 
getDecoder(const CameraMetaData * meta)123 std::unique_ptr<RawDecoder> FiffParser::getDecoder(const CameraMetaData* meta) {
124   if (!rootIFD)
125     parseData();
126 
127   // WARNING: do *NOT* fallback to ordinary TIFF parser here!
128   // All the FIFF raws are '.RAF' (Fujifilm). Do use RafDecoder directly.
129 
130   try {
131     if (!RafDecoder::isAppropriateDecoder(rootIFD.get(), mInput))
132       ThrowFPE("Not a FUJIFILM RAF FIFF.");
133 
134     return std::make_unique<RafDecoder>(std::move(rootIFD), mInput);
135   } catch (const TiffParserException&) {
136     ThrowFPE("No decoder found. Sorry.");
137   }
138 }
139 
140 } // namespace rawspeed
141