libopenraw
raffile.cpp
1 /*
2  * libopenraw - raffile.cpp
3  *
4  * Copyright (C) 2011-2016 Hubert Figuière
5  *
6  * This library is free software: you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation, either version 3 of
9  * the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <stddef.h>
22 #include <sys/types.h>
23 #include <algorithm>
24 #include <cstdint>
25 
26 #include <memory>
27 
28 #include <libopenraw/cameraids.h>
29 #include <libopenraw/debug.h>
30 #include <libopenraw/metadata.h>
31 
32 #include "rawdata.hpp"
33 #include "rawfile.hpp"
34 #include "metavalue.hpp"
35 
36 #include "ifd.hpp"
37 #include "ifddir.hpp"
38 #include "ifdentry.hpp"
39 #include "rawfile_private.hpp"
40 #include "raffile.hpp"
41 #include "rafcontainer.hpp"
42 #include "rafmetacontainer.hpp"
43 #include "jfifcontainer.hpp"
44 #include "unpack.hpp"
45 #include "trace.hpp"
46 #include "io/streamclone.hpp"
47 #include "xtranspattern.hpp"
48 
49 namespace OpenRaw {
50 namespace Internals {
51 
52 #define OR_MAKE_FUJIFILM_TYPEID(camid) \
53  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_FUJIFILM, camid)
54 
55 /* taken from dcraw, by default */
56 static const BuiltinColourMatrix s_matrices[] = {
57  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_F700),
58  0,
59  0,
60  { 10004, -3219, -1201, -7036, 15047, 2107, -1863, 2565, 7736 } },
61  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_F810),
62  0,
63  0,
64  { 11044, -3888, -1120, -7248, 15168, 2208, -1531, 2277, 8069 } },
65  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_E900),
66  0,
67  0,
68  { 9183, -2526, -1078, -7461, 15071, 2574, -2022, 2440, 8639 } },
69  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S2PRO),
70  128,
71  0,
72  { 12492, -4690, -1402, -7033, 15423, 1647, -1507, 2111, 7697 } },
73  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S3PRO),
74  0,
75  0,
76  { 11807, -4612, -1294, -8927, 16968, 1988, -2120, 2741, 8006 } },
77  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S5PRO),
78  0,
79  0,
80  { 12300, -5110, -1304, -9117, 17143, 1998, -1947, 2448, 8100 } },
81  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S5600),
82  0,
83  0,
84  { 9636, -2804, -988, -7442, 15040, 2589, -1803, 2311, 8621 } },
85  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S9500),
86  0,
87  0,
88  { 10491, -3423, -1145, -7385, 15027, 2538, -1809, 2275, 8692 } },
89  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S6500FD),
90  0,
91  0,
92  { 12628, -4887, -1401, -6861, 14996, 1962, -2198, 2782, 7091 } },
93  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_HS10),
94  0,
95  0xf68,
96  { 12440, -3954, -1183, -1123, 9674, 1708, -83, 1614, 4086 } },
97  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100),
98  0,
99  0,
100  { 12161, -4457, -1069, -5034, 12874, 2400, -795, 1724, 6904 } },
101  // From DNG Convert 7.4
102  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100S),
103  0,
104  0,
105  { 10592, -4262, -1008, -3514, 11355, 2465, -870, 2025, 6386 } },
106  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X10),
107  0,
108  0,
109  { 13509, -6199, -1254, -4430, 12733, 1865, -331, 1441, 5022 } },
110  // From DNG Convert 7.4
111  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X20),
112  0,
113  0,
114  { 11768, -4971, -1133, -4904, 12927, 2183, -480, 1723, 4605 } },
115  // From DNG Convert 8.7-rc
116  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X30),
117  0,
118  0,
119  { 12328, -5256, -1144, -4469, 12927, 1675, -87, 1291, 4351 } },
120  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO1),
121  0,
122  0,
123  { 10413, -3996, -993, -3721, 11640, 2361, -733, 1540, 6011 } },
124  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE1),
125  0,
126  0,
127  { 10413, -3996, -993, -3721, 11640, 2361, -733, 1540, 6011 } },
128  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2),
129  0,
130  0,
131  { 8458, -2451, -855, -4597, 12447, 2407, -1475, 2482, 6526 } },
132  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XM1),
133  0,
134  0,
135  { 10413, -3996, -993, -3721, 11640, 2361, -733, 1540, 6011 } },
136  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT1),
137  0,
138  0,
139  { 8458, -2451, -855, -4597, 12447, 2407, -1475, 2482, 6526 } },
140  // From DNG Converter 7.1-rc
141  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XS1),
142  0,
143  0,
144  { 13509, -6199, -1254, -4430, 12733, 1865, -331, 1441, 5022 } },
145  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XF1),
146  0,
147  0,
148  { 13509, -6199, -1254, -4430, 12733, 1865, -331, 1441, 5022 } },
149  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S200EXR),
150  512,
151  0x3fff,
152  { 11401, -4498, -1312, -5088, 12751, 2613, -838, 1568, 5941 } },
153 
154  { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
155 };
156 
157 const RawFile::camera_ids_t RafFile::s_def[] = {
158  { "FinePix F700 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_F700) },
159  { "FinePix F810 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_F810) },
160  { "FinePix E900 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_E900) },
161  { "FinePixS2Pro", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S2PRO) },
162  { "FinePix S3Pro ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S3PRO) },
163  { "FinePix S5Pro ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S5PRO) },
164  { "FinePix S5600 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S5600) },
165  { "FinePix S9500 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S9500) },
166  { "FinePix S6500fd", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S6500FD) },
167  { "FinePix HS10 HS11", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_HS10) },
168  { "FinePix X100", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100) },
169  { "X10", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X10) },
170  { "X20", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X20) },
171  { "X30", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X30) },
172  { "X-Pro1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO1) },
173  { "X-S1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XS1) },
174  { "FinePix S200EXR", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S200EXR) },
175  { "X-A1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA1) },
176  { "XQ1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XQ1) },
177  { "X-E1 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE1) },
178  { "X-E2", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2) },
179  { "X-M1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XM1) },
180  { "X-T1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT1) },
181  { "X-T10", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT10) },
182  { "XF1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XF1) },
183  { "X100S", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100S) },
184  { "X100T", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100T) },
185  { nullptr, 0 }
186 };
187 
188 RawFile *RafFile::factory(const IO::Stream::Ptr &s)
189 {
190  return new RafFile(s);
191 }
192 
193 RafFile::RafFile(const IO::Stream::Ptr &s)
194  : RawFile(OR_RAWFILE_TYPE_RAF), m_io(s), m_container(new RafContainer(s))
195 {
196  _setIdMap(s_def);
197  _setMatrices(s_matrices);
198 }
199 
200 RafFile::~RafFile()
201 {
202  delete m_container;
203 }
204 
205 ::or_error RafFile::_enumThumbnailSizes(std::vector<uint32_t> &list)
206 {
207  or_error ret = OR_ERROR_NOT_FOUND;
208 
209  JfifContainer *jpegPreview = m_container->getJpegPreview();
210  if (!jpegPreview) {
211  return ret;
212  }
213 
214  uint32_t x, y;
215  if (jpegPreview->getDimensions(x, y)) {
216  uint32_t size = std::max(x, y);
217 
218  list.push_back(size);
219  _addThumbnail(size, ThumbDesc(x, y, OR_DATA_TYPE_JPEG,
220  m_container->getJpegOffset(),
221  m_container->getJpegLength()));
222  ret = OR_ERROR_NONE;
223  }
224  IfdDir::Ref dir = jpegPreview->getIfdDirAt(1);
225  if (!dir) {
226  return ret;
227  }
228 
229  bool got_it = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_WIDTH, x);
230 
231  if (got_it) {
232  got_it = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_LENGTH, y);
233  }
234 
235  if (!got_it) {
236  uint32_t jpeg_offset = 0;
237  uint32_t jpeg_size = 0;
238  got_it =
239  dir->getValue(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT, jpeg_offset);
240 
241  if (!got_it) {
242  return ret;
243  }
244 
245  jpeg_offset += 12; // magic number. uh?
246  // I need to re-read the Exif spec.
247  got_it = dir->getValue(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
248  jpeg_size);
249 
250  if (!got_it) {
251  return ret;
252  }
253 
254  IO::Stream::Ptr s(std::make_shared<IO::StreamClone>(jpegPreview->file(),
255  jpeg_offset));
256  std::unique_ptr<JfifContainer> thumb(new JfifContainer(s, 0));
257 
258  if (thumb->getDimensions(x, y)) {
259  uint32_t size = std::max(x, y);
260 
261  list.push_back(size);
262  _addThumbnail(size,
263  ThumbDesc(x, y, OR_DATA_TYPE_JPEG,
264  jpeg_offset + m_container->getJpegOffset(),
265  jpeg_size));
266  ret = OR_ERROR_NONE;
267  }
268  }
269 
270  return ret;
271 }
272 
274 {
275  return m_container;
276 }
277 
278 ::or_error RafFile::_getRawData(RawData &data, uint32_t /*options*/)
279 {
280  ::or_error ret = OR_ERROR_NOT_FOUND;
281 
282  RafMetaContainer *meta = m_container->getMetaContainer();
283 
284  RafMetaValue::Ref value = meta->getValue(RAF_TAG_SENSOR_DIMENSION);
285  if (!value) {
286  // use this tag if the other is missing
287  value = meta->getValue(RAF_TAG_IMG_HEIGHT_WIDTH);
288  }
289  uint32_t dims = value->get().getInteger(0);
290  uint16_t h = (dims & 0xFFFF0000) >> 16;
291  uint16_t w = (dims & 0x0000FFFF);
292 
293  value = meta->getValue(RAF_TAG_RAW_INFO);
294  uint32_t rawProps = value->get().getInteger(0);
295  // TODO re-enable if needed.
296  // uint8_t layout = (rawProps & 0xFF000000) >> 24 >> 7; // MSBit in byte.
297  uint8_t compressed = ((rawProps & 0xFF0000) >> 16) & 8; // 8 == compressed
298 
299  // printf("layout %x - compressed %x\n", layout, compressed);
300 
301  data.setDataType(OR_DATA_TYPE_RAW);
302  data.setDimensions(w, h);
303  switch (typeId()) {
304  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO1):
305  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE1):
306  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2):
307  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XM1):
308  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XQ1):
309  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT1):
310  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT10):
311  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100S):
312  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100T):
313  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X20):
314  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X30):
315  data.setCfaPattern(XTransPattern::xtransPattern());
316  break;
317  default:
318  // TODO get the right pattern.
319  data.setCfaPatternType(OR_CFA_PATTERN_GBRG);
320  }
321  // TODO actually read the 2048.
322  // TODO make sure this work for the other file formats...
323  size_t byte_size = m_container->getCfaLength() - 2048;
324  size_t fetched = 0;
325  off_t offset = m_container->getCfaOffset() + 2048;
326 
327  uint32_t finaldatalen = 2 * h * w;
328  bool is_compressed = byte_size < finaldatalen; //(compressed == 8);
329  uint32_t datalen = (is_compressed ? byte_size : finaldatalen);
330  void *buf = data.allocData(finaldatalen);
331 
332  Debug::Trace(DEBUG2) << "byte_size = " << byte_size
333  << " finaldatalen = " << finaldatalen
334  << " compressed = " << compressed << "\n";
335 
336  ret = OR_ERROR_NONE;
337 
338  if (is_compressed) {
339  Unpack unpack(w, IFD::COMPRESS_NONE);
340  size_t blocksize = unpack.block_size();
341  std::unique_ptr<uint8_t[]> block(new uint8_t[blocksize]);
342  uint8_t *outdata = (uint8_t *)data.data();
343  size_t outsize = finaldatalen;
344  size_t got;
345  do {
346  // Debug::Trace(DEBUG2) << "fatchData @offset " << offset <<
347  // "\n";
348  got = m_container->fetchData(block.get(), offset, blocksize);
349  fetched += got;
350  offset += got;
351  // Debug::Trace(DEBUG2) << "got " << got << "\n";
352  if (got) {
353  size_t out;
354  or_error err = unpack.unpack_be12to16(outdata, outsize,
355  block.get(), got, out);
356  outdata += out;
357  outsize -= out;
358  // Debug::Trace(DEBUG2) << "unpacked " << out
359  // << " bytes from " << got << "\n";
360  if (err != OR_ERROR_NONE) {
361  Debug::Trace(DEBUG2) << "error is " << err << "\n";
362  ret = err;
363  break;
364  }
365  // Debug::Trace(DEBUG2) << "got = " << got
366  // << " fetched = " << fetched
367  // << " datalen = " << datalen <<
368  // "\n";
369  }
370  } while ((got != 0) && (fetched < datalen));
371  } else {
372  m_container->fetchData(buf, offset, datalen);
373  }
374 
375  return ret;
376 }
377 
378 MetaValue *RafFile::_getMetaValue(int32_t meta_index)
379 {
380  if (META_INDEX_MASKOUT(meta_index) == META_NS_EXIF ||
381  META_INDEX_MASKOUT(meta_index) == META_NS_TIFF) {
382 
383  JfifContainer *jpegPreview = m_container->getJpegPreview();
384  IfdDir::Ref dir = jpegPreview->mainIfd();
385  IfdEntry::Ref e = dir->getEntry(META_NS_MASKOUT(meta_index));
386  if (e) {
387  return e->make_meta_value();
388  }
389  }
390 
391  return nullptr;
392 }
393 
394 void RafFile::_identifyId()
395 {
396  _setTypeId(_typeIdFromModel("FujiFilm", m_container->getModel()));
397 }
398 }
399 }
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
Definition: arwfile.cpp:30
or_error unpack_be12to16(uint8_t *dest, size_t destsize, const uint8_t *src, size_t size, size_t &outsize)
Definition: unpack.cpp:58
virtual ::or_error _getRawData(RawData &data, uint32_t options) override
Definition: raffile.cpp:278
std::shared_ptr< IfdEntry > Ref
Definition: ifdentry.hpp:178
virtual RawContainer * getContainer() const override
Definition: raffile.cpp:273
void setDataType(DataType _type)
Definition: bitmapdata.cpp:100
virtual ::or_error _enumThumbnailSizes(std::vector< uint32_t > &list) override
Definition: raffile.cpp:205
virtual void setDimensions(uint32_t x, uint32_t y) override
Definition: rawdata.cpp:260