libopenraw  0.3.7
canon.cpp
1 /* -*- mode:c++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil; -*- */
2 /*
3  * libopenraw - canon.cpp
4  *
5  * Copyright (C) 2018-2022 Hubert Figuière
6  *
7  * This library is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation, either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <array>
23 
24 #include "canon.hpp"
25 #include "ifddir.hpp"
26 #include "option.hpp"
27 #include "trace.hpp"
28 
29 namespace OpenRaw {
30 namespace Internals {
31 
32 #define OR_MAKE_CANON_TYPEID(camid) \
33  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON, camid)
34 
36  // TIF
37  { 0x80000001, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1D) },
38  { 0x80000167, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DS) },
39  // CRW and CR2
40  { 0x80000174, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKII) },
41  { 0x80000175, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_20D) },
42  { 0x80000188, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DSMKII) },
43  { 0x80000189, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_350D) },
44  { 0x80000213, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5D) },
45  { 0x80000232, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKIIN) },
46  { 0x80000234, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_30D) },
47  { 0x80000236, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_400D) },
48  { 0x80000169, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKIII) },
49  { 0x80000190, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_40D) },
50  { 0x80000215, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DSMKIII) },
51  { 0x02230000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9) },
52  { 0x80000176, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_450D) },
53  { 0x80000254, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1000D) },
54  { 0x80000261, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_50D) },
55  { 0x02490000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G10) },
56  { 0x80000218, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKII) },
57  { 0x02460000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_SX1_IS) },
58  { 0x80000252, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_500D) },
59  { 0x02700000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G11) },
60  { 0x02720000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S90) },
61  { 0x80000250, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_7D) },
62  { 0x80000281, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DMKIV) },
63  { 0x80000270, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_550D) },
64  { 0x02950000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S95) },
65  { 0x80000287, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_60D) },
66  { 0x02920000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G12) },
67  { 0x80000286, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_600D) },
68  { 0x80000288, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1100D) },
69  { 0x03110000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S100) },
70  { 0x80000269, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DX) },
71  { 0x03080000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1X) },
72  { 0x80000285, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKIII) },
73  { 0x80000301, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_650D) },
74  { 0x80000331, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M) },
75  { 0x03320000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S100V) },
76  { 0x03360000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S110) },
77  { 0x03330000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G15) },
78  { 0x03340000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_SX50_HS) },
79  { 0x80000302, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_6D) },
80  { 0x80000326, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_700D) },
81  { 0x80000346, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_100D) },
82  { 0x80000325, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_70D) },
83  { 0x03540000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G16) },
84  { 0x03550000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S120) },
85  { 0x80000355, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M2) },
86  { 0x80000327, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1200D) },
87  { 0x03640000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1XMKII) },
88  { 0x80000289, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_7DMKII) },
89  { 0x03780000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G7X) },
90  { 0x03750000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_SX60_HS) },
91  { 0x80000382, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DS) },
92  { 0x80000401, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DS_R) },
93  { 0x80000393, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_750D) },
94  { 0x80000347, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_760D) },
95  { 0x03740000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M3) },
96  { 0x03850000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G3X) },
97  { 0x03950000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G5X) },
98  { 0x03930000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9X) },
99  { 0x03840000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M10) },
100  { 0x80000328, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DXMKII) },
101  { 0x80000350, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_80D) },
102  { 0x03970000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G7XMKII) },
103  { 0x80000404, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1300D) },
104  { 0x80000349, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_5DMKIV) },
105  { 0x03940000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M5) },
106  { 0x04100000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G9XMKII) },
107  { 0x80000405, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_800D) },
108  { 0x80000408, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_77D) },
109  { 0x04070000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M6) },
110  { 0x80000417, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_200D) },
111  { 0x80000406, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_6DMKII) },
112  { 0x03980000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M100) },
113  { 0x04180000, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1XMKIII) },
114  { 0x80000432, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_2000D) },
115  { 0x80000422, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_3000D) },
116  // CR3
117  { 0x00000412, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M50) },
118  { 0x80000424, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R) },
119  { 0x80000433, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_RP) },
120  { 0x80000421, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R5) },
121  { 0x80000453, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R6) },
122  { 0x80000436, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_250D) },
123  { 0x00000804, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G5XMKII) },
124  { 0x00000805, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_SX70_HS) },
125  { 0x00000808, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G7XMKIII) },
126  { 0x80000437, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_90D) },
127  { 0x00000811, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M6MKII) },
128  { 0x00000812, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M200) },
129  { 0x80000428, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_1DXMKIII) },
130  { 0x80000435, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_850D) },
131  { 0x80000468, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_M50MKII) },
132  { 0x80000450, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R3) },
133  { 0x80000464, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R7) },
134  { 0x80000465, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R10) },
135  { 0x80000480, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R50) },
136  { 0x80000481, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R6MKII) },
137  { 0x80000487, OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_EOS_R8) },
138 };
139 
141 canon_parse_sensorinfo(const std::vector<uint16_t>& sensor_info)
142 {
143  if (sensor_info.size() > 8) {
144  std::array<uint32_t, 4> result;
145  result[0] = sensor_info[5];
146  result[1] = sensor_info[6];
147  if (sensor_info[7] <= sensor_info[5]) {
148  LOGWARN("sensor_info: bottom %u <= top %u\n",
149  sensor_info[7], sensor_info[5]);
150  return OptionNone();
151  }
152  uint32_t w = sensor_info[7] - sensor_info[5];
153  // it seems that this could lead to an odd number. Make it even.
154  if (w % 2) {
155  w++;
156  }
157  result[2] = w;
158  if (sensor_info[8] <= sensor_info[6]) {
159  LOGWARN("sensor_info: right %u <= left %u\n",
160  sensor_info[8], sensor_info[6]);
161  return OptionNone();
162  }
163  uint32_t h = sensor_info[8] - sensor_info[6];
164  // same as for width
165  if (h % 2) {
166  h++;
167  }
168  result[3] = h;
169  return option_some(std::move(result));
170  }
171  else {
172  LOGWARN("SensorInfo is too small: %lu - skipping.\n",
173  (LSIZE)sensor_info.size());
174  }
175  return OptionNone();
176 }
177 
179 {
180  auto e = ifddir->getEntry(IFD::MNOTE_CANON_SENSORINFO);
181  if (!e) {
182  return OptionNone();
183  }
184  auto result = ifddir->getEntryArrayValue<uint16_t>(*e);
185  if (result) {
186  return canon_parse_sensorinfo(result.value());
187  }
188  return OptionNone();
189 }
190 
191 }
192 }
std::shared_ptr< IfdDir > Ref
Shared ptr of an IfdDir.
Definition: ifddir.hpp:56
Tag class to help create an empty Option.
Definition: option.hpp:41
An option type inspired by Rust.
Definition: option.hpp:47
Option< std::array< uint32_t, 4 > > canon_get_sensorinfo(const IfdDir::Ref &ifddir)
Get the sensor info from and IfdDir.
Definition: canon.cpp:178
Option< std::array< uint32_t, 4 > > canon_parse_sensorinfo(const std::vector< uint16_t > &sensor_info)
Parse the sensor info from a buffer of uint16_t.
Definition: canon.cpp:141
const ModelIdMap canon_modelid_map
The model ID map for Canon cameras.
Definition: canon.cpp:35
Option< T > option_some(T &&value)
Create an Option<T> is some value.
Definition: option.hpp:131
std::map< uint32_t, ::or_rawfile_typeid > ModelIdMap
Definition: rawfile.hpp:54
Global namespace for libopenraw.
Definition: arwfile.cpp:29