libopenraw
rw2file.cpp
1 /*
2  * libopenraw - rw2file.cpp
3  *
4  * Copyright (C) 2011-2017 Hubert Figuiere
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 
23 #include <algorithm>
24 #include <cstdint>
25 #include <memory>
26 
27 #include <libopenraw/cameraids.h>
28 #include <libopenraw/debug.h>
29 
30 #include "rawdata.hpp"
31 #include "trace.hpp"
32 #include "io/streamclone.hpp"
33 #include "rw2file.hpp"
34 #include "rw2container.hpp"
35 #include "jfifcontainer.hpp"
36 #include "rawfile_private.hpp"
37 
38 using namespace Debug;
39 
40 namespace OpenRaw {
41 
42 namespace Internals {
43 
44 #define OR_MAKE_PANASONIC_TYPEID(camid) \
45  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PANASONIC,camid)
46 #define OR_MAKE_LEICA_TYPEID(camid) \
47  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,camid)
48 
49 /* taken from dcraw, by default */
50 static const BuiltinColourMatrix s_matrices[] = {
51  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_CM1),
52  15,
53  0,
54  { 8770, -3194, -820, -2871, 11281, 1803, -513, 1552, 4434 } },
55  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF1),
56  15,
57  0xf92,
58  { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
59  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF2),
60  15,
61  0xfff,
62  { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
63  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF3),
64  15,
65  0xfff,
66  { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
67  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF5),
68  15,
69  0xfff,
70  { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
71  // Adobe DNG convert 7.4
72  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF6),
73  15,
74  0xfff,
75  { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
76  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF7),
77  15,
78  0,
79  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
80  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX1),
81  15,
82  0,
83  { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
84  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX7),
85  15,
86  0,
87  { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
88  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX8),
89  15,
90  0,
91  { 7564, -2263, -606, -3148, 11239, 2177, -540, 1435, 4853 } },
92  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX80),
93  15,
94  0,
95  { 7771, -3020, -629, -4029, 1195, 2345, -821, 1977, 6119 } },
96  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX800),
97  15,
98  0,
99  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
100  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX9),
101  15,
102  0,
103  { 7564, -2263, -606, -3148, 11239, 2177, -540, 1435, 4853 } },
104  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ8),
105  0,
106  0xf7f,
107  { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
108  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ18),
109  0,
110  0,
111  { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
112  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ28),
113  15,
114  0xf96,
115  { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
116  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ200),
117  143,
118  0xfff,
119  { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
120  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ2500),
121  143,
122  0xfff,
123  { 7386, -2443, -743, -3437, 11864, 1757, -608, 1660, 4766 } },
124  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ30),
125  0,
126  0xf94,
127  { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
128  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ330),
129  15,
130  0,
131  { 8378, -2798, -769, -3068, 11410, 1877, -538, 1792, 4623 } },
132  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ50),
133  0,
134  0,
135  { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
136  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ100),
137  143,
138  0xfff,
139  { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
140  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G1),
141  15,
142  0xf94,
143  { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
144  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G2),
145  15,
146  0xf3c,
147  { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
148  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G3),
149  143,
150  0xfff,
151  { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
152  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G5),
153  143,
154  0xfff,
155  { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
156  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G10),
157  0,
158  0,
159  { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
160  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G80),
161  15,
162  0,
163  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
164  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G9),
165  0,
166  0,
167  { 7685, -2375, -634, -3687, 11700, 2249, -748, 1546, 5111 } },
168  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH1),
169  15,
170  0xf92,
171  { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
172  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH2),
173  15,
174  0xf95,
175  { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
176  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH3),
177  144,
178  0,
179  { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
180  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH4),
181  15,
182  0,
183  { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
184  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GM1),
185  15,
186  0,
187  { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
188  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX2),
189  0,
190  0,
191  { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
192  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX3),
193  15,
194  0,
195  { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
196  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX5),
197  143,
198  0,
199  { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
200  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX7),
201  143,
202  0,
203  { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
204  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX100),
205  143,
206  0,
207  { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
208  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_L1),
209  0,
210  0xf7f,
211  { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
212  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_L10),
213  15,
214  0xf96,
215  { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
216  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ70),
217  15,
218  0,
219  { 8802, -3135, -789, -3151, 11468, 1904, -550, 1745, 4810 } },
220  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ80),
221  15,
222  0,
223  { 8550, -2908, -842, -3195, 11529, 1881, -338, 1603, 4631 } },
224  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ100),
225  15,
226  0,
227  { 7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898 } },
228  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ110),
229  15,
230  0,
231  { 7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898 } },
232  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ202),
233  15,
234  0,
235  { 7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898 } },
236 
237  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DIGILUX2),
238  0,
239  0,
240  { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
241  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_3),
242  0,
243  0,
244  { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
245  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_TYP109),
246  0,
247  0,
248  { 8844, -3538, -768, -3709, 11762, 2200, -698, 1792, 5220 } },
249  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_1),
250  0,
251  0,
252  { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
253  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_4),
254  0,
255  0,
256  { 8112, -2563, -740, -3730, 11784, 2197, -941, 2075, 4933 } },
257 
258  { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
259 };
260 
261 const IfdFile::camera_ids_t Rw2File::s_def[] = {
262  { "DMC-CM1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_CM1) },
263  { "DMC-GF1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF1) },
264  { "DMC-GF2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF2) },
265  { "DMC-GF3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF3) },
266  { "DMC-GF5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF5) },
267  { "DMC-GF6", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF6) },
268  { "DMC-GF7", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF7) },
269  { "DMC-GX1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX1) },
270  { "DMC-GX7", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX7) },
271  { "DMC-GX8", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX8) },
272  { "DMC-GX80", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX80) },
273  { "DC-GX800", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX800) },
274  { "DC-GX850", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX850) },
275  { "DC-GX9", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX9) },
276  { "DMC-FZ8", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ8) },
277  { "DMC-FZ18", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ18) },
278  { "DMC-FZ28", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ28) },
279  { "DMC-FZ30", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ30) },
280  { "DMC-FZ50", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ50) },
281  { "DMC-FZ100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ100) },
282  { "DMC-FZ200", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ200) },
283  { "DMC-FZ2500", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ2500) },
284  { "DMC-FZ330", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ330) },
285  { "DC-FZ82", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ82) },
286  { "DMC-G1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G1) },
287  { "DMC-G2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G2) },
288  { "DMC-G3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G3) },
289  { "DMC-G5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G5) },
290  { "DMC-G10", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G10) },
291  { "DMC-G80", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G80) },
292  { "DC-G9", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G9) },
293  { "DMC-GH1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH1) },
294  { "DMC-GH2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH2) },
295  { "DMC-GH3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH3) },
296  { "DMC-GH4", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH4) },
297  { "DC-GH5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH5) },
298  { "DMC-GM1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GM1) },
299  { "DMC-GM5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GM5) },
300  { "DMC-LX2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX2) },
301  { "DMC-LX3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX3) },
302  { "DMC-LX5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX5) },
303  { "DMC-LX7", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX7) },
304  { "DMC-LX10", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX10) },
305  { "DMC-LX100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX100) },
306  { "DMC-L1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_L1) },
307  { "DMC-L10", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_L10) },
308  { "DMC-TZ100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ100) },
309  { "DMC-TZ110", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ110) },
310  { "DC-TZ202", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ202) },
311  { "DMC-TZ70", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ70) },
312  { "DMC-TZ80", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ80) },
313  { "DMC-ZS100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS100) },
314 
315  { "DIGILUX 2", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DIGILUX2) },
316  { "D-LUX 3", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_3) },
317  { "V-LUX 1", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_1) },
318  { "D-LUX (Typ 109)", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_TYP109) },
319  { "V-LUX 4", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_4) },
320 
321  { 0, 0 }
322 };
323 
324 RawFile *Rw2File::factory(const IO::Stream::Ptr & s)
325 {
326  return new Rw2File(s);
327 }
328 
329 Rw2File::Rw2File(const IO::Stream::Ptr & s)
330  : IfdFile(s, OR_RAWFILE_TYPE_RW2, false)
331 {
332  _setIdMap(s_def);
333  _setMatrices(s_matrices);
334  m_container = new Rw2Container(m_io, 0);
335 }
336 
337 Rw2File::~Rw2File()
338 {
339 }
340 
341 
342 IfdDir::Ref Rw2File::_locateCfaIfd()
343 {
344  return mainIfd();
345 }
346 
347 
348 IfdDir::Ref Rw2File::_locateMainIfd()
349 {
350  return m_container->setDirectory(0);
351 }
352 
353 ::or_error Rw2File::_locateThumbnail(const IfdDir::Ref & dir,
354  std::vector<uint32_t> &list)
355 {
356  uint32_t offset = 0;
357  uint32_t size = 0;
358 
359  offset = _getJpegThumbnailOffset(dir, size);
360  if(size == 0) {
361  return OR_ERROR_NOT_FOUND;
362  }
363  LOGDBG1("Jpeg offset: %u\n", offset);
364 
365  uint32_t x = 0;
366  uint32_t y = 0;
367  ::or_data_type _type = OR_DATA_TYPE_JPEG;
368  IO::Stream::Ptr s(new IO::StreamClone(m_io, offset));
369  std::unique_ptr<JfifContainer> jfif(new JfifContainer(s, 0));
370  if (jfif->getDimensions(x,y)) {
371  LOGDBG1("JPEG dimensions x=%u y=%u\n", x, y);
372  }
373  if(_type != OR_DATA_TYPE_NONE) {
374  uint32_t dim = std::max(x, y);
375  _addThumbnail(dim, ThumbDesc(x, y, _type, offset, size));
376  list.push_back(dim);
377  }
378 
379  return OR_ERROR_NONE;
380 }
381 
382 uint32_t Rw2File::_getJpegThumbnailOffset(const IfdDir::Ref & dir, uint32_t & len)
383 {
384  IfdEntry::Ref e = dir->getEntry(IFD::RW2_TAG_JPEG_FROM_RAW);
385  if(!e) {
386  len = 0;
387  LOGDBG1("JpegFromRaw not found\n");
388  return 0;
389  }
390  uint32_t offset = e->offset();
391  len = e->count();
392  return offset;
393 }
394 
395 
396 ::or_error Rw2File::_getRawData(RawData & data, uint32_t /*options*/)
397 {
398  ::or_error ret = OR_ERROR_NONE;
399  const IfdDir::Ref & _cfaIfd = cfaIfd();
400  if(!_cfaIfd) {
401  LOGDBG1("cfa IFD not found\n");
402  return OR_ERROR_NOT_FOUND;
403  }
404 
405  LOGDBG1("_getRawData()\n");
406  uint32_t offset = 0;
407  uint32_t byte_length = 0;
408  // RW2 file
409  auto result = _cfaIfd->getIntegerValue(IFD::RW2_TAG_STRIP_OFFSETS);
410  if(result) {
411  offset = result.value();
412  byte_length = m_container->file()->filesize() - offset;
413  }
414  else {
415  // RAW file alternative.
416  result = _cfaIfd->getIntegerValue(IFD::EXIF_TAG_STRIP_OFFSETS);
417  if(result.empty()) {
418  LOGDBG1("offset not found\n");
419  return OR_ERROR_NOT_FOUND;
420  }
421  offset = result.value();
422  result = _cfaIfd->getIntegerValue(IFD::EXIF_TAG_STRIP_BYTE_COUNTS);
423  if(result.empty()) {
424  LOGDBG1("byte len not found\n");
425  return OR_ERROR_NOT_FOUND;
426  }
427  byte_length = result.value();
428  }
429 
430  result = _cfaIfd->getIntegerValue(IFD::RW2_TAG_SENSOR_WIDTH);
431  if(result.empty()) {
432  LOGDBG1("X not found\n");
433  return OR_ERROR_NOT_FOUND;
434  }
435  uint32_t x = result.value();
436 
437  result = _cfaIfd->getIntegerValue(IFD::RW2_TAG_SENSOR_HEIGHT);
438  if(result.empty()) {
439  LOGDBG1("Y not found\n");
440  return OR_ERROR_NOT_FOUND;
441  }
442  uint32_t y = result.value();
443 
444  // this is were things are complicated. The real size of the raw data
445  // is whatever is read (if compressed)
446  void *p = data.allocData(byte_length);
447  size_t real_size = m_container->fetchData(p, offset,
448  byte_length);
449 
450  if (real_size / (x * 8 / 7) == y) {
451  data.setDataType(OR_DATA_TYPE_COMPRESSED_RAW);
452  data.setCompression(PANA_RAW_COMPRESSION);
453  }
454  else if (real_size < byte_length) {
455  LOGWARN("Size mismatch for data: expected %u got %lu ignoring.\n",
456  byte_length, real_size);
457  return OR_ERROR_NOT_FOUND;
458  }
459  else {
460  data.setDataType(OR_DATA_TYPE_RAW);
461  }
462  data.setCfaPatternType(OR_CFA_PATTERN_BGGR);
463 
464 
465  // they are not all RGGB.
466  // but I don't seem to see where this is encoded.
467  //
468  data.setDimensions(x, y);
469 
470  LOGDBG1("In size is %ux%u\n", data.width(), data.height());
471  // get the sensor info
472  // XXX what if it is not found?
473  IfdEntry::Ref e = _cfaIfd->getEntry(IFD::RW2_TAG_SENSOR_LEFTBORDER);
474  x = e->getIntegerArrayItem(0);
475  e = _cfaIfd->getEntry(IFD::RW2_TAG_SENSOR_TOPBORDER);
476  y = e->getIntegerArrayItem(0);
477  e = _cfaIfd->getEntry(IFD::RW2_TAG_IMAGE_HEIGHT);
478  uint32_t h = e->getIntegerArrayItem(0);
479  e = _cfaIfd->getEntry(IFD::RW2_TAG_IMAGE_WIDTH);
480  uint32_t w = e->getIntegerArrayItem(0);
481 
482  data.setRoi(x, y, w, h);
483 
484  return ret;
485 }
486 
487 }
488 }
489 /*
490  Local Variables:
491  mode:c++
492  c-file-style:"stroustrup"
493  c-file-offsets:((innamespace . 0))
494  tab-width:2
495  c-basic-offset:2
496  indent-tabs-mode:nil
497  fill-column:80
498  End:
499 */
OpenRaw::Internals::IfdFile::cfaIfd
const IfdDir::Ref & cfaIfd()
Definition: ifdfile.cpp:332
OpenRaw
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition: arwfile.cpp:30
OpenRaw::Internals::IfdFile::m_container
IfdFileContainer * m_container
Definition: ifdfile.hpp:90
OpenRaw::Internals::IfdFileContainer::setDirectory
IfdDir::Ref setDirectory(int dir)
Definition: ifdfilecontainer.cpp:88
OpenRaw::Internals::RawContainer::fetchData
size_t fetchData(void *buf, off_t offset, size_t buf_size)
Definition: rawcontainer.cpp:203
OpenRaw::Internals::IfdEntry::Ref
std::shared_ptr< IfdEntry > Ref
Definition: ifdentry.hpp:165
OpenRaw::Internals::IfdFile::m_io
IO::Stream::Ptr m_io
Definition: ifdfile.hpp:89