libopenraw
orffile.cpp
1 /*
2  * libopenraw - orffile.cpp
3  *
4  * Copyright (C) 2006-2017 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 <algorithm>
22 #include <cstdint>
23 #include <memory>
24 
25 #include <libopenraw/debug.h>
26 #include <libopenraw/cameraids.h>
27 #include <libopenraw/consts.h>
28 
29 #include "cfapattern.hpp"
30 #include "rawdata.hpp"
31 #include "rawfile.hpp"
32 
33 #include "ifdfilecontainer.hpp"
34 #include "makernotedir.hpp"
35 
36 #include "trace.hpp"
37 #include "orffile.hpp"
38 #include "ifd.hpp"
39 #include "ifddir.hpp"
40 #include "ifdentry.hpp"
41 #include "orfcontainer.hpp"
42 #include "olympusdecompressor.hpp"
43 #include "rawfile_private.hpp"
44 #include "io/streamclone.hpp"
45 #include "jfifcontainer.hpp"
46 
47 using namespace Debug;
48 
49 namespace OpenRaw {
50 namespace Internals {
51 
52 #define OR_MAKE_OLYMPUS_TYPEID(camid) \
53  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS,camid)
54 
55 /* taken from dcraw, by default */
56 static const BuiltinColourMatrix s_matrices[] = {
57  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E1),
58  0,
59  0,
60  { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
61  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E10),
62  0,
63  0xffc,
64  { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
65  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E3),
66  0,
67  0xf99,
68  { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
69  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E5),
70  0,
71  0,
72  { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
73  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E300),
74  0,
75  0,
76  { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
77  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E330),
78  0,
79  0,
80  { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
81  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E400),
82  0,
83  0,
84  { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
85  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E410),
86  0,
87  0xf6a,
88  { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
89  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E500),
90  0,
91  0,
92  { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
93  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E510),
94  0,
95  0xf6a,
96  { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
97  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E620),
98  0,
99  0xfaf,
100  { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
101  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SP350),
102  0,
103  0,
104  { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
105  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SP500),
106  0,
107  0xfff,
108  { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
109  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SP510),
110  0,
111  0xffe,
112  { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
113  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SP550),
114  0,
115  0xffe,
116  { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
117  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EP1),
118  0,
119  0xffd,
120  { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
121  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EP2),
122  0,
123  0xffd,
124  { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
125  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EP3),
126  0,
127  0,
128  { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
129  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL1),
130  0,
131  0,
132  { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
133  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL2),
134  0,
135  0,
136  { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
137  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL3),
138  0,
139  0,
140  { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
141  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL5),
142  0,
143  0xfcb,
144  { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
145  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL6),
146  0,
147  0xfcb,
148  { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
149  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL7),
150  0,
151  0xfcb,
152  { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
153  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL8),
154  0,
155  0xfcb,
156  { 9197, -3190, -659, -2606, 10830, 2039, -458, 1250, 5458 } },
157  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL9),
158  0,
159  0xfcb,
160  { 8380, -2630, -639, -2887, 10725, 2496, -627, 1427, 5438 } },
161  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPM1),
162  0,
163  0,
164  { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
165  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPM2),
166  0,
167  0,
168  { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
169  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_XZ1),
170  0,
171  0,
172  { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
173  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_XZ10),
174  0,
175  0,
176  { 9777, -3483, -925, -2886, 11297, 1800, -602, 1663, 5134 } },
177  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_XZ2),
178  0,
179  0,
180  { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
181  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM5),
182  0,
183  0xfe1,
184  { 8380, -2630, -639, -2887, 725, 2496, -627, 1427, 5438 } },
185  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM5II),
186  0,
187  0,
188  { 9422, -3258, -711, -2655, 10898, 2015, -512, 1354, 5512 } },
189  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM1),
190  0,
191  0,
192  { 7687, -1984, -606, -4327, 11928, 2721, -1381, 2339, 6452 } },
193  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM10),
194  0,
195  0,
196  { 8380, -2630, -639, -2887, 10725, 2496, -627, 1427, 5438 } },
197  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM10II), // Identical to MarkI
198  0,
199  0,
200  { 8380, -2630, -639, -2887, 10725, 2496, -627, 1427, 5438 } },
201  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_STYLUS1),
202  0,
203  0,
204  { 8360, -2420, -880, -3928, 12353, 1739, -1381, 2416, 5173 } },
205  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_PEN_F),
206  0,
207  0,
208  { 9476, -3182, -765, -2613, 10958, 1893, -449, 1315, 5268 } },
209  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SH2),
210  0,
211  0,
212  { 10156, -3425, -1077, -2611, 11177, 1624, -385, 1592, 5080 } },
213  { OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_TG4),
214  0,
215  0,
216  { 11426, -4159, -1126, -2066, 10678, 1593, -120, 1327, 4998 } },
217 
218  { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
219 
220 };
221 
222 const struct IfdFile::camera_ids_t OrfFile::s_def[] = {
223  { "E-1 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E1) },
224  { "E-10 " , OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E10) },
225  { "E-3 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E3) },
226  { "E-5 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E5) },
227  { "E-300 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E300) },
228  { "E-330 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E330) },
229  { "E-400 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E400) },
230  { "E-410 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E410) },
231  { "E-500 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E500) },
232  { "E-510 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E510) },
233  { "E-620 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_E620) },
234  { "SP350" , OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SP350) },
235  { "SP500UZ" , OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SP500) },
236  { "SP510UZ" , OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SP510) },
237  { "SP550UZ ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SP550) },
238  { "E-P1 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EP1) },
239  { "E-P2 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EP2) },
240  { "E-P3 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EP3) },
241  { "E-PL1 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL1) },
242  { "E-PL2 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL2) },
243  { "E-PL3 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL3) },
244  { "E-PL5 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL5) },
245  { "E-PL6 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL6) },
246  { "E-PL7 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL7) },
247  { "E-PL8 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL8) },
248  { "E-PL9 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPL9) },
249  { "E-PM1 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPM1) },
250  { "E-PM2 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EPM2) },
251  { "XZ-1 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_XZ1) },
252  { "XZ-10 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_XZ10) },
253  { "XZ-2 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_XZ2) },
254  { "E-M5 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM5) },
255  { "E-M5MarkII ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM5II) },
256  { "E-M1 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM1) },
257  { "E-M1MarkII ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM1II) },
258  { "E-M10 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM10) },
259  { "E-M10MarkII ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_EM10II) },
260  { "STYLUS1 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_STYLUS1) },
261  { "PEN-F ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_PEN_F) },
262  { "SH-2 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_SH2) },
263  { "TG-4 ", OR_MAKE_OLYMPUS_TYPEID(OR_TYPEID_OLYMPUS_TG4) },
264  { 0, 0 }
265 };
266 
267 RawFile *OrfFile::factory(const IO::Stream::Ptr &s)
268 {
269  return new OrfFile(s);
270 }
271 
272 OrfFile::OrfFile(const IO::Stream::Ptr &s)
273  : IfdFile(s, OR_RAWFILE_TYPE_ORF, false)
274 {
275  _setIdMap(s_def);
276  _setMatrices(s_matrices);
277  m_container = new OrfContainer(m_io, 0);
278 }
279 
280 OrfFile::~OrfFile()
281 {
282 }
283 
284 IfdDir::Ref OrfFile::_locateCfaIfd()
285 {
286  // in ORF the CFA IFD is the main IFD
287  return mainIfd();
288 }
289 
290 
291 IfdDir::Ref OrfFile::_locateMainIfd()
292 {
293  return m_container->setDirectory(0);
294 }
295 
296 ::or_error OrfFile::_enumThumbnailSizes(std::vector<uint32_t> &list)
297 {
298  auto err = OR_ERROR_NOT_FOUND;
299 
300  err = IfdFile::_enumThumbnailSizes(list);
301 
302  auto exif = exifIfd();
303  if (!exif) {
304  return err;
305  }
306 
307  auto ifd = exif->getMakerNoteIfd();
308  if (!ifd) {
309  return err;
310  }
311  auto makerNote = std::dynamic_pointer_cast<MakerNoteDir>(ifd);
312  if (!makerNote) {
313  return err;
314  }
315 
316  auto e = makerNote->getEntry(0x100);
317  if (e) {
318  auto val_offset = e->offset();
319 
320  val_offset += makerNote->getMnoteOffset();
321 
322  LOGDBG1("fetching JPEG\n");
323  IO::Stream::Ptr s(
324  std::make_shared<IO::StreamClone>(m_io, val_offset));
325  std::unique_ptr<JfifContainer> jfif(new JfifContainer(s, 0));
326 
327  uint32_t x, y;
328  x = y = 0;
329  jfif->getDimensions(x, y);
330  LOGDBG1("JPEG dimensions x=%d y=%d\n", x, y);
331 
332  uint32_t dim = std::max(x, y);
333  if (dim) {
334  _addThumbnail(dim, ThumbDesc(x, y, OR_DATA_TYPE_JPEG,
335  val_offset, e->count()));
336  list.push_back(dim);
337  err = OR_ERROR_NONE;
338  }
339  }
340 
341  return err;
342 }
343 
344 ::or_error OrfFile::_getRawData(RawData & data, uint32_t options)
345 {
346  ::or_error err;
347  const IfdDir::Ref & _cfaIfd = cfaIfd();
348  err = _getRawDataFromDir(data, _cfaIfd);
349  if(err == OR_ERROR_NONE) {
350  // ORF files seems to be marked as uncompressed even if they are.
351  uint32_t x = data.width();
352  uint32_t y = data.height();
353  uint32_t compression = 0;
354  if(data.size() < x * y * 2) {
355  compression = ORF_COMPRESSION;
356  data.setCompression(ORF_COMPRESSION);
357  data.setDataType(OR_DATA_TYPE_COMPRESSED_RAW);
358  }
359  else {
360  compression = data.compression();
361  }
362  switch(compression) {
363  case ORF_COMPRESSION:
364  if((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) {
365  OlympusDecompressor decomp((const uint8_t*)data.data(),
366  data.size(), m_container, x, y);
367  RawDataPtr dData = decomp.decompress();
368  if (dData) {
369  dData->setCfaPatternType(data.cfaPattern()->patternType());
370  data.swap(*dData);
371  data.setDataType(OR_DATA_TYPE_RAW);
372  data.setDimensions(x, y);
373  }
374  }
375  break;
376  default:
377  break;
378  }
379  }
380  return err;
381 }
382 
383 uint32_t OrfFile::_translateCompressionType(IFD::TiffCompress tiffCompression)
384 {
385  if(tiffCompression == IFD::COMPRESS_CUSTOM) {
386  return ORF_COMPRESSION;
387  }
388  return (uint32_t)tiffCompression;
389 }
390 
391 }
392 }
393 /*
394  Local Variables:
395  mode:c++
396  c-file-style:"stroustrup"
397  c-file-offsets:((innamespace . 0))
398  indent-tabs-mode:nil
399  fill-column:80
400  End:
401 */
OpenRaw::Internals::OrfFile
Definition: orffile.cpp:222
OpenRaw::Internals::IfdFile::_enumThumbnailSizes
virtual ::or_error _enumThumbnailSizes(std::vector< uint32_t > &list) override
Definition: ifdfile.cpp:112
OpenRaw
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition: arwfile.cpp:30
OpenRaw::RawFile
Definition: rawfile.hpp:50
OpenRaw::RawFile::camera_ids_t
Definition: rawfile.hpp:147