libopenraw  0.3.7
cr2file.cpp
1 /* -*- mode:c++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil; -*- */
2 /*
3  * libopenraw - cr2file.cpp
4  *
5  * Copyright (C) 2006-2022 Hubert Figuière
6  * Copyright (C) 2008 Novell, Inc.
7  *
8  * This library is free software: you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library. If not, see
20  * <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <stddef.h>
24 #include <cstdint>
25 #include <vector>
26 #include <limits>
27 #include <memory>
28 
29 #include <libopenraw/cameraids.h>
30 #include <libopenraw/consts.h>
31 #include <libopenraw/debug.h>
32 
33 #include "rawdata.hpp"
34 #include "rawfile.hpp"
35 #include "mosaicinfo.hpp"
36 #include "trace.hpp"
37 #include "io/memstream.hpp"
38 #include "ifdfilecontainer.hpp"
39 #include "ifdentry.hpp"
40 #include "makernotedir.hpp"
41 #include "cr2file.hpp"
42 #include "jfifcontainer.hpp"
43 #include "ljpegdecompressor.hpp"
44 #include "rawfile_private.hpp"
45 #include "canon.hpp"
46 
47 using namespace Debug;
48 
49 namespace OpenRaw {
50 
51 namespace Internals {
52 
57 #define OR_MAKE_CANON_TYPEID(camid) \
58  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON, camid)
59 
60 /* taken from dcraw, by default */
61 /* all relative to the D65 calibration illuminant */
62 static const BuiltinColourMatrix s_matrices[] = {
63  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKII),
64  0,
65  0xe80,
66  { 6264, -582, -724, -8312, 15948, 2504, -1744, 1919, 8664 } },
67  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKIIN),
68  0,
69  0xe80,
70  { 6240, -466, -822, -8180, 15825, 2500, -1801, 1938, 8042 } },
71  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKIII),
72  0,
73  0xe80,
74  { 6291, -540, -976, -8350, 16145, 2311, -1714, 1858, 7326 } },
75  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKIV),
76  0,
77  0x3bb0,
78  { 6014, -220, -795, -4109, 12014, 2361, -561, 1824, 5787 } },
79  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DSMKII),
80  0,
81  0xe80,
82  { 6517, -602, -867, -8180, 15926, 2378, -1618, 1771, 7633 } },
83  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DSMKIII),
84  0,
85  0x3bb0,
86  { 5859, -211, -930, -8255, 16017, 2353, -1732, 1887, 7448 } },
87  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DX),
88  0,
89  0x3c4e,
90  { 6847, -614, -1014, -4669, 12737, 2139, -1197, 2488, 6846 } },
91  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DXMKII),
92  0,
93  0x3c4e,
94  { 7596, -978, -967, -4808, 12571, 2503, -1398, 2567, 5752 } },
95  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_20D),
96  0,
97  0xfff,
98  { 6599, -537, -891, -8071, 15783, 2424, -1983, 2234, 7462 } },
99  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_20DA),
100  0,
101  0,
102  { 14155, -5065, -1382, -6550, 14633, 2039, -1623, 1824, 6561 } },
103  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_30D),
104  0,
105  0,
106  { 6257, -303, -1000, -7880, 15621, 2396, -1714, 1904, 7046 } },
107  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_350D),
108  0,
109  0xfff,
110  { 6018, -617, -965, -8645, 15881, 2975, -1530, 1719, 7642 } },
111  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_40D),
112  0,
113  0x3f60,
114  { 6071, -747, -856, -7653, 15365, 2441, -2025, 2553, 7315 } },
115  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_400D),
116  0,
117  0xe8e,
118  { 7054, -1501, -990, -8156, 15544, 2812, -1278, 1414, 7796 } },
119  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_450D),
120  0,
121  0x390d,
122  { 5784, -262, -821, -7539, 15064, 2672, -1982, 2681, 7427 } },
123  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_50D),
124  0,
125  0x3d93,
126  { 4920, 616, -593, -6493, 13964, 2784, -1774, 3178, 7005 } },
127  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_500D),
128  0,
129  0x3479,
130  { 4763, 712, -646, -6821, 14399, 2640, -1921, 3276, 6561 } },
131  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_550D),
132  0,
133  0x3dd7,
134  { 6941, -1164, -857, -3825, 11597, 2534, -416, 1540, 6039 } },
135  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_600D),
136  0,
137  0x3510,
138  { 6461, -907, -882, -4300, 12184, 2378, -819, 1944, 5931 } },
139  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_60D),
140  0,
141  0x2ff7,
142  { 6719, -994, -925, -4408, 12426, 2211, -887, 2129, 6051 } },
143  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_650D),
144  0,
145  0x354d,
146  { 6602, -841, -939, -4472, 12458, 2247, -975, 2039, 6148 } },
147  // from DNG Convert 7.4
148  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_700D),
149  0,
150  0x3c00,
151  { 6602, -841, -939, -4472, 12458, 2247, -975, 2039, 6148 } },
152  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_80D),
153  0,
154  0,
155  { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } },
156  // From DNG Converter 10.3
157  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_800D),
158  0,
159  0,
160  { 6970, -512, -968, -4425, 12161, 2553, -739, 1982, 5601 } },
161  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_100D),
162  0,
163  0x350f,
164  { 6602, -841, -939, -4472, 12458, 2247, -975, 2039, 6148 } },
165  // From DNG Converter 10.3
166  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_200D),
167  0,
168  0x350f,
169  { 7377, -742, -998, -4235, 11981, 2549, -673, 1918, 5538 } },
170  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1000D),
171  0,
172  0xe43,
173  { 6771, -1139, -977, -7818, 15123, 2928, -1244, 1437, 7533 } },
174  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1100D),
175  0,
176  0x3510,
177  { 6444, -904, -893, -4563, 12308, 2535, -903, 2016, 6728 } },
178  // from DNG Convert 7.4
179  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_100D),
180  0,
181  0x3806,
182  { 6602, -841, -939, -4472, 12458, 2247, -975, 2039, 6148 } },
183  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1200D), // Rebel T5
184  0,
185  0x37c2,
186  { 6461, -907, -882, -4300, 12184, 2378, -819, 1944, 5931 } },
187  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1300D), // Rebel T6
188  0,
189  0x3510,
190  { 6939, -1016, -866, -4428, 12473, 2177, -1175, 2178, 6162 } },
191  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_2000D), // Rebel T7
192  0,
193  0,
194  { 8532, -701, -1167, -4095, 11879, 2508, -797, 2424, 7010 } },
195  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_3000D), // 4000D, Rebel T100
196  0,
197  0,
198  { 6939, -1016, -866, -4428, 12473, 2177, -1175, 2178, 6162 } },
199  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5D),
200  0,
201  0xe6c,
202  { 6347, -479, -972, -8297, 15954, 2480, -1968, 2131, 7649 } },
203  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKII),
204  0,
205  0x3cf0,
206  { 4716, 603, -830, -7798, 15474, 2480, -1496, 1937, 6651 } },
207  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKIII),
208  0,
209  0,
210  { 6722, -635, -963, -4287, 12460, 2028, -908, 2162, 5668 } },
211  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKIV),
212  0,
213  0x3bb0,
214  { 6014, -220, -795, -4109, 12014, 2361, -561, 1824, 5787 } },
215  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DS),
216  0,
217  0xe6c,
218  { 6250, -711, -808, -5153, 12794, 2636, -1249, 2198, 5610 } },
219  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DS_R),
220  0,
221  0xe6c,
222  { 6250, -711, -808, -5153, 12794, 2636, -1249, 2198, 5610 } },
223  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_6D),
224  0,
225  0x3c82,
226  { 7034, -804, -1014, -4420, 12564, 2058, -851, 1994, 5758 } },
227  // From DNG Converter 10.3
228  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_6DMKII),
229  0,
230  0,
231  { 6875, -970, -932, -4691, 12459, 2501, -874, 1953, 5809 } },
232  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_7D),
233  0,
234  0x3510,
235  { 6844, -996, -856, -3876, 11761, 2396, -593, 1772, 6198 } },
236  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_7DMKII),
237  0,
238  0x3510,
239  { 7268, -1082, -969, -4186, 11839, 2663, -825, 2029, 5839 } },
240  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_70D),
241  0,
242  0x3bc7,
243  { 7034, -804, -1014, -4420, 12564, 2058, -851, 1994, 5758 } },
244  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_750D),
245  0,
246  0x368e,
247  { 6362, -823, -847, -4426, 12109, 2616, -743, 1857, 5635 } },
248  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_760D),
249  0,
250  0x350f,
251  { 6362, -823, -847, -4426, 12109, 2616, -743, 1857, 5635 } },
252  // Fron DNG Converter 10.3
253  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_77D),
254  0,
255  0,
256  { 7377, -742, -998, -4235, 11981, 2549, -673, 1918, 5538 } },
257  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M),
258  0,
259  0,
260  { 6602, -841, -939, -4472, 12458, 2247, -975, 2039, 6148 } },
261  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M2),
262  0,
263  0,
264  { 6400, -480, -888, -5294, 13416, 2047, -1296, 2203, 6137 } },
265  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M3),
266  0,
267  0,
268  { 6362, -823, -847, -4426, 12109, 2616, -743, 1857, 5635 } },
269  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M5),
270  0,
271  0,
272  { 8532, -701, -1167, -4095, 11879, 2508, -797, 2424, 7010 } },
273  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M6),
274  0,
275  0,
276  { 8532, -701, -1167, -4095, 11879, 2508, -797, 2424, 7010 } },
277  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M10),
278  0,
279  0,
280  { 6400, -480, -888, -5294, 13416, 2047, -1296, 2203, 6137 } },
281  // From DNG Converter 10.3
282  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M100),
283  0,
284  0,
285  { 8532, -701, -1167, -4095, 11879, 2508, -797, 2424, 7010 } },
286  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9),
287  0,
288  0,
289  { 7368, -2141, -598, -5621, 13254, 2625, -1418, 1696, 5743 } },
290  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G10),
291  0,
292  0,
293  { 11093, -3906, -1028, -5047, 12492, 2879, -1003, 1750, 5561 } },
294  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G11),
295  0,
296  0,
297  { 12177, -4817, -1069, -1612, 9864, 2049, -98, 850, 4471 } },
298  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G12),
299  0,
300  0,
301  { 13244, -5501, -1248, -1508, 9858, 1935, -270, 1083, 4366 } },
302  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G15),
303  0,
304  0,
305  { 7474, -2301, -567, -4056, 11456, 2975, -222, 716, 4181 } },
306  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G16),
307  0,
308  0,
309  { 8020, -2687, -682, -3704, 11879, 2052, -965, 1921, 5556 } },
310  // From DNG Converter 7.1-rc
311  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1X),
312  0,
313  0,
314  { 7378, -1255, -1043, -4088, 12251, 2048, -876, 1946, 5805 } },
315  // From DNG Converter 8.7-rc
316  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1XMKII),
317  0,
318  0,
319  { 7378, -1255, -1043, -4088, 12251, 2048, -876, 1946, 5805 } },
320  // From DNG Converter 10.3
321  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1XMKIII),
322  0,
323  0,
324  { 8532, -701, -1167, -4095, 11879, 2508, -797, 2424, 7010 } },
325  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G3X),
326  0,
327  0,
328  { 9701, -3857, -921, -3149, 11537, 1817, -786, 1817, 5147 } },
329  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G5X),
330  0,
331  0,
332  { 9602, -3823, -937, -2984, 11495, 1675, -407, 1415, 5049 } },
333  // From DNG Converter 10.3
334  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G7X),
335  0,
336  0,
337  { 9602, -3823, -937, -2984, 11495, 1675, -407, 1415, 5049 } },
338  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G7XMKII),
339  0,
340  0,
341  { 9602, -3823, -937, -2984, 11495, 1675, -407, 1415, 5049 } },
342  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9X),
343  0,
344  0,
345  { 9602, -3823, -937, -2984, 11495, 1675, -407, 1415, 5049 } },
346  // From DNG Converter 10.3
347  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9XMKII),
348  0,
349  0,
350  { 10056, -4131, -944, -2576, 11143, 1625, -238, 1294, 5179} },
351  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S90),
352  0,
353  0,
354  { 12374, -5016, -1049, -1677, 9902, 2078, -83, 852, 4683 } },
355  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S95),
356  0,
357  0,
358  { 13440, -5896, -1279, -1236, 9598, 1931, -180, 1001, 4651 } },
359  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S100),
360  0,
361  0,
362  { 7968, -2565, -636, -2873, 10697, 2513, 180, 667, 4211 } },
363  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S100V),
364  0,
365  0,
366  { 7968, -2565, -636, -2873, 10697, 2513, 180, 667, 4211 } },
367  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S110),
368  0,
369  0,
370  { 8039, -2643, -654, -3783, 11230, 2930, -206, 690, 4194 } },
371  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S120),
372  0,
373  0,
374  { 6961, -1685, -695, -4625, 12945, 1836, -1114, 2152, 5518 } },
375  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_SX50_HS),
376  0,
377  0,
378  { 12432, -4753, -1247, -2110, 10691, 1629, -412, 1623, 4926 } },
379  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_SX60_HS),
380  0,
381  0,
382  { 13161, -5451, -1344, -1989, 10654, 1531, -47, 1271, 4955 } },
383  { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_SX1_IS),
384  0,
385  0,
386  { 6578, -259, -502, -5974, 13030, 3309, -308, 1058, 4970 } },
387 
388  /*
389  { "Canon EOS-1DS", 0, 0xe20,
390  { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
391  { "Canon EOS-1D", 0, 0xe20,
392  { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
393  */
394  { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
395 };
396 
397 const IfdFile::camera_ids_t Cr2File::s_def[] = {
398  { "Canon EOS-1D Mark II", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKII) },
399  { "Canon EOS-1D Mark III", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKIII) },
400  { "Canon EOS-1D Mark IV", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKIV) },
401  { "Canon EOS-1Ds Mark II", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DSMKII) },
402  { "Canon EOS-1Ds Mark III",
403  OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DSMKIII) },
404  { "Canon EOS-1D X", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DX) },
405  { "Canon EOS-1D X Mark II", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DXMKII) },
406  { "Canon EOS 20D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_20D) },
407  { "Canon EOS 20Da", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_20DA) },
408  { "Canon EOS 30D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_30D) },
409  { "Canon EOS 350D DIGITAL", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_350D) },
410  { "Canon EOS DIGITAL REBEL XT",
411  OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_XT) },
412  { "Canon EOS Kiss Digital N", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_KISS_DIGITAL_N) },
413  { "Canon EOS 40D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_40D) },
414  { "Canon EOS 400D DIGITAL", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_400D) },
415  { "Canon EOS 450D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_450D) },
416  { "Canon EOS DIGITAL REBEL XSi", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_XSI) },
417  { "Canon EOS 50D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_50D) },
418  { "Canon EOS 500D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_500D) },
419  { "Canon EOS 550D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_550D) },
420  { "Canon EOS REBEL T2i", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T2I) },
421  { "Canon EOS 600D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_600D) },
422  { "Canon EOS REBEL T3i", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T3I) },
423  { "Canon EOS 60D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_60D) },
424  { "Canon EOS 650D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_650D) },
425  { "Canon EOS REBEL T4i", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T4I) },
426  { "Canon EOS 70D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_70D) },
427  { "Canon EOS 700D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_700D) },
428  { "Canon EOS 750D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_750D) },
429  { "Canon EOS 760D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_760D) },
430  { "Canon EOS 80D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_80D) },
431  { "Canon EOS 800D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_800D) },
432  { "Canon EOS REBEL T1i", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T1I) },
433  { "Canon EOS Rebel T5", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T5) },
434  { "Canon EOS REBEL T5i", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T5I) },
435  { "Canon EOS Rebel T6i", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T6I) },
436  { "Canon EOS Rebel T6s", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T6S) },
437  { "Canon EOS Rebel T6", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T6) },
438  { "Canon EOS Rebel T7i", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T7I) },
439  { "Canon EOS Rebel T7", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T7) },
440  { "Canon EOS 1000D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1000D) },
441  { "Canon EOS 2000D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_2000D) },
442  { "Canon EOS DIGITAL REBEL XS",
443  OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_XS) },
444  { "Canon EOS 1100D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1100D) },
445  { "Canon EOS 1200D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1200D) },
446  { "Canon EOS 1300D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1300D) },
447  { "Canon EOS REBEL T3", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_T3) },
448  { "Canon EOS 100D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_100D) },
449  { "Canon EOS REBEL SL1", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_SL1) },
450  { "Canon EOS 200D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_200D) },
451  { "Canon EOS Rebel SL2", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_REBEL_SL2) },
452  { "Canon EOS 5D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5D) },
453  { "Canon EOS 5D Mark II", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKII) },
454  { "Canon EOS 5D Mark III", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKIII) },
455  { "Canon EOS 5D Mark IV", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKIV) },
456  { "Canon EOS 5DS", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DS) },
457  { "Canon EOS 5DS R", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DS_R) },
458  { "Canon EOS 6D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_6D) },
459  { "Canon EOS 6D Mark II", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_6DMKII) },
460  { "Canon EOS 7D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_7D) },
461  { "Canon EOS 7D Mark II", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_7DMKII) },
462  { "Canon EOS 77D", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_77D) },
463  { "Canon EOS Kiss X3", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_KISS_X3) },
464  { "Canon EOS M", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M) },
465  { "Canon EOS M10", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M10) },
466  { "Canon EOS M100", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M100) },
467  { "Canon EOS M2", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M2) },
468  { "Canon EOS M3", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M3) },
469  { "Canon EOS M5", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M5) },
470  { "Canon EOS M6", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M6) },
471  { "Canon PowerShot G9", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9) },
472  { "Canon PowerShot G10", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G10) },
473  { "Canon PowerShot G11", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G11) },
474  { "Canon PowerShot G12", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G12) },
475  { "Canon PowerShot G15", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G15) },
476  { "Canon PowerShot G16", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G16) },
477  { "Canon PowerShot G1 X", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1X) },
478  { "Canon PowerShot G1 X Mark II",
479  OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1XMKII) },
480  { "Canon PowerShot G1 X Mark III",
481  OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1XMKIII) },
482  { "Canon PowerShot G3 X", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G3X) },
483  { "Canon PowerShot G5 X", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G5X) },
484  { "Canon PowerShot G7 X", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G7X) },
485  { "Canon PowerShot G7 X Mark II", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G7XMKII) },
486  { "Canon PowerShot G9 X", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9X) },
487  { "Canon PowerShot G9 X Mark II", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9XMKII) },
488  { "Canon PowerShot S90", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S90) },
489  { "Canon PowerShot S95", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S95) },
490  { "Canon PowerShot S100", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S100) },
491  { "Canon PowerShot S100V", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S100V) },
492  { "Canon PowerShot S110", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S110) },
493  { "Canon PowerShot SX50 HS",
494  OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_SX50_HS) },
495  { 0, 0 }
496 };
497 
498 RawFile *Cr2File::factory(const IO::Stream::Ptr &s)
499 {
500  return new Cr2File(s);
501 }
502 
503 Cr2File::Cr2File(const IO::Stream::Ptr &s) : IfdFile(s, OR_RAWFILE_TYPE_CR2)
504 {
505  _setIdMap(s_def);
506  _setMatrices(s_matrices);
507 }
508 
509 Cr2File::~Cr2File()
510 {
511 }
512 
513 IfdDir::Ref Cr2File::_locateCfaIfd()
514 {
515  if (!isCr2()) {
516  return makerNoteIfd();
517  }
518  auto ifd = m_container->setDirectory(3);
519  if (ifd) {
520  ifd->setType(OR_IFD_RAW);
521  }
522  return ifd;
523 }
524 
525 IfdDir::Ref Cr2File::_locateMainIfd()
526 {
527  auto ifd = m_container->setDirectory(0);
528  if (ifd) {
529  ifd->setType(OR_IFD_MAIN);
530  }
531  return ifd;
532 }
533 
534 ::or_error Cr2File::_locateThumbnail(const IfdDir::Ref & dir,
535  std::vector<uint32_t> &list)
536 {
537  if (isCr2()) {
538  return IfdFile::_locateThumbnail(dir, list);
539  }
541  ::or_data_type _type = OR_DATA_TYPE_NONE;
542  uint32_t x = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_WIDTH).value_or(0);
543  uint32_t y = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_LENGTH).value_or(0);
544  uint32_t offset = 0;
545  uint32_t byte_count = dir->getValue<uint32_t>(IFD::EXIF_TAG_STRIP_BYTE_COUNTS).value_or(0);
546 
547  auto result = dir->getValue<uint32_t>(IFD::EXIF_TAG_STRIP_OFFSETS);
548  bool got_it = result.has_value();
549  if (got_it) {
550  offset = result.value();
551  }
552 
553  if (x != 0 && y != 0) {
554  // See bug 72270 - some CR2 have 16 bpc RGB thumbnails.
555  // by default it is RGB8. Unless stated otherwise.
556  bool isRGB8 = true;
557  IfdEntry::Ref entry = dir->getEntry(IFD::EXIF_TAG_BITS_PER_SAMPLE);
558  auto result2 = dir->getEntryArrayValue<uint16_t>(*entry);
559  if (result2) {
560  std::vector<uint16_t> arr = result2.value();
561  for(auto bpc : arr) {
562  isRGB8 = (bpc == 8);
563  if (!isRGB8) {
564  LOGDBG1("bpc != 8, not RGB8 %u\n", bpc);
565  break;
566  }
567  }
568  } else {
569  LOGDBG1("Error getting BPS\n");
570  }
571  if (isRGB8) {
572  _type = OR_DATA_TYPE_PIXMAP_8RGB;
573  }
574  }
575 
576  if(_type != OR_DATA_TYPE_NONE) {
577  uint32_t dim = std::max(x, y);
578  offset += dir->container().offset();
579  _addThumbnail(dim, ThumbDesc(x, y, _type,
580  offset, byte_count));
581  list.push_back(dim);
582  ret = OR_ERROR_NONE;
583  }
584  return ret;
585 }
586 
587 ::or_error Cr2File::getRawDataTif(RawData &data, uint32_t options)
588 {
589  const IfdDir::Ref &_cfaIfd = cfaIfd();
590  if (!_cfaIfd) {
591  LOGDBG1("cfa IFD not found\n");
592  return OR_ERROR_NOT_FOUND;
593  }
594 
595  auto result = _cfaIfd->getValue<uint32_t>(IFD::MNOTE_CANON_RAW_DATA_OFFSET);
596  if (result.empty()) {
597  LOGDBG1("offset not found\n");
598  return OR_ERROR_NOT_FOUND;
599  }
600  uint32_t offset = result.value();
601  uint32_t byte_length = 0;
602 
603  result = _cfaIfd->getValue<uint32_t>(IFD::MNOTE_CANON_RAW_DATA_LENGTH);
604  if (!result.empty()) {
605  byte_length = result.value();
606  } else {
607  LOGDBG1("byte len not found\n");
608  auto len = std::min<off_t>(
609  m_container->size(), std::numeric_limits<uint32_t>::max());
610  byte_length = len - offset;
611  }
612 
613  std::vector<uint16_t> slices;
614 
615  getRawBytes(data, offset, byte_length, 0, 0, slices, options);
616  return OR_ERROR_NONE;
617 }
618 
619 void Cr2File::getRawBytes(RawData &data, uint32_t offset, uint32_t byte_length,
620  uint16_t x, uint16_t y,
621  const std::vector<uint16_t>& slices,
622  uint32_t options)
623 {
624  void *p = data.allocData(byte_length);
625  size_t real_size = m_container->fetchData(p, offset, byte_length);
626  if (real_size < byte_length) {
627  LOGWARN("Size mismatch for data: ignoring.\n");
628  }
629  // they are not all RGGB.
630  // but I don't seem to see where this is encoded.
631  //
632  data.setCfaPatternType(OR_CFA_PATTERN_RGGB);
633  data.setDataType(OR_DATA_TYPE_COMPRESSED_RAW);
634  data.setDimensions(x, y);
635 
636  LOGDBG1("In size is %dx%d\n", data.width(), data.height());
637  // decompress if we need
638  if ((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) {
639  IO::Stream::Ptr s(new IO::MemStream((const uint8_t*)data.data(),
640  data.size()));
641  s->open(); // TODO check success
642  auto jfif = std::make_unique<JfifContainer>(s, 0);
643  LJpegDecompressor decomp(s.get(), jfif.get());
644  // in fact on Canon CR2 files slices either do not exists
645  // or is 3.
646  if (slices.size() > 1) {
647  decomp.setSlices(slices);
648  }
649  RawDataPtr dData = decomp.decompress();
650  if (dData) {
651  LOGDBG1("Out size is %dx%d\n", dData->width(), dData->height());
652  // must re-set the cfaPattern and photometric interpretation
653  dData->setCfaPatternType(data.mosaicInfo()->patternType());
654  dData->setPhotometricInterpretation(data.getPhotometricInterpretation());
655  data.swap(*dData);
656  if (!isCr2()) {
657  // In TIF the raw image width needs to be divided by two
658  uint16_t w = data.width();
659  uint16_t h = data.height();
660  data.setDimensions(w / 2, h);
661  }
662  }
663  }
664 }
665 
666 ::or_error Cr2File::getRawDataCr2(RawData &data, uint32_t options)
667 {
668  const IfdDir::Ref &_cfaIfd = cfaIfd();
669  if (!_cfaIfd) {
670  LOGDBG1("cfa IFD not found\n");
671  return OR_ERROR_NOT_FOUND;
672  }
673 
674  LOGDBG1("_getRawData()\n");
675 
676  auto result = _cfaIfd->getValue<uint32_t>(IFD::EXIF_TAG_STRIP_OFFSETS);
677  if (result.empty()) {
678  LOGDBG1("offset not found\n");
679  return OR_ERROR_NOT_FOUND;
680  }
681  uint32_t offset = result.value();
682 
683  result = _cfaIfd->getValue<uint32_t>(IFD::EXIF_TAG_STRIP_BYTE_COUNTS);
684  if (result.empty()) {
685  LOGDBG1("byte len not found\n");
686  return OR_ERROR_NOT_FOUND;
687  }
688  uint32_t byte_length = result.value();
689 
690  // get the "slicing", tag 0xc640 (3 SHORT)
691  std::vector<uint16_t> slices;
692  IfdEntry::Ref e = _cfaIfd->getEntry(IFD::CR2_TAG_SLICE);
693  if (e) {
694  auto result2 = _cfaIfd->getEntryArrayValue<uint16_t>(*e);
695  if (result2) {
696  slices = result2.value();
697  LOGDBG1("Found slice entry count %lu\n", (LSIZE)slices.size());
698  }
699  }
700 
701  const IfdDir::Ref &_exifIfd = exifIfd();
702  if (!_exifIfd) {
703  LOGERR("unable to find ExifIFD\n");
704  return OR_ERROR_NOT_FOUND;
705  }
706 
707  auto result2 = _exifIfd->getValue<uint16_t>(IFD::EXIF_TAG_PIXEL_X_DIMENSION);
708  if (result2.empty()) {
709  LOGDBG1("X not found\n");
710  return OR_ERROR_NOT_FOUND;
711  }
712  uint16_t x = result2.value();
713 
714  result2 = _exifIfd->getValue<uint16_t>(IFD::EXIF_TAG_PIXEL_Y_DIMENSION);
715  if (result2.empty()) {
716  LOGDBG1("Y not found\n");
717  return OR_ERROR_NOT_FOUND;
718  }
719  uint16_t y = result2.value();
720 
721  getRawBytes(data, offset, byte_length, x, y, slices, options);
722 
723  // get the sensor info
724  const IfdDir::Ref &_makerNoteIfd = makerNoteIfd();
725  auto sensorInfo = canon_get_sensorinfo(_makerNoteIfd);
726  if (sensorInfo) {
727  data.setActiveArea((*sensorInfo)[0], (*sensorInfo)[1],
728  (*sensorInfo)[2], (*sensorInfo)[3]);
729  }
730 
731  return OR_ERROR_NONE;
732 }
733 
734 ::or_error Cr2File::_getRawData(RawData &data, uint32_t options)
735 {
736  if (!isCr2()) {
737  return getRawDataTif(data, options);
738  }
739  return getRawDataCr2(data, options);
740 }
741 
742 bool Cr2File::vendorCameraIdLocation(Internals::IfdDir::Ref& ifd, uint16_t& index,
743  const ModelIdMap*& model_map)
744 {
745  auto mn = makerNoteIfd();
746  if (mn) {
747  // There is a camera model ID in the MakerNote tag 0x0010.
748  ifd = mn;
749  index = IFD::MNOTE_CANON_MODEL_ID;
750  model_map = &canon_modelid_map;
751  return true;
752  }
753  return false;
754 }
755 
756 bool Cr2File::isCr2()
757 {
758  return ((OR_GET_FILE_TYPEID_CAMERA(typeId()) != OR_TYPEID_CANON_1D)
759  && (OR_GET_FILE_TYPEID_CAMERA(typeId()) != OR_TYPEID_CANON_1DS));
760 }
761 
764 }
765 }
766 
std::shared_ptr< IfdDir > Ref
Shared ptr of an IfdDir.
Definition: ifddir.hpp:56
Option< std::array< uint32_t, 4 > > canon_get_sensorinfo(const IfdDir::Ref &ifddir)
Get the sensor info from and IfdDir.
Definition: canon.cpp:178
const ModelIdMap canon_modelid_map
The model ID map for Canon cameras.
Definition: canon.cpp:35
#define OR_GET_FILE_TYPEID_CAMERA(ftypeid)
Get the camera from the or_rawfile_typeid.
Definition: consts.h:137
or_data_type
Data types.
Definition: consts.h:80
or_error
Error codes returned by libopenraw.
Definition: consts.h:42
@ CR2_TAG_SLICE
Definition: exif.h:192
@ OR_DATA_TYPE_COMPRESSED_RAW
Definition: consts.h:88
@ OR_DATA_TYPE_PIXMAP_8RGB
Definition: consts.h:82
@ OR_OPTIONS_DONT_DECOMPRESS
Definition: consts.h:114
@ OR_IFD_RAW
RAW data.
Definition: consts.h:150
@ OR_IFD_MAIN
Main (like in TIFF)
Definition: consts.h:144
@ OR_RAWFILE_TYPE_CR2
Definition: consts.h:61
@ OR_ERROR_NONE
Definition: consts.h:43
@ OR_ERROR_NOT_FOUND
Definition: consts.h:48
std::map< uint32_t, ::or_rawfile_typeid > ModelIdMap
Definition: rawfile.hpp:54
Global namespace for libopenraw.
Definition: arwfile.cpp:29