libopenraw  0.3.7
rw2file.cpp
1 /*
2  * libopenraw - rw2file.cpp
3  *
4  * Copyright (C) 2011-2023 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 
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 "rawfile_private.hpp"
36 
37 using namespace Debug;
38 
39 namespace OpenRaw {
40 
41 namespace Internals {
42 
43 #define OR_MAKE_PANASONIC_TYPEID(camid) \
44  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PANASONIC,camid)
45 #define OR_MAKE_LEICA_TYPEID(camid) \
46  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,camid)
47 
48 /* taken from dcraw, by default */
49 static const BuiltinColourMatrix s_matrices[] = {
50  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_CM1),
51  15,
52  0,
53  { 8770, -3194, -820, -2871, 11281, 1803, -513, 1552, 4434 } },
54  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF1),
55  15,
56  0xf92,
57  { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
58  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF2),
59  15,
60  0xfff,
61  { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
62  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF3),
63  15,
64  0xfff,
65  { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
66  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF5),
67  15,
68  0xfff,
69  { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
70  // Adobe DNG convert 7.4
71  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF6),
72  15,
73  0xfff,
74  { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
75  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF7),
76  15,
77  0,
78  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
79  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF8),
80  15,
81  0,
82  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
83  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF10),
84  15,
85  0,
86  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
87  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX1),
88  15,
89  0,
90  { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
91  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX7),
92  15,
93  0,
94  { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
95  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX7MK2),
96  15,
97  0,
98  { 7771, -3020, -629, -4029, 1195, 2345, -821, 1977, 6119 } },
99  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX8),
100  15,
101  0,
102  { 7564, -2263, -606, -3148, 11239, 2177, -540, 1435, 4853 } },
103  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX80),
104  15,
105  0,
106  { 7771, -3020, -629, -4029, 1195, 2345, -821, 1977, 6119 } },
107  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX800),
108  15,
109  0,
110  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
111  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX850),
112  15,
113  0,
114  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
115  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX9),
116  15,
117  0,
118  { 7564, -2263, -606, -3148, 11239, 2177, -540, 1435, 4853 } },
119  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ8),
120  0,
121  0xf7f,
122  { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
123  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ18),
124  0,
125  0,
126  { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
127  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ28),
128  15,
129  0xf96,
130  { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
131  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ200),
132  143,
133  0xfff,
134  { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
135  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ2500),
136  143,
137  0xfff,
138  { 7386, -2443, -743, -3437, 11864, 1757, -608, 1660, 4766 } },
139  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ30),
140  0,
141  0xf94,
142  { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
143  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ300),
144  0,
145  0,
146  { 8378, -2798, -769, -3068, 11410, 1877, -538, 1792, 4623 } },
147  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ330),
148  15,
149  0,
150  { 8378, -2798, -769, -3068, 11410, 1877, -538, 1792, 4623 } },
151  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ35),
152  15,
153  0,
154  { 9938, -2780, -890, -4604, 12393, 2480, -1117, 2304, 4620 } },
155  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DMC_FZ45),
156  0,
157  0,
158  { 13639, -5535, -1371, -1698, 9633, 2430, 316, 1152, 4108 } },
159  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ50),
160  0,
161  0,
162  { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
163  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ70),
164  0,
165  0,
166  { 11532, -4324, -1066, -2375, 10847, 1749, -564, 1699, 4351 } },
167  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ100),
168  143,
169  0xfff,
170  { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
171  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DMC_FZ1000),
172  0,
173  0,
174  { 7830, -2696, -763, -3325, 11667, 1866, -641, 1712, 4824 } },
175  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_FZ1000M2),
176  0,
177  0,
178  { 9803, -4185, -992, -4066, 12578, 1628, -838, 1824, 5288 } },
179  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ150),
180  0,
181  0,
182  { 11904, -4541, -1189, -2355, 10899, 1662, -296, 1586, 4289 } },
183  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ80),
184  0,
185  0,
186  { 11532, -4324, -1066, -2375, 10847, 1749, -564, 1699, 4351 } },
187  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G1),
188  15,
189  0xf94,
190  { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
191  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G2),
192  15,
193  0xf3c,
194  { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
195  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G3),
196  143,
197  0xfff,
198  { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
199  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G5),
200  143,
201  0xfff,
202  { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
203  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G6),
204  143,
205  0xfff,
206  { 8294, -2891, -651, -3869, 11590, 2595, -1183, 2267, 5352 } },
207  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G10),
208  0,
209  0,
210  { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
211  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G7),
212  0,
213  0,
214  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
215  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G80),
216  15,
217  0,
218  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
219  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G8),
220  15,
221  0,
222  { 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 } },
223  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G9),
224  0,
225  0,
226  { 7685, -2375, -634, -3687, 11700, 2249, -748, 1546, 5111 } },
227  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G95),
228  0,
229  0,
230  { 9657, -3963, -748, -3361, 11378, 2258, -568, 1415, 5158 } },
231  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G99),
232  0,
233  0,
234  { 9657, -3963, -748, -3361, 11378, 2258, -568, 1415, 5158 } },
235  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G100),
236  0,
237  0,
238  { 8370, -2869, -710, -3389, 11372, 2298, -640, 1599, 4887 } },
239  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH1),
240  15,
241  0xf92,
242  { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
243  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH2),
244  15,
245  0xf95,
246  { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
247  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH3),
248  144,
249  0,
250  { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
251  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH4),
252  15,
253  0,
254  { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
255  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH5),
256  15,
257  0,
258  { 7641, -2336, -605, -3218, 11299, 2187, -485, 1338, 5121 } },
259  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH5S),
260  15,
261  0,
262  { 6929, -2355, -708, -4192, 12534, 1828, -1097, 1989, 5195 } },
263  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH5M2),
264  15,
265  0,
266  { 9300, -3659, -755, -2981, 10988, 2287, -190, 1077, 5016 } },
267  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH6),
268  15,
269  0,
270  { 7949, -3491, -710, -3435, 11681, 1977, -503, 1622, 5065 } },
271  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GM1),
272  15,
273  0,
274  { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
275  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GM5),
276  15,
277  0,
278  { 8238, -3244, -679, -3921, 11814, 2384, -836, 2022, 5852 } },
279  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LF1),
280  0,
281  0,
282  { 9379, -3267, -816, -3227, 11560, 1881, -926, 1928, 5340 } },
283  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX1),
284  0,
285  0,
286  { 10704, -4187, -1230, -8314, 15952, 2501, -920, 945, 8927 } },
287  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX2),
288  0,
289  0,
290  { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
291  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX3),
292  15,
293  0,
294  { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
295  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX5),
296  143,
297  0,
298  { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
299  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX7),
300  143,
301  0,
302  { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
303  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX10), // and LX15 (alias)
304  15,
305  0,
306  { 7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898 } },
307  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX100),
308  143,
309  0,
310  { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
311  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX100M2),
312  0,
313  0,
314  { 11577, -4230, -1106, -3967, 12211, 1957, -758, 1762, 5610 } },
315  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_L1),
316  0,
317  0xf7f,
318  { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
319  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_L10),
320  15,
321  0xf96,
322  { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
323  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ70),
324  15,
325  0,
326  { 8802, -3135, -789, -3151, 11468, 1904, -550, 1745, 4810 } },
327  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS40),
328  15,
329  0,
330  { 8607, -2822, -808, -3755, 11930, 2049, -820, 2060, 5224 } },
331  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS50),
332  0,
333  0,
334  { 8802, -3135, -789, -3151, 11468, 1904, -550, 1745, 4810 } },
335  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS60),
336  15,
337  0,
338  { 8550, -2908, -842, -3195, 11529, 1881, -338, 1603, 4631 } },
339  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS100),
340  0,
341  0,
342  { 7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898 } },
343  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS200),
344  0,
345  0,
346  { 7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898 } },
347  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S1),
348  0,
349  0,
350  { 9744, -3905, -779, -4899, 12807, 2324, -798, 1630, 5827 } },
351  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S1R),
352  0,
353  0,
354  { 11822, -5321, -1249, -5958, 15114, 766, -614, 1264, 7043 } },
355  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S1H),
356  0,
357  0,
358  { 9397, -3719, -805, -5425, 13326, 2309, -972, 1715, 6034 } },
359  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S5),
360  0,
361  0,
362  { 9744, -3905, -779, -4899, 12807, 2324, -798, 1630, 5827 } },
363  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S5M2),
364  0,
365  0,
366  { 10308, -4206, -783, -4088, 12102, 2229, -125, 1051, 5912 } },
367  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS70),
368  0,
369  0,
370  { 9052, -3117, -883, -3045, 11346, 1927, -205, 1520, 4730 } },
371  { OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_ZS80),
372  0,
373  0,
374  { 12194, -5340, -1329, -3035, 11394, 1858, -50, 1418, 5219 } },
375 
376  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DIGILUX2),
377  0,
378  0,
379  { 11340, -4069, -1275, -7555, 15266, 2448, -2960, 3426, 7685 } },
380  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DIGILUX3),
381  0,
382  0,
383  { 8054, -1886, -1025, -8348, 16367, 2040, -2805, 3542, 7630 } },
384  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_3),
385  0,
386  0,
387  { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
388  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_TYP109),
389  0,
390  0,
391  { 8844, -3538, -768, -3709, 11762, 2200, -698, 1792, 5220 } },
392  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_4),
393  0,
394  0,
395  { 8128, -2668, -655, -6134, 13307, 3161, -1782, 2568, 6083 } },
396  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_5),
397  143,
398  0,
399  { 10909, -4295, -948, -1333, 9306, 2399, 22, 1738, 4582 } },
400  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_1),
401  0,
402  0,
403  { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
404  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_4),
405  0,
406  0,
407  { 8112, -2563, -740, -3730, 11784, 2197, -941, 2075, 4933 } },
408  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_TYP114),
409  0,
410  0,
411  { 7830, -2696, -763, -3325, 11667, 1866, -641, 1712, 4824 } },
412  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_5),
413  0,
414  0,
415  { 9803, -4185, -992, -4066, 12578, 1628, -838, 1824, 5288 } },
416  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_CLUX),
417  15,
418  0,
419  { 7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898 } },
420  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_6),
421  0,
422  0,
423  { 10148, -3743, -991, -2837, 11366, 1659, -701, 1893, 4899 } },
424  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_7),
425  0,
426  0,
427  { 11577, -4230, -1106, -3967, 12211, 1957, -758, 1762, 5610 } },
428  { OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_C_TYP112),
429  0,
430  0,
431  { 9379, -3267, -816, -3227, 11560, 1881, -926, 1928, 5340 } },
432 
433  { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
434 };
435 
436 const IfdFile::camera_ids_t Rw2File::s_def[] = {
437  { "DMC-CM1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_CM1) },
438  { "DMC-GF1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF1) },
439  { "DMC-GF2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF2) },
440  { "DMC-GF3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF3) },
441  { "DMC-GF5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF5) },
442  { "DMC-GF6", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF6) },
443  { "DMC-GF7", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF7) },
444  { "DMC-GF8", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF8) },
445  { "DC-GF10", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GF10) },
446  { "DMC-GX1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX1) },
447  { "DMC-GX7", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX7) },
448  { "DMC-GX7MK2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX7MK2) },
449  { "DC-GX7MK3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX7MK3) },
450  { "DMC-GX8", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX8) },
451  { "DMC-GX80", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX80) },
452  { "DMC-GX85", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX85) },
453  { "DC-GX800", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX800) },
454  { "DC-GX850", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX850) },
455  { "DC-GX880", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX880) },
456  { "DC-GX9", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GX9) },
457  { "DMC-FZ8", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ8) },
458  { "DMC-FZ1000", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DMC_FZ1000) },
459  { "DC-FZ10002", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_FZ1000M2) },
460  { "DC-FZ1000M2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_FZ1000M2) },
461  { "DMC-FZ18", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ18) },
462  { "DMC-FZ150", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ150) },
463  { "DMC-FZ28", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ28) },
464  { "DMC-FZ30", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ30) },
465  { "DMC-FZ300", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ300) },
466  { "DMC-FZ35", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ35) },
467  { "DMC-FZ38", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ38) },
468  { "DMC-FZ40", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DMC_FZ40) },
469  { "DMC-FZ45", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DMC_FZ45) },
470  // Not the same as above
471  { "DC-FZ45", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_FZ45) },
472  { "DMC-FZ50", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ50) },
473  { "DMC-FZ70", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ70) },
474  { "DMC-FZ72", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ72) },
475  { "DMC-FZ100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ100) },
476  { "DMC-FZ200", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ200) },
477  { "DMC-FZ2500", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ2500) },
478  // Alias to DMC-FZ2500
479  { "DMC-FZ2000", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ2000) },
480  { "DMC-FZ330", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ330) },
481  { "DC-FZ80", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ80) },
482  { "DC-FZ82", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_FZ82) },
483  { "DMC-G1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G1) },
484  { "DMC-G2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G2) },
485  { "DMC-G3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G3) },
486  { "DMC-G5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G5) },
487  { "DMC-G6", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G6) },
488  { "DMC-G7", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G7) },
489  { "DMC-G70", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G70) },
490  { "DMC-G10", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G10) },
491  { "DMC-G80", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G80) },
492  { "DMC-G81", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G81) },
493  { "DC-G9", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_G9) },
494  { "DC-G90", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G90) },
495  { "DC-G91", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G91) },
496  { "DC-G95", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G95) },
497  { "DC-G95D", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G95D) },
498  { "DC-G99", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G99) },
499  { "DC-G100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G100) },
500  { "DC-G110", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_G110) },
501  { "DMC-GH1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH1) },
502  { "DMC-GH2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH2) },
503  { "DMC-GH3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH3) },
504  { "DMC-GH4", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH4) },
505  { "DC-GH5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH5) },
506  { "DC-GH5S", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH5S) },
507  { "DC-GH5M2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH5M2) },
508  { "DC-GH6", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GH6) },
509  { "DMC-GM1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GM1) },
510  { "DMC-GM1S", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GM1S) },
511  { "DMC-GM5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_GM5) },
512  { "DMC-LF1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LF1) },
513  { "DMC-LX1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX1) },
514  { "DMC-LX2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX2) },
515  { "DMC-LX3", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX3) },
516  { "DMC-LX5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX5) },
517  { "DMC-LX7", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX7) },
518  { "DMC-LX10", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX10) },
519  { "DMC-LX15", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX15) },
520  { "DMC-LX100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX100) },
521  { "DC-LX100M2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_LX100M2) },
522  { "DMC-L1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_L1) },
523  { "DMC-L10", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_L10) },
524  { "DC-S1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S1) },
525  { "DC-S1R", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S1R) },
526  { "DC-S1H", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S1H) },
527  { "DC-S5", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S5) },
528  { "DC-S5M2", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_S5M2) },
529  { "DMC-TZ70", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ70) },
530  { "DMC-ZS60", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS60) },
531  // Aliases to DMC-ZS60
532  { "DMC-TZ80", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ80) },
533  { "DMC-TZ81", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ81) },
534  { "DMC-ZS100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS100) },
535  // Aliases to DMC-ZS100
536  { "DMC-TX1", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TX1) },
537  { "DMC-TZ100", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ100) },
538  { "DMC-TZ101", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ101) },
539  { "DMC-TZ110", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ110) },
540  { "DC-ZS200", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS200) },
541  // Aliases to DMC-ZS200
542  { "DC-TZ202", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ202) },
543  { "DC-ZS80", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_ZS80) },
544  // Aliases to DC-ZS80
545  { "DC-TZ95", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_TZ95) },
546  { "DC-TZ96", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_DC_TZ96) },
547 
548  { "DMC-ZS40", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_ZS40) },
549  // Aliases to DMC-ZS40
550  { "DMC-TZ60", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ60) },
551  { "DMC-TZ61", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ61) },
552 
553  // Also to DMC-ZS50
554  { "DMC-TZ71", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ71) },
555 
556  // Aliases to DC-ZS70
557  { "DC-TZ90", OR_MAKE_PANASONIC_TYPEID(OR_TYPEID_PANASONIC_TZ90) },
558 
559  { "DIGILUX 2", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DIGILUX2) },
560  { "DIGILUX 3", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DIGILUX3) },
561  { "D-LUX 3", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_3) },
562  { "D-LUX 4", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_4) },
563  { "D-LUX 5", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_5) },
564  { "D-LUX 6", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_6) },
565  { "D-Lux 7", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_7) },
566  { "V-LUX 1", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_1) },
567  { "D-LUX (Typ 109)", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_DLUX_TYP109) },
568  { "V-LUX 4", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_4) },
569  { "V-Lux 5", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_5) },
570  { "V-LUX (Typ 114)", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_VLUX_TYP114) },
571  { "C-Lux", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_CLUX) },
572  { "C (Typ 112)", OR_MAKE_LEICA_TYPEID(OR_TYPEID_LEICA_C_TYP112) },
573 
574  { 0, 0 }
575 };
576 
577 RawFile *Rw2File::factory(const IO::Stream::Ptr & s)
578 {
579  return new Rw2File(s);
580 }
581 
582 Rw2File::Rw2File(const IO::Stream::Ptr & s)
583  : IfdFile(s, OR_RAWFILE_TYPE_RW2, false)
584  , m_jfif_offset(0)
585  , m_jfif_size(0)
586 {
587  _setIdMap(s_def);
588  _setMatrices(s_matrices);
589  m_container = new Rw2Container(m_io, 0);
590 }
591 
592 Rw2File::~Rw2File()
593 {
594 }
595 
596 IfdDir::Ref Rw2File::_locateCfaIfd()
597 {
598  return mainIfd();
599 }
600 
601 IfdDir::Ref Rw2File::_locateMainIfd()
602 {
603  auto ifd = m_container->setDirectory(0);
604  if (ifd) {
605  ifd->setTagTable(raw_panasonic_tag_names);
606  ifd->setType(OR_IFD_MAIN);
607  }
608  return ifd;
609 }
610 
611 IfdDir::Ref Rw2File::_locateExifIfd()
612 {
613  auto _mainIfd = mainIfd();
614  if (!_mainIfd) {
615  LOGERR("IfdFile::_locateExifIfd() main IFD not found\n");
616  return IfdDir::Ref();
617  }
618  uint32_t offset = 0;
619  uint32_t size = 0;
620  auto& jfif = getJpegContainer(_mainIfd, offset, size);
621  if (!jfif) {
622  LOGDBG1("IfdFile::_locateExifIfd() JPEG container not found\n");
623  // the fall back is the regular IFD. Older RAW file use that.
624  auto exifIfd = IfdFile::_locateExifIfd();
625  if (exifIfd) {
626  return exifIfd;
627  }
628  return IfdDir::Ref();
629  }
630  return jfif->exifIfd();
631 }
632 
633 const std::unique_ptr<JfifContainer>&
634 Rw2File::getJpegContainer(const IfdDir::Ref& dir, uint32_t& offset, uint32_t& size)
635 {
636  if (!m_jfif) {
637  m_jfif_offset = _getJpegThumbnailOffset(dir, m_jfif_size);
638  if (m_jfif_size == 0) {
639  return m_jfif; // is it nullptr?
640  }
641  LOGDBG1("Jpeg offset: %u\n", m_jfif_offset);
642 
643  IO::Stream::Ptr s(new IO::StreamClone(m_io, m_jfif_offset));
644  m_jfif = std::make_unique<JfifContainer>(s, 0);
645  }
646  offset = m_jfif_offset;
647  size = m_jfif_size;
648  return m_jfif;
649 }
650 
651 ::or_error Rw2File::_locateThumbnail(const IfdDir::Ref & dir,
652  std::vector<uint32_t> &list)
653 {
654  uint32_t offset = 0;
655  uint32_t size = 0;
656 
657  auto& jfif = getJpegContainer(dir, offset, size);
658  if (!jfif) {
659  return OR_ERROR_NOT_FOUND;
660  }
661 
662  auto jdir = jfif->getIfdDirAt(1);
663  if (jdir) {
664  auto byte_count =
665  jdir->getValue<uint32_t>(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH).value_or(0);
666  auto result = jdir->getValue<uint32_t>(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT);
667  LOGDBG1("byte count %u\n", byte_count);
668  LOGASSERT(result.has_value());
669  if (result.has_value()) {
670  auto toffset = result.value();
671  LOGDBG1("toffset %u\n", toffset);
672  uint32_t tnail_offset = offset + toffset + jfif->exifOffset();
673  auto s = std::make_shared<IO::StreamClone>(m_io, tnail_offset);
674  auto tnail = std::make_unique<JfifContainer>(s, 0);
675 
676  uint32_t x = 0;
677  uint32_t y = 0;
678  if (tnail->getDimensions(x, y)) {
679  uint32_t dim = std::max(x, y);
680  _addThumbnail(dim, ThumbDesc(x, y, OR_DATA_TYPE_JPEG, tnail_offset, byte_count));
681  list.push_back(dim);
682  }
683  }
684 
685  }
686 
687  uint32_t x = 0;
688  uint32_t y = 0;
689  if (jfif->getDimensions(x,y)) {
690  LOGDBG1("JPEG dimensions x=%u y=%u\n", x, y);
691  uint32_t dim = std::max(x, y);
692  _addThumbnail(dim, ThumbDesc(x, y, OR_DATA_TYPE_JPEG, offset, size));
693  list.push_back(dim);
694  }
695 
696  return OR_ERROR_NONE;
697 }
698 
699 uint32_t Rw2File::_getJpegThumbnailOffset(const IfdDir::Ref& dir, uint32_t & len)
700 {
701  IfdEntry::Ref e = dir->getEntry(IFD::RW2_TAG_JPEG_FROM_RAW);
702  if (!e) {
703  len = 0;
704  LOGDBG1("JpegFromRaw not found\n");
705  return 0;
706  }
707  uint32_t offset = e->offset();
708  len = e->count();
709  return offset;
710 }
711 
712 
713 ::or_error Rw2File::_getRawData(RawData & data, uint32_t /*options*/)
714 {
716  const IfdDir::Ref & _cfaIfd = cfaIfd();
717  if (!_cfaIfd) {
718  LOGDBG1("cfa IFD not found\n");
719  return OR_ERROR_NOT_FOUND;
720  }
721 
722  LOGDBG1("_getRawData()\n");
723  uint32_t offset = 0;
724  uint32_t byte_length = 0;
725  // RW2 file
726  auto result = _cfaIfd->getIntegerValue(IFD::RW2_TAG_STRIP_OFFSETS);
727  if (result) {
728  offset = result.value();
729  byte_length = m_container->file()->filesize() - offset;
730  } else {
731  // RAW file alternative.
732  result = _cfaIfd->getIntegerValue(IFD::EXIF_TAG_STRIP_OFFSETS);
733  if (result.empty()) {
734  LOGDBG1("offset not found\n");
735  return OR_ERROR_NOT_FOUND;
736  }
737  offset = result.value();
738  result = _cfaIfd->getIntegerValue(IFD::EXIF_TAG_STRIP_BYTE_COUNTS);
739  if (result.empty()) {
740  LOGDBG1("byte len not found\n");
741  return OR_ERROR_NOT_FOUND;
742  }
743  byte_length = result.value();
744  }
745 
746  result = _cfaIfd->getIntegerValue(IFD::RW2_TAG_SENSOR_WIDTH);
747  if (result.empty()) {
748  LOGDBG1("X not found\n");
749  return OR_ERROR_NOT_FOUND;
750  }
751  uint32_t x = result.value();
752 
753  result = _cfaIfd->getIntegerValue(IFD::RW2_TAG_SENSOR_HEIGHT);
754  if (result.empty()) {
755  LOGDBG1("Y not found\n");
756  return OR_ERROR_NOT_FOUND;
757  }
758  uint32_t y = result.value();
759 
760  // this is were things are complicated. The real size of the raw data
761  // is whatever is read (if compressed)
762  void *p = data.allocData(byte_length);
763  size_t real_size = m_container->fetchData(p, offset,
764  byte_length);
765  if (real_size < byte_length) {
766  LOGDBG1("adjusting size");
767  data.adjustSize(real_size);
768  }
769  bool packed = false;
770  if ((x * y * 2) == real_size) {
771  data.setDataType(OR_DATA_TYPE_RAW);
772  } else if ((x * y * 3 / 2) == real_size) {
773  data.setDataType(OR_DATA_TYPE_RAW);
774  packed = true;
775  } else {
776  data.setDataType(OR_DATA_TYPE_COMPRESSED_RAW);
777  auto v = _cfaIfd->getValue<uint16_t>(RW2_TAG_IMAGE_COMPRESSION);
778  if (v) {
779  data.setCompression(v.value());
780  }
781  }
782  // It seems that they are all RGB
783  auto pattern = _cfaIfd->getValue<uint16_t>(RW2_TAG_IMAGE_CFAPATTERN);
784  if (!pattern) {
785  LOGERR("Pattern not found.\n");
786  } else {
787  auto v = pattern.value();
788  switch (v) {
789  case 1:
790  data.setCfaPatternType(OR_CFA_PATTERN_RGGB);
791  break;
792  case 2:
793  data.setCfaPatternType(OR_CFA_PATTERN_GRBG);
794  break;
795  case 3:
796  data.setCfaPatternType(OR_CFA_PATTERN_GBRG);
797  break;
798  case 4:
799  data.setCfaPatternType(OR_CFA_PATTERN_BGGR);
800  break;
801  default:
802  LOGERR("Pattern is %u (UNKNOWN).\n", v);
803  }
804  }
805 
806  data.setDimensions(x, y);
807  auto bpc = _cfaIfd->getValue<uint16_t>(RW2_TAG_IMAGE_BITSPERSAMPLE).value_or(0);
808  if (bpc != 0) {
809  data.setBpc(bpc);
810  }
811 
812  LOGDBG1("In size is %ux%u\n", data.width(), data.height());
813  // get the sensor info
814  // XXX what if it is not found?
815  x = _cfaIfd->getValue<uint16_t>(IFD::RW2_TAG_SENSOR_LEFTBORDER).value_or(0);
816  y = _cfaIfd->getValue<uint16_t>(IFD::RW2_TAG_SENSOR_TOPBORDER).value_or(0);
817  auto v = _cfaIfd->getValue<uint16_t>(IFD::RW2_TAG_SENSOR_BOTTOMBORDER);
818  int32_t h = v.value_or(0);
819  h -= y;
820  if (h < 0) {
821  h = 0;
822  }
823 
824  v = _cfaIfd->getValue<uint16_t>(IFD::RW2_TAG_SENSOR_RIGHTBORDER);
825  int32_t w = v.value_or(0);
826  w -= x;
827  if (w < 0) {
828  w = 0;
829  }
830 
831  data.setActiveArea(x, y, w, h);
832 
833  return ret;
834 }
835 
836 }
837 }
838 /*
839  Local Variables:
840  mode:c++
841  c-file-style:"stroustrup"
842  c-file-offsets:((innamespace . 0))
843  tab-width:4
844  c-basic-offset:4
845  indent-tabs-mode:nil
846  fill-column:80
847  End:
848 */
cloned stream. Allow reading from a different offset
Definition: streamclone.hpp:41
std::shared_ptr< Stream > Ptr
Definition: stream.hpp:47
std::shared_ptr< IfdDir > Ref
Shared ptr of an IfdDir.
Definition: ifddir.hpp:56
or_error
Error codes returned by libopenraw.
Definition: consts.h:42
@ OR_DATA_TYPE_JPEG
Definition: consts.h:84
@ OR_DATA_TYPE_COMPRESSED_RAW
Definition: consts.h:88
@ OR_DATA_TYPE_RAW
Definition: consts.h:87
@ OR_IFD_MAIN
Main (like in TIFF)
Definition: consts.h:144
@ OR_RAWFILE_TYPE_RW2
Definition: consts.h:72
@ OR_ERROR_NONE
Definition: consts.h:43
@ OR_ERROR_NOT_FOUND
Definition: consts.h:48
Global namespace for libopenraw.
Definition: arwfile.cpp:29