libopenraw
raffile.cpp
1 /* -*- mode:c++; tab-width:4; c-basic-offset:4 -*- */
2 /*
3  * libopenraw - raffile.cpp
4  *
5  * Copyright (C) 2011-2018 Hubert Figuière
6  *
7  * This library is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation, either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <stddef.h>
23 #include <sys/types.h>
24 #include <algorithm>
25 #include <cstdint>
26 
27 #include <memory>
28 
29 #include <libopenraw/cameraids.h>
30 #include <libopenraw/debug.h>
31 #include <libopenraw/metadata.h>
32 
33 #include "rawdata.hpp"
34 #include "rawfile.hpp"
35 #include "metavalue.hpp"
36 
37 #include "ifd.hpp"
38 #include "ifddir.hpp"
39 #include "ifdentry.hpp"
40 #include "rawfile_private.hpp"
41 #include "raffile.hpp"
42 #include "rafcontainer.hpp"
43 #include "rafmetacontainer.hpp"
44 #include "jfifcontainer.hpp"
45 #include "unpack.hpp"
46 #include "trace.hpp"
47 #include "io/streamclone.hpp"
48 #include "xtranspattern.hpp"
49 
50 namespace OpenRaw {
51 namespace Internals {
52 
53 #define OR_MAKE_FUJIFILM_TYPEID(camid) \
54  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_FUJIFILM, camid)
55 
56 /* taken from dcraw, by default */
57 static const BuiltinColourMatrix s_matrices[] = {
58  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_F700),
59  0,
60  0,
61  { 10004, -3219, -1201, -7036, 15047, 2107, -1863, 2565, 7736 } },
62  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_F810),
63  0,
64  0,
65  { 11044, -3888, -1120, -7248, 15168, 2208, -1531, 2277, 8069 } },
66  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_E900),
67  0,
68  0,
69  { 9183, -2526, -1078, -7461, 15071, 2574, -2022, 2440, 8639 } },
70  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S2PRO),
71  128,
72  0,
73  { 12492, -4690, -1402, -7033, 15423, 1647, -1507, 2111, 7697 } },
74  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S3PRO),
75  0,
76  0,
77  { 11807, -4612, -1294, -8927, 16968, 1988, -2120, 2741, 8006 } },
78  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S5PRO),
79  0,
80  0,
81  { 12300, -5110, -1304, -9117, 17143, 1998, -1947, 2448, 8100 } },
82  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S5600),
83  0,
84  0,
85  { 9636, -2804, -988, -7442, 15040, 2589, -1803, 2311, 8621 } },
86  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S9500),
87  0,
88  0,
89  { 10491, -3423, -1145, -7385, 15027, 2538, -1809, 2275, 8692 } },
90  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S6500FD),
91  0,
92  0,
93  { 12628, -4887, -1401, -6861, 14996, 1962, -2198, 2782, 7091 } },
94  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_HS10),
95  0,
96  0xf68,
97  { 12440, -3954, -1183, -1123, 9674, 1708, -83, 1614, 4086 } },
98  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100),
99  0,
100  0,
101  { 12161, -4457, -1069, -5034, 12874, 2400, -795, 1724, 6904 } },
102  // From DNG Convert 7.4
103  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100S),
104  0,
105  0,
106  { 10592, -4262, -1008, -3514, 11355, 2465, -870, 2025, 6386 } },
107  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100T),
108  0,
109  0,
110  { 10592, -4262, -1008, -3514, 11355, 2465, -870, 2025, 6386 } },
111  // From DNG Converter 10.3
112  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100F),
113  0,
114  0,
115  { 11434, -4948, -1210, -3746, 12042, 1903, -666, 1479, 5235 } },
116  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X10),
117  0,
118  0,
119  { 13509, -6199, -1254, -4430, 12733, 1865, -331, 1441, 5022 } },
120  // From DNG Convert 7.4
121  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X20),
122  0,
123  0,
124  { 11768, -4971, -1133, -4904, 12927, 2183, -480, 1723, 4605 } },
125  // From DNG Convert 8.7-rc
126  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X30),
127  0,
128  0,
129  { 12328, -5256, -1144, -4469, 12927, 1675, -87, 1291, 4351 } },
130  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X70),
131  0,
132  0,
133  { 10450, -4329, -878, -3217, 11105, 2421, -752, 1758, 6519 } },
134  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO1),
135  0,
136  0,
137  { 10413, -3996, -993, -3721, 11640, 2361, -733, 1540, 6011 } },
138  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO2),
139  0,
140  0,
141  { 11434, -4948, -1210, -3746, 12042, 1903, -666, 1479, 5235 } },
142  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA1),
143  0,
144  0,
145  { 11086, -4555, -839, -3512, 11310, 2517, -815, 1341, 5940 } },
146  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA2),
147  0,
148  0,
149  { 10763, -4560, -917, -3346, 11311, 2322, -475, 1135, 5843 } },
150  // From DNG Converter 10.3
151  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA3),
152  0,
153  0,
154  { 12407, -5222, -1086, -2971, 11116, 2120, -294, 1029, 5284 } },
155  // From DNG Converter 10.3
156  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA5),
157  0,
158  0,
159  { 11673, -476, -1041, -3988, 12058, 2166, -771, 1417, 5569 } },
160  // From DNG Converter 10.3
161  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XQ1),
162  0,
163  0,
164  { 9252, -2704, -1064, -5893, 14265, 1717, -1101, 2341, 4349 } },
165  // From DNG Converter 10.3
166  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XQ2),
167  0,
168  0,
169  { 9252, -2704, -1064, -5893, 14265, 1717, -1101, 2341, 4349 } },
170  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE1),
171  0,
172  0,
173  { 10413, -3996, -993, -3721, 11640, 2361, -733, 1540, 6011 } },
174  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2),
175  0,
176  0,
177  { 8458, -2451, -855, -4597, 12447, 2407, -1475, 2482, 6526 } },
178  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2S),
179  0,
180  0,
181  { 11562, -5118, -961, -3022, 11007, 2311, -525, 1569, 6097 } },
182  // From DNG Converter 10.3
183  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE3),
184  0,
185  0,
186  { 11434, -4948, -1210, -3746, 12042, 1903, -666, 1479, 5235 } },
187  // From DNG Converter 10.3
188  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XH1),
189  0,
190  0,
191  { 11434, -4948, -1210, -3746, 12042, 1903, -666, 1479, 5235 } },
192  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XM1),
193  0,
194  0,
195  { 10413, -3996, -993, -3721, 11640, 2361, -733, 1540, 6011 } },
196  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT1),
197  0,
198  0,
199  { 8458, -2451, -855, -4597, 12447, 2407, -1475, 2482, 6526 } },
200  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT10),
201  0,
202  0,
203  { 8458, -2451, -855, -4597, 12447, 2407, -1475, 2482, 6526 } },
204  // From DNG Converter 10.3
205  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT2),
206  0,
207  0,
208  { 11434, -4948, -1210, -3746, 12042, 1903, -666, 1479, 5235 } },
209  // From DNG Converter 10.3
210  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT20),
211  0,
212  0,
213  { 11434, -4948, -1210, -3746, 12042, 1903, -666, 1479, 5235 } },
214  // From DNG Converter 7.1-rc
215  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XS1),
216  0,
217  0,
218  { 13509, -6199, -1254, -4430, 12733, 1865, -331, 1441, 5022 } },
219  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XF1),
220  0,
221  0,
222  { 13509, -6199, -1254, -4430, 12733, 1865, -331, 1441, 5022 } },
223  { OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S200EXR),
224  512,
225  0x3fff,
226  { 11401, -4498, -1312, -5088, 12751, 2613, -838, 1568, 5941 } },
227 
228  { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
229 };
230 
231 const RawFile::camera_ids_t RafFile::s_def[] = {
232  { "GFX 50S", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_GFX50S) },
233  { "FinePix F700 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_F700) },
234  { "FinePix F810 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_F810) },
235  { "FinePix E900 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_E900) },
236  { "FinePixS2Pro", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S2PRO) },
237  { "FinePix S3Pro ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S3PRO) },
238  { "FinePix S5Pro ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S5PRO) },
239  { "FinePix S5600 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S5600) },
240  { "FinePix S9500 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S9500) },
241  { "FinePix S6500fd", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S6500FD) },
242  { "FinePix HS10 HS11", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_HS10) },
243  { "FinePix X100", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100) },
244  { "X10", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X10) },
245  { "X20", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X20) },
246  { "X30", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X30) },
247  { "X70", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X70) },
248  { "X-Pro1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO1) },
249  { "X-Pro2", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO2) },
250  { "X-S1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XS1) },
251  { "FinePix S200EXR", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_S200EXR) },
252  { "X-A1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA1) },
253  { "X-A2", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA2) },
254  { "X-A3", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA3) },
255  { "X-A5", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XA5) },
256  { "XQ1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XQ1) },
257  { "XQ2", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XQ2) },
258  { "X-E1 ", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE1) },
259  { "X-E2", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2) },
260  { "X-E2S", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2S) },
261  { "X-M1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XM1) },
262  { "X-T1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT1) },
263  { "X-T10", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT10) },
264  { "X-T2", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT2) },
265  { "X-T20", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT20) },
266  { "XF1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XF1) },
267  { "X100S", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100S) },
268  { "X100T", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100T) },
269  { "X100F", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100F) },
270  { "X-E3", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE3) },
271  { "X-H1", OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XH1) },
272 
273  { nullptr, 0 }
274 };
275 
276 RawFile *RafFile::factory(const IO::Stream::Ptr &s)
277 {
278  return new RafFile(s);
279 }
280 
281 RafFile::RafFile(const IO::Stream::Ptr &s)
282  : RawFile(OR_RAWFILE_TYPE_RAF), m_io(s), m_container(new RafContainer(s))
283 {
284  _setIdMap(s_def);
285  _setMatrices(s_matrices);
286 }
287 
288 RafFile::~RafFile()
289 {
290  delete m_container;
291 }
292 
293 ::or_error RafFile::_enumThumbnailSizes(std::vector<uint32_t> &list)
294 {
295  or_error ret = OR_ERROR_NOT_FOUND;
296 
297  JfifContainer *jpegPreview = m_container->getJpegPreview();
298  if (!jpegPreview) {
299  return OR_ERROR_NOT_FOUND;
300  }
301 
302  uint32_t x, y;
303  if (jpegPreview->getDimensions(x, y)) {
304  uint32_t size = std::max(x, y);
305 
306  list.push_back(size);
307  _addThumbnail(size, ThumbDesc(x, y, OR_DATA_TYPE_JPEG,
308  m_container->getJpegOffset(),
309  m_container->getJpegLength()));
310  ret = OR_ERROR_NONE;
311  }
312  IfdDir::Ref dir = jpegPreview->getIfdDirAt(1);
313  if (!dir) {
314  return ret;
315  }
316 
317  auto result = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_WIDTH);
318  if (result) {
319  x = result.value();
320  result = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_LENGTH);
321  y = result.value_or(0);
322  }
323 
324  if (result.empty()) {
325  result =
326  dir->getValue<uint32_t>(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT);
327  if (result.empty()) {
328  return ret;
329  }
330  uint32_t jpeg_offset = result.value();
331 
332  jpeg_offset += 12; // XXX magic number. eh?
333  // I need to re-read the Exif spec.
334  result = dir->getValue<uint32_t>(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
335  if (result.empty()) {
336  return ret;
337  }
338  uint32_t jpeg_size = result.value();
339 
340  IO::Stream::Ptr s(std::make_shared<IO::StreamClone>(jpegPreview->file(),
341  jpeg_offset));
342  std::unique_ptr<JfifContainer> thumb(new JfifContainer(s, 0));
343 
344  if (thumb->getDimensions(x, y)) {
345  uint32_t size = std::max(x, y);
346 
347  list.push_back(size);
348  _addThumbnail(size,
349  ThumbDesc(x, y, OR_DATA_TYPE_JPEG,
350  jpeg_offset + m_container->getJpegOffset(),
351  jpeg_size));
352  ret = OR_ERROR_NONE;
353  }
354  }
355 
356  return ret;
357 }
358 
360 {
361  return m_container;
362 }
363 
364 bool
365 RafFile::isXTrans(RawFile::TypeId type_) const
366 {
367  switch (type_) {
368  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO1):
369  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XPRO2):
370  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE1):
371  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2):
372  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE2S):
373  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XE3):
374  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XH1):
375  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XM1):
376  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XQ1):
377  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XQ2):
378  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT1):
379  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT10):
380  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT2):
381  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_XT20):
382  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100S):
383  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100T):
384  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X100F):
385  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X20):
386  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X30):
387  case OR_MAKE_FUJIFILM_TYPEID(OR_TYPEID_FUJIFILM_X70):
388  return true;
389 
390  default:
391  return false;
392  }
393 }
394 
395 ::or_error RafFile::_getRawData(RawData &data, uint32_t /*options*/)
396 {
397  ::or_error ret = OR_ERROR_NOT_FOUND;
398 
399  RafMetaContainer *meta = m_container->getMetaContainer();
400  if (!meta) {
401  LOGERR("RAF: Can't get meta container\n");
402  return ret;
403  }
404 
405  RafMetaValue::Ref value = meta->getValue(RAF_TAG_SENSOR_DIMENSION);
406  if (!value) {
407  // use this tag if the other is missing
408  value = meta->getValue(RAF_TAG_IMG_HEIGHT_WIDTH);
409  }
410  uint32_t dims = value->get().getInteger(0);
411  uint16_t h = (dims & 0xFFFF0000) >> 16;
412  uint16_t w = (dims & 0x0000FFFF);
413 
414  value = meta->getValue(RAF_TAG_RAW_INFO);
415  uint32_t rawProps = value->get().getInteger(0);
416  // TODO re-enable if needed.
417  // uint8_t layout = (rawProps & 0xFF000000) >> 24 >> 7; // MSBit in byte.
418  uint8_t compressed = ((rawProps & 0xFF0000) >> 16) & 8; // 8 == compressed
419 
420  // printf("layout %x - compressed %x\n", layout, compressed);
421 
422  data.setDataType(OR_DATA_TYPE_RAW);
423  data.setDimensions(w, h);
424  if (isXTrans(typeId())) {
425  data.setCfaPattern(XTransPattern::xtransPattern());
426  } else {
427  data.setCfaPatternType(OR_CFA_PATTERN_GBRG);
428  }
429  // TODO actually read the 2048.
430  // TODO make sure this work for the other file formats...
431  size_t byte_size = m_container->getCfaLength() - 2048;
432  size_t fetched = 0;
433  off_t offset = m_container->getCfaOffset() + 2048;
434 
435  uint32_t finaldatalen = 2 * h * w;
436  bool is_compressed = byte_size < finaldatalen; //(compressed == 8);
437  uint32_t datalen = (is_compressed ? byte_size : finaldatalen);
438  void *buf = data.allocData(finaldatalen);
439 
440  LOGDBG2("byte_size = %lu finaldatalen = %u compressed = %u", byte_size,
441  finaldatalen, compressed);
442 
443  ret = OR_ERROR_NONE;
444 
445  if (is_compressed) {
446  Unpack unpack(w, IFD::COMPRESS_NONE);
447  size_t blocksize = unpack.block_size();
448  std::unique_ptr<uint8_t[]> block(new uint8_t[blocksize]);
449  uint8_t *outdata = (uint8_t *)data.data();
450  size_t outsize = finaldatalen;
451  size_t got;
452  do {
453  got = m_container->fetchData(block.get(), offset, blocksize);
454  fetched += got;
455  offset += got;
456 
457  if (got) {
458  size_t out;
459  or_error err = unpack.unpack_be12to16(outdata, outsize,
460  block.get(), got, out);
461  outdata += out;
462  outsize -= out;
463  if (err != OR_ERROR_NONE) {
464  LOGDBG2("error is %d\n", static_cast<int>(err));
465  ret = err;
466  break;
467  }
468  }
469  } while ((got != 0) && (fetched < datalen));
470  } else {
471  m_container->fetchData(buf, offset, datalen);
472  }
473 
474  return ret;
475 }
476 
477 MetaValue *RafFile::_getMetaValue(int32_t meta_index)
478 {
479  if (META_INDEX_MASKOUT(meta_index) == META_NS_EXIF ||
480  META_INDEX_MASKOUT(meta_index) == META_NS_TIFF) {
481 
482  JfifContainer *jpegPreview = m_container->getJpegPreview();
483  if (!jpegPreview) {
484  LOGERR("RAF: Can't get JPEG preview\n");
485  return nullptr;
486  }
487 
488  IfdDir::Ref dir = jpegPreview->mainIfd();
489  IfdEntry::Ref e = dir->getEntry(META_NS_MASKOUT(meta_index));
490  if (e) {
491  return e->make_meta_value();
492  }
493  }
494 
495  return nullptr;
496 }
497 
498 void RafFile::_identifyId()
499 {
500  _setTypeId(_typeIdFromModel("FujiFilm", m_container->getModel()));
501 }
502 }
503 }
OpenRaw::Internals::RawContainer
Definition: rawcontainer.hpp:41
OpenRaw::Internals::Unpack::unpack_be12to16
or_error unpack_be12to16(uint8_t *dest, size_t destsize, const uint8_t *src, size_t size, size_t &outsize)
Definition: unpack.cpp:58
OpenRaw::Internals::RafMetaContainer
Definition: rafmetacontainer.hpp:65
OpenRaw::Internals::JfifContainer::mainIfd
IfdDir::Ref mainIfd()
Definition: jfifcontainer.cpp:251
OpenRaw::Internals::RafFile::_getRawData
virtual ::or_error _getRawData(RawData &data, uint32_t options) override
Definition: raffile.cpp:395
OpenRaw
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition: arwfile.cpp:30
OpenRaw::MetaValue
Definition: metavalue.hpp:33
OpenRaw::Internals::JfifContainer
Definition: jfifcontainer.hpp:51
OpenRaw::RawFile::_setTypeId
void _setTypeId(TypeId _type_id)
Definition: rawfile.cpp:348
OpenRaw::BitmapData::setDataType
void setDataType(DataType _type)
Definition: bitmapdata.cpp:100
OpenRaw::RawData::setDimensions
virtual void setDimensions(uint32_t x, uint32_t y) override
Definition: rawdata.cpp:260
OpenRaw::Internals::JfifContainer::getIfdDirAt
IfdDir::Ref getIfdDirAt(int idx)
Definition: jfifcontainer.cpp:259
OpenRaw::RawFile::typeId
TypeId typeId()
Definition: rawfile.cpp:335
OpenRaw::Internals::RawContainer::fetchData
size_t fetchData(void *buf, off_t offset, size_t buf_size)
Definition: rawcontainer.cpp:203
OpenRaw::Internals::RafFile::getContainer
virtual RawContainer * getContainer() const override
Definition: raffile.cpp:359
OpenRaw::Internals::ThumbDesc
Definition: rawfile_private.hpp:45
OpenRaw::Internals::IfdEntry::Ref
std::shared_ptr< IfdEntry > Ref
Definition: ifdentry.hpp:165
OpenRaw::Internals::Unpack
Definition: unpack.hpp:34
OpenRaw::RawData
Definition: rawdata.hpp:35
OpenRaw::Internals::RafFile::_enumThumbnailSizes
virtual ::or_error _enumThumbnailSizes(std::vector< uint32_t > &list) override
Definition: raffile.cpp:293