1#------------------------------------------------------------------------------
2# File:         Canon.pm
3#
4# Description:  Canon EXIF maker notes tags
5#
6# Revisions:    11/25/2003 - P. Harvey Created
7#               12/03/2003 - P. Harvey Decode lots more tags and add CanonAFInfo
8#               02/17/2004 - Michael Rommel Added IxusAFPoint
9#               01/27/2005 - P. Harvey Disable validation of CanonAFInfo
10#               01/30/2005 - P. Harvey Added a few more tags (ref 4)
11#               02/10/2006 - P. Harvey Decode a lot of new tags (ref 12)
12#               [ongoing]  - P. Harvey Constantly decoding new information
13#
14# Notes:        Must check FocalPlaneX/YResolution values for each new model!
15#
16# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
17#               2) Michael Rommel private communication (Digital Ixus)
18#               3) Daniel Pittman private communication (PowerShot S70)
19#               4) http://www.wonderland.org/crw/
20#               5) Juha Eskelinen private communication (20D)
21#               6) Richard S. Smith private communication (20D)
22#               7) Denny Priebe private communication (1DmkII)
23#               8) Irwin Poche private communication
24#               9) Michael Tiemann private communication (1DmkII)
25#              10) Volker Gering private communication (1DmkII)
26#              11) "cip" private communication
27#              12) Rainer Honle private communication (5D)
28#              13) http://www.cybercom.net/~dcoffin/dcraw/
29#              14) (bozi) http://www.cpanforum.com/threads/2476 and /2563
30#              15) http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm (2007/11/19)
31#                + http://homepage3.nifty.com/kamisaka/makernote/CanonLens.htm (2007/11/19)
32#              16) Emil Sit private communication (30D)
33#              17) http://www.asahi-net.or.jp/~xp8t-ymzk/s10exif.htm
34#              18) Samson Tai private communication (G7)
35#              19) Warren Stockton private communication
36#              20) Bogdan private communication
37#              21) Heiko Hinrichs private communication
38#              22) Dave Nicholson private communication (PowerShot S30)
39#              23) Magne Nilsen private communication (400D)
40#              24) Wolfgang Hoffmann private communication (40D)
41#              25) Laurent Clevy private communication
42#              26) Steve Balcombe private communication
43#              27) Chris Huebsch private communication (40D)
44#              28) Hal Williamson private communication (XTi)
45#              29) Ger Vermeulen private communication
46#              30) David Pitcher private communication (1DmkIII)
47#              31) Darryl Zurn private communication (A590IS)
48#              32) Rich Taylor private communication (5D)
49#              33) D.J. Cristi private communication
50#              34) Andreas Huggel and Pascal de Bruijn private communication
51#              35) Jan Boelsma private communication
52#              36) Karl-Heinz Klotz private communication (http://www.dslr-forum.de/showthread.php?t=430900)
53#              37) Vesa Kivisto private communication (30D)
54#              38) Kurt Garloff private communication (5DmkII)
55#              39) Irwin Poche private communication (5DmkII)
56#              40) Jose Oliver-Didier private communication
57#              41) http://www.cpanforum.com/threads/10730
58#              42) Norbert Wasser private communication
59#              43) Karsten Sote private communication
60#              44) Hugh Griffiths private communication (5DmkII)
61#              45) Mark Berger private communication (5DmkII)
62#              46) Dieter Steiner private communication (7D)
63#              47) http://www.exiv2.org/
64#              48) Tomasz A. Kawecki private communication (550D, firmware 1.0.6, 1.0.8)
65#              49) http://www.listware.net/201101/digikam-users/49795-digikam-users-re-lens-recognition.html
66#              50) https://exiftool.org/forum/index.php/topic,3833.0.html
67#              51) https://exiftool.org/forum/index.php/topic,4110.0.html
68#              52) Kai Harrekilde-Petersen private communication
69#              53) Anton Reiser private communication
70#              54) https://github.com/lclevy/canon_cr3
71#              IB) Iliah Borg private communication (LibRaw)
72#              JD) Jens Duttke private communication
73#              JR) Jos Roost private communication
74#              NJ) Niels Kristian Bech Jensen private communication
75#------------------------------------------------------------------------------
76
77package Image::ExifTool::Canon;
78
79use strict;
80use vars qw($VERSION %canonModelID %canonLensTypes);
81use Image::ExifTool qw(:DataAccess :Utils);
82use Image::ExifTool::Exif;
83
84sub WriteCanon($$$);
85sub ProcessSerialData($$$);
86sub ProcessFilters($$$);
87sub ProcessCTMD($$$);
88sub ProcessExifInfo($$$);
89sub SwapWords($);
90
91$VERSION = '4.50';
92
93# Note: Removed 'USM' from 'L' lenses since it is redundant - PH
94# (or is it?  Ref 32 shows 5 non-USM L-type lenses)
95# --> have relaxed this for new lenses because Canon has been
96#     consistent about keeping "USM" in the model name
97%canonLensTypes = ( #4
98     Notes => q{
99        Decimal values have been added to differentiate lenses which would otherwise
100        have the same LensType, and are used by the Composite LensID tag when
101        attempting to identify the specific lens model.
102     },
103    -1 => 'n/a',
104     1 => 'Canon EF 50mm f/1.8',
105     2 => 'Canon EF 28mm f/2.8 or Sigma Lens',
106     2.1 => 'Sigma 24mm f/2.8 Super Wide II', #ClaudeJolicoeur
107     # (3 removed in current Kamisaka list)
108     3 => 'Canon EF 135mm f/2.8 Soft', #15/32
109     4 => 'Canon EF 35-105mm f/3.5-4.5 or Sigma Lens', #28
110     4.1 => 'Sigma UC Zoom 35-135mm f/4-5.6',
111     5 => 'Canon EF 35-70mm f/3.5-4.5', #32
112     6 => 'Canon EF 28-70mm f/3.5-4.5 or Sigma or Tokina Lens', #32
113     6.1 => 'Sigma 18-50mm f/3.5-5.6 DC', #23
114     6.2 => 'Sigma 18-125mm f/3.5-5.6 DC IF ASP',
115     6.3 => 'Tokina AF 193-2 19-35mm f/3.5-4.5',
116     6.4 => 'Sigma 28-80mm f/3.5-5.6 II Macro', #47
117     6.5 => 'Sigma 28-300mm f/3.5-6.3 DG Macro', #IB
118     7 => 'Canon EF 100-300mm f/5.6L', #15
119     8 => 'Canon EF 100-300mm f/5.6 or Sigma or Tokina Lens', #32
120     8.1 => 'Sigma 70-300mm f/4-5.6 [APO] DG Macro', #15 (both APO and non-APO, ref forum2947)
121     8.2 => 'Tokina AT-X 242 AF 24-200mm f/3.5-5.6', #15
122     9 => 'Canon EF 70-210mm f/4', #32
123     9.1 => 'Sigma 55-200mm f/4-5.6 DC', #34
124    10 => 'Canon EF 50mm f/2.5 Macro or Sigma Lens', #10 (+ LSC Life Size Converter --> 70mm - PH)
125    10.1 => 'Sigma 50mm f/2.8 EX', #4
126    10.2 => 'Sigma 28mm f/1.8',
127    10.3 => 'Sigma 105mm f/2.8 Macro EX', #15
128    10.4 => 'Sigma 70mm f/2.8 EX DG Macro EF', #Jean-Michel Dubois
129    11 => 'Canon EF 35mm f/2', #9
130    13 => 'Canon EF 15mm f/2.8 Fisheye', #9
131    14 => 'Canon EF 50-200mm f/3.5-4.5L', #32
132    15 => 'Canon EF 50-200mm f/3.5-4.5', #32
133    16 => 'Canon EF 35-135mm f/3.5-4.5', #32
134    17 => 'Canon EF 35-70mm f/3.5-4.5A', #32
135    18 => 'Canon EF 28-70mm f/3.5-4.5', #32
136    20 => 'Canon EF 100-200mm f/4.5A', #32
137    21 => 'Canon EF 80-200mm f/2.8L',
138    22 => 'Canon EF 20-35mm f/2.8L or Tokina Lens', #32
139    22.1 => 'Tokina AT-X 280 AF Pro 28-80mm f/2.8 Aspherical', #15
140    23 => 'Canon EF 35-105mm f/3.5-4.5', #32
141    24 => 'Canon EF 35-80mm f/4-5.6 Power Zoom', #32
142    25 => 'Canon EF 35-80mm f/4-5.6 Power Zoom', #32
143    26 => 'Canon EF 100mm f/2.8 Macro or Other Lens',
144    26.1 => 'Cosina 100mm f/3.5 Macro AF',
145    26.2 => 'Tamron SP AF 90mm f/2.8 Di Macro', #15
146    26.3 => 'Tamron SP AF 180mm f/3.5 Di Macro', #15
147    26.4 => 'Carl Zeiss Planar T* 50mm f/1.4', #PH
148    26.5 => 'Voigtlander APO Lanthar 125mm F2.5 SL Macro', #JR
149    26.6 => 'Carl Zeiss Planar T 85mm f/1.4 ZE', #IB
150    27 => 'Canon EF 35-80mm f/4-5.6', #32
151    # 27 => 'Carl Zeiss Distagon T* 28mm f/2 ZF', #PH (must be with an adapter, because the ZF version is a Nikon mount)
152    # 27 => 'EMF adapter for Canon EOS digital cameras', #50 (reports MaxFocalLength of 65535)
153    # 27 => optix adapter
154    # 27 => Venus Optics Laowa 12mm f2.8 Zero-D or 105mm f2 (T3.2) Smooth Trans Focus (ref IB)
155    # 27 => Venus Optics Laowa 105mm f2 STF (ref IB)
156    28 => 'Canon EF 80-200mm f/4.5-5.6 or Tamron Lens', #32
157    28.1 => 'Tamron SP AF 28-105mm f/2.8 LD Aspherical IF', #15
158    28.2 => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro', #4
159  # 28.3 => 'Tamron AF 70-300mm f/4.5-5.6 Di LD 1:2 Macro Zoom', #11
160    28.3 => 'Tamron AF 70-300mm f/4-5.6 Di LD 1:2 Macro', #47
161    28.4 => 'Tamron AF Aspherical 28-200mm f/3.8-5.6', #14
162    29 => 'Canon EF 50mm f/1.8 II',
163    30 => 'Canon EF 35-105mm f/4.5-5.6', #32
164    31 => 'Canon EF 75-300mm f/4-5.6 or Tamron Lens', #32
165    31.1 => 'Tamron SP AF 300mm f/2.8 LD IF', #15
166    32 => 'Canon EF 24mm f/2.8 or Sigma Lens', #10
167    32.1 => 'Sigma 15mm f/2.8 EX Fisheye', #11
168    33 => 'Voigtlander or Carl Zeiss Lens',
169    33.1 => 'Voigtlander Ultron 40mm f/2 SLII Aspherical', #45
170    33.2 => 'Voigtlander Color Skopar 20mm f/3.5 SLII Aspherical', #50
171    33.3 => 'Voigtlander APO-Lanthar 90mm f/3.5 SLII Close Focus', #50
172    33.4 => 'Carl Zeiss Distagon T* 15mm f/2.8 ZE', #PH
173    33.5 => 'Carl Zeiss Distagon T* 18mm f/3.5 ZE', #PH
174    33.6 => 'Carl Zeiss Distagon T* 21mm f/2.8 ZE', #PH
175    33.7 => 'Carl Zeiss Distagon T* 25mm f/2 ZE', #IB
176    33.8 => 'Carl Zeiss Distagon T* 28mm f/2 ZE', #PH
177    33.9 => 'Carl Zeiss Distagon T* 35mm f/2 ZE', #PH
178   '33.10' => 'Carl Zeiss Distagon T* 35mm f/1.4 ZE', #IB
179   '33.11' => 'Carl Zeiss Planar T* 50mm f/1.4 ZE', #IB
180   '33.12' => 'Carl Zeiss Makro-Planar T* 50mm f/2 ZE', #IB
181   '33.13' => 'Carl Zeiss Makro-Planar T* 100mm f/2 ZE', #IB
182   '33.14' => 'Carl Zeiss Apo-Sonnar T* 135mm f/2 ZE', #JR
183    35 => 'Canon EF 35-80mm f/4-5.6', #32
184    36 => 'Canon EF 38-76mm f/4.5-5.6', #32
185    37 => 'Canon EF 35-80mm f/4-5.6 or Tamron Lens', #32
186    37.1 => 'Tamron 70-200mm f/2.8 Di LD IF Macro', #PH
187    37.2 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro (A20)', #38
188    37.3 => 'Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical [IF]', #34
189    37.4 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical [IF] Macro', #forum2937
190    38 => 'Canon EF 80-200mm f/4.5-5.6', #32
191    39 => 'Canon EF 75-300mm f/4-5.6',
192    40 => 'Canon EF 28-80mm f/3.5-5.6',
193    41 => 'Canon EF 28-90mm f/4-5.6', #32
194    42 => 'Canon EF 28-200mm f/3.5-5.6 or Tamron Lens', #32
195    42.1 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro (A20)', #15
196    43 => 'Canon EF 28-105mm f/4-5.6', #10
197    44 => 'Canon EF 90-300mm f/4.5-5.6', #32
198    45 => 'Canon EF-S 18-55mm f/3.5-5.6 [II]', #PH (same ID for version II, ref 20)
199    46 => 'Canon EF 28-90mm f/4-5.6', #32
200    47 => 'Zeiss Milvus 35mm f/2 or 50mm f/2', #IB
201    47.1 => 'Zeiss Milvus 50mm f/2 Makro', #IB
202    47.2 => 'Zeiss Milvus 135mm f/2 ZE', #IB
203    48 => 'Canon EF-S 18-55mm f/3.5-5.6 IS', #20
204    49 => 'Canon EF-S 55-250mm f/4-5.6 IS', #23
205    50 => 'Canon EF-S 18-200mm f/3.5-5.6 IS',
206    51 => 'Canon EF-S 18-135mm f/3.5-5.6 IS', #PH
207    52 => 'Canon EF-S 18-55mm f/3.5-5.6 IS II', #PH
208    53 => 'Canon EF-S 18-55mm f/3.5-5.6 III', #Jon Charnas
209    54 => 'Canon EF-S 55-250mm f/4-5.6 IS II', #47
210    60 => 'Irix 11mm f/4', #50
211    80 => 'Canon TS-E 50mm f/2.8L Macro', #42
212    81 => 'Canon TS-E 90mm f/2.8L Macro', #42
213    82 => 'Canon TS-E 135mm f/4L Macro', #42
214    94 => 'Canon TS-E 17mm f/4L', #42
215    95 => 'Canon TS-E 24mm f/3.5L II', #43
216    103 => 'Samyang AF 14mm f/2.8 EF or Rokinon Lens', #IB
217    103.1 => 'Rokinon SP 14mm f/2.4', #IB
218    103.2 => 'Rokinon AF 14mm f/2.8 EF', #IB
219    106 => 'Rokinon SP / Samyang XP 35mm f/1.2', #IB
220    112 => 'Sigma 28mm f/1.5 FF High-speed Prime or other Sigma Lens', #IB
221    112.1 => 'Sigma 40mm f/1.5 FF High-speed Prime', #IB
222    112.2 => 'Sigma 105mm f/1.5 FF High-speed Prime', #IB
223    117 => 'Tamron 35-150mm f/2.8-4.0 Di VC OSD (A043) or other Tamron Lens', #IB
224    117.1 => 'Tamron SP 35mm f/1.4 Di USD (F045)', #Exiv2#1064
225    124 => 'Canon MP-E 65mm f/2.8 1-5x Macro Photo', #9
226    125 => 'Canon TS-E 24mm f/3.5L',
227    126 => 'Canon TS-E 45mm f/2.8', #15
228    127 => 'Canon TS-E 90mm f/2.8 or Tamron Lens', #15
229    127.1 => 'Tamron 18-200mm f/3.5-6.3 Di II VC (B018)', #TomLachecki
230    129 => 'Canon EF 300mm f/2.8L USM', #32
231    130 => 'Canon EF 50mm f/1.0L USM', #10/15
232    131 => 'Canon EF 28-80mm f/2.8-4L USM or Sigma Lens', #32
233    131.1 => 'Sigma 8mm f/3.5 EX DG Circular Fisheye', #15
234    131.2 => 'Sigma 17-35mm f/2.8-4 EX DG Aspherical HSM', #15
235    131.3 => 'Sigma 17-70mm f/2.8-4.5 DC Macro', #PH (NC)
236    131.4 => 'Sigma APO 50-150mm f/2.8 [II] EX DC HSM', #15 ([II] ref PH)
237    131.5 => 'Sigma APO 120-300mm f/2.8 EX DG HSM', #15
238           # 'Sigma APO 120-300mm f/2.8 EX DG HSM + 1.4x', #15
239           # 'Sigma APO 120-300mm f/2.8 EX DG HSM + 2x', #15
240    131.6 => 'Sigma 4.5mm f/2.8 EX DC HSM Circular Fisheye', #PH
241    131.7 => 'Sigma 70-200mm f/2.8 APO EX HSM', #PH (http://www.lensrentals.com/blog/2012/08/canon-illumination-correction-and-third-party-lenses)
242    131.8 => 'Sigma 28-70mm f/2.8-4 DG', #IB
243    132 => 'Canon EF 1200mm f/5.6L USM', #32
244    134 => 'Canon EF 600mm f/4L IS USM', #15
245    135 => 'Canon EF 200mm f/1.8L USM',
246    136 => 'Canon EF 300mm f/2.8L USM',
247    136.1 => 'Tamron SP 15-30mm f/2.8 Di VC USD (A012)', #TomLachecki
248    137 => 'Canon EF 85mm f/1.2L USM or Sigma or Tamron Lens', #10
249    137.1 => 'Sigma 18-50mm f/2.8-4.5 DC OS HSM', #PH
250    137.2 => 'Sigma 50-200mm f/4-5.6 DC OS HSM', #PH
251    137.3 => 'Sigma 18-250mm f/3.5-6.3 DC OS HSM', #PH (also Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM)
252    137.4 => 'Sigma 24-70mm f/2.8 IF EX DG HSM', #PH
253    137.5 => 'Sigma 18-125mm f/3.8-5.6 DC OS HSM', #PH
254    137.6 => 'Sigma 17-70mm f/2.8-4 DC Macro OS HSM | C', #forum2819 (Contemporary version has this ID - PH)
255    137.7 => 'Sigma 17-50mm f/2.8 OS HSM', #47
256    137.8 => 'Sigma 18-200mm f/3.5-6.3 DC OS HSM [II]', #PH
257    137.9 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD (B008)', #forum3090
258   '137.10' => 'Sigma 8-16mm f/4.5-5.6 DC HSM', #50-Zwielicht
259   '137.11' => 'Tamron SP 17-50mm f/2.8 XR Di II VC (B005)', #50
260   '137.12' => 'Tamron SP 60mm f/2 Macro Di II (G005)', #50
261   '137.13' => 'Sigma 10-20mm f/3.5 EX DC HSM', #Gerald Erdmann
262   '137.14' => 'Tamron SP 24-70mm f/2.8 Di VC USD', #PH
263   '137.15' => 'Sigma 18-35mm f/1.8 DC HSM', #David Monro
264   '137.16' => 'Sigma 12-24mm f/4.5-5.6 DG HSM II', #IB
265   '137.17' => 'Sigma 70-300mm f/4-5.6 DG OS', #IB
266    138 => 'Canon EF 28-80mm f/2.8-4L', #32
267    139 => 'Canon EF 400mm f/2.8L USM',
268    140 => 'Canon EF 500mm f/4.5L USM', #32
269    141 => 'Canon EF 500mm f/4.5L USM',
270    142 => 'Canon EF 300mm f/2.8L IS USM', #15
271    143 => 'Canon EF 500mm f/4L IS USM or Sigma Lens', #15
272    143.1 => 'Sigma 17-70mm f/2.8-4 DC Macro OS HSM', #NJ (Exiv2 #1167)
273    144 => 'Canon EF 35-135mm f/4-5.6 USM', #26
274    145 => 'Canon EF 100-300mm f/4.5-5.6 USM', #32
275    146 => 'Canon EF 70-210mm f/3.5-4.5 USM', #32
276    147 => 'Canon EF 35-135mm f/4-5.6 USM', #32
277    148 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32
278    149 => 'Canon EF 100mm f/2 USM', #9
279    150 => 'Canon EF 14mm f/2.8L USM or Sigma Lens', #10
280    150.1 => 'Sigma 20mm EX f/1.8', #4
281    150.2 => 'Sigma 30mm f/1.4 DC HSM', #15
282    150.3 => 'Sigma 24mm f/1.8 DG Macro EX', #15
283    150.4 => 'Sigma 28mm f/1.8 DG Macro EX', #IB
284    150.5 => 'Sigma 18-35mm f/1.8 DC HSM | A', #IB
285    151 => 'Canon EF 200mm f/2.8L USM',
286    152 => 'Canon EF 300mm f/4L IS USM or Sigma Lens', #15
287    152.1 => 'Sigma 12-24mm f/4.5-5.6 EX DG ASPHERICAL HSM', #15
288    152.2 => 'Sigma 14mm f/2.8 EX Aspherical HSM', #15
289    152.3 => 'Sigma 10-20mm f/4-5.6', #14
290    152.4 => 'Sigma 100-300mm f/4', # (ref Bozi)
291    152.5 => 'Sigma 300-800mm f/5.6 APO EX DG HSM', #IB
292    153 => 'Canon EF 35-350mm f/3.5-5.6L USM or Sigma or Tamron Lens', #PH
293    153.1 => 'Sigma 50-500mm f/4-6.3 APO HSM EX', #15
294    153.2 => 'Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical [IF] Macro',
295    153.3 => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical [IF] Macro (A14)', #15
296    153.4 => 'Tamron 18-250mm f/3.5-6.3 Di II LD Aspherical [IF] Macro', #PH
297    154 => 'Canon EF 20mm f/2.8 USM or Zeiss Lens', #15
298    154.1 => 'Zeiss Milvus 21mm f/2.8', #IB
299    154.2 => 'Zeiss Milvus 15mm f/2.8 ZE', #IB
300    154.3 => 'Zeiss Milvus 18mm f/2.8 ZE', #IB
301    155 => 'Canon EF 85mm f/1.8 USM or Sigma Lens',
302    155.1 => 'Sigma 14mm f/1.8 DG HSM | A', #IB (A017)
303    156 => 'Canon EF 28-105mm f/3.5-4.5 USM or Tamron Lens',
304    156.1 => 'Tamron SP 70-300mm f/4-5.6 Di VC USD (A005)', #PH
305    156.2 => 'Tamron SP AF 28-105mm f/2.8 LD Aspherical IF (176D)', #JR
306    160 => 'Canon EF 20-35mm f/3.5-4.5 USM or Tamron or Tokina Lens',
307    160.1 => 'Tamron AF 19-35mm f/3.5-4.5', #44
308    160.2 => 'Tokina AT-X 124 AF Pro DX 12-24mm f/4', #49
309    160.3 => 'Tokina AT-X 107 AF DX 10-17mm f/3.5-4.5 Fisheye', #PH (http://osdir.com/ml/digikam-devel/2011-04/msg00275.html)
310    160.4 => 'Tokina AT-X 116 AF Pro DX 11-16mm f/2.8', #forum3967
311    160.5 => 'Tokina AT-X 11-20 F2.8 PRO DX Aspherical 11-20mm f/2.8', #NJ (Exiv2 #1166)
312    161 => 'Canon EF 28-70mm f/2.8L USM or Other Lens',
313    161.1 => 'Sigma 24-70mm f/2.8 EX',
314    161.2 => 'Sigma 28-70mm f/2.8 EX', #PH (http://www.breezesys.com/forum/showthread.php?t=3718)
315    161.3 => 'Sigma 24-60mm f/2.8 EX DG', #PH (http://www.lensrentals.com/blog/2012/08/canon-illumination-correction-and-third-party-lenses)
316    161.4 => 'Tamron AF 17-50mm f/2.8 Di-II LD Aspherical', #40
317    161.5 => 'Tamron 90mm f/2.8',
318    161.6 => 'Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical IF (A05)', #IB
319    161.7 => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro', #IB/NJ
320    161.8 => 'Tokina AT-X 24-70mm f/2.8 PRO FX (IF)', #IB
321    162 => 'Canon EF 200mm f/2.8L USM', #32
322    163 => 'Canon EF 300mm f/4L', #32
323    164 => 'Canon EF 400mm f/5.6L', #32
324    165 => 'Canon EF 70-200mm f/2.8L USM',
325    166 => 'Canon EF 70-200mm f/2.8L USM + 1.4x',
326    167 => 'Canon EF 70-200mm f/2.8L USM + 2x',
327    168 => 'Canon EF 28mm f/1.8 USM or Sigma Lens', #15
328    168.1 => 'Sigma 50-100mm f/1.8 DC HSM | A', #IB
329    169 => 'Canon EF 17-35mm f/2.8L USM or Sigma Lens', #15
330    169.1 => 'Sigma 18-200mm f/3.5-6.3 DC OS', #23
331    169.2 => 'Sigma 15-30mm f/3.5-4.5 EX DG Aspherical', #4
332    169.3 => 'Sigma 18-50mm f/2.8 Macro', #26
333    169.4 => 'Sigma 50mm f/1.4 EX DG HSM', #PH
334    169.5 => 'Sigma 85mm f/1.4 EX DG HSM', #Rolando Ruzic
335    169.6 => 'Sigma 30mm f/1.4 EX DC HSM', #Rodolfo Borges
336    169.7 => 'Sigma 35mm f/1.4 DG HSM', #PH (also "| A" version, ref 50)
337    169.8 => 'Sigma 35mm f/1.5 FF High-Speed Prime | 017', #IB
338    169.9 => 'Sigma 70mm f/2.8 Macro EX DG', #IB
339    170 => 'Canon EF 200mm f/2.8L II USM or Sigma Lens', #9
340    170.1 => 'Sigma 300mm f/2.8 APO EX DG HSM', #IB
341    170.2 => 'Sigma 800mm f/5.6 APO EX DG HSM', #IB
342    171 => 'Canon EF 300mm f/4L USM', #15
343    172 => 'Canon EF 400mm f/5.6L USM or Sigma Lens', #32
344    172.1 =>'Sigma 150-600mm f/5-6.3 DG OS HSM | S', #50
345    172.2 => 'Sigma 500mm f/4.5 APO EX DG HSM', #IB
346    173 => 'Canon EF 180mm Macro f/3.5L USM or Sigma Lens', #9
347    173.1 => 'Sigma 180mm EX HSM Macro f/3.5', #14
348    173.2 => 'Sigma APO Macro 150mm f/2.8 EX DG HSM', #14
349    173.3 => 'Sigma 10mm f/2.8 EX DC Fisheye', #IB
350    173.4 => 'Sigma 15mm f/2.8 EX DG Diagonal Fisheye', #IB
351    173.5 => 'Venus Laowa 100mm F2.8 2X Ultra Macro APO', #IB
352    174 => 'Canon EF 135mm f/2L USM or Other Lens', #9
353    174.1 => 'Sigma 70-200mm f/2.8 EX DG APO OS HSM', #PH (probably version II of this lens)
354    174.2 => 'Sigma 50-500mm f/4.5-6.3 APO DG OS HSM', #forum4031
355    174.3 => 'Sigma 150-500mm f/5-6.3 APO DG OS HSM', #47
356    174.4 => 'Zeiss Milvus 100mm f/2 Makro', #IB
357    174.5 => 'Sigma APO 50-150mm f/2.8 EX DC OS HSM', #IB
358    174.6 => 'Sigma APO 120-300mm f/2.8 EX DG OS HSM', #IB
359    174.7 => 'Sigma 120-300mm f/2.8 DG OS HSM S013', #IB
360    174.8 => 'Sigma 120-400mm f/4.5-5.6 APO DG OS HSM', #IB
361    174.9 => 'Sigma 200-500mm f/2.8 APO EX DG', #IB
362    175 => 'Canon EF 400mm f/2.8L USM', #32
363    176 => 'Canon EF 24-85mm f/3.5-4.5 USM',
364    177 => 'Canon EF 300mm f/4L IS USM', #9
365    178 => 'Canon EF 28-135mm f/3.5-5.6 IS',
366    179 => 'Canon EF 24mm f/1.4L USM', #20
367    180 => 'Canon EF 35mm f/1.4L USM or Other Lens', #9
368    180.1 => 'Sigma 50mm f/1.4 DG HSM | A', #50
369    180.2 => 'Sigma 24mm f/1.4 DG HSM | A', #NJ
370    180.3 => 'Zeiss Milvus 50mm f/1.4', #IB
371    180.4 => 'Zeiss Milvus 85mm f/1.4', #IB
372    180.5 => 'Zeiss Otus 28mm f/1.4 ZE', #PH
373    180.6 => 'Sigma 24mm f/1.5 FF High-Speed Prime | 017', #IB
374    180.7 => 'Sigma 50mm f/1.5 FF High-Speed Prime | 017', #IB
375    180.8 => 'Sigma 85mm f/1.5 FF High-Speed Prime | 017', #IB
376    180.9 => 'Tokina Opera 50mm f/1.4 FF', #IB
377   '180.10' => 'Sigma 20mm f/1.4 DG HSM | A', #IB (015)
378    181 => 'Canon EF 100-400mm f/4.5-5.6L IS USM + 1.4x or Sigma Lens', #15
379    181.1 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | S + 1.4x', #50
380    182 => 'Canon EF 100-400mm f/4.5-5.6L IS USM + 2x or Sigma Lens',
381    182.1 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | S + 2x', #PH (NC)
382    183 => 'Canon EF 100-400mm f/4.5-5.6L IS USM or Sigma Lens',
383    183.1 => 'Sigma 150mm f/2.8 EX DG OS HSM APO Macro', #50
384    183.2 => 'Sigma 105mm f/2.8 EX DG OS HSM Macro', #50
385    183.3 => 'Sigma 180mm f/2.8 EX DG OS HSM APO Macro', #IB
386    183.4 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | C', #47
387    183.5 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | S', #forum7109 (Sports 014)
388    183.6 => 'Sigma 100-400mm f/5-6.3 DG OS HSM', #PH ("| C" ?)
389    183.7 => 'Sigma 180mm f/3.5 APO Macro EX DG IF HSM', #IB
390    184 => 'Canon EF 400mm f/2.8L USM + 2x', #15
391    185 => 'Canon EF 600mm f/4L IS USM', #32
392    186 => 'Canon EF 70-200mm f/4L USM', #9
393    187 => 'Canon EF 70-200mm f/4L USM + 1.4x', #26
394    188 => 'Canon EF 70-200mm f/4L USM + 2x', #PH
395    189 => 'Canon EF 70-200mm f/4L USM + 2.8x', #32
396    190 => 'Canon EF 100mm f/2.8 Macro USM', # (+USM ref 42)
397    191 => 'Canon EF 400mm f/4 DO IS or Sigma Lens', #9
398    191.1 => 'Sigma 500mm f/4 DG OS HSM', #AndrewSheih
399    193 => 'Canon EF 35-80mm f/4-5.6 USM', #32
400    194 => 'Canon EF 80-200mm f/4.5-5.6 USM', #32
401    195 => 'Canon EF 35-105mm f/4.5-5.6 USM', #32
402    196 => 'Canon EF 75-300mm f/4-5.6 USM', #15/32
403    197 => 'Canon EF 75-300mm f/4-5.6 IS USM or Sigma Lens',
404    197.1 => 'Sigma 18-300mm f/3.5-6.3 DC Macro OS HSM', #50
405    198 => 'Canon EF 50mm f/1.4 USM or Other Lens',
406    198.1 => 'Zeiss Otus 55mm f/1.4 ZE', #JR (seen only on Sony camera)
407    198.2 => 'Zeiss Otus 85mm f/1.4 ZE', #JR (NC)
408    198.3 => 'Zeiss Milvus 25mm f/1.4', #IB
409    198.4 => 'Zeiss Otus 100mm f/1.4', #IB
410    198.5 => 'Zeiss Milvus 35mm f/1.4 ZE', #IB
411    198.6 => 'Yongnuo YN 35mm f/2', #IB
412    199 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32
413    200 => 'Canon EF 75-300mm f/4-5.6 USM', #32
414    201 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32
415    202 => 'Canon EF 28-80mm f/3.5-5.6 USM IV',
416    208 => 'Canon EF 22-55mm f/4-5.6 USM', #32
417    209 => 'Canon EF 55-200mm f/4.5-5.6', #32 (USM mk I version? ref IB)
418    210 => 'Canon EF 28-90mm f/4-5.6 USM', #32
419    211 => 'Canon EF 28-200mm f/3.5-5.6 USM', #15
420    212 => 'Canon EF 28-105mm f/4-5.6 USM', #15
421    213 => 'Canon EF 90-300mm f/4.5-5.6 USM or Tamron Lens',
422    213.1 => 'Tamron SP 150-600mm f/5-6.3 Di VC USD (A011)', #forum5565
423    213.2 => 'Tamron 16-300mm f/3.5-6.3 Di II VC PZD Macro (B016)', #PH
424    213.3 => 'Tamron SP 35mm f/1.8 Di VC USD (F012)', #PH
425    213.4 => 'Tamron SP 45mm f/1.8 Di VC USD (F013)', #PH
426    214 => 'Canon EF-S 18-55mm f/3.5-5.6 USM', #PH/34
427    215 => 'Canon EF 55-200mm f/4.5-5.6 II USM',
428    217 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD', #47
429    220 => 'Yongnuo YN 50mm f/1.8', #IB
430    224 => 'Canon EF 70-200mm f/2.8L IS USM', #11
431    225 => 'Canon EF 70-200mm f/2.8L IS USM + 1.4x', #11
432    226 => 'Canon EF 70-200mm f/2.8L IS USM + 2x', #14
433    227 => 'Canon EF 70-200mm f/2.8L IS USM + 2.8x', #32
434    228 => 'Canon EF 28-105mm f/3.5-4.5 USM', #32
435    229 => 'Canon EF 16-35mm f/2.8L USM', #PH
436    230 => 'Canon EF 24-70mm f/2.8L USM', #9
437    231 => 'Canon EF 17-40mm f/4L USM or Sigma Lens',
438    231.1 => 'Sigma 12-24mm f/4 DG HSM A016', #IB
439    232 => 'Canon EF 70-300mm f/4.5-5.6 DO IS USM', #15
440    233 => 'Canon EF 28-300mm f/3.5-5.6L IS USM', #PH
441    234 => 'Canon EF-S 17-85mm f/4-5.6 IS USM or Tokina Lens', #19
442    234.1 => 'Tokina AT-X 12-28 PRO DX 12-28mm f/4', #50/NJ
443    235 => 'Canon EF-S 10-22mm f/3.5-4.5 USM', #15
444    236 => 'Canon EF-S 60mm f/2.8 Macro USM', #15
445    237 => 'Canon EF 24-105mm f/4L IS USM', #15
446    238 => 'Canon EF 70-300mm f/4-5.6 IS USM', #15 (and version II? ref 42)
447    239 => 'Canon EF 85mm f/1.2L II USM or Rokinon Lens', #15
448    239.1 => 'Rokinon SP 85mm f/1.2', #IB
449    240 => 'Canon EF-S 17-55mm f/2.8 IS USM or Sigma Lens', #15
450    240.1 => 'Sigma 17-50mm f/2.8 EX DC OS HSM', #https://github.com/Exiv2/exiv2/issues/397
451    241 => 'Canon EF 50mm f/1.2L USM', #15
452    242 => 'Canon EF 70-200mm f/4L IS USM', #PH
453    243 => 'Canon EF 70-200mm f/4L IS USM + 1.4x', #15
454    244 => 'Canon EF 70-200mm f/4L IS USM + 2x', #PH
455    245 => 'Canon EF 70-200mm f/4L IS USM + 2.8x', #32
456    246 => 'Canon EF 16-35mm f/2.8L II USM', #PH
457    247 => 'Canon EF 14mm f/2.8L II USM', #32
458    248 => 'Canon EF 200mm f/2L IS USM or Sigma Lens', #42
459    248.1 => 'Sigma 24-35mm f/2 DG HSM | A', #JR
460    248.2 => 'Sigma 135mm f/2 FF High-Speed Prime | 017', #IB
461    248.3 => 'Sigma 24-35mm f/2.2 FF Zoom | 017', #IB
462    248.4 => 'Sigma 135mm f/1.8 DG HSM A017', #IB
463    249 => 'Canon EF 800mm f/5.6L IS USM', #35
464    250 => 'Canon EF 24mm f/1.4L II USM or Sigma Lens', #41
465    250.1 => 'Sigma 20mm f/1.4 DG HSM | A', #IB
466    250.2 => 'Sigma 20mm f/1.5 FF High-Speed Prime | 017', #IB
467    250.3 => 'Tokina Opera 16-28mm f/2.8 FF', #IB
468    250.4 => 'Sigma 85mm f/1.4 DG HSM A016', #IB
469    251 => 'Canon EF 70-200mm f/2.8L IS II USM',
470    251.1 => 'Canon EF 70-200mm f/2.8L IS III USM', #IB
471    252 => 'Canon EF 70-200mm f/2.8L IS II USM + 1.4x', #50 (1.4x Mk II)
472    252.1 => 'Canon EF 70-200mm f/2.8L IS III USM + 1.4x', #PH (NC)
473    253 => 'Canon EF 70-200mm f/2.8L IS II USM + 2x', #PH (NC)
474    253.1 => 'Canon EF 70-200mm f/2.8L IS III USM + 2x', #PH (NC)
475    # 253.2 => 'Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025) + 2x', #forum9367
476    254 => 'Canon EF 100mm f/2.8L Macro IS USM or Tamron Lens', #42
477    254.1 => 'Tamron SP 90mm f/2.8 Di VC USD 1:1 Macro (F017)', #PH
478    255 => 'Sigma 24-105mm f/4 DG OS HSM | A or Other Lens', #50
479    255.1 => 'Sigma 180mm f/2.8 EX DG OS HSM APO Macro', #50
480    255.2 => 'Tamron SP 70-200mm f/2.8 Di VC USD', #exiv issue 1202 (A009)
481    368 => 'Sigma 14-24mm f/2.8 DG HSM | A or other Sigma Lens', #IB (A018)
482    368.1 => 'Sigma 20mm f/1.4 DG HSM | A', #50 (newer firmware)
483    368.2 => 'Sigma 50mm f/1.4 DG HSM | A', #50
484    368.3 => 'Sigma 40mm f/1.4 DG HSM | A', #IB (018)
485    368.4 => 'Sigma 60-600mm f/4.5-6.3 DG OS HSM | S', #IB (018)
486    368.5 => 'Sigma 28mm f/1.4 DG HSM | A', #IB (A019)
487    368.6 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | S', #50
488    368.7 => 'Sigma 85mm f/1.4 DG HSM | A', #IB (016)
489    368.8 => 'Sigma 105mm f/1.4 DG HSM', #IB (A018)
490    368.9 => 'Sigma 14-24mm f/2.8 DG HSM', #IB (A018)
491   '368.10' => 'Sigma 35mm f/1.4 DG HSM | A', #PH (012)
492   '368.11' => 'Sigma 70mm f/2.8 DG Macro', #IB (A018)
493   '368.12' => 'Sigma 18-35mm f/1.8 DC HSM | A', #50
494    # Note: LensType 488 (0x1e8) is reported as 232 (0xe8) in 7D CameraSettings
495    488 => 'Canon EF-S 15-85mm f/3.5-5.6 IS USM', #PH
496    489 => 'Canon EF 70-300mm f/4-5.6L IS USM', #Gerald Kapounek
497    490 => 'Canon EF 8-15mm f/4L Fisheye USM', #Klaus Reinfeld (PH added "Fisheye")
498    491 => 'Canon EF 300mm f/2.8L IS II USM or Tamron Lens', #42
499    491.1 => 'Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025)', #IB
500    491.2 => 'Tamron 18-400mm f/3.5-6.3 Di II VC HLD (B028)', #IB
501    491.3 => 'Tamron 100-400mm f/4.5-6.3 Di VC USD (A035)', #IB
502    491.4 => 'Tamron 70-210mm f/4 Di VC USD (A034)', #IB
503    491.5 => 'Tamron 70-210mm f/4 Di VC USD (A034) + 1.4x', #IB
504    491.6 => 'Tamron SP 24-70mm f/2.8 Di VC USD G2 (A032)',
505    492 => 'Canon EF 400mm f/2.8L IS II USM', #PH
506    493 => 'Canon EF 500mm f/4L IS II USM or EF 24-105mm f4L IS USM', #PH
507    493.1 => 'Canon EF 24-105mm f/4L IS USM', #PH (should recheck this)
508    494 => 'Canon EF 600mm f/4L IS II USM', #PH
509    495 => 'Canon EF 24-70mm f/2.8L II USM or Sigma Lens', #PH
510    495.1 => 'Sigma 24-70mm f/2.8 DG OS HSM | A', #IB (017)
511    496 => 'Canon EF 200-400mm f/4L IS USM', #PH
512    499 => 'Canon EF 200-400mm f/4L IS USM + 1.4x', #50
513    502 => 'Canon EF 28mm f/2.8 IS USM or Tamron Lens', #PH
514    502.1 => 'Tamron 35mm f/1.8 Di VC USD (F012)', #forum9757
515    503 => 'Canon EF 24mm f/2.8 IS USM', #PH
516    504 => 'Canon EF 24-70mm f/4L IS USM', #PH
517    505 => 'Canon EF 35mm f/2 IS USM', #PH
518    506 => 'Canon EF 400mm f/4 DO IS II USM', #42
519    507 => 'Canon EF 16-35mm f/4L IS USM', #42
520    508 => 'Canon EF 11-24mm f/4L USM or Tamron Lens', #PH
521    508.1 => 'Tamron 10-24mm f/3.5-4.5 Di II VC HLD (B023)', #PH
522    624 => 'Sigma 70-200mm f/2.8 DG OS HSM | S', #IB (018)
523    747 => 'Canon EF 100-400mm f/4.5-5.6L IS II USM or Tamron Lens', #JR
524    747.1 => 'Tamron SP 150-600mm f/5-6.3 Di VC USD G2', #50
525    748 => 'Canon EF 100-400mm f/4.5-5.6L IS II USM + 1.4x or Tamron Lens', #JR (1.4x Mk III)
526    748.1 => 'Tamron 100-400mm f/4.5-6.3 Di VC USD A035E + 1.4x', #IB
527    748.2 => 'Tamron 70-210mm f/4 Di VC USD (A034) + 2x', #IB
528    749 => 'Tamron 100-400mm f/4.5-6.3 Di VC USD A035E + 2x', #IB
529    750 => 'Canon EF 35mm f/1.4L II USM or Tamron Lens', #42
530    750.1 => 'Tamron SP 85mm f/1.8 Di VC USD (F016)', #Exiv2#1072
531    750.2 => 'Tamron SP 45mm f/1.8 Di VC USD (F013)', #PH
532    751 => 'Canon EF 16-35mm f/2.8L III USM', #42
533    752 => 'Canon EF 24-105mm f/4L IS II USM', #42
534    753 => 'Canon EF 85mm f/1.4L IS USM', #42
535    754 => 'Canon EF 70-200mm f/4L IS II USM', #IB
536    757 => 'Canon EF 400mm f/2.8L IS III USM', #IB
537    758 => 'Canon EF 600mm f/4L IS III USM', #IB
538
539    1136 => 'Sigma 24-70mm f/2.8 DG OS HSM | A', #IB (017)
540    # (STM lenses - 0x10xx)
541    4142 => 'Canon EF-S 18-135mm f/3.5-5.6 IS STM',
542    4143 => 'Canon EF-M 18-55mm f/3.5-5.6 IS STM or Tamron Lens',
543    4143.1 => 'Tamron 18-200mm f/3.5-6.3 Di III VC', #42
544    4144 => 'Canon EF 40mm f/2.8 STM', #50
545    4145 => 'Canon EF-M 22mm f/2 STM', #34
546    4146 => 'Canon EF-S 18-55mm f/3.5-5.6 IS STM', #PH
547    4147 => 'Canon EF-M 11-22mm f/4-5.6 IS STM', #42
548    4148 => 'Canon EF-S 55-250mm f/4-5.6 IS STM', #42
549    4149 => 'Canon EF-M 55-200mm f/4.5-6.3 IS STM', #42
550    4150 => 'Canon EF-S 10-18mm f/4.5-5.6 IS STM', #42
551    4152 => 'Canon EF 24-105mm f/3.5-5.6 IS STM', #42
552    4153 => 'Canon EF-M 15-45mm f/3.5-6.3 IS STM', #PH
553    4154 => 'Canon EF-S 24mm f/2.8 STM', #IB
554    4155 => 'Canon EF-M 28mm f/3.5 Macro IS STM', #42
555    4156 => 'Canon EF 50mm f/1.8 STM', #42
556    4157 => 'Canon EF-M 18-150mm f/3.5-6.3 IS STM', #42
557    4158 => 'Canon EF-S 18-55mm f/4-5.6 IS STM', #PH
558    4159 => 'Canon EF-M 32mm f/1.4 STM', #42
559    4160 => 'Canon EF-S 35mm f/2.8 Macro IS STM', #42
560    4208 => 'Sigma 56mm f/1.4 DC DN | C or other Sigma Lens', #forum10603
561    4208.1 => 'Sigma 30mm F1.4 DC DN | C', #git issue#83 (016)
562    # (Nano USM lenses - 0x90xx)
563    36910 => 'Canon EF 70-300mm f/4-5.6 IS II USM', #42
564    36912 => 'Canon EF-S 18-135mm f/3.5-5.6 IS USM', #42
565    # (CN-E lenses - 0xf0xx)
566    61491 => 'Canon CN-E 14mm T3.1 L F', #PH
567    61492 => 'Canon CN-E 24mm T1.5 L F', #PH
568  # 61493 - missing CN-E 50mm T1.3 L F ?
569    61494 => 'Canon CN-E 85mm T1.3 L F', #PH
570    61495 => 'Canon CN-E 135mm T2.2 L F', #PH
571    61496 => 'Canon CN-E 35mm T1.5 L F', #PH
572    # see RFLensType tag for master list of 61182 RF lenses
573    61182 => 'Canon RF 50mm F1.2L USM or other Canon RF Lens',
574    61182.1 => 'Canon RF 24-105mm F4L IS USM',
575    61182.2 => 'Canon RF 28-70mm F2L USM',
576    61182.3 => 'Canon RF 35mm F1.8 MACRO IS STM',
577    61182.4 => 'Canon RF 85mm F1.2L USM',
578    61182.5 => 'Canon RF 85mm F1.2L USM DS',
579    61182.6 => 'Canon RF 24-70mm F2.8L IS USM',
580    61182.7 => 'Canon RF 15-35mm F2.8L IS USM',
581    61182.8 => 'Canon RF 24-240mm F4-6.3 IS USM',
582    61182.9 => 'Canon RF 70-200mm F2.8L IS USM',
583   '61182.10' => 'Canon RF 85mm F2 MACRO IS STM',
584   '61182.11' => 'Canon RF 600mm F11 IS STM',
585   '61182.12' => 'Canon RF 600mm F11 IS STM + RF1.4x',
586   '61182.13' => 'Canon RF 600mm F11 IS STM + RF2x',
587   '61182.14' => 'Canon RF 800mm F11 IS STM',
588   '61182.15' => 'Canon RF 800mm F11 IS STM + RF1.4x',
589   '61182.16' => 'Canon RF 800mm F11 IS STM + RF2x',
590   '61182.17' => 'Canon RF 24-105mm F4-7.1 IS STM',
591   '61182.18' => 'Canon RF 100-500mm F4.5-7.1L IS USM',
592   '61182.19' => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF1.4x',
593   '61182.20' => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
594   '61182.21' => 'Canon RF 70-200mm F4L IS USM', #42
595   '61182.22' => 'Canon RF 50mm F1.8 STM', #42
596    65535 => 'n/a',
597);
598
599# Canon model ID numbers (PH)
600%canonModelID = (
601    0x1010000 => 'PowerShot A30',
602    0x1040000 => 'PowerShot S300 / Digital IXUS 300 / IXY Digital 300',
603    0x1060000 => 'PowerShot A20',
604    0x1080000 => 'PowerShot A10',
605    0x1090000 => 'PowerShot S110 / Digital IXUS v / IXY Digital 200',
606    0x1100000 => 'PowerShot G2',
607    0x1110000 => 'PowerShot S40',
608    0x1120000 => 'PowerShot S30',
609    0x1130000 => 'PowerShot A40',
610    0x1140000 => 'EOS D30',
611    0x1150000 => 'PowerShot A100',
612    0x1160000 => 'PowerShot S200 / Digital IXUS v2 / IXY Digital 200a',
613    0x1170000 => 'PowerShot A200',
614    0x1180000 => 'PowerShot S330 / Digital IXUS 330 / IXY Digital 300a',
615    0x1190000 => 'PowerShot G3',
616    0x1210000 => 'PowerShot S45',
617    0x1230000 => 'PowerShot SD100 / Digital IXUS II / IXY Digital 30',
618    0x1240000 => 'PowerShot S230 / Digital IXUS v3 / IXY Digital 320',
619    0x1250000 => 'PowerShot A70',
620    0x1260000 => 'PowerShot A60',
621    0x1270000 => 'PowerShot S400 / Digital IXUS 400 / IXY Digital 400',
622    0x1290000 => 'PowerShot G5',
623    0x1300000 => 'PowerShot A300',
624    0x1310000 => 'PowerShot S50',
625    0x1340000 => 'PowerShot A80',
626    0x1350000 => 'PowerShot SD10 / Digital IXUS i / IXY Digital L',
627    0x1360000 => 'PowerShot S1 IS',
628    0x1370000 => 'PowerShot Pro1',
629    0x1380000 => 'PowerShot S70',
630    0x1390000 => 'PowerShot S60',
631    0x1400000 => 'PowerShot G6',
632    0x1410000 => 'PowerShot S500 / Digital IXUS 500 / IXY Digital 500',
633    0x1420000 => 'PowerShot A75',
634    0x1440000 => 'PowerShot SD110 / Digital IXUS IIs / IXY Digital 30a',
635    0x1450000 => 'PowerShot A400',
636    0x1470000 => 'PowerShot A310',
637    0x1490000 => 'PowerShot A85',
638    0x1520000 => 'PowerShot S410 / Digital IXUS 430 / IXY Digital 450',
639    0x1530000 => 'PowerShot A95',
640    0x1540000 => 'PowerShot SD300 / Digital IXUS 40 / IXY Digital 50',
641    0x1550000 => 'PowerShot SD200 / Digital IXUS 30 / IXY Digital 40',
642    0x1560000 => 'PowerShot A520',
643    0x1570000 => 'PowerShot A510',
644    0x1590000 => 'PowerShot SD20 / Digital IXUS i5 / IXY Digital L2',
645    0x1640000 => 'PowerShot S2 IS',
646    0x1650000 => 'PowerShot SD430 / Digital IXUS Wireless / IXY Digital Wireless',
647    0x1660000 => 'PowerShot SD500 / Digital IXUS 700 / IXY Digital 600',
648    0x1668000 => 'EOS D60',
649    0x1700000 => 'PowerShot SD30 / Digital IXUS i Zoom / IXY Digital L3',
650    0x1740000 => 'PowerShot A430',
651    0x1750000 => 'PowerShot A410',
652    0x1760000 => 'PowerShot S80',
653    0x1780000 => 'PowerShot A620',
654    0x1790000 => 'PowerShot A610',
655    0x1800000 => 'PowerShot SD630 / Digital IXUS 65 / IXY Digital 80',
656    0x1810000 => 'PowerShot SD450 / Digital IXUS 55 / IXY Digital 60',
657    0x1820000 => 'PowerShot TX1',
658    0x1870000 => 'PowerShot SD400 / Digital IXUS 50 / IXY Digital 55',
659    0x1880000 => 'PowerShot A420',
660    0x1890000 => 'PowerShot SD900 / Digital IXUS 900 Ti / IXY Digital 1000',
661    0x1900000 => 'PowerShot SD550 / Digital IXUS 750 / IXY Digital 700',
662    0x1920000 => 'PowerShot A700',
663    0x1940000 => 'PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS',
664    0x1950000 => 'PowerShot S3 IS',
665    0x1960000 => 'PowerShot A540',
666    0x1970000 => 'PowerShot SD600 / Digital IXUS 60 / IXY Digital 70',
667    0x1980000 => 'PowerShot G7',
668    0x1990000 => 'PowerShot A530',
669    0x2000000 => 'PowerShot SD800 IS / Digital IXUS 850 IS / IXY Digital 900 IS',
670    0x2010000 => 'PowerShot SD40 / Digital IXUS i7 / IXY Digital L4',
671    0x2020000 => 'PowerShot A710 IS',
672    0x2030000 => 'PowerShot A640',
673    0x2040000 => 'PowerShot A630',
674    0x2090000 => 'PowerShot S5 IS',
675    0x2100000 => 'PowerShot A460',
676    0x2120000 => 'PowerShot SD850 IS / Digital IXUS 950 IS / IXY Digital 810 IS',
677    0x2130000 => 'PowerShot A570 IS',
678    0x2140000 => 'PowerShot A560',
679    0x2150000 => 'PowerShot SD750 / Digital IXUS 75 / IXY Digital 90',
680    0x2160000 => 'PowerShot SD1000 / Digital IXUS 70 / IXY Digital 10',
681    0x2180000 => 'PowerShot A550',
682    0x2190000 => 'PowerShot A450',
683    0x2230000 => 'PowerShot G9',
684    0x2240000 => 'PowerShot A650 IS',
685    0x2260000 => 'PowerShot A720 IS',
686    0x2290000 => 'PowerShot SX100 IS',
687    0x2300000 => 'PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS',
688    0x2310000 => 'PowerShot SD870 IS / Digital IXUS 860 IS / IXY Digital 910 IS',
689    0x2320000 => 'PowerShot SD890 IS / Digital IXUS 970 IS / IXY Digital 820 IS',
690    0x2360000 => 'PowerShot SD790 IS / Digital IXUS 90 IS / IXY Digital 95 IS',
691    0x2370000 => 'PowerShot SD770 IS / Digital IXUS 85 IS / IXY Digital 25 IS',
692    0x2380000 => 'PowerShot A590 IS',
693    0x2390000 => 'PowerShot A580',
694    0x2420000 => 'PowerShot A470',
695    0x2430000 => 'PowerShot SD1100 IS / Digital IXUS 80 IS / IXY Digital 20 IS',
696    0x2460000 => 'PowerShot SX1 IS',
697    0x2470000 => 'PowerShot SX10 IS',
698    0x2480000 => 'PowerShot A1000 IS',
699    0x2490000 => 'PowerShot G10',
700    0x2510000 => 'PowerShot A2000 IS',
701    0x2520000 => 'PowerShot SX110 IS',
702    0x2530000 => 'PowerShot SD990 IS / Digital IXUS 980 IS / IXY Digital 3000 IS',
703    0x2540000 => 'PowerShot SD880 IS / Digital IXUS 870 IS / IXY Digital 920 IS',
704    0x2550000 => 'PowerShot E1',
705    0x2560000 => 'PowerShot D10',
706    0x2570000 => 'PowerShot SD960 IS / Digital IXUS 110 IS / IXY Digital 510 IS',
707    0x2580000 => 'PowerShot A2100 IS',
708    0x2590000 => 'PowerShot A480',
709    0x2600000 => 'PowerShot SX200 IS',
710    0x2610000 => 'PowerShot SD970 IS / Digital IXUS 990 IS / IXY Digital 830 IS',
711    0x2620000 => 'PowerShot SD780 IS / Digital IXUS 100 IS / IXY Digital 210 IS',
712    0x2630000 => 'PowerShot A1100 IS',
713    0x2640000 => 'PowerShot SD1200 IS / Digital IXUS 95 IS / IXY Digital 110 IS',
714    0x2700000 => 'PowerShot G11',
715    0x2710000 => 'PowerShot SX120 IS',
716    0x2720000 => 'PowerShot S90',
717    0x2750000 => 'PowerShot SX20 IS',
718    0x2760000 => 'PowerShot SD980 IS / Digital IXUS 200 IS / IXY Digital 930 IS',
719    0x2770000 => 'PowerShot SD940 IS / Digital IXUS 120 IS / IXY Digital 220 IS',
720    0x2800000 => 'PowerShot A495',
721    0x2810000 => 'PowerShot A490',
722    0x2820000 => 'PowerShot A3100/A3150 IS', # (different cameras, same ID)
723    0x2830000 => 'PowerShot A3000 IS',
724    0x2840000 => 'PowerShot SD1400 IS / IXUS 130 / IXY 400F',
725    0x2850000 => 'PowerShot SD1300 IS / IXUS 105 / IXY 200F',
726    0x2860000 => 'PowerShot SD3500 IS / IXUS 210 / IXY 10S',
727    0x2870000 => 'PowerShot SX210 IS',
728    0x2880000 => 'PowerShot SD4000 IS / IXUS 300 HS / IXY 30S',
729    0x2890000 => 'PowerShot SD4500 IS / IXUS 1000 HS / IXY 50S',
730    0x2920000 => 'PowerShot G12',
731    0x2930000 => 'PowerShot SX30 IS',
732    0x2940000 => 'PowerShot SX130 IS',
733    0x2950000 => 'PowerShot S95',
734    0x2980000 => 'PowerShot A3300 IS',
735    0x2990000 => 'PowerShot A3200 IS',
736    0x3000000 => 'PowerShot ELPH 500 HS / IXUS 310 HS / IXY 31S',
737    0x3010000 => 'PowerShot Pro90 IS',
738    0x3010001 => 'PowerShot A800',
739    0x3020000 => 'PowerShot ELPH 100 HS / IXUS 115 HS / IXY 210F',
740    0x3030000 => 'PowerShot SX230 HS',
741    0x3040000 => 'PowerShot ELPH 300 HS / IXUS 220 HS / IXY 410F',
742    0x3050000 => 'PowerShot A2200',
743    0x3060000 => 'PowerShot A1200',
744    0x3070000 => 'PowerShot SX220 HS',
745    0x3080000 => 'PowerShot G1 X',
746    0x3090000 => 'PowerShot SX150 IS',
747    0x3100000 => 'PowerShot ELPH 510 HS / IXUS 1100 HS / IXY 51S',
748    0x3110000 => 'PowerShot S100 (new)',
749    0x3130000 => 'PowerShot SX40 HS',
750    0x3120000 => 'PowerShot ELPH 310 HS / IXUS 230 HS / IXY 600F',
751    # the Canon page lists the IXY 32S as "Japan only", but many other
752    # sites list the ELPH 500 HS and IXUS 320 HS as being the same model.
753    # I haven't been able to find an IXUS 320 sample, and the ELPH 500 HS
754    # is already associated with other IXUS and IXY models - PH
755    0x3140000 => 'IXY 32S', # (PowerShot ELPH 500 HS / IXUS 320 HS ??)
756    0x3160000 => 'PowerShot A1300',
757    0x3170000 => 'PowerShot A810',
758    0x3180000 => 'PowerShot ELPH 320 HS / IXUS 240 HS / IXY 420F',
759    0x3190000 => 'PowerShot ELPH 110 HS / IXUS 125 HS / IXY 220F',
760    0x3200000 => 'PowerShot D20',
761    0x3210000 => 'PowerShot A4000 IS',
762    0x3220000 => 'PowerShot SX260 HS',
763    0x3230000 => 'PowerShot SX240 HS',
764    0x3240000 => 'PowerShot ELPH 530 HS / IXUS 510 HS / IXY 1',
765    0x3250000 => 'PowerShot ELPH 520 HS / IXUS 500 HS / IXY 3',
766    0x3260000 => 'PowerShot A3400 IS',
767    0x3270000 => 'PowerShot A2400 IS',
768    0x3280000 => 'PowerShot A2300',
769    0x3320000 => 'PowerShot S100V', #IB
770    0x3330000 => 'PowerShot G15', #25
771    0x3340000 => 'PowerShot SX50 HS', #25/forum8196
772    0x3350000 => 'PowerShot SX160 IS',
773    0x3360000 => 'PowerShot S110 (new)',
774    0x3370000 => 'PowerShot SX500 IS',
775    0x3380000 => 'PowerShot N',
776    0x3390000 => 'IXUS 245 HS / IXY 430F', # (no PowerShot)
777    0x3400000 => 'PowerShot SX280 HS',
778    0x3410000 => 'PowerShot SX270 HS',
779    0x3420000 => 'PowerShot A3500 IS',
780    0x3430000 => 'PowerShot A2600',
781    0x3440000 => 'PowerShot SX275 HS', #forum8199
782    0x3450000 => 'PowerShot A1400',
783    0x3460000 => 'PowerShot ELPH 130 IS / IXUS 140 / IXY 110F',
784    0x3470000 => 'PowerShot ELPH 115/120 IS / IXUS 132/135 / IXY 90F/100F',
785    0x3490000 => 'PowerShot ELPH 330 HS / IXUS 255 HS / IXY 610F',
786    0x3510000 => 'PowerShot A2500',
787    0x3540000 => 'PowerShot G16',
788    0x3550000 => 'PowerShot S120',
789    0x3560000 => 'PowerShot SX170 IS',
790    0x3580000 => 'PowerShot SX510 HS',
791    0x3590000 => 'PowerShot S200 (new)',
792    0x3600000 => 'IXY 620F', # (no PowerShot or IXUS?)
793    0x3610000 => 'PowerShot N100',
794    0x3640000 => 'PowerShot G1 X Mark II',
795    0x3650000 => 'PowerShot D30',
796    0x3660000 => 'PowerShot SX700 HS',
797    0x3670000 => 'PowerShot SX600 HS',
798    0x3680000 => 'PowerShot ELPH 140 IS / IXUS 150 / IXY 130',
799    0x3690000 => 'PowerShot ELPH 135 / IXUS 145 / IXY 120',
800    0x3700000 => 'PowerShot ELPH 340 HS / IXUS 265 HS / IXY 630',
801    0x3710000 => 'PowerShot ELPH 150 IS / IXUS 155 / IXY 140',
802    0x3740000 => 'EOS M3', #IB
803    0x3750000 => 'PowerShot SX60 HS', #IB/NJ
804    0x3760000 => 'PowerShot SX520 HS', #IB
805    0x3770000 => 'PowerShot SX400 IS',
806    0x3780000 => 'PowerShot G7 X', #IB
807    0x3790000 => 'PowerShot N2',
808    0x3800000 => 'PowerShot SX530 HS',
809    0x3820000 => 'PowerShot SX710 HS',
810    0x3830000 => 'PowerShot SX610 HS',
811    0x3840000 => 'EOS M10',
812    0x3850000 => 'PowerShot G3 X',
813    0x3860000 => 'PowerShot ELPH 165 HS / IXUS 165 / IXY 160',
814    0x3870000 => 'PowerShot ELPH 160 / IXUS 160',
815    0x3880000 => 'PowerShot ELPH 350 HS / IXUS 275 HS / IXY 640',
816    0x3890000 => 'PowerShot ELPH 170 IS / IXUS 170',
817    0x3910000 => 'PowerShot SX410 IS',
818    0x3930000 => 'PowerShot G9 X',
819    0x3940000 => 'EOS M5', #IB
820    0x3950000 => 'PowerShot G5 X',
821    0x3970000 => 'PowerShot G7 X Mark II',
822    0x3980000 => 'EOS M100', #42
823    0x3990000 => 'PowerShot ELPH 360 HS / IXUS 285 HS / IXY 650',
824    0x4010000 => 'PowerShot SX540 HS',
825    0x4020000 => 'PowerShot SX420 IS',
826    0x4030000 => 'PowerShot ELPH 190 IS / IXUS 180 / IXY 190',
827    0x4040000 => 'PowerShot G1',
828    0x4040001 => 'PowerShot ELPH 180 IS / IXUS 175 / IXY 180', #forum10402
829    0x4050000 => 'PowerShot SX720 HS',
830    0x4060000 => 'PowerShot SX620 HS',
831    0x4070000 => 'EOS M6',
832    0x4100000 => 'PowerShot G9 X Mark II',
833    0x412     => 'EOS M50 / Kiss M', # (yes, no "0000")
834    0x4150000 => 'PowerShot ELPH 185 / IXUS 185 / IXY 200',
835    0x4160000 => 'PowerShot SX430 IS',
836    0x4170000 => 'PowerShot SX730 HS',
837    0x4180000 => 'PowerShot G1 X Mark III', #IB
838    0x6040000 => 'PowerShot S100 / Digital IXUS / IXY Digital',
839    0x801     => 'PowerShot SX740 HS',
840    0x804     => 'PowerShot G5 X Mark II',
841    0x805     => 'PowerShot SX70 HS',
842    0x808     => 'PowerShot G7 X Mark III',
843    0x811     => 'EOS M6 Mark II', #IB
844    0x812     => 'EOS M200', #25
845
846# (see http://cweb.canon.jp/e-support/faq/answer/digitalcamera/10447-1.html for PowerShot/IXUS/IXY names)
847
848    0x4007d673 => 'DC19/DC21/DC22',
849    0x4007d674 => 'XH A1',
850    0x4007d675 => 'HV10',
851    0x4007d676 => 'MD130/MD140/MD150/MD160/ZR850',
852    0x4007d777 => 'DC50', # (iVIS)
853    0x4007d778 => 'HV20', # (iVIS)
854    0x4007d779 => 'DC211', #29
855    0x4007d77a => 'HG10',
856    0x4007d77b => 'HR10', #29 (iVIS)
857    0x4007d77d => 'MD255/ZR950',
858    0x4007d81c => 'HF11',
859    0x4007d878 => 'HV30',
860    0x4007d87c => 'XH A1S',
861    0x4007d87e => 'DC301/DC310/DC311/DC320/DC330',
862    0x4007d87f => 'FS100',
863    0x4007d880 => 'HF10', #29 (iVIS/VIXIA)
864    0x4007d882 => 'HG20/HG21', # (VIXIA)
865    0x4007d925 => 'HF21', # (LEGRIA)
866    0x4007d926 => 'HF S11', # (LEGRIA)
867    0x4007d978 => 'HV40', # (LEGRIA)
868    0x4007d987 => 'DC410/DC411/DC420',
869    0x4007d988 => 'FS19/FS20/FS21/FS22/FS200', # (LEGRIA)
870    0x4007d989 => 'HF20/HF200', # (LEGRIA)
871    0x4007d98a => 'HF S10/S100', # (LEGRIA/VIXIA)
872    0x4007da8e => 'HF R10/R16/R17/R18/R100/R106', # (LEGRIA/VIXIA)
873    0x4007da8f => 'HF M30/M31/M36/M300/M306', # (LEGRIA/VIXIA)
874    0x4007da90 => 'HF S20/S21/S200', # (LEGRIA/VIXIA)
875    0x4007da92 => 'FS31/FS36/FS37/FS300/FS305/FS306/FS307',
876    0x4007dca0 => 'EOS C300',
877    0x4007dda9 => 'HF G25', # (LEGRIA)
878    0x4007dfb4 => 'XC10',
879    0x4007e1c3 => 'EOS C200',
880
881    # NOTE: some pre-production models may have a model name of
882    # "Canon EOS Kxxx", where "xxx" is the last 3 digits of the model ID below.
883    # This has been observed for the 1DSmkIII/K215 and 400D/K236.
884    0x80000001 => 'EOS-1D',
885    0x80000167 => 'EOS-1DS',
886    0x80000168 => 'EOS 10D',
887    0x80000169 => 'EOS-1D Mark III',
888    0x80000170 => 'EOS Digital Rebel / 300D / Kiss Digital',
889    0x80000174 => 'EOS-1D Mark II',
890    0x80000175 => 'EOS 20D',
891    0x80000176 => 'EOS Digital Rebel XSi / 450D / Kiss X2',
892    0x80000188 => 'EOS-1Ds Mark II',
893    0x80000189 => 'EOS Digital Rebel XT / 350D / Kiss Digital N',
894    0x80000190 => 'EOS 40D',
895    0x80000213 => 'EOS 5D',
896    0x80000215 => 'EOS-1Ds Mark III',
897    0x80000218 => 'EOS 5D Mark II',
898    0x80000219 => 'WFT-E1',
899    0x80000232 => 'EOS-1D Mark II N',
900    0x80000234 => 'EOS 30D',
901    0x80000236 => 'EOS Digital Rebel XTi / 400D / Kiss Digital X',
902    0x80000241 => 'WFT-E2',
903    0x80000246 => 'WFT-E3',
904    0x80000250 => 'EOS 7D',
905    0x80000252 => 'EOS Rebel T1i / 500D / Kiss X3',
906    0x80000254 => 'EOS Rebel XS / 1000D / Kiss F',
907    0x80000261 => 'EOS 50D',
908    0x80000269 => 'EOS-1D X',
909    0x80000270 => 'EOS Rebel T2i / 550D / Kiss X4',
910    0x80000271 => 'WFT-E4',
911    0x80000273 => 'WFT-E5',
912    0x80000281 => 'EOS-1D Mark IV',
913    0x80000285 => 'EOS 5D Mark III',
914    0x80000286 => 'EOS Rebel T3i / 600D / Kiss X5',
915    0x80000287 => 'EOS 60D',
916    0x80000288 => 'EOS Rebel T3 / 1100D / Kiss X50',
917    0x80000289 => 'EOS 7D Mark II', #IB
918    0x80000297 => 'WFT-E2 II',
919    0x80000298 => 'WFT-E4 II',
920    0x80000301 => 'EOS Rebel T4i / 650D / Kiss X6i',
921    0x80000302 => 'EOS 6D', #25
922    0x80000324 => 'EOS-1D C', #(NC)
923    0x80000325 => 'EOS 70D',
924    0x80000326 => 'EOS Rebel T5i / 700D / Kiss X7i',
925    0x80000327 => 'EOS Rebel T5 / 1200D / Kiss X70 / Hi',
926    0x80000328 => 'EOS-1D X Mark II', #42
927    0x80000331 => 'EOS M',
928    0x80000350 => 'EOS 80D', #42
929    0x80000355 => 'EOS M2',
930    0x80000346 => 'EOS Rebel SL1 / 100D / Kiss X7',
931    0x80000347 => 'EOS Rebel T6s / 760D / 8000D',
932    0x80000349 => 'EOS 5D Mark IV', #42
933    0x80000382 => 'EOS 5DS',
934    0x80000393 => 'EOS Rebel T6i / 750D / Kiss X8i',
935    0x80000401 => 'EOS 5DS R',
936    0x80000404 => 'EOS Rebel T6 / 1300D / Kiss X80',
937    0x80000405 => 'EOS Rebel T7i / 800D / Kiss X9i',
938    0x80000406 => 'EOS 6D Mark II', #IB/42
939    0x80000408 => 'EOS 77D / 9000D',
940    0x80000417 => 'EOS Rebel SL2 / 200D / Kiss X9', #IB/42
941    0x80000421 => 'EOS R5', #PH
942    0x80000422 => 'EOS Rebel T100 / 4000D / 3000D', #IB (3000D in China; Kiss? - PH)
943    0x80000424 => 'EOS R', #IB
944    0x80000428 => 'EOS-1D X Mark III', #IB
945    0x80000432 => 'EOS Rebel T7 / 2000D / 1500D / Kiss X90', #IB
946    0x80000433 => 'EOS RP',
947    0x80000435 => 'EOS Rebel T8i / 850D / X10i', #JR/PH
948    0x80000436 => 'EOS SL3 / 250D / Kiss X10', #25
949    0x80000437 => 'EOS 90D', #IB
950    0x80000453 => 'EOS R6', #PH
951    0x80000467 => 'PowerShot ZOOM',
952    0x80000468 => 'EOS M50 Mark II / Kiss M2', #IB
953    0x80000520 => 'EOS D2000C', #IB
954    0x80000560 => 'EOS D6000C', #PH (guess)
955);
956
957my %canonQuality = (
958    -1 => 'n/a', # (PH, EOS M MOV video)
959    1 => 'Economy',
960    2 => 'Normal',
961    3 => 'Fine',
962    4 => 'RAW',
963    5 => 'Superfine',
964    7 => 'CRAW', #42
965    130 => 'Normal Movie', #22
966    131 => 'Movie (2)', #PH (7DmkII 1920x1080)
967);
968my %canonImageSize = (
969   -1 => 'n/a',
970    0 => 'Large',
971    1 => 'Medium',
972    2 => 'Small',
973    5 => 'Medium 1', #PH
974    6 => 'Medium 2', #PH
975    7 => 'Medium 3', #PH
976    8 => 'Postcard', #PH (SD200 1600x1200 with DateStamp option)
977    9 => 'Widescreen', #PH (SD900 3648x2048), 22 (HFS200 3264x1840)
978    10 => 'Medium Widescreen', #22 (HFS200 1920x1080)
979    14 => 'Small 1', #PH
980    15 => 'Small 2', #PH
981    16 => 'Small 3', #PH
982    128 => '640x480 Movie', #PH (7D 60fps)
983    129 => 'Medium Movie', #22
984    130 => 'Small Movie', #22
985    137 => '1280x720 Movie', #PH (S95 24fps; D60 50fps)
986    142 => '1920x1080 Movie', #PH (D60 25fps)
987    143 => '4096x2160 Movie', #PH (C200)
988);
989my %canonWhiteBalance = (
990    # -1='Click", -2='Pasted' ?? - PH
991    0 => 'Auto',
992    1 => 'Daylight',
993    2 => 'Cloudy',
994    3 => 'Tungsten',
995    4 => 'Fluorescent',
996    5 => 'Flash',
997    6 => 'Custom',
998    7 => 'Black & White',
999    8 => 'Shade',
1000    9 => 'Manual Temperature (Kelvin)',
1001    10 => 'PC Set1', #PH
1002    11 => 'PC Set2', #PH
1003    12 => 'PC Set3', #PH
1004    14 => 'Daylight Fluorescent', #3
1005    15 => 'Custom 1', #PH
1006    16 => 'Custom 2', #PH
1007    17 => 'Underwater', #3
1008    18 => 'Custom 3', #PH
1009    19 => 'Custom 4', #PH
1010    20 => 'PC Set4', #PH
1011    21 => 'PC Set5', #PH
1012    # 22 - Custom 2?
1013    23 => 'Auto (ambience priority)', #PH (5DS)
1014    # 30 - Click White Balance?
1015    # 31 - Shot Settings?
1016    # 137 - Tungsten?
1017    # 138 - White Fluorescent?
1018    # 139 - Fluorescent H?
1019    # 140 - Manual?
1020);
1021
1022# picture styles used by the 5D
1023# (styles 0x4X may be downloaded from Canon)
1024# (called "ColorMatrix" in 1D owner manual)
1025my %pictureStyles = ( #12
1026    0x00 => 'None', #PH
1027    0x01 => 'Standard', #15
1028    0x02 => 'Portrait', #15
1029    0x03 => 'High Saturation', #15
1030    0x04 => 'Adobe RGB', #15
1031    0x05 => 'Low Saturation', #15
1032    0x06 => 'CM Set 1', #PH
1033    0x07 => 'CM Set 2', #PH
1034    # "ColorMatrix" values end here
1035    0x21 => 'User Def. 1',
1036    0x22 => 'User Def. 2',
1037    0x23 => 'User Def. 3',
1038    # "External" styles currently available from Canon are Nostalgia, Clear,
1039    # Twilight and Emerald.  The "User Def" styles change to these "External"
1040    # codes when these styles are installed in the camera
1041    0x41 => 'PC 1', #PH
1042    0x42 => 'PC 2', #PH
1043    0x43 => 'PC 3', #PH
1044    0x81 => 'Standard',
1045    0x82 => 'Portrait',
1046    0x83 => 'Landscape',
1047    0x84 => 'Neutral',
1048    0x85 => 'Faithful',
1049    0x86 => 'Monochrome',
1050    0x87 => 'Auto', #PH
1051    0x88 => 'Fine Detail', #PH
1052    0xff => 'n/a', #PH (guess)
1053    0xffff => 'n/a', #PH (guess)
1054);
1055my %userDefStyles = ( #12/48
1056    Notes => q{
1057        Base style for user-defined picture styles.  PC values represent external
1058        picture styles which may be downloaded from Canon and installed in the
1059        camera.
1060    },
1061    0x41 => 'PC 1',
1062    0x42 => 'PC 2',
1063    0x43 => 'PC 3',
1064    0x81 => 'Standard',
1065    0x82 => 'Portrait',
1066    0x83 => 'Landscape',
1067    0x84 => 'Neutral',
1068    0x85 => 'Faithful',
1069    0x86 => 'Monochrome',
1070    0x87 => 'Auto', #PH
1071);
1072
1073# picture style tag information for CameraInfo550D
1074my %psConv = (
1075    -559038737 => 'n/a', # = 0xdeadbeef ! LOL
1076    OTHER => sub { shift },
1077);
1078my %psInfo = (
1079    Format => 'int32s',
1080    PrintHex => 1,
1081    PrintConv => \%psConv,
1082);
1083
1084# ValueConv that makes long values binary type
1085my %longBin = (
1086    ValueConv => 'length($val) > 64 ? \$val : $val',
1087    ValueConvInv => '$val',
1088);
1089
1090# conversions, etc for CameraColorCalibration tags
1091my %cameraColorCalibration = (
1092    Format => 'int16s[4]',
1093    Unknown => 1,
1094    PrintConv => 'sprintf("%4d %4d %4d (%dK)", split(" ",$val))',
1095    PrintConvInv => '$val=~s/\s+/ /g; $val=~tr/()K//d; $val',
1096);
1097
1098# conversions, etc for PowerShot CameraColorCalibration tags
1099my %cameraColorCalibration2 = (
1100    Format => 'int16s[5]',
1101    Unknown => 1,
1102    PrintConv => 'sprintf("%4d %4d %4d %4d (%dK)", split(" ",$val))',
1103    PrintConvInv => '$val=~s/\s+/ /g; $val=~tr/()K//d; $val',
1104);
1105# conversions, etc for byte-swapped FocusDistance tags
1106my %focusDistanceByteSwap = (
1107    # this is very odd (little-endian number on odd boundary),
1108    # but it does seem to work better with my sample images - PH
1109    Format => 'int16uRev',
1110    ValueConv => '$val / 100',
1111    ValueConvInv => '$val * 100',
1112    PrintConv => '$val > 655.345 ? "inf" : "$val m"',
1113    PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
1114);
1115
1116# common attributes for writable BinaryData directories
1117my %binaryDataAttrs = (
1118    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
1119    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
1120    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
1121    WRITABLE => 1,
1122);
1123
1124my %offOn = ( 0 => 'Off', 1 => 'On' );
1125
1126#------------------------------------------------------------------------------
1127# Canon EXIF Maker Notes
1128%Image::ExifTool::Canon::Main = (
1129    WRITE_PROC => \&WriteCanon,
1130    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1131    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1132    0x1 => {
1133        Name => 'CanonCameraSettings',
1134        SubDirectory => {
1135            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1136            TagTable => 'Image::ExifTool::Canon::CameraSettings',
1137        },
1138    },
1139    0x2 => {
1140        Name => 'CanonFocalLength',
1141        SubDirectory => { TagTable => 'Image::ExifTool::Canon::FocalLength' },
1142    },
1143    0x3 => {
1144        Name => 'CanonFlashInfo',
1145        Unknown => 1,
1146    },
1147    0x4 => {
1148        Name => 'CanonShotInfo',
1149        SubDirectory => {
1150            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1151            TagTable => 'Image::ExifTool::Canon::ShotInfo',
1152        },
1153    },
1154    0x5 => {
1155        Name => 'CanonPanorama',
1156        SubDirectory => { TagTable => 'Image::ExifTool::Canon::Panorama' },
1157    },
1158    0x6 => {
1159        Name => 'CanonImageType',
1160        Writable => 'string',
1161        Groups => { 2 => 'Image' },
1162    },
1163    0x7 => {
1164        Name => 'CanonFirmwareVersion',
1165        Writable => 'string',
1166    },
1167    0x8 => {
1168        Name => 'FileNumber',
1169        Writable => 'int32u',
1170        Groups => { 2 => 'Image' },
1171        PrintConv => '$_=$val,s/(\d+)(\d{4})/$1-$2/,$_',
1172        PrintConvInv => '$val=~s/-//g;$val',
1173    },
1174    0x9 => {
1175        Name => 'OwnerName',
1176        Writable => 'string',
1177        # pad to 32 bytes (including null terminator which will be added)
1178        # to avoid bug which crashes DPP if length is 4 bytes
1179        ValueConvInv => '$val .= "\0" x (31 - length $val) if length $val < 31; $val',
1180    },
1181    0xa => {
1182        Name => 'UnknownD30',
1183        SubDirectory => {
1184            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1185            TagTable => 'Image::ExifTool::Canon::UnknownD30',
1186        },
1187    },
1188    0xc => [   # square brackets for a conditional list
1189        {
1190            # D30
1191            Name => 'SerialNumber',
1192            Condition => '$$self{Model} =~ /EOS D30\b/',
1193            Writable => 'int32u',
1194            PrintConv => 'sprintf("%.4x%.5d",$val>>16,$val&0xffff)',
1195            PrintConvInv => '$val=~/(.*)-?(\d{5})$/ ? (hex($1)<<16)+$2 : undef',
1196        },
1197        {
1198            # serial number of 1D/1Ds/1D Mark II/1Ds Mark II is usually
1199            # displayed w/o leeding zeros (ref 7) (1D uses 6 digits - PH)
1200            Name => 'SerialNumber',
1201            Condition => '$$self{Model} =~ /EOS-1D/',
1202            Writable => 'int32u',
1203            PrintConv => 'sprintf("%.6u",$val)',
1204            PrintConvInv => '$val',
1205        },
1206        {
1207            # all other models (D60,300D,350D,REBEL,10D,20D,etc)
1208            Name => 'SerialNumber',
1209            Writable => 'int32u',
1210            PrintConv => 'sprintf("%.10u",$val)',
1211            PrintConvInv => '$val',
1212        },
1213    ],
1214    0xd => [
1215        {
1216            Name => 'CanonCameraInfo1D',
1217            # (save size of this record as "CameraInfoCount" for later tests)
1218            Condition => '($$self{CameraInfoCount} = $count) and $$self{Model} =~ /\b1DS?$/',
1219            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1D' },
1220        },
1221        {
1222            Name => 'CanonCameraInfo1DmkII',
1223            Condition => '$$self{Model} =~ /\b1Ds? Mark II$/',
1224            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkII' },
1225        },
1226        {
1227            Name => 'CanonCameraInfo1DmkIIN',
1228            Condition => '$$self{Model} =~ /\b1Ds? Mark II N$/',
1229            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIIN' },
1230        },
1231        {
1232            Name => 'CanonCameraInfo1DmkIII',
1233            Condition => '$$self{Model} =~ /\b1Ds? Mark III$/',
1234            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIII' },
1235        },
1236        {
1237            Name => 'CanonCameraInfo1DmkIV',
1238            Condition => '$$self{Model} =~ /\b1D Mark IV$/',
1239            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIV' },
1240        },
1241        {
1242            Name => 'CanonCameraInfo1DX',
1243            Condition => '$$self{Model} =~ /EOS-1D X$/',
1244            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DX' },
1245        },
1246        {
1247            Name => 'CanonCameraInfo5D',
1248            Condition => '$$self{Model} =~ /EOS 5D$/',
1249            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo5D' },
1250        },
1251        {
1252            Name => 'CanonCameraInfo5DmkII',
1253            Condition => '$$self{Model} =~ /EOS 5D Mark II$/',
1254            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkII' },
1255        },
1256        {
1257            Name => 'CanonCameraInfo5DmkIII',
1258            Condition => '$$self{Model} =~ /EOS 5D Mark III$/',
1259            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkIII' },
1260        },
1261        {
1262            Name => 'CanonCameraInfo6D',
1263            Condition => '$$self{Model} =~ /EOS 6D$/',
1264            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo6D' },
1265        },
1266        {
1267            Name => 'CanonCameraInfo7D',
1268            Condition => '$$self{Model} =~ /EOS 7D$/',
1269            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo7D' },
1270        },
1271        {
1272            Name => 'CanonCameraInfo40D',
1273            Condition => '$$self{Model} =~ /EOS 40D$/',
1274            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo40D' },
1275        },
1276        {
1277            Name => 'CanonCameraInfo50D',
1278            Condition => '$$self{Model} =~ /EOS 50D$/',
1279            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo50D' },
1280        },
1281        {
1282            Name => 'CanonCameraInfo60D',
1283            Condition => '$$self{Model} =~ /EOS 60D$/',
1284            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo60D' },
1285        },
1286        {
1287            Name => 'CanonCameraInfo70D',
1288            Condition => '$$self{Model} =~ /EOS 70D$/',
1289            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo70D' },
1290        },
1291        {
1292            Name => 'CanonCameraInfo80D',
1293            Condition => '$$self{Model} =~ /EOS 80D$/',
1294            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo80D' },
1295        },
1296        {
1297            Name => 'CanonCameraInfo450D',
1298            Condition => '$$self{Model} =~ /\b(450D|REBEL XSi|Kiss X2)\b/',
1299            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo450D' },
1300        },
1301        {
1302            Name => 'CanonCameraInfo500D',
1303            Condition => '$$self{Model} =~ /\b(500D|REBEL T1i|Kiss X3)\b/',
1304            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo500D' },
1305        },
1306        {
1307            Name => 'CanonCameraInfo550D',
1308            Condition => '$$self{Model} =~ /\b(550D|REBEL T2i|Kiss X4)\b/',
1309            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo550D' },
1310        },
1311        {
1312            Name => 'CanonCameraInfo600D',
1313            Condition => '$$self{Model} =~ /\b(600D|REBEL T3i|Kiss X5)\b/',
1314            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo600D' },
1315        },
1316        {
1317            Name => 'CanonCameraInfo650D',
1318            Condition => '$$self{Model} =~ /\b(650D|REBEL T4i|Kiss X6i)\b/',
1319            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo650D' },
1320        },
1321        {
1322            Name => 'CanonCameraInfo700D',
1323            Condition => '$$self{Model} =~ /\b(700D|REBEL T5i|Kiss X7i)\b/',
1324            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo650D' },
1325        },
1326        {
1327            Name => 'CanonCameraInfo750D',
1328            Condition => '$$self{Model} =~ /\b(750D|Rebel T6i|Kiss X8i)\b/',
1329            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo750D' },
1330        },
1331        {
1332            Name => 'CanonCameraInfo760D',
1333            Condition => '$$self{Model} =~ /\b(760D|Rebel T6s|8000D)\b/',
1334            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo750D' },
1335        },
1336        {
1337            Name => 'CanonCameraInfo1000D',
1338            Condition => '$$self{Model} =~ /\b(1000D|REBEL XS|Kiss F)\b/',
1339            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1000D' },
1340        },
1341        {
1342            Name => 'CanonCameraInfo1100D',
1343            Condition => '$$self{Model} =~ /\b(1100D|REBEL T3|Kiss X50)\b/',
1344            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo600D' },
1345        },
1346        {
1347            Name => 'CanonCameraInfo1200D',
1348            Condition => '$$self{Model} =~ /\b(1200D|REBEL T5|Kiss X70)\b/',
1349            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo60D' },
1350        },
1351        {
1352            Name => 'CanonCameraInfoPowerShot',
1353            # valid if format is int32u[138] or int32u[148]
1354            Condition => '$format eq "int32u" and ($count == 138 or $count == 148)',
1355            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoPowerShot' },
1356        },
1357        {
1358            Name => 'CanonCameraInfoPowerShot2',
1359            # valid if format is int32u[162], int32u[167], int32u[171] or int32u[264]
1360            Condition => q{
1361                $format eq "int32u" and ($count == 156 or $count == 162 or
1362                $count == 167 or $count == 171 or $count == 264)
1363            },
1364            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoPowerShot2' },
1365        },
1366        {
1367            Name => 'CanonCameraInfoUnknown32',
1368            Condition => '$format =~ /^int32/',
1369            # (counts of 72, 85, 86, 93, 94, 96, 104) - PH
1370            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown32' },
1371        },
1372        {
1373            Name => 'CanonCameraInfoUnknown16',
1374            Condition => '$format =~ /^int16/',
1375            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown16' },
1376        },
1377        {
1378            Name => 'CanonCameraInfoUnknown',
1379            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown' },
1380        },
1381    ],
1382    0xe => {
1383        Name => 'CanonFileLength',
1384        Writable => 'int32u',
1385        Groups => { 2 => 'Image' },
1386    },
1387    0xf => [
1388        {   # used by 1DmkII, 1DSmkII and 1DmkIIN
1389            Name => 'CustomFunctions1D',
1390            Condition => '$$self{Model} =~ /EOS-1D/',
1391            SubDirectory => {
1392                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1393                TagTable => 'Image::ExifTool::CanonCustom::Functions1D',
1394            },
1395        },
1396        {
1397            Name => 'CustomFunctions5D',
1398            Condition => '$$self{Model} =~ /EOS 5D/',
1399            SubDirectory => {
1400                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1401                TagTable => 'Image::ExifTool::CanonCustom::Functions5D',
1402            },
1403        },
1404        {
1405            Name => 'CustomFunctions10D',
1406            Condition => '$$self{Model} =~ /EOS 10D/',
1407            SubDirectory => {
1408                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1409                TagTable => 'Image::ExifTool::CanonCustom::Functions10D',
1410            },
1411        },
1412        {
1413            Name => 'CustomFunctions20D',
1414            Condition => '$$self{Model} =~ /EOS 20D/',
1415            SubDirectory => {
1416                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1417                TagTable => 'Image::ExifTool::CanonCustom::Functions20D',
1418            },
1419        },
1420        {
1421            Name => 'CustomFunctions30D',
1422            Condition => '$$self{Model} =~ /EOS 30D/',
1423            SubDirectory => {
1424                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1425                TagTable => 'Image::ExifTool::CanonCustom::Functions30D',
1426            },
1427        },
1428        {
1429            Name => 'CustomFunctions350D',
1430            Condition => '$$self{Model} =~ /\b(350D|REBEL XT|Kiss Digital N)\b/',
1431            SubDirectory => {
1432                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1433                TagTable => 'Image::ExifTool::CanonCustom::Functions350D',
1434            },
1435        },
1436        {
1437            Name => 'CustomFunctions400D',
1438            Condition => '$$self{Model} =~ /\b(400D|REBEL XTi|Kiss Digital X|K236)\b/',
1439            SubDirectory => {
1440                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1441                TagTable => 'Image::ExifTool::CanonCustom::Functions400D',
1442            },
1443        },
1444        {
1445            Name => 'CustomFunctionsD30',
1446            Condition => '$$self{Model} =~ /EOS D30\b/',
1447            SubDirectory => {
1448                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1449                TagTable => 'Image::ExifTool::CanonCustom::FunctionsD30',
1450            },
1451        },
1452        {
1453            Name => 'CustomFunctionsD60',
1454            Condition => '$$self{Model} =~ /EOS D60\b/',
1455            SubDirectory => {
1456                # the stored size in the D60 apparently doesn't include the size word:
1457                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size-2,$size)',
1458                # (D60 custom functions are basically the same as D30)
1459                TagTable => 'Image::ExifTool::CanonCustom::FunctionsD30',
1460            },
1461        },
1462        {
1463            Name => 'CustomFunctionsUnknown',
1464            SubDirectory => {
1465                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1466                TagTable => 'Image::ExifTool::CanonCustom::FuncsUnknown',
1467            },
1468        },
1469    ],
1470    0x10 => { #PH
1471        Name => 'CanonModelID',
1472        Writable => 'int32u',
1473        PrintHex => 1,
1474        SeparateTable => 1,
1475        PrintConv => \%canonModelID,
1476    },
1477    0x11 => { #PH
1478        Name => 'MovieInfo',
1479        SubDirectory => {
1480            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1481            TagTable => 'Image::ExifTool::Canon::MovieInfo',
1482        },
1483    },
1484    0x12 => {
1485        Name => 'CanonAFInfo',
1486        # not really a condition -- just need to store the count for later
1487        Condition => '$$self{AFInfoCount} = $count',
1488        SubDirectory => {
1489            # this record does not begin with a length word, so it
1490            # has to be validated differently
1491            Validate => 'Image::ExifTool::Canon::ValidateAFInfo($dirData,$subdirStart,$size)',
1492            TagTable => 'Image::ExifTool::Canon::AFInfo',
1493        },
1494    },
1495    0x13 => { #PH
1496        Name => 'ThumbnailImageValidArea',
1497        # left,right,top,bottom edges of image in thumbnail, or all zeros for full frame
1498        Notes => 'all zeros for full frame',
1499        Writable => 'int16u',
1500        Count => 4,
1501    },
1502    0x15 => { #PH
1503        # display format for serial number
1504        Name => 'SerialNumberFormat',
1505        Writable => 'int32u',
1506        PrintHex => 1,
1507        PrintConv => {
1508            0x90000000 => 'Format 1',
1509            0xa0000000 => 'Format 2',
1510        },
1511    },
1512    0x1a => { #15
1513        Name => 'SuperMacro',
1514        Writable => 'int16u',
1515        PrintConv => {
1516            0 => 'Off',
1517            1 => 'On (1)',
1518            2 => 'On (2)',
1519        },
1520    },
1521    0x1c => { #PH (A570IS)
1522        Name => 'DateStampMode',
1523        Writable => 'int16u',
1524        Notes => 'used only in postcard mode',
1525        PrintConv => {
1526            0 => 'Off',
1527            1 => 'Date',
1528            2 => 'Date & Time',
1529        },
1530    },
1531    0x1d => { #PH
1532        Name => 'MyColors',
1533        SubDirectory => {
1534            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1535            TagTable => 'Image::ExifTool::Canon::MyColors',
1536        },
1537    },
1538    0x1e => { #PH
1539        Name => 'FirmwareRevision',
1540        Writable => 'int32u',
1541        # as a hex number: 0xAVVVRR00, where (a bit of guessing here...)
1542        #  A = 'a' for alpha, 'b' for beta?
1543        #  V = version? (100,101 for normal releases, 100,110,120,130,170 for alpha/beta)
1544        #  R = revision? (01-07, except 00 for alpha/beta releases)
1545        PrintConv => q{
1546            my $rev = sprintf("%.8x", $val);
1547            my ($rel, $v1, $v2, $r1, $r2) = ($rev =~ /^(.)(.)(..)0?(.+)(..)$/);
1548            my %r = ( a => 'Alpha ', b => 'Beta ', '0' => '' );
1549            $rel = defined $r{$rel} ? $r{$rel} : "Unknown($rel) ";
1550            return "$rel$v1.$v2 rev $r1.$r2",
1551        },
1552        PrintConvInv => q{
1553            $_=$val; s/Alpha ?/a/i; s/Beta ?/b/i;
1554            s/Unknown ?\((.)\)/$1/i; s/ ?rev ?(.)\./0$1/; s/ ?rev ?//;
1555            tr/a-fA-F0-9//dc; return hex $_;
1556        },
1557    },
1558    # 0x1f - used for red-eye-corrected images - PH (A570IS)
1559    # 0x22 - values 1 and 2 are 2 and 1 for flash pics, 0 otherwise - PH (A570IS)
1560    0x23 => { #31
1561        Name => 'Categories',
1562        Writable => 'int32u',
1563        Format => 'int32u', # (necessary to perform conversion for Condition)
1564        Notes => '2 values: 1. always 8, 2. Categories',
1565        Count => '2',
1566        Condition => '$$valPt =~ /^\x08\0\0\0/',
1567        ValueConv => '$val =~ s/^8 //; $val',
1568        ValueConvInv => '"8 $val"',
1569        PrintConvColumns => 2,
1570        PrintConv => {
1571            0 => '(none)',
1572            BITMASK => {
1573                0 => 'People',
1574                1 => 'Scenery',
1575                2 => 'Events',
1576                3 => 'User 1',
1577                4 => 'User 2',
1578                5 => 'User 3',
1579                6 => 'To Do',
1580            },
1581        },
1582    },
1583    0x24 => { #PH
1584        Name => 'FaceDetect1',
1585        SubDirectory => {
1586            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1587            TagTable => 'Image::ExifTool::Canon::FaceDetect1',
1588        },
1589    },
1590    0x25 => { #PH
1591        Name => 'FaceDetect2',
1592        SubDirectory => {
1593            TagTable => 'Image::ExifTool::Canon::FaceDetect2',
1594            # (can't validate because this record uses a 1-byte count instead of a 2-byte count)
1595        },
1596    },
1597    0x26 => { #PH (A570IS,1DmkIII)
1598        Name => 'CanonAFInfo2',
1599        Condition => '$$valPt !~ /^\0\0\0\0/', # (data may be all zeros in thumbnail of 60D MOV video)
1600        SubDirectory => {
1601            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1602            TagTable => 'Image::ExifTool::Canon::AFInfo2',
1603        },
1604    },
1605    0x27 => { #PH
1606        Name => 'ContrastInfo',
1607        Condition => '$$valPt =~ /^\x0a\0/', # (seems to be various versions of this information)
1608        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ContrastInfo' },
1609    },
1610    # 0x27 - value 1 is 1 for high ISO pictures, 0 otherwise
1611    #        value 4 is 9 for Flexizone and FaceDetect AF, 1 for Centre AF, 0 otherwise (SX10IS)
1612    0x28 => { #JD
1613        # bytes 0-1=sequence number (encrypted), 2-5=date/time (encrypted) (ref JD)
1614        Name => 'ImageUniqueID',
1615        Format => 'undef',
1616        Writable => 'int8u',
1617        Groups => { 2 => 'Image' },
1618        RawConv => '$val eq "\0" x 16 ? undef : $val',
1619        ValueConv => 'unpack("H*", $val)',
1620        ValueConvInv => 'pack("H*", $val)',
1621    },
1622    0x29 => { #IB (G9)
1623        Name => 'WBInfo',
1624        SubDirectory => { TagTable => 'Image::ExifTool::Canon::WBInfo' },
1625    },
1626    # 0x2d - changes with categories (ref 31)
1627    0x2f => { #PH (G12)
1628        Name => 'FaceDetect3',
1629        SubDirectory => {
1630            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1631            TagTable => 'Image::ExifTool::Canon::FaceDetect3',
1632        },
1633    },
1634    # 0x32 - if length is 768, starting at offset 4 there are 6 RGGB 1/val int16 records:
1635    #        daylight,cloudy,tungsten,fluorescent,flash,kelvin (D30 2001, ref IB)
1636    0x35 => { #PH
1637        Name => 'TimeInfo',
1638        SubDirectory => {
1639            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1640            TagTable => 'Image::ExifTool::Canon::TimeInfo',
1641        },
1642    },
1643    0x38 => { #PH
1644        Name => 'BatteryType',
1645        Writable => 'undef',
1646        Condition => '$count == 76',
1647        RawConv => '$val=~/^.{4}([^\0]+)/s ? $1 : undef',
1648        RawConvInv => 'substr("\x4c\0\0\0".$val.("\0"x72), 0, 76)',
1649    },
1650    0x3c => { #PH (G1XmkII)
1651        Name => 'AFInfo3',
1652        Condition => '$$self{AFInfo3} = 1',
1653        SubDirectory => {
1654            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1655            TagTable => 'Image::ExifTool::Canon::AFInfo2',
1656        },
1657    },
1658    # 0x44 (ShootInfo)
1659    # 0x62 (UserSetting)
1660    0x81 => { #13
1661        Name => 'RawDataOffset',
1662        # (can't yet write 1D raw files)
1663        # Writable => 'int32u',
1664        # Protected => 2,
1665    },
1666    0x83 => { #PH
1667        Name => 'OriginalDecisionDataOffset',
1668        Writable => 'int32u',
1669        OffsetPair => 1, # (just used as a flag, since this tag has no pair)
1670        # this is an offset to the original decision data block
1671        # (offset relative to start of file in JPEG images, but NOT DNG images!)
1672        IsOffset => '$val and $$et{FILE_TYPE} ne "JPEG"',
1673        Protected => 2,
1674        DataTag => 'OriginalDecisionData',
1675    },
1676    0x90 => {   # used by 1D and 1Ds
1677        Name => 'CustomFunctions1D',
1678        SubDirectory => {
1679            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1680            TagTable => 'Image::ExifTool::CanonCustom::Functions1D',
1681        },
1682    },
1683    0x91 => { #PH
1684        Name => 'PersonalFunctions',
1685        SubDirectory => {
1686            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1687            TagTable => 'Image::ExifTool::CanonCustom::PersonalFuncs',
1688        },
1689    },
1690    0x92 => { #PH
1691        Name => 'PersonalFunctionValues',
1692        SubDirectory => {
1693            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1694            TagTable => 'Image::ExifTool::CanonCustom::PersonalFuncValues',
1695        },
1696    },
1697    0x93 => {
1698        Name => 'CanonFileInfo', # (ShootInfoEx)
1699        SubDirectory => {
1700            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1701            TagTable => 'Image::ExifTool::Canon::FileInfo',
1702        },
1703    },
1704    0x94 => { #PH
1705        # AF points for 1D (45 points in 5 rows)
1706        Name => 'AFPointsInFocus1D',
1707        Notes => 'EOS 1D -- 5 rows: A1-7, B1-10, C1-11, D1-10, E1-7, center point is C6',
1708        PrintConv => 'Image::ExifTool::Canon::PrintAFPoints1D($val)',
1709    },
1710    0x95 => { #PH (observed in 5D sample image)
1711        Name => 'LensModel', # (LensName)
1712        Writable => 'string',
1713    },
1714    0x96 => [ #PH (CMOSNumber)
1715        {
1716            Name => 'SerialInfo',
1717            Condition => '$$self{Model} =~ /EOS 5D/',
1718            SubDirectory => { TagTable => 'Image::ExifTool::Canon::SerialInfo' },
1719        },
1720        {
1721            Name => 'InternalSerialNumber',
1722            Writable => 'string',
1723            # remove trailing 0xff's if they exist (Kiss X3)
1724            ValueConv => '$val=~s/\xff+$//; $val',
1725            ValueConvInv => '$val',
1726        },
1727    ],
1728    0x97 => { #PH (also see http://www.freepatentsonline.com/7657116.html)
1729        Name => 'DustRemovalData', # (DustDeleteData)
1730        Writable => 'undef',
1731        Flags => [ 'Binary', 'Protected' ],
1732        # 0x00: int8u  - Version (0 or 1)
1733        # 0x01: int8u  - LensInfo ? (1)
1734        # 0x02: int8u  - AVValue ? (int8u for version 0, int16u for version 1)
1735        # 0x03: int8u  - POValue ? (int8u for version 0, int16u for version 1)
1736        # 0x04: int16u - DustCount
1737        # 0x06: int16u - FocalLength ?
1738        # 0x08: int16u - LensID ?
1739        # 0x0a: int16u - Width
1740        # 0x0c: int16u - Height
1741        # 0x0e: int16u - RAW_Width
1742        # 0x10: int16u - RAW_Height
1743        # 0x12: int16u - PixelPitch [um * 1000]
1744        # 0x14: int16u - LpfDistance [mm * 1000]
1745        # 0x16: int8u  - TopOffset
1746        # 0x17: int8u  - BottomOffset
1747        # 0x18: int8u  - LeftOffset
1748        # 0x19: int8u  - RightOffset
1749        # 0x1a: int8u  - Year [-1900]
1750        # 0x1b: int8u  - Month
1751        # 0x1c: int8u  - Day
1752        # 0x1d: int8u  - Hour
1753        # 0x1e: int8u  - Minutes
1754        # 0x1f: int8u  - BrightDiff
1755        # Table with DustCount entries:
1756        # 0x22: int16u - DustX
1757        # 0x24: int16u - DustY
1758        # 0x26: int16u - DustSize
1759    },
1760    0x98 => { #PH
1761        Name => 'CropInfo', # (ImageSizeOffset)
1762        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CropInfo' },
1763    },
1764    0x99 => { #PH (EOS 1D Mark III, 40D, etc)
1765        Name => 'CustomFunctions2', # (CustomFunEx)
1766        SubDirectory => {
1767            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1768            TagTable => 'Image::ExifTool::CanonCustom::Functions2',
1769        },
1770    },
1771    0x9a => { #PH
1772        Name => 'AspectInfo', # (AspectRatioInfo)
1773        SubDirectory => { TagTable => 'Image::ExifTool::Canon::AspectInfo' },
1774    },
1775    0xa0 => {
1776        Name => 'ProcessingInfo', # (DevelopParam)
1777        SubDirectory => {
1778            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1779            TagTable => 'Image::ExifTool::Canon::Processing',
1780        },
1781    },
1782    0xa1 => { Name => 'ToneCurveTable', %longBin }, #PH
1783    0xa2 => { Name => 'SharpnessTable', %longBin }, #PH
1784    0xa3 => { Name => 'SharpnessFreqTable', %longBin }, #PH
1785    0xa4 => { Name => 'WhiteBalanceTable', %longBin }, #PH
1786    0xa9 => {
1787        Name => 'ColorBalance',
1788        SubDirectory => {
1789            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1790            TagTable => 'Image::ExifTool::Canon::ColorBalance',
1791        },
1792    },
1793    0xaa => {
1794        Name => 'MeasuredColor', # (PresetWBDS)
1795        SubDirectory => {
1796            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1797            TagTable => 'Image::ExifTool::Canon::MeasuredColor',
1798        },
1799    },
1800    0xae => {
1801        Name => 'ColorTemperature',
1802        Writable => 'int16u',
1803    },
1804    0xb0 => { #PH
1805        Name => 'CanonFlags',
1806        SubDirectory => {
1807            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1808            TagTable => 'Image::ExifTool::Canon::Flags',
1809        },
1810    },
1811    0xb1 => { #PH
1812        Name => 'ModifiedInfo',
1813        SubDirectory => {
1814            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1815            TagTable => 'Image::ExifTool::Canon::ModifiedInfo',
1816        },
1817    },
1818    0xb2 => { Name => 'ToneCurveMatching', %longBin }, #PH
1819    0xb3 => { Name => 'WhiteBalanceMatching', %longBin }, #PH
1820    0xb4 => { #PH
1821        Name => 'ColorSpace',
1822        Writable => 'int16u',
1823        PrintConv => {
1824            1 => 'sRGB',
1825            2 => 'Adobe RGB',
1826            65535 => 'n/a',
1827        },
1828    },
1829    0xb6 => {
1830        Name => 'PreviewImageInfo',
1831        SubDirectory => {
1832            # Note: the first word of this block gives the correct block size in bytes, but
1833            # the size is wrong by a factor of 2 in the IFD, so we must account for this
1834            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size/2)',
1835            TagTable => 'Image::ExifTool::Canon::PreviewImageInfo',
1836        },
1837    },
1838    0xd0 => { #PH
1839        Name => 'VRDOffset',
1840        Writable => 'int32u',
1841        OffsetPair => 1, # (just used as a flag, since this tag has no pair)
1842        Protected => 2,
1843        DataTag => 'CanonVRD',
1844        Notes => 'offset of VRD "recipe data" if it exists',
1845    },
1846    0xe0 => { #12
1847        Name => 'SensorInfo', # (ImageAreaDesc)
1848        SubDirectory => {
1849            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1850            TagTable => 'Image::ExifTool::Canon::SensorInfo',
1851        },
1852    },
1853    0x4001 => [ #13 (WBPacket)
1854        {   # (int16u[582]) - 20D and 350D
1855            Condition => '$count == 582',
1856            Name => 'ColorData1',
1857            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData1' },
1858        },
1859        {   # (int16u[653]) - 1DmkII and 1DSmkII
1860            Condition => '$count == 653',
1861            Name => 'ColorData2',
1862            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData2' },
1863        },
1864        {   # (int16u[796]) - 1DmkIIN, 5D, 30D, 400D
1865            Condition => '$count == 796',
1866            Name => 'ColorData3',
1867            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData3' },
1868        },
1869        {   # (int16u[692|674|702|1227|1250|1251|1337])
1870            # 40D (692), 1DmkIII (674), 1DSmkIII (702), 450D/1000D (1227)
1871            # 50D/5DmkII (1250), 500D/7D_pre-prod/1DmkIV_pre-prod (1251),
1872            # 1DmkIV/7D/550D_pre-prod (1337), 550D (1338), 60D/1100D (1346)
1873            Condition => q{
1874                $count == 692  or $count == 674  or $count == 702 or
1875                $count == 1227 or $count == 1250 or $count == 1251 or
1876                $count == 1337 or $count == 1338 or $count == 1346
1877            },
1878            Name => 'ColorData4',
1879            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData4' },
1880        },
1881        {   # (int16u[5120]) - G10, G7X
1882            Condition => '$count == 5120',
1883            Name => 'ColorData5',
1884            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData5' },
1885        },
1886        {   # (int16u[1273|1275]) - 600D (1273), 1200D (1275)
1887            Condition => '$count == 1273 or $count == 1275',
1888            Name => 'ColorData6',
1889            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData6' },
1890        },
1891        {   # (int16u[1312|1313|1316])
1892            # 1DX/5DmkIII/650D/700D/M (1312), 6D/70D/100D (1313),
1893            # 1DX firmware 1.x (1316), 7DmkII (1506)
1894            Condition => '$count == 1312 or $count == 1313 or $count == 1316 or
1895                          $count == 1506',
1896            Name => 'ColorData7',
1897            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData7' },
1898        },
1899        {   # (int16u[1560|1592]) - 5DS/5DSR (1560), 80D (1592), 1300D (1353) ref IB
1900            Condition => '$count == 1560 or $count == 1592 or $count == 1353 or $count == 1602',
1901            Name => 'ColorData8',
1902            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData8' },
1903        },
1904        {   # (int16u[1816|1820|1824]) - M50 (1820) ref PH, EOS R (1824), EOS RP, SX70 (1816) ref IB
1905            Condition => '$count == 1816 or $count == 1820 or $count == 1824',
1906            Name => 'ColorData9',
1907            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData9' },
1908        },
1909        {   # (int16u[2024|3656]) - 1DXmkIII (2024) ref IB, R5/R6 (3656) ref PH
1910            Condition => '$count == 2024 or $count == 3656',
1911            Name => 'ColorData10',
1912            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData10' },
1913        },
1914        {
1915            Name => 'ColorDataUnknown',
1916            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorDataUnknown' },
1917        },
1918    ],
1919    0x4002 => { #PH
1920        # unknown data block in some JPEG and CR2 images
1921        # (5kB for most models, but 22kb for 5D and 30D, and 43kB for 5DmkII so Drop it)
1922        Name => 'CRWParam',
1923        Format => 'undef',
1924        Flags => [ 'Unknown', 'Binary', 'Drop' ],
1925    },
1926    0x4003 => { #PH
1927        Name => 'ColorInfo',
1928        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorInfo' },
1929    },
1930    0x4005 => { #PH
1931        Name => 'Flavor',
1932        Notes => 'unknown 49kB block, not copied to JPEG images',
1933        # 'Drop' because not found in JPEG images (too large for APP1 anyway)
1934        Flags => [ 'Unknown', 'Binary', 'Drop' ],
1935    },
1936    0x4008 => { #53
1937        Name => 'PictureStyleUserDef', # (BasePictStyleOfUser)
1938        Writable => 'int16u',
1939        Count => 3, # UserDef1, UserDef2, UserDef3
1940        PrintHex => 1,
1941        SeparateTable => 'PictureStyle',
1942        PrintConv => [\%pictureStyles,\%pictureStyles,\%pictureStyles],
1943    },
1944    0x4009 => { #53
1945        Name => 'PictureStylePC', # (BasePictStyleOfUser)
1946        Writable => 'int16u',
1947        Count => 3, # PC1, PC2, PC3
1948        PrintHex => 1,
1949        SeparateTable => 'PictureStyle',
1950        PrintConv => [\%pictureStyles,\%pictureStyles,\%pictureStyles],
1951    },
1952    0x4010 => { #forum2933
1953        Name => 'CustomPictureStyleFileName', # (PictStyleCaption)
1954        Writable => 'string',
1955    },
1956    # 0x4011 (PictStyleAppendInfo)
1957    # 0x4012 (CustomWBCaption)
1958    0x4013 => { #PH
1959        Name => 'AFMicroAdj', # (AFMicroAdjust)
1960        SubDirectory => {
1961            # Canon DPP 3.13 is known to truncate this data to 0x14 bytes (from 0x2c),
1962            # so specifically check for 0x2c to avoid giving a warning in this case
1963            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size,0x2c)',
1964            TagTable => 'Image::ExifTool::Canon::AFMicroAdj',
1965        },
1966    },
1967    # 0x4014 (similar to 0x83?)
1968    0x4015 => [{
1969        Name => 'VignettingCorr', # (LensPacket)
1970        Condition => '$$valPt =~ /^\0/ and $$valPt !~ /^\0\0\0\0/', # (data may be all zeros for 60D)
1971        SubDirectory => {
1972            # (the size word is at byte 2 in this structure)
1973            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart+2,$size)',
1974            TagTable => 'Image::ExifTool::Canon::VignettingCorr',
1975        },
1976    },{
1977        Name => 'VignettingCorrUnknown1',
1978        Condition => '$$valPt =~ /^[\x01\x02\x10\x20]/ and $$valPt !~ /^\0\0\0\0/',
1979        SubDirectory => {
1980            # (the size word is at byte 2 in this structure)
1981            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart+2,$size)',
1982            TagTable => 'Image::ExifTool::Canon::VignettingCorrUnknown',
1983        },
1984    },{
1985        Name => 'VignettingCorrUnknown2',
1986        Condition => '$$valPt !~ /^\0\0\0\0/',
1987        SubDirectory => {
1988            # (the size word is at byte 4 for version 3 of this structure, but not always!)
1989            # Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart+4,$size)',
1990            TagTable => 'Image::ExifTool::Canon::VignettingCorrUnknown',
1991        },
1992    }],
1993    0x4016 => {
1994        Name => 'VignettingCorr2', # (ImageCorrectActual)
1995        SubDirectory => {
1996            # (the size word is actually 4 bytes, but it doesn't matter if little-endian)
1997            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
1998            TagTable => 'Image::ExifTool::Canon::VignettingCorr2',
1999        },
2000    },
2001    0x4018 => { #PH
2002        Name => 'LightingOpt', # (ImageCorrect)
2003        SubDirectory => {
2004            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
2005            TagTable => 'Image::ExifTool::Canon::LightingOpt',
2006        }
2007    },
2008    0x4019 => { #20
2009        Name => 'LensInfo', # (LensInfoForService)
2010        SubDirectory => {
2011            TagTable => 'Image::ExifTool::Canon::LensInfo',
2012        }
2013    },
2014    0x4020 => { #PH
2015        Name => 'AmbienceInfo',
2016        Condition => '$$valPt !~ /^\0\0\0\0/', # (data may be all zeros for 60D)
2017        SubDirectory => {
2018            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
2019            TagTable => 'Image::ExifTool::Canon::Ambience',
2020        }
2021    },
2022    0x4021 => { #PH
2023        Name => 'MultiExp', # (ExifDSTagMultipleExposure)
2024        SubDirectory => {
2025            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
2026            TagTable => 'Image::ExifTool::Canon::MultiExp',
2027        }
2028    },
2029    0x4024 => { #PH
2030        Name => 'FilterInfo',
2031        SubDirectory => {
2032            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
2033            TagTable => 'Image::ExifTool::Canon::FilterInfo',
2034        }
2035    },
2036    0x4025 => { #PH
2037        Name => 'HDRInfo', # (HighDynamicRange)
2038        SubDirectory => {
2039            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
2040            TagTable => 'Image::ExifTool::Canon::HDRInfo',
2041        }
2042    },
2043    0x4028 => { #PH
2044        Name => 'AFConfig', # (AFTabInfo)
2045        SubDirectory => {
2046            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
2047            TagTable => 'Image::ExifTool::Canon::AFConfig',
2048        }
2049    },
2050    0x403f => { #25
2051        Name => 'RawBurstModeRoll',
2052        SubDirectory => {
2053            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
2054            TagTable => 'Image::ExifTool::Canon::RawBurstInfo',
2055        }
2056    },
2057);
2058
2059#..............................................................................
2060# Canon camera settings (MakerNotes tag 0x01)
2061# BinaryData (keys are indices into the int16s array)
2062%Image::ExifTool::Canon::CameraSettings = (
2063    %binaryDataAttrs,
2064    FORMAT => 'int16s',
2065    FIRST_ENTRY => 1,
2066    DATAMEMBER => [ 22, 25 ],   # necessary for writing
2067    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
2068    1 => {
2069        Name => 'MacroMode',
2070        PrintConv => {
2071            1 => 'Macro',
2072            2 => 'Normal',
2073        },
2074    },
2075    2 => {
2076        Name => 'SelfTimer',
2077        # Custom timer mode if bit 0x4000 is set - PH (A570IS)
2078        PrintConv => q{
2079            return 'Off' unless $val;
2080            return (($val&0xfff) / 10) . ' s' . ($val & 0x4000 ? ', Custom' : '');
2081        },
2082        PrintConvInv => q{
2083            return 0 if $val =~ /^Off/i;
2084            $val =~ s/\s*s(ec)?\b//i;
2085            $val =~ s/,?\s*Custom$//i ? ($val*10) | 0x4000 : $val*10;
2086        },
2087    },
2088    3 => {
2089        Name => 'Quality',
2090        PrintConv => \%canonQuality,
2091    },
2092    4 => {
2093        Name => 'CanonFlashMode',
2094        PrintConv => {
2095            -1 => 'n/a', # (PH, EOS M MOV video)
2096            0 => 'Off',
2097            1 => 'Auto',
2098            2 => 'On',
2099            3 => 'Red-eye reduction',
2100            4 => 'Slow-sync',
2101            5 => 'Red-eye reduction (Auto)',
2102            6 => 'Red-eye reduction (On)',
2103            16 => 'External flash', # not set in D30 or 300D
2104        },
2105    },
2106    5 => {
2107        Name => 'ContinuousDrive',
2108        PrintConv => {
2109            0 => 'Single',
2110            1 => 'Continuous',
2111            2 => 'Movie', #PH
2112            3 => 'Continuous, Speed Priority', #PH
2113            4 => 'Continuous, Low', #PH
2114            5 => 'Continuous, High', #PH
2115            6 => 'Silent Single', #PH
2116            # ref A: https://exiftool.org/forum/index.php/topic,5701.msg27843.html#msg27843
2117            9 => 'Single, Silent', #A
2118            10 => 'Continuous, Silent', #A
2119            # 11 - seen for SX260
2120            # 32-34 - Self-timer?
2121        },
2122    },
2123    7 => {
2124        Name => 'FocusMode',
2125        PrintConv => {
2126            0 => 'One-shot AF',
2127            1 => 'AI Servo AF',
2128            2 => 'AI Focus AF',
2129            3 => 'Manual Focus (3)',
2130            4 => 'Single',
2131            5 => 'Continuous',
2132            6 => 'Manual Focus (6)',
2133           16 => 'Pan Focus', #PH
2134           # 137 - Single?
2135           256 => 'AF + MF', #PH (NC, EOS M)
2136           257 => 'Live View', #forum12082
2137           512 => 'Movie Snap Focus', #48
2138           519 => 'Movie Servo AF', #PH (NC, EOS M)
2139        },
2140    },
2141    9 => { #PH
2142        Name => 'RecordMode',
2143        RawConv => '$val==-1 ? undef : $val', #22
2144        PrintConv => {
2145            1 => 'JPEG',
2146            2 => 'CRW+THM', # (300D,etc)
2147            3 => 'AVI+THM', # (30D)
2148            4 => 'TIF', # +THM? (1Ds) (unconfirmed)
2149            5 => 'TIF+JPEG', # (1D) (unconfirmed)
2150            6 => 'CR2', # +THM? (1D,30D,350D)
2151            7 => 'CR2+JPEG', # (S30)
2152            9 => 'MOV', # (S95 MOV)
2153            10 => 'MP4', # (SX280 MP4)
2154            11 => 'CRM', #PH (C200 CRM)
2155            12 => 'CR3', #PH (EOS R)
2156            13 => 'CR3+JPEG', #PH (EOS R)
2157            14 => 'HIF', #PH (NC)
2158            15 => 'CR3+HIF', #PH (1DXmkIII)
2159        },
2160    },
2161    10 => {
2162        Name => 'CanonImageSize',
2163        PrintConvColumns => 2,
2164        PrintConv => \%canonImageSize,
2165    },
2166    11 => {
2167        Name => 'EasyMode',
2168        PrintConvColumns => 3,
2169        PrintConv => {
2170            # references:
2171            # A = http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm
2172            # B = http://www.burren.cx/david/canon.html
2173            # C = DPP 3.11.26
2174            0 => 'Full auto',
2175            1 => 'Manual',
2176            2 => 'Landscape',
2177            3 => 'Fast shutter',
2178            4 => 'Slow shutter',
2179            5 => 'Night', # (C='Night Scene')
2180            6 => 'Gray Scale', #PH (A/B/C='Black & White')
2181            7 => 'Sepia',
2182            8 => 'Portrait',
2183            9 => 'Sports',
2184            10 => 'Macro',
2185            11 => 'Black & White', #PH (A='Black & White', B/C='Pan focus')
2186            12 => 'Pan focus', # (A='Pan focus', C='Vivid')
2187            13 => 'Vivid', #PH (A='Vivid', C='Neutral')
2188            14 => 'Neutral', #PH (A='Natural', C='Black & White')
2189            15 => 'Flash Off',  #8 (C=<none>)
2190            16 => 'Long Shutter', #PH
2191            17 => 'Super Macro', #PH (C='Macro')
2192            18 => 'Foliage', #PH
2193            19 => 'Indoor', #PH
2194            20 => 'Fireworks', #PH
2195            21 => 'Beach', #PH
2196            22 => 'Underwater', #PH
2197            23 => 'Snow', #PH
2198            24 => 'Kids & Pets', #PH
2199            25 => 'Night Snapshot', #PH
2200            26 => 'Digital Macro', #PH
2201            27 => 'My Colors', #PH
2202            28 => 'Movie Snap', #PH
2203            29 => 'Super Macro 2', #PH
2204            30 => 'Color Accent', #18
2205            31 => 'Color Swap', #18
2206            32 => 'Aquarium', #18
2207            33 => 'ISO 3200', #18
2208            34 => 'ISO 6400', #PH
2209            35 => 'Creative Light Effect', #PH
2210            36 => 'Easy', #PH
2211            37 => 'Quick Shot', #PH
2212            38 => 'Creative Auto', #39
2213            39 => 'Zoom Blur', #PH
2214            40 => 'Low Light', #PH
2215            41 => 'Nostalgic', #PH
2216            42 => 'Super Vivid', #PH (SD4500)
2217            43 => 'Poster Effect', #PH (SD4500)
2218            44 => 'Face Self-timer', #PH
2219            45 => 'Smile', #PH
2220            46 => 'Wink Self-timer', #PH
2221            47 => 'Fisheye Effect', #PH (SX30IS,IXUS240)
2222            48 => 'Miniature Effect', #PH (SD4500)
2223            49 => 'High-speed Burst', #PH
2224            50 => 'Best Image Selection', #PH
2225            51 => 'High Dynamic Range', #PH (S95)
2226            52 => 'Handheld Night Scene', #PH
2227            53 => 'Movie Digest', #PH
2228            54 => 'Live View Control', #PH
2229            55 => 'Discreet', #PH
2230            56 => 'Blur Reduction', #PH
2231            57 => 'Monochrome', #PH (SX260 B&W,Sepia,Blue tone)
2232            58 => 'Toy Camera Effect', #51
2233            59 => 'Scene Intelligent Auto', #PH (T3i) (C='High-speed Burst HQ' !!)
2234            60 => 'High-speed Burst HQ', #PH (C='High-speed Burst HQ', same as 59)
2235            61 => 'Smooth Skin', #51
2236            62 => 'Soft Focus', #PH (SX260,IXUS240)
2237            68 => 'Food', #PH (250D)
2238            # 83 - seen for EOS M200 (ref PH)
2239            84 => 'HDR Art Standard', #PH (80D)
2240            85 => 'HDR Art Vivid', #PH (80D)
2241            93 => 'HDR Art Bold', #PH (80D)
2242            # 83 - seen for EOS M3 night shot (PH)
2243            257 => 'Spotlight', #PH
2244            258 => 'Night 2', #PH
2245            259 => 'Night+',
2246            260 => 'Super Night', #PH
2247            261 => 'Sunset', #PH (SX10IS)
2248            263 => 'Night Scene', #PH
2249            264 => 'Surface', #PH
2250            265 => 'Low Light 2', #PH
2251        },
2252    },
2253    12 => {
2254        Name => 'DigitalZoom',
2255        PrintConv => {
2256            0 => 'None',
2257            1 => '2x',
2258            2 => '4x',
2259            3 => 'Other',  # value obtained from 2*$val[37]/$val[36]
2260        },
2261    },
2262    13 => {
2263        Name => 'Contrast',
2264        RawConv => '$val == 0x7fff ? undef : $val',
2265        %Image::ExifTool::Exif::printParameter,
2266    },
2267    14 => {
2268        Name => 'Saturation',
2269        RawConv => '$val == 0x7fff ? undef : $val',
2270        %Image::ExifTool::Exif::printParameter,
2271    },
2272    15 => {
2273        Name => 'Sharpness',
2274        RawConv => '$val == 0x7fff ? undef : $val',
2275        Notes => q{
2276            some models use a range of -2 to +2 where 0 is normal sharpening, and
2277            others use a range of 0 to 7 where 0 is no sharpening
2278        },
2279        PrintConv => '$val > 0 ? "+$val" : $val',
2280        PrintConvInv => '$val',
2281    },
2282    16 => {
2283        Name => 'CameraISO',
2284        RawConv => '$val == 0x7fff ? undef : $val',
2285        ValueConv => 'Image::ExifTool::Canon::CameraISO($val)',
2286        ValueConvInv => 'Image::ExifTool::Canon::CameraISO($val,1)',
2287    },
2288    17 => {
2289        Name => 'MeteringMode',
2290        PrintConv => {
2291            0 => 'Default', # older Ixus
2292            1 => 'Spot',
2293            2 => 'Average', #PH
2294            3 => 'Evaluative',
2295            4 => 'Partial',
2296            5 => 'Center-weighted average',
2297        },
2298    },
2299    18 => {
2300        # this is always 2 for the 300D - PH
2301        Name => 'FocusRange',
2302        PrintConv => {
2303            0 => 'Manual',
2304            1 => 'Auto',
2305            2 => 'Not Known',
2306            3 => 'Macro',
2307            4 => 'Very Close', #PH
2308            5 => 'Close', #PH
2309            6 => 'Middle Range', #PH
2310            7 => 'Far Range',
2311            8 => 'Pan Focus',
2312            9 => 'Super Macro', #PH
2313            10=> 'Infinity', #PH
2314        },
2315    },
2316    19 => {
2317        Name => 'AFPoint',
2318        Flags => 'PrintHex',
2319        RawConv => '$val==0 ? undef : $val',
2320        PrintConv => {
2321            0x2005 => 'Manual AF point selection',
2322            0x3000 => 'None (MF)',
2323            0x3001 => 'Auto AF point selection',
2324            0x3002 => 'Right',
2325            0x3003 => 'Center',
2326            0x3004 => 'Left',
2327            0x4001 => 'Auto AF point selection',
2328            0x4006 => 'Face Detect', #PH (A570IS)
2329        },
2330    },
2331    20 => {
2332        Name => 'CanonExposureMode',
2333        PrintConv => {
2334            0 => 'Easy',
2335            1 => 'Program AE',
2336            2 => 'Shutter speed priority AE',
2337            3 => 'Aperture-priority AE',
2338            4 => 'Manual',
2339            5 => 'Depth-of-field AE',
2340            6 => 'M-Dep', #PH
2341            7 => 'Bulb', #30
2342            8 => 'Flexible-priority AE', #ArnoldVanOostrum
2343        },
2344    },
2345    22 => { #4
2346        Name => 'LensType',
2347        Format => 'int16u',
2348        RawConv => '$val ? $$self{LensType}=$val : undef', # don't use if value is zero
2349        Notes => 'this value is incorrect for EOS 7D images with lenses of type 256 or greater',
2350        SeparateTable => 1,
2351        DataMember => 'LensType',
2352        ValueConvInv => 'int($val)', # (must truncate decimal part)
2353        PrintConv => \%canonLensTypes,
2354    },
2355    23 => {
2356        Name => 'MaxFocalLength',
2357        Format => 'int16u',
2358        # this is a bit tricky, but we need the FocalUnits to convert this to mm
2359        RawConvInv => '$val * ($$self{FocalUnits} || 1)',
2360        ValueConv => '$val / ($$self{FocalUnits} || 1)',
2361        ValueConvInv => '$val',
2362        PrintConv => '"$val mm"',
2363        PrintConvInv => '$val=~s/\s*mm//;$val',
2364    },
2365    24 => {
2366        Name => 'MinFocalLength',
2367        Format => 'int16u',
2368        RawConvInv => '$val * ($$self{FocalUnits} || 1)',
2369        ValueConv => '$val / ($$self{FocalUnits} || 1)',
2370        ValueConvInv => '$val',
2371        PrintConv => '"$val mm"',
2372        PrintConvInv => '$val=~s/\s*mm//;$val',
2373    },
2374    25 => {
2375        Name => 'FocalUnits',
2376        # conversion from raw focal length values to mm
2377        DataMember => 'FocalUnits',
2378        RawConv => '$$self{FocalUnits} = $val',
2379        PrintConv => '"$val/mm"',
2380        PrintConvInv => '$val=~s/\s*\/?\s*mm//;$val',
2381    },
2382    26 => { #9
2383        Name => 'MaxAperture',
2384        RawConv => '$val > 0 ? $val : undef',
2385        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val)*log(2)/2)',
2386        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))',
2387        PrintConv => 'sprintf("%.2g",$val)',
2388        PrintConvInv => '$val',
2389    },
2390    27 => { #PH
2391        Name => 'MinAperture',
2392        RawConv => '$val > 0 ? $val : undef',
2393        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val)*log(2)/2)',
2394        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))',
2395        PrintConv => 'sprintf("%.2g",$val)',
2396        PrintConvInv => '$val',
2397    },
2398    28 => {
2399        Name => 'FlashActivity',
2400        RawConv => '$val==-1 ? undef : $val',
2401    },
2402    29 => {
2403        Name => 'FlashBits',
2404        PrintConvColumns => 2,
2405        PrintConv => {
2406            0 => '(none)',
2407            BITMASK => {
2408                0 => 'Manual', #PH
2409                1 => 'TTL', #PH
2410                2 => 'A-TTL', #PH
2411                3 => 'E-TTL', #PH
2412                4 => 'FP sync enabled',
2413                7 => '2nd-curtain sync used',
2414                11 => 'FP sync used',
2415                13 => 'Built-in',
2416                14 => 'External', #(may not be set in manual mode - ref 37)
2417            },
2418        },
2419    },
2420    32 => {
2421        Name => 'FocusContinuous',
2422        RawConv => '$val==-1 ? undef : $val',
2423        PrintConv => {
2424            0 => 'Single',
2425            1 => 'Continuous',
2426            8 => 'Manual', #22
2427        },
2428    },
2429    33 => { #PH
2430        Name => 'AESetting',
2431        RawConv => '$val==-1 ? undef : $val',
2432        PrintConv => {
2433            0 => 'Normal AE',
2434            1 => 'Exposure Compensation',
2435            2 => 'AE Lock',
2436            3 => 'AE Lock + Exposure Comp.',
2437            4 => 'No AE',
2438        },
2439    },
2440    34 => { #PH
2441        Name => 'ImageStabilization',
2442        RawConv => '$val==-1 ? undef : $val',
2443        PrintConv => {
2444            0 => 'Off',
2445            1 => 'On',
2446            2 => 'Shoot Only', #15
2447            3 => 'Panning', # (A570IS)
2448            4 => 'Dynamic', # (SX30IS) (was 'On, Video')
2449            # (don't know what bit 0x100 indicates)
2450            256 => 'Off (2)',
2451            257 => 'On (2)',
2452            258 => 'Shoot Only (2)',
2453            259 => 'Panning (2)',
2454            260 => 'Dynamic (2)',
2455        },
2456    },
2457    35 => { #PH
2458        Name => 'DisplayAperture',
2459        RawConv => '$val ? $val : undef',
2460        ValueConv => '$val / 10',
2461        ValueConvInv => '$val * 10',
2462    },
2463    36 => 'ZoomSourceWidth', #PH
2464    37 => 'ZoomTargetWidth', #PH
2465    39 => { #22
2466        Name => 'SpotMeteringMode',
2467        RawConv => '$val==-1 ? undef : $val',
2468        PrintConv => {
2469            0 => 'Center',
2470            1 => 'AF Point',
2471        },
2472    },
2473    40 => { #PH
2474        Name => 'PhotoEffect',
2475        RawConv => '$val==-1 ? undef : $val',
2476        PrintConvColumns => 2,
2477        PrintConv => {
2478            0 => 'Off',
2479            1 => 'Vivid',
2480            2 => 'Neutral',
2481            3 => 'Smooth',
2482            4 => 'Sepia',
2483            5 => 'B&W',
2484            6 => 'Custom',
2485            100 => 'My Color Data',
2486        },
2487    },
2488    41 => { #PH (A570IS)
2489        Name => 'ManualFlashOutput',
2490        PrintHex => 1,
2491        PrintConv => {
2492            0 => 'n/a',
2493            0x500 => 'Full',
2494            0x502 => 'Medium',
2495            0x504 => 'Low',
2496            0x7fff => 'n/a', # (EOS models)
2497        },
2498    },
2499    # 41 => non-zero for manual flash intensity - PH (A570IS)
2500    42 => {
2501        Name => 'ColorTone',
2502        RawConv => '$val == 0x7fff ? undef : $val',
2503        %Image::ExifTool::Exif::printParameter,
2504    },
2505    46 => { #PH
2506        Name => 'SRAWQuality',
2507        RawConv => '$val==-1 ? undef : $val',
2508        PrintConv => {
2509            0 => 'n/a',
2510            1 => 'sRAW1 (mRAW)',
2511            2 => 'sRAW2 (sRAW)',
2512        },
2513    },
2514    # 47 - related to aspect ratio: 100=4:3,70=1:1/16:9,90=3:2,60=4:5 (PH G12)
2515    #      (roughly image area in percent - 4:3=100%,1:1/16:9=75%,3:2=89%,4:5=60%)
2516);
2517
2518# focal length information (MakerNotes tag 0x02)
2519%Image::ExifTool::Canon::FocalLength = (
2520    %binaryDataAttrs,
2521    FORMAT => 'int16u',
2522    FIRST_ENTRY => 0,
2523    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2524    0 => { #9
2525        Name => 'FocalType',
2526        RawConv => '$val ? $val : undef', # don't use if value is zero
2527        PrintConv => {
2528            1 => 'Fixed',
2529            2 => 'Zoom',
2530        },
2531    },
2532    1 => {
2533        Name => 'FocalLength',
2534        # the EXIF FocalLength is more reliable, so set this priority to zero
2535        Priority => 0,
2536        RawConv => '$val ? $val : undef', # don't use if value is zero
2537        RawConvInv => q{
2538            my $focalUnits = $$self{FocalUnits};
2539            unless ($focalUnits) {
2540                $focalUnits = 1;
2541                # (this happens when writing FocalLength to CRW images)
2542                $self->Warn("FocalUnits not available for FocalLength conversion (1 assumed)");
2543            }
2544            return $val * $focalUnits;
2545        },
2546        ValueConv => '$val / ($$self{FocalUnits} || 1)',
2547        ValueConvInv => '$val',
2548        PrintConv => '"$val mm"',
2549        PrintConvInv => '$val=~s/\s*mm//;$val',
2550    },
2551    2 => [ #4
2552        {
2553            Name => 'FocalPlaneXSize',
2554            Notes => q{
2555                these focal plane sizes are only valid for some models, and are affected by
2556                digital zoom if applied
2557            },
2558            # this conversion is valid only for PowerShot models and these EOS models:
2559            # D30, D60, 1D, 1DS, 5D, 10D, 20D, 30D, 300D, 350D, and 400D
2560            Condition => q{
2561                $$self{Model} !~ /EOS/ or
2562                $$self{Model} =~ /\b(1DS?|5D|D30|D60|10D|20D|30D|K236)$/ or
2563                $$self{Model} =~ /\b((300D|350D|400D) DIGITAL|REBEL( XTi?)?|Kiss Digital( [NX])?)$/
2564            },
2565            # focal plane image dimensions in 1/1000 inch -- convert to mm
2566            RawConv => '$val < 40 ? undef : $val',  # must be reasonable
2567            ValueConv => '$val * 25.4 / 1000',
2568            ValueConvInv => 'int($val * 1000 / 25.4 + 0.5)',
2569            PrintConv => 'sprintf("%.2f mm",$val)',
2570            PrintConvInv => '$val=~s/\s*mm$//;$val',
2571        },{
2572            Name => 'FocalPlaneXUnknown',
2573            Unknown => 1,
2574        },
2575    ],
2576    3 => [ #4
2577        {
2578            Name => 'FocalPlaneYSize',
2579            Condition => q{
2580                $$self{Model} !~ /EOS/ or
2581                $$self{Model} =~ /\b(1DS?|5D|D30|D60|10D|20D|30D|K236)$/ or
2582                $$self{Model} =~ /\b((300D|350D|400D) DIGITAL|REBEL( XTi?)?|Kiss Digital( [NX])?)$/
2583            },
2584            RawConv => '$val < 40 ? undef : $val',  # must be reasonable
2585            ValueConv => '$val * 25.4 / 1000',
2586            ValueConvInv => 'int($val * 1000 / 25.4 + 0.5)',
2587            PrintConv => 'sprintf("%.2f mm",$val)',
2588            PrintConvInv => '$val=~s/\s*mm$//;$val',
2589        },{
2590            Name => 'FocalPlaneYUnknown',
2591            Unknown => 1,
2592        },
2593    ],
2594);
2595
2596# Canon shot information (MakerNotes tag 0x04)
2597# BinaryData (keys are indices into the int16s array)
2598%Image::ExifTool::Canon::ShotInfo = (
2599    %binaryDataAttrs,
2600    FORMAT => 'int16s',
2601    FIRST_ENTRY => 1,
2602    DATAMEMBER => [ 19 ],
2603    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2604    1 => { #PH
2605        Name => 'AutoISO',
2606        Notes => 'actual ISO used = BaseISO * AutoISO / 100',
2607        ValueConv => 'exp($val/32*log(2))*100',
2608        ValueConvInv => '32*log($val/100)/log(2)',
2609        PrintConv => 'sprintf("%.0f",$val)',
2610        PrintConvInv => '$val',
2611    },
2612    2 => {
2613        Name => 'BaseISO',
2614        Priority => 0,
2615        RawConv => '$val ? $val : undef',
2616        ValueConv => 'exp($val/32*log(2))*100/32',
2617        ValueConvInv => '32*log($val*32/100)/log(2)',
2618        PrintConv => 'sprintf("%.0f",$val)',
2619        PrintConvInv => '$val',
2620    },
2621    3 => { #9/PH
2622        Name => 'MeasuredEV',
2623        Notes => q{
2624            this is the Canon name for what could better be called MeasuredLV, and
2625            should be close to the calculated LightValue for a proper exposure with most
2626            models
2627        },
2628        # empirical offset of +5 seems to be good for EOS models, but maybe
2629        # the offset should be less by up to 1 EV for some PowerShot models
2630        ValueConv => '$val / 32 + 5',
2631        ValueConvInv => '($val - 5) * 32',
2632        PrintConv => 'sprintf("%.2f",$val)',
2633        PrintConvInv => '$val',
2634    },
2635    4 => { #2, 9
2636        Name => 'TargetAperture',
2637        RawConv => '$val > 0 ? $val : undef',
2638        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val)*log(2)/2)',
2639        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))',
2640        PrintConv => 'sprintf("%.2g",$val)',
2641        PrintConvInv => '$val',
2642    },
2643    5 => { #2
2644        Name => 'TargetExposureTime',
2645        # ignore obviously bad values (also, -32768 may be used for n/a)
2646        # (note that a few models always write 0: DC211, and video models)
2647        RawConv => '($val > -1000 and ($val or $$self{Model}=~/(EOS|PowerShot|IXUS|IXY)/))? $val : undef',
2648        ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))',
2649        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val)/log(2))',
2650        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2651        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
2652    },
2653    6 => {
2654        Name => 'ExposureCompensation',
2655        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
2656        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
2657        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
2658        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
2659    },
2660    7 => {
2661        Name => 'WhiteBalance',
2662        PrintConv => \%canonWhiteBalance,
2663        SeparateTable => 1,
2664    },
2665    8 => { #PH
2666        Name => 'SlowShutter',
2667        PrintConv => {
2668            -1 => 'n/a',
2669            0 => 'Off',
2670            1 => 'Night Scene',
2671            2 => 'On',
2672            3 => 'None',
2673        },
2674    },
2675    9 => {
2676        Name => 'SequenceNumber',
2677        Description => 'Shot Number In Continuous Burst',
2678        Notes => 'valid only for some models', #PH (eg. not the 5DmkIII)
2679    },
2680    10 => { #PH/17
2681        Name => 'OpticalZoomCode',
2682        Groups => { 2 => 'Camera' },
2683        Notes => 'for many PowerShot models, a this is 0-6 for wide-tele zoom',
2684        # (for many models, 0-6 represent 0-100% zoom, but it is always 8 for
2685        #  EOS models, and I have seen values of 16,20,28,32 and 39 too...)
2686        # - set to 8 for "n/a" by Canon software (ref 22)
2687        PrintConv => '$val == 8 ? "n/a" : $val',
2688        PrintConvInv => '$val =~ /[a-z]/i ? 8 : $val',
2689    },
2690    # 11 - (8 for all EOS samples, [0,8] for other models - PH)
2691    12 => { #37
2692        Name => 'CameraTemperature',
2693        Condition => '$$self{Model} =~ /EOS/ and $$self{Model} !~ /EOS-1DS?$/',
2694        Groups => { 2 => 'Camera' },
2695        Notes => 'newer EOS models only',
2696        # usually zero if not valid for an EOS model (exceptions: 1D, 1DS)
2697        RawConv => '$val ? $val : undef',
2698        ValueConv => '$val - 128',
2699        ValueConvInv => '$val + 128',
2700        PrintConv => '"$val C"',
2701        PrintConvInv => '$val=~s/ ?C//; $val',
2702    },
2703    13 => { #PH
2704        Name => 'FlashGuideNumber',
2705        RawConv => '$val==-1 ? undef : $val',
2706        ValueConv => '$val / 32',
2707        ValueConvInv => '$val * 32',
2708    },
2709    # AF points for Ixus and IxusV cameras - 02/17/04 M. Rommel (also D30/D60 - PH)
2710    14 => { #2
2711        Name => 'AFPointsInFocus',
2712        Notes => 'used by D30, D60 and some PowerShot/Ixus models',
2713        Groups => { 2 => 'Camera' },
2714        Flags => 'PrintHex',
2715        RawConv => '$val==0 ? undef : $val',
2716        PrintConvColumns => 2,
2717        PrintConv => {
2718            0x3000 => 'None (MF)',
2719            0x3001 => 'Right',
2720            0x3002 => 'Center',
2721            0x3003 => 'Center+Right',
2722            0x3004 => 'Left',
2723            0x3005 => 'Left+Right',
2724            0x3006 => 'Left+Center',
2725            0x3007 => 'All',
2726        },
2727    },
2728    15 => {
2729        Name => 'FlashExposureComp',
2730        Description => 'Flash Exposure Compensation',
2731        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
2732        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
2733        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
2734        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
2735    },
2736    16 => {
2737        Name => 'AutoExposureBracketing',
2738        PrintConv => {
2739            -1 => 'On',
2740            0 => 'Off',
2741            1 => 'On (shot 1)',
2742            2 => 'On (shot 2)',
2743            3 => 'On (shot 3)',
2744        },
2745    },
2746    17 => {
2747        Name => 'AEBBracketValue',
2748        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
2749        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
2750        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
2751        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
2752    },
2753    18 => { #22
2754        Name => 'ControlMode',
2755        PrintConv => {
2756            0 => 'n/a',
2757            1 => 'Camera Local Control',
2758            # 2 - have seen this for EOS M studio picture
2759            3 => 'Computer Remote Control',
2760        },
2761    },
2762    19 => {
2763        Name => 'FocusDistanceUpper',
2764        DataMember => 'FocusDistanceUpper',
2765        Format => 'int16u',
2766        Notes => 'FocusDistance tags are only extracted if FocusDistanceUpper is non-zero',
2767        RawConv => '($$self{FocusDistanceUpper} = $val) || undef',
2768        ValueConv => '$val / 100',
2769        ValueConvInv => '$val * 100',
2770        PrintConv => '$val > 655.345 ? "inf" : "$val m"',
2771        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
2772    },
2773    20 => {
2774        Name => 'FocusDistanceLower', # (seems to be the upper distance for the 400D)
2775        Condition => '$$self{FocusDistanceUpper}',
2776        Format => 'int16u',
2777        ValueConv => '$val / 100',
2778        ValueConvInv => '$val * 100',
2779        PrintConv => '$val > 655.345 ? "inf" : "$val m"',
2780        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
2781    },
2782    21 => {
2783        Name => 'FNumber',
2784        Priority => 0,
2785        RawConv => '$val ? $val : undef',
2786        # approximate big translation table by simple calculation - PH
2787        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val)*log(2)/2)',
2788        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))',
2789        PrintConv => 'sprintf("%.2g",$val)',
2790        PrintConvInv => '$val',
2791    },
2792    22 => [
2793        {
2794            Name => 'ExposureTime',
2795            # encoding is different for 20D and 350D (darn!)
2796            # (but note that encoding is the same for TargetExposureTime - PH)
2797            Condition => '$$self{Model} =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
2798            Priority => 0,
2799            # many models write 0 here in JPEG images (even though 0 is the
2800            # value for an exposure time of 1 sec), but apparently a value of 0
2801            # is valid in a CRW image (=1s, D60 sample)
2802            RawConv => '($val or $$self{FILE_TYPE} eq "CRW") ? $val : undef',
2803            # approximate big translation table by simple calculation - PH
2804            ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))*1000/32',
2805            ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*32/1000)/log(2))',
2806            PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2807            PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
2808        },
2809        {
2810            Name => 'ExposureTime',
2811            Priority => 0,
2812            # many models write 0 here in JPEG images (even though 0 is the
2813            # value for an exposure time of 1 sec), but apparently a value of 0
2814            # is valid in a CRW image (=1s, D60 sample)
2815            RawConv => '($val or $$self{FILE_TYPE} eq "CRW") ? $val : undef',
2816            # approximate big translation table by simple calculation - PH
2817            ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))',
2818            ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val)/log(2))',
2819            PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2820            PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
2821        },
2822    ],
2823    23 => { #37
2824        Name => 'MeasuredEV2',
2825        Description => 'Measured EV 2',
2826        RawConv => '$val ? $val : undef',
2827        ValueConv => '$val / 8 - 6',
2828        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
2829    },
2830    24 => {
2831        Name => 'BulbDuration',
2832        ValueConv => '$val / 10',
2833        ValueConvInv => '$val * 10',
2834    },
2835    # 25 - (usually 0, but 1 for 2s timer?, 19 for small AVI, 14 for large
2836    #       AVI, and -6 and -10 for shots 1 and 2 with stitch assist - PH)
2837    26 => { #15
2838        Name => 'CameraType',
2839        Groups => { 2 => 'Camera' },
2840        PrintConv => {
2841            0 => 'n/a',
2842            248 => 'EOS High-end',
2843            250 => 'Compact',
2844            252 => 'EOS Mid-range',
2845            255 => 'DV Camera', #PH
2846        },
2847    },
2848    27 => {
2849        Name => 'AutoRotate',
2850        RawConv => '$val >= 0 ? $val : undef',
2851        PrintConv => {
2852           -1 => 'n/a', # (set to -1 when rotated by Canon software)
2853            0 => 'None',
2854            1 => 'Rotate 90 CW',
2855            2 => 'Rotate 180',
2856            3 => 'Rotate 270 CW',
2857        },
2858    },
2859    28 => { #15
2860        Name => 'NDFilter',
2861        PrintConv => { -1 => 'n/a', 0 => 'Off', 1 => 'On' },
2862    },
2863    29 => {
2864        Name => 'SelfTimer2',
2865        RawConv => '$val >= 0 ? $val : undef',
2866        ValueConv => '$val / 10',
2867        ValueConvInv => '$val * 10',
2868    },
2869    33 => { #PH (A570IS)
2870        Name => 'FlashOutput',
2871        RawConv => '($$self{Model}=~/(PowerShot|IXUS|IXY)/ or $val) ? $val : undef',
2872        Notes => q{
2873            used only for PowerShot models, this has a maximum value of 500 for models
2874            like the A570IS
2875        },
2876    },
2877);
2878
2879# Canon panorama information (MakerNotes tag 0x05)
2880%Image::ExifTool::Canon::Panorama = (
2881    %binaryDataAttrs,
2882    FORMAT => 'int16s',
2883    FIRST_ENTRY => 0,
2884    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2885    # 0 - values: always 1
2886    # 1 - values: 0,256,512(3 sequential L->R images); 0,-256(2 R->L images)
2887    2 => 'PanoramaFrameNumber', #(some models this is always 0)
2888    # 3 - values: 160(SX10IS,A570IS); 871(S30)
2889    # 4 - values: always 0
2890    5 => {
2891        Name => 'PanoramaDirection',
2892        PrintConv => {
2893            0 => 'Left to Right',
2894            1 => 'Right to Left',
2895            2 => 'Bottom to Top',
2896            3 => 'Top to Bottom',
2897            4 => '2x2 Matrix (Clockwise)',
2898        },
2899     },
2900);
2901
2902# D30 color information (MakerNotes tag 0x0a)
2903%Image::ExifTool::Canon::UnknownD30 = (
2904    %binaryDataAttrs,
2905    FORMAT => 'int16s',
2906    FIRST_ENTRY => 1,
2907    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
2908);
2909
2910#..............................................................................
2911# common CameraInfo tag definitions
2912my %ciFNumber = (
2913    Name => 'FNumber',
2914    Format => 'int8u',
2915    Groups => { 2 => 'Image' },
2916    RawConv => '$val ? $val : undef',
2917    ValueConv => 'exp(($val-8)/16*log(2))',
2918    ValueConvInv => 'log($val)*16/log(2)+8',
2919    PrintConv => 'sprintf("%.2g",$val)',
2920    PrintConvInv => '$val',
2921);
2922my %ciExposureTime = (
2923    Name => 'ExposureTime',
2924    Format => 'int8u',
2925    Groups => { 2 => 'Image' },
2926    RawConv => '$val ? $val : undef',
2927    ValueConv => 'exp(4*log(2)*(1-Image::ExifTool::Canon::CanonEv($val-24)))',
2928    ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(1-log($val)/(4*log(2)))+24',
2929    PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2930    PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
2931);
2932my %ciISO = (
2933    Name => 'ISO',
2934    Format => 'int8u',
2935    Groups => { 2 => 'Image' },
2936    ValueConv => '100*exp(($val/8-9)*log(2))',
2937    ValueConvInv => '(log($val/100)/log(2)+9)*8',
2938    PrintConv => 'sprintf("%.0f",$val)',
2939    PrintConvInv => '$val',
2940);
2941my %ciCameraTemperature = (
2942    Name => 'CameraTemperature',
2943    Format => 'int8u',
2944    ValueConv => '$val - 128',
2945    ValueConvInv => '$val + 128',
2946    PrintConv => '"$val C"',
2947    PrintConvInv => '$val=~s/ ?C//; $val',
2948);
2949my %ciMacroMagnification = (
2950    Name => 'MacroMagnification',
2951    Notes => 'currently decoded only for the MP-E 65mm f/2.8 1-5x Macro Photo',
2952    Condition => '$$self{LensType} and $$self{LensType} == 124',
2953    # 75=1x, 44=5x, log relationship
2954    ValueConv => 'exp((75-$val) * log(2) * 3 / 40)',
2955    ValueConvInv => '$val > 0 ? 75 - log($val) / log(2) * 40 / 3 : undef',
2956    PrintConv => 'sprintf("%.1fx",$val)',
2957    PrintConvInv => '$val=~s/\s*x//; $val',
2958);
2959my %ciFocalLength = (
2960    Name => 'FocalLength',
2961    Format => 'int16uRev', # (just to make things confusing, the focal lengths are big-endian)
2962    # ignore if zero
2963    RawConv => '$val ? $val : undef',
2964    PrintConv => '"$val mm"',
2965    PrintConvInv => '$val=~s/\s*mm//;$val',
2966);
2967my %ciMinFocal = (
2968    Name => 'MinFocalLength',
2969    Format => 'int16uRev', # byte order is big-endian
2970    PrintConv => '"$val mm"',
2971    PrintConvInv => '$val=~s/\s*mm//;$val',
2972);
2973my %ciMaxFocal = (
2974    Name => 'MaxFocalLength',
2975    Format => 'int16uRev', # byte order is big-endian
2976    PrintConv => '"$val mm"',
2977    PrintConvInv => '$val=~s/\s*mm//;$val',
2978);
2979
2980#..............................................................................
2981# Camera information for 1D and 1DS (MakerNotes tag 0x0d)
2982# (ref 15 unless otherwise noted)
2983%Image::ExifTool::Canon::CameraInfo1D = (
2984    %binaryDataAttrs,
2985    FORMAT => 'int8u',
2986    FIRST_ENTRY => 0,
2987    PRIORITY => 0,  # these tags are not reliable since they change with firmware version
2988    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
2989    NOTES => q{
2990        Information in the "CameraInfo" records is tricky to decode because the
2991        encodings are very different than in other Canon records (even sometimes
2992        switching endianness between values within a single camera), plus there is
2993        considerable variation in format from model to model. The first table below
2994        lists CameraInfo tags for the 1D and 1DS.
2995    },
2996    0x04 => { %ciExposureTime }, #9
2997    0x0a => {
2998        Name => 'FocalLength',
2999        Format => 'int16u',
3000        # ignore if zero
3001        RawConv => '$val ? $val : undef',
3002        PrintConv => '"$val mm"',
3003        PrintConvInv => '$val=~s/\s*mm//;$val',
3004    },
3005    0x0d => { #9
3006        Name => 'LensType',
3007        Format => 'int16uRev', # value is little-endian
3008        SeparateTable => 1,
3009        RawConv => '$val ? $val : undef', # don't use if value is zero
3010        ValueConvInv => 'int($val)', # (must truncate decimal part)
3011        PrintConv => \%canonLensTypes,
3012    },
3013    0x0e => {
3014        Name => 'MinFocalLength',
3015        Format => 'int16u',
3016        PrintConv => '"$val mm"',
3017        PrintConvInv => '$val=~s/\s*mm//;$val',
3018    },
3019    0x10 => {
3020        Name => 'MaxFocalLength',
3021        Format => 'int16u',
3022        PrintConv => '"$val mm"',
3023        PrintConvInv => '$val=~s/\s*mm//;$val',
3024    },
3025    0x41 => {
3026        Name => 'SharpnessFrequency', # PatternSharpness?
3027        Condition => '$$self{Model} =~ /\b1D$/',
3028        Notes => '1D only',
3029        PrintConvColumns => 2,
3030        PrintConv => {
3031            0 => 'n/a',
3032            1 => 'Lowest',
3033            2 => 'Low',
3034            3 => 'Standard',
3035            4 => 'High',
3036            5 => 'Highest',
3037        },
3038    },
3039    0x42 => {
3040        Name => 'Sharpness',
3041        Format => 'int8s',
3042        Condition => '$$self{Model} =~ /\b1D$/',
3043        Notes => '1D only',
3044    },
3045    0x44 => {
3046        Name => 'WhiteBalance',
3047        Condition => '$$self{Model} =~ /\b1D$/',
3048        Notes => '1D only',
3049        SeparateTable => 1,
3050        PrintConv => \%canonWhiteBalance,
3051    },
3052    0x47 => {
3053        Name => 'SharpnessFrequency', # PatternSharpness?
3054        Condition => '$$self{Model} =~ /\b1DS$/',
3055        Notes => '1DS only',
3056        PrintConvColumns => 2,
3057        PrintConv => {
3058            0 => 'n/a',
3059            1 => 'Lowest',
3060            2 => 'Low',
3061            3 => 'Standard',
3062            4 => 'High',
3063            5 => 'Highest',
3064        },
3065    },
3066    0x48 => [
3067        {
3068            Name => 'ColorTemperature',
3069            Format => 'int16u',
3070            Condition => '$$self{Model} =~ /\b1D$/',
3071            Notes => '1D only',
3072        },
3073        {
3074            Name => 'Sharpness',
3075            Format => 'int8s',
3076            Condition => '$$self{Model} =~ /\b1DS$/',
3077            Notes => '1DS only',
3078        },
3079    ],
3080    0x4a => {
3081        Name => 'WhiteBalance',
3082        Condition => '$$self{Model} =~ /\b1DS$/',
3083        Notes => '1DS only',
3084        SeparateTable => 1,
3085        PrintConv => \%canonWhiteBalance,
3086    },
3087    0x4b => {
3088        Name => 'PictureStyle',
3089        Condition => '$$self{Model} =~ /\b1D$/',
3090        Notes => "1D only, called 'Color Matrix' in owner's manual",
3091        Flags => ['PrintHex','SeparateTable'],
3092        PrintConv => \%pictureStyles,
3093    },
3094    0x4e => {
3095        Name => 'ColorTemperature',
3096        Format => 'int16u',
3097        Condition => '$$self{Model} =~ /\b1DS$/',
3098        Notes => '1DS only',
3099    },
3100    0x51 => {
3101        Name => 'PictureStyle',
3102        Condition => '$$self{Model} =~ /\b1DS$/',
3103        Notes => '1DS only',
3104        Flags => ['PrintHex','SeparateTable'],
3105        PrintConv => \%pictureStyles,
3106    },
3107);
3108
3109# Camera information for 1DmkII and 1DSmkII (MakerNotes tag 0x0d)
3110# (ref 15 unless otherwise noted)
3111%Image::ExifTool::Canon::CameraInfo1DmkII = (
3112    %binaryDataAttrs,
3113    FORMAT => 'int8u',
3114    FIRST_ENTRY => 0,
3115    PRIORITY => 0,
3116    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
3117    NOTES => 'CameraInfo tags for the 1DmkII and 1DSmkII.',
3118    0x04 => { %ciExposureTime }, #9
3119    0x09 => { %ciFocalLength }, #9
3120    0x0c => { #9
3121        Name => 'LensType',
3122        Format => 'int16uRev', # value is big-endian
3123        SeparateTable => 1,
3124        RawConv => '$val ? $val : undef', # don't use if value is zero
3125        ValueConvInv => 'int($val)', # (must truncate decimal part)
3126        PrintConv => \%canonLensTypes,
3127    },
3128    0x11 => { %ciMinFocal }, #9
3129    0x13 => { %ciMaxFocal }, #9
3130    0x2d => { #9
3131        Name => 'FocalType',
3132        PrintConv => {
3133           0 => 'Fixed',
3134           2 => 'Zoom',
3135        },
3136    },
3137    0x36 => {
3138        Name => 'WhiteBalance',
3139        SeparateTable => 1,
3140        PrintConv => \%canonWhiteBalance,
3141    },
3142    0x37 => {
3143        Name => 'ColorTemperature',
3144        Format => 'int16uRev',
3145    },
3146    0x39 => {
3147        Name => 'CanonImageSize',
3148        Format => 'int16u',
3149        PrintConvColumns => 2,
3150        PrintConv => \%canonImageSize,
3151    },
3152    0x66 => {
3153        Name => 'JPEGQuality',
3154        Notes => 'a number from 1 to 10',
3155    },
3156    0x6c => { #12
3157        Name => 'PictureStyle',
3158        Flags => ['PrintHex','SeparateTable'],
3159        PrintConv => \%pictureStyles,
3160    },
3161    0x6e => {
3162        Name => 'Saturation',
3163        Format => 'int8s',
3164        %Image::ExifTool::Exif::printParameter,
3165    },
3166    0x6f => {
3167        Name => 'ColorTone',
3168        Format => 'int8s',
3169        %Image::ExifTool::Exif::printParameter,
3170    },
3171    0x72 => {
3172        Name => 'Sharpness',
3173        Format => 'int8s',
3174    },
3175    0x73 => {
3176        Name => 'Contrast',
3177        Format => 'int8s',
3178        %Image::ExifTool::Exif::printParameter,
3179    },
3180    0x75 => {
3181        Name => 'ISO',
3182        Format => 'string[5]',
3183    },
3184);
3185
3186# Camera information for the 1DmkIIN (MakerNotes tag 0x0d)
3187# (ref 9 unless otherwise noted)
3188%Image::ExifTool::Canon::CameraInfo1DmkIIN = (
3189    %binaryDataAttrs,
3190    FORMAT => 'int8u',
3191    FIRST_ENTRY => 0,
3192    PRIORITY => 0,
3193    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
3194    NOTES => 'CameraInfo tags for the 1DmkIIN.',
3195    0x04 => { %ciExposureTime },
3196    0x09 => { %ciFocalLength },
3197    0x0c => {
3198        Name => 'LensType',
3199        Format => 'int16uRev', # value is big-endian
3200        SeparateTable => 1,
3201        RawConv => '$val ? $val : undef', # don't use if value is zero
3202        ValueConvInv => 'int($val)', # (must truncate decimal part)
3203        PrintConv => \%canonLensTypes,
3204    },
3205    0x11 => { %ciMinFocal },
3206    0x13 => { %ciMaxFocal },
3207    0x36 => { #15
3208        Name => 'WhiteBalance',
3209        SeparateTable => 1,
3210        PrintConv => \%canonWhiteBalance,
3211    },
3212    0x37 => { #15
3213        Name => 'ColorTemperature',
3214        Format => 'int16uRev',
3215    },
3216    0x73 => { #15
3217        Name => 'PictureStyle',
3218        Flags => ['PrintHex','SeparateTable'],
3219        PrintConv => \%pictureStyles,
3220    },
3221    0x74 => { #15
3222        Name => 'Sharpness',
3223        Format => 'int8s',
3224    },
3225    0x75 => { #15
3226        Name => 'Contrast',
3227        Format => 'int8s',
3228        %Image::ExifTool::Exif::printParameter,
3229    },
3230    0x76 => { #15
3231        Name => 'Saturation',
3232        Format => 'int8s',
3233        %Image::ExifTool::Exif::printParameter,
3234    },
3235    0x77 => { #15
3236        Name => 'ColorTone',
3237        Format => 'int8s',
3238        %Image::ExifTool::Exif::printParameter,
3239    },
3240    0x79 => { #15
3241        Name => 'ISO',
3242        Format => 'string[5]',
3243    },
3244);
3245
3246# Canon camera information for 1DmkIII and 1DSmkIII (MakerNotes tag 0x0d) (ref PH)
3247%Image::ExifTool::Canon::CameraInfo1DmkIII = (
3248    %binaryDataAttrs,
3249    FORMAT => 'int8u',
3250    FIRST_ENTRY => 0,
3251    PRIORITY => 0,
3252    IS_SUBDIR => [ 0x2aa ],
3253    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
3254    NOTES => 'CameraInfo tags for the 1DmkIII and 1DSmkIII.',
3255    0x03 => { %ciFNumber },
3256    0x04 => { %ciExposureTime }, #9
3257    0x06 => { %ciISO },
3258    0x18 => { %ciCameraTemperature }, #36
3259    0x1b => { %ciMacroMagnification }, #(NC)
3260    0x1d => { %ciFocalLength },
3261    0x30 => { # <-- (follows pattern /\xbb\xbb(.{64})?\x01\x01\0\0.{4}/s for all models - Dave Coffin)
3262        Name => 'CameraOrientation',
3263        PrintConv => {
3264            0 => 'Horizontal (normal)',
3265            1 => 'Rotate 90 CW',
3266            2 => 'Rotate 270 CW',
3267        },
3268    },
3269    0x43 => { #21/24
3270        Name => 'FocusDistanceUpper',
3271        # (it looks like the focus distances are also odd-byte big-endian)
3272        %focusDistanceByteSwap,
3273    },
3274    0x45 => { #21/24
3275        Name => 'FocusDistanceLower',
3276        %focusDistanceByteSwap,
3277    },
3278    0x5e => { #15
3279        Name => 'WhiteBalance',
3280        Format => 'int16u',
3281        PrintConv => \%canonWhiteBalance,
3282        SeparateTable => 1,
3283    },
3284    0x62 => { #15
3285        Name => 'ColorTemperature',
3286        Format => 'int16u',
3287    },
3288    0x86 => {
3289        Name => 'PictureStyle',
3290        Flags => ['PrintHex','SeparateTable'],
3291        PrintConv => \%pictureStyles,
3292    },
3293    0x111 => { #15
3294        Name => 'LensType',
3295        Format => 'int16uRev', # value is big-endian
3296        SeparateTable => 1,
3297        ValueConvInv => 'int($val)', # (must truncate decimal part)
3298        PrintConv => \%canonLensTypes,
3299    },
3300    0x113 => { %ciMinFocal },
3301    0x115 => { %ciMaxFocal },
3302    0x136 => { #15
3303        Name => 'FirmwareVersion',
3304        Format => 'string[6]',
3305    },
3306    0x172 => {
3307        Name => 'FileIndex',
3308        Groups => { 2 => 'Image' },
3309        Format => 'int32u',
3310        ValueConv => '$val + 1',
3311        ValueConvInv => '$val - 1',
3312    },
3313    0x176 => {
3314        Name => 'ShutterCount',
3315        Notes => 'may be valid only for some 1DmkIII copies, even running the same firmware',
3316        Format => 'int32u',
3317        ValueConv => '$val + 1',
3318        ValueConvInv => '$val - 1',
3319    },
3320    0x17e => { #(NC)
3321        Name => 'DirectoryIndex',
3322        Groups => { 2 => 'Image' },
3323        Format => 'int32u',
3324        ValueConv => '$val - 1',
3325        ValueConvInv => '$val + 1',
3326    },
3327    0x2aa => { #48
3328        Name => 'PictureStyleInfo',
3329        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
3330    },
3331    0x45a => { #29
3332        Name => 'TimeStamp1',
3333        Condition => '$$self{Model} =~ /\b1D Mark III$/',
3334        Format => 'int32u',
3335        Groups => { 2 => 'Time' },
3336        # observed in 1DmkIII firmware 5.3.1 (pre-production), 1.0.3, 1.0.8
3337        Notes => 'only valid for some versions of the 1DmkIII firmware',
3338        Shift => 'Time',
3339        RawConv => '$val ? $val : undef',
3340        ValueConv => 'ConvertUnixTime($val)',
3341        ValueConvInv => 'GetUnixTime($val)',
3342        PrintConv => '$self->ConvertDateTime($val)',
3343        PrintConvInv => '$self->InverseDateTime($val)',
3344    },
3345    0x45e => {
3346        Name => 'TimeStamp',
3347        Format => 'int32u',
3348        Groups => { 2 => 'Time' },
3349        # observed in 1DmkIII firmware 1.1.0, 1.1.3 and
3350        # 1DSmkIII firmware 1.0.0, 1.0.4, 2.1.2, 2.7.1
3351        Notes => 'valid for the 1DSmkIII and some versions of the 1DmkIII firmware',
3352        Shift => 'Time',
3353        RawConv => '$val ? $val : undef',
3354        ValueConv => 'ConvertUnixTime($val)',
3355        ValueConvInv => 'GetUnixTime($val)',
3356        PrintConv => '$self->ConvertDateTime($val)',
3357        PrintConvInv => '$self->InverseDateTime($val)',
3358    },
3359);
3360
3361# Canon camera information for 1DmkIV (MakerNotes tag 0x0d) (ref PH)
3362%Image::ExifTool::Canon::CameraInfo1DmkIV = (
3363    %binaryDataAttrs,
3364    FIRST_ENTRY => 0,
3365    PRIORITY => 0,
3366    DATAMEMBER => [ 0x00, 0x56, 0x153 ],
3367    IS_SUBDIR => [ 0x368 ],
3368    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
3369    NOTES => q{
3370        CameraInfo tags for the EOS 1D Mark IV.  Indices shown are for firmware
3371        versions 1.0.x, but they may be different for other firmware versions.
3372    },
3373    0x00 => {
3374        Name => 'FirmwareVersionLookAhead',
3375        Hidden => 1,
3376        # look ahead to check location of FirmwareVersion string
3377        Format => 'undef[0x1fd]',
3378        RawConv => q{
3379            my $t = substr($val, 0x1e8, 6); # 1 = firmware 4.2.1
3380            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
3381            $t = substr($val, 0x1ed, 6);    # 2 = firmware 1.0.4
3382            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
3383            $self->Warn('Unrecognized CameraInfo1DmkIV firmware version');
3384            $$self{CanonFirm} = 0;
3385            return undef;   # not a real tag
3386        },
3387    },
3388    0x03 => { %ciFNumber },
3389    0x04 => { %ciExposureTime },
3390    0x06 => { %ciISO },
3391    0x07 => {
3392        Name => 'HighlightTonePriority',
3393        PrintConv => \%offOn,
3394    },
3395    0x08 => {
3396        Name => 'MeasuredEV2',
3397        Description => 'Measured EV 2',
3398        RawConv => '$val ? $val : undef',
3399        ValueConv => '$val / 8 - 6',
3400        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
3401    },
3402    0x09 => {
3403        Name => 'MeasuredEV3',
3404        Description => 'Measured EV 3',
3405        RawConv => '$val ? $val : undef',
3406        ValueConv => '$val / 8 - 6',
3407        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
3408    },
3409    0x15 => {
3410        Name => 'FlashMeteringMode',
3411        PrintConv => {
3412            0 => 'E-TTL',
3413            3 => 'TTL',
3414            4 => 'External Auto',
3415            5 => 'External Manual',
3416            6 => 'Off',
3417        },
3418    },
3419    0x19 => { %ciCameraTemperature },
3420    0x1e => { %ciFocalLength },
3421    0x35 => {
3422        Name => 'CameraOrientation',
3423        PrintConv => {
3424            0 => 'Horizontal (normal)',
3425            1 => 'Rotate 90 CW',
3426            2 => 'Rotate 270 CW',
3427        },
3428    },
3429    0x54 => {
3430        Name => 'FocusDistanceUpper',
3431        %focusDistanceByteSwap,
3432    },
3433    0x56 => {
3434        Name => 'FocusDistanceLower',
3435        %focusDistanceByteSwap,
3436        Hook => '$varSize += ($$self{CanonFirm} ? -1 : 0x10000) if $$self{CanonFirm} < 2',
3437    },
3438    0x78 => {
3439        Name => 'WhiteBalance',
3440        Format => 'int16u',
3441        SeparateTable => 1,
3442        PrintConv => \%canonWhiteBalance,
3443    },
3444    0x7c => {
3445        Name => 'ColorTemperature',
3446        Format => 'int16u',
3447    },
3448    0x14f => {
3449        Name => 'LensType',
3450        Format => 'int16uRev', # value is big-endian
3451        SeparateTable => 1,
3452        ValueConvInv => 'int($val)', # (must truncate decimal part)
3453        PrintConv => \%canonLensTypes,
3454    },
3455    0x151 => { %ciMinFocal },
3456    0x153 => { %ciMaxFocal,
3457        Hook => '$varSize -= 4 if $$self{CanonFirm} < 2',
3458    },
3459    0x1ed => {
3460        Name => 'FirmwareVersion',
3461        Format => 'string[6]',
3462        Writable => 0,
3463    },
3464    0x22c => { #(NC)
3465        Name => 'FileIndex',
3466        Groups => { 2 => 'Image' },
3467        Format => 'int32u',
3468        ValueConv => '$val + 1',
3469        ValueConvInv => '$val - 1',
3470    },
3471    0x238 => { #(NC)
3472        Name => 'DirectoryIndex',
3473        Groups => { 2 => 'Image' },
3474        Format => 'int32u',
3475        ValueConv => '$val - 1',
3476        ValueConvInv => '$val + 1',
3477    },
3478    0x368 => {
3479        Name => 'PictureStyleInfo',
3480        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
3481    },
3482);
3483
3484# Camera information for 1D X (MakerNotes tag 0x0d) (ref PH)
3485%Image::ExifTool::Canon::CameraInfo1DX = (
3486    %binaryDataAttrs,
3487    FORMAT => 'int8u',
3488    FIRST_ENTRY => 0,
3489    PRIORITY => 0,
3490    DATAMEMBER => [ 0x00, 0x1b, 0x8e, 0x1ab ],
3491    IS_SUBDIR => [ 0x3f4 ],
3492    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
3493    NOTES => q{
3494        CameraInfo tags for the EOS 1D X.  Indices shown are for firmware version
3495        1.0.2, but they may be different for other firmware versions.
3496    },
3497    0x00 => {
3498        Name => 'FirmwareVersionLookAhead',
3499        Hidden => 1,
3500        # look ahead to check location of FirmwareVersion string
3501        Format => 'undef[0x28b]',
3502        RawConv => q{
3503            my $t = substr($val, 0x271, 6); # 1 = firmware 5.7.1
3504            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
3505            $t = substr($val, 0x279, 6);    # 2 = firmware 6.5.1
3506            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
3507            $t = substr($val, 0x280, 6);    # 3 = firmware 0.0.8/1.0.2/1.1.1
3508            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 3, return undef;
3509            $t = substr($val, 0x285, 6);    # 4 = firmware 2.1.0
3510            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 4, return undef;
3511            $self->Warn('Unrecognized CameraInfo1DX firmware version');
3512            $$self{CanonFirm} = 0;
3513            return undef;   # not a real tag
3514        },
3515    },
3516    0x03 => { %ciFNumber },
3517    0x04 => { %ciExposureTime },
3518    0x06 => { %ciISO },
3519    0x1b => { %ciCameraTemperature,
3520        Hook => '$varSize -= 3 if $$self{CanonFirm} < 3',
3521    },
3522    0x23 => { %ciFocalLength },
3523    0x7d => {
3524        Name => 'CameraOrientation',
3525        PrintConv => {
3526            0 => 'Horizontal (normal)',
3527            1 => 'Rotate 90 CW',
3528            2 => 'Rotate 270 CW',
3529        },
3530    },
3531    0x8c => {
3532        Name => 'FocusDistanceUpper',
3533        %focusDistanceByteSwap,
3534    },
3535    0x8e => {
3536        Name => 'FocusDistanceLower',
3537        %focusDistanceByteSwap,
3538        Hook => '$varSize -= 4 if $$self{CanonFirm} < 3; $varSize += 5 if $$self{CanonFirm} == 4',
3539    },
3540    0xbc => {
3541        Name => 'WhiteBalance',
3542        Format => 'int16u',
3543        SeparateTable => 1,
3544        PrintConv => \%canonWhiteBalance,
3545    },
3546    0xc0 => {
3547        Name => 'ColorTemperature',
3548        Format => 'int16u',
3549    },
3550    0xf4 => {
3551        Name => 'PictureStyle',
3552        Format => 'int8u',
3553        Flags => ['PrintHex','SeparateTable'],
3554        PrintConv => \%pictureStyles,
3555    },
3556    0x1a7 => {
3557        Name => 'LensType',
3558        Format => 'int16uRev', # value is big-endian
3559        SeparateTable => 1,
3560        ValueConvInv => 'int($val)', # (must truncate decimal part)
3561        PrintConv => \%canonLensTypes,
3562    },
3563    0x1a9 => { %ciMinFocal },
3564    0x1ab => { %ciMaxFocal,
3565        # add another offset of -8 for firmware 5.7.1, and a large offset
3566        # to effectively abort processing for unknown firmware
3567        Hook => '$varSize += ($$self{CanonFirm} ? -8 : 0x10000) if $$self{CanonFirm} < 2',
3568    },
3569    0x280 => {
3570        Name => 'FirmwareVersion',
3571        Format => 'string[6]',
3572        Writable => 0,
3573    },
3574    0x2d0 => { # (doesn't seem to work for firmware 2.0.3 - PH)
3575        Name => 'FileIndex',
3576        Groups => { 2 => 'Image' },
3577        Format => 'int32u',
3578        ValueConv => '$val + 1',
3579        ValueConvInv => '$val - 1',
3580    },
3581    0x2dc => { #(NC)
3582        Name => 'DirectoryIndex',
3583        Groups => { 2 => 'Image' },
3584        Format => 'int32u',
3585        ValueConv => '$val - 1',
3586        ValueConvInv => '$val + 1',
3587    },
3588    0x3f4 => {
3589        Name => 'PictureStyleInfo',
3590        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
3591    },
3592);
3593
3594# Camera information for 5D (MakerNotes tag 0x0d)
3595# (ref 12 unless otherwise noted)
3596%Image::ExifTool::Canon::CameraInfo5D = (
3597    %binaryDataAttrs,
3598    FORMAT => 'int8s',
3599    FIRST_ENTRY => 0,
3600    PRIORITY => 0,
3601    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
3602    NOTES => 'CameraInfo tags for the EOS 5D.',
3603    0x03 => { %ciFNumber }, #PH
3604    0x04 => { %ciExposureTime }, #9
3605    0x06 => { %ciISO }, #PH
3606    0x0c => { #9
3607        Name => 'LensType',
3608        Format => 'int16uRev', # value is big-endian
3609        SeparateTable => 1,
3610        RawConv => '$val ? $val : undef', # don't use if value is zero
3611        ValueConvInv => 'int($val)', # (must truncate decimal part)
3612        PrintConv => \%canonLensTypes,
3613    },
3614    0x17 => { %ciCameraTemperature }, #PH
3615    0x1b => { %ciMacroMagnification }, #PH
3616    0x27 => { #PH
3617        Name => 'CameraOrientation',
3618        PrintConv => {
3619            0 => 'Horizontal (normal)',
3620            1 => 'Rotate 90 CW',
3621            2 => 'Rotate 270 CW',
3622        },
3623    },
3624    0x28 => { %ciFocalLength }, #15
3625    0x38 => {
3626        Name => 'AFPointsInFocus5D',
3627        Format => 'int16uRev',
3628        PrintConvColumns => 2,
3629        PrintConv => { 0 => '(none)',
3630            BITMASK => {
3631                0 => 'Center',
3632                1 => 'Top',
3633                2 => 'Bottom',
3634                3 => 'Upper-left',
3635                4 => 'Upper-right',
3636                5 => 'Lower-left',
3637                6 => 'Lower-right',
3638                7 => 'Left',
3639                8 => 'Right',
3640                9 => 'AI Servo1',
3641               10 => 'AI Servo2',
3642               11 => 'AI Servo3',
3643               12 => 'AI Servo4',
3644               13 => 'AI Servo5',
3645               14 => 'AI Servo6',
3646           },
3647        },
3648    },
3649    0x54 => { #15
3650        Name => 'WhiteBalance',
3651        Format => 'int16u',
3652        SeparateTable => 1,
3653        PrintConv => \%canonWhiteBalance,
3654    },
3655    0x58 => { #15
3656        Name => 'ColorTemperature',
3657        Format => 'int16u',
3658    },
3659    0x6c => {
3660        Name => 'PictureStyle',
3661        Format => 'int8u',
3662        Flags => ['PrintHex','SeparateTable'],
3663        PrintConv => \%pictureStyles,
3664    },
3665    0x93 => { %ciMinFocal }, #15
3666    0x95 => { %ciMaxFocal }, #15
3667    0x97 => { #15
3668        Name => 'LensType',
3669        Format => 'int16uRev', # value is big-endian
3670        SeparateTable => 1,
3671        ValueConvInv => 'int($val)', # (must truncate decimal part)
3672        PrintConv => \%canonLensTypes,
3673    },
3674    0xa4 => { #PH
3675        Name => 'FirmwareRevision',
3676        Format => 'string[8]',
3677    },
3678    0xac => { #PH
3679        Name => 'ShortOwnerName',
3680        Format => 'string[16]',
3681    },
3682    0xcc => { #PH (NC)
3683        Name => 'DirectoryIndex',
3684        Groups => { 2 => 'Image' },
3685        Format => 'int32u',
3686    },
3687    0xd0 => {
3688        Name => 'FileIndex',
3689        Format => 'int16u',
3690        Groups => { 2 => 'Image' },
3691        ValueConv => '$val + 1',
3692        ValueConvInv => '$val - 1',
3693    },
3694    0xe8 => 'ContrastStandard',
3695    0xe9 => 'ContrastPortrait',
3696    0xea => 'ContrastLandscape',
3697    0xeb => 'ContrastNeutral',
3698    0xec => 'ContrastFaithful',
3699    0xed => 'ContrastMonochrome',
3700    0xee => 'ContrastUserDef1',
3701    0xef => 'ContrastUserDef2',
3702    0xf0 => 'ContrastUserDef3',
3703    # sharpness values are 0-7
3704    0xf1 => 'SharpnessStandard',
3705    0xf2 => 'SharpnessPortrait',
3706    0xf3 => 'SharpnessLandscape',
3707    0xf4 => 'SharpnessNeutral',
3708    0xf5 => 'SharpnessFaithful',
3709    0xf6 => 'SharpnessMonochrome',
3710    0xf7 => 'SharpnessUserDef1',
3711    0xf8 => 'SharpnessUserDef2',
3712    0xf9 => 'SharpnessUserDef3',
3713    0xfa => 'SaturationStandard',
3714    0xfb => 'SaturationPortrait',
3715    0xfc => 'SaturationLandscape',
3716    0xfd => 'SaturationNeutral',
3717    0xfe => 'SaturationFaithful',
3718    0xff => {
3719        Name => 'FilterEffectMonochrome',
3720        PrintConv => {
3721            0 => 'None',
3722            1 => 'Yellow',
3723            2 => 'Orange',
3724            3 => 'Red',
3725            4 => 'Green',
3726            -559038737 => 'n/a', # (0xdeadbeef)
3727        },
3728    },
3729    0x100 => 'SaturationUserDef1',
3730    0x101 => 'SaturationUserDef2',
3731    0x102 => 'SaturationUserDef3',
3732    0x103 => 'ColorToneStandard',
3733    0x104 => 'ColorTonePortrait',
3734    0x105 => 'ColorToneLandscape',
3735    0x106 => 'ColorToneNeutral',
3736    0x107 => 'ColorToneFaithful',
3737    0x108 => {
3738        Name => 'ToningEffectMonochrome',
3739        PrintConv => {
3740            0 => 'None',
3741            1 => 'Sepia',
3742            2 => 'Blue',
3743            3 => 'Purple',
3744            4 => 'Green',
3745            -559038737 => 'n/a', # (0xdeadbeef)
3746        },
3747    },
3748    0x109 => 'ColorToneUserDef1',
3749    0x10a => 'ColorToneUserDef2',
3750    0x10b => 'ColorToneUserDef3',
3751    0x10c => {
3752        Name => 'UserDef1PictureStyle',
3753        Format => 'int16u',
3754        PrintHex => 1, # (only needed for one tag)
3755        SeparateTable => 'UserDefStyle',
3756        PrintConv => \%userDefStyles,
3757    },
3758    0x10e => {
3759        Name => 'UserDef2PictureStyle',
3760        Format => 'int16u',
3761        SeparateTable => 'UserDefStyle',
3762        PrintConv => \%userDefStyles,
3763    },
3764    0x110 => {
3765        Name => 'UserDef3PictureStyle',
3766        Format => 'int16u',
3767        SeparateTable => 'UserDefStyle',
3768        PrintConv => \%userDefStyles,
3769    },
3770    0x11c => {
3771        Name => 'TimeStamp',
3772        Format => 'int32u',
3773        Groups => { 2 => 'Time' },
3774        Shift => 'Time',
3775        RawConv => '$val ? $val : undef',
3776        ValueConv => 'ConvertUnixTime($val)',
3777        ValueConvInv => 'GetUnixTime($val)',
3778        PrintConv => '$self->ConvertDateTime($val)',
3779        PrintConvInv => '$self->InverseDateTime($val)',
3780    },
3781);
3782
3783# Camera information for 5D Mark II (MakerNotes tag 0x0d) (ref PH)
3784%Image::ExifTool::Canon::CameraInfo5DmkII = (
3785    %binaryDataAttrs,
3786    FORMAT => 'int8u',
3787    FIRST_ENTRY => 0,
3788    PRIORITY => 0,
3789    DATAMEMBER => [ 0x00, 0xea ],
3790    IS_SUBDIR => [ 0x2f7 ],
3791    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
3792    NOTES => q{
3793        CameraInfo tags for the EOS 5D Mark II.  Indices shown are for firmware
3794        version 1.0.6, but they may be different for other firmware versions.
3795    },
3796    0x00 => {
3797        Name => 'FirmwareVersionLookAhead',
3798        Hidden => 1,
3799        # look ahead to check location of FirmwareVersion string
3800        Format => 'undef[0x184]',
3801        RawConv => q{
3802            my $t = substr($val, 0x15a, 6); # 1 = firmware 3.4.6/3.6.1
3803            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
3804            $t = substr($val, 0x17e, 6);    # 2 = firmware 4.1.1/1.0.6
3805            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
3806            $self->Warn('Unrecognized CameraInfo5DmkII firmware version');
3807            $$self{CanonFirm} = 0;
3808            return undef;   # not a real tag
3809        },
3810    },
3811    0x03 => { %ciFNumber },
3812    0x04 => { %ciExposureTime },
3813    0x06 => { %ciISO },
3814    0x07 => {
3815        Name => 'HighlightTonePriority',
3816        PrintConv => \%offOn,
3817    },
3818    0x1b => { %ciMacroMagnification }, #PH
3819    0x15 => { #PH (580 EX II)
3820        Name => 'FlashMeteringMode',
3821        PrintConv => {
3822            0 => 'E-TTL',
3823            3 => 'TTL',
3824            4 => 'External Auto',
3825            5 => 'External Manual',
3826            6 => 'Off',
3827        },
3828    },
3829    0x19 => { %ciCameraTemperature }, #36
3830    # 0x1b, 0x1c, 0x1d - same as FileInfo 0x10 - PH
3831    0x1e => { %ciFocalLength },
3832    0x31 => {
3833        Name => 'CameraOrientation',
3834        PrintConv => {
3835            0 => 'Horizontal (normal)',
3836            1 => 'Rotate 90 CW',
3837            2 => 'Rotate 270 CW',
3838        },
3839    },
3840    0x50 => {
3841        Name => 'FocusDistanceUpper',
3842        %focusDistanceByteSwap,
3843    },
3844    0x52 => {
3845        Name => 'FocusDistanceLower',
3846        %focusDistanceByteSwap,
3847    },
3848    0x6f => {
3849        Name => 'WhiteBalance',
3850        Format => 'int16u',
3851        SeparateTable => 1,
3852        PrintConv => \%canonWhiteBalance,
3853    },
3854    0x73 => {
3855        Name => 'ColorTemperature',
3856        Format => 'int16u',
3857    },
3858    0xa7 => {
3859        Name => 'PictureStyle',
3860        Format => 'int8u',
3861        Flags => ['PrintHex','SeparateTable'],
3862        PrintConv => \%pictureStyles,
3863    },
3864    0xbd => {
3865        Name => 'HighISONoiseReduction',
3866        PrintConv => {
3867            0 => 'Standard',
3868            1 => 'Low',
3869            2 => 'Strong',
3870            3 => 'Off',
3871        },
3872    },
3873    0xbf => {
3874        Name => 'AutoLightingOptimizer',
3875        PrintConv => {
3876            0 => 'Standard',
3877            1 => 'Low',
3878            2 => 'Strong',
3879            3 => 'Off',
3880        },
3881    },
3882    0xe6 => {
3883        Name => 'LensType',
3884        Format => 'int16uRev', # value is big-endian
3885        SeparateTable => 1,
3886        ValueConvInv => 'int($val)', # (must truncate decimal part)
3887        PrintConv => \%canonLensTypes,
3888    },
3889    0xe8 => { %ciMinFocal },
3890    0xea => { %ciMaxFocal,
3891        # offset changes after this for different firmware versions
3892        Hook => '$varSize += ($$self{CanonFirm} ? -36 : 0x10000) if $$self{CanonFirm} < 2',
3893    },
3894    0x17e => {
3895        Name => 'FirmwareVersion',
3896        Format => 'string[6]',
3897        Writable => 0, # not writable for logic reasons
3898        # some firmwares have a null instead of a space after the version number
3899        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
3900    },
3901    0x1bb => {
3902        Name => 'FileIndex',
3903        Groups => { 2 => 'Image' },
3904        Format => 'int32u',
3905        ValueConv => '$val + 1',
3906        ValueConvInv => '$val - 1',
3907    },
3908    0x1c7 => { #(NC)
3909        Name => 'DirectoryIndex',
3910        Groups => { 2 => 'Image' },
3911        Format => 'int32u',
3912        ValueConv => '$val - 1',
3913        ValueConvInv => '$val + 1',
3914    },
3915    0x2f7 => { #48
3916        Name => 'PictureStyleInfo',
3917        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
3918    },
3919);
3920
3921# Camera information for 5D Mark III (MakerNotes tag 0x0d) (ref PH)
3922%Image::ExifTool::Canon::CameraInfo5DmkIII = (
3923    %binaryDataAttrs,
3924    FORMAT => 'int8u',
3925    FIRST_ENTRY => 0,
3926    PRIORITY => 0,
3927    DATAMEMBER => [ 0x00, 0x1b, 0x23, 0x8e, 0x157 ],
3928    IS_SUBDIR => [ 0x3b0 ],
3929    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
3930    NOTES => q{
3931        CameraInfo tags for the EOS 5D Mark III.  Indices shown are for firmware
3932        versions 1.0.x, but they may be different for other firmware versions.
3933    },
3934    0x00 => {
3935        Name => 'FirmwareVersionLookAhead',
3936        Hidden => 1,
3937        # look ahead to check location of FirmwareVersion string
3938        Format => 'undef[0x24d]',
3939        RawConv => q{
3940            my $t = substr($val, 0x22c, 6); # 1 = firmware 4.5.4/4.5.6
3941            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
3942            $t = substr($val, 0x22d, 6);    # 2 = firmware 5.2.2/5.3.1/5.4.2
3943            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
3944            $t = substr($val, 0x23c, 6);    # 3 = firmware 1.0.3/1.0.7
3945            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 3, return undef;
3946            $t = substr($val, 0x242, 6);    # 4 = firmware 1.2.1
3947            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 4, return undef;
3948            $t = substr($val, 0x247, 6);    # 5 = firmware 1.3.5
3949            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 5, return undef;
3950            $self->Warn('Unrecognized CameraInfo5DmkIII firmware version');
3951            $$self{CanonFirm} = 0;
3952            return undef;   # not a real tag
3953        },
3954    },
3955    0x03 => { %ciFNumber },
3956    0x04 => { %ciExposureTime },
3957    0x06 => { %ciISO },
3958    0x1b => { %ciCameraTemperature,
3959        # decrement $varSize for missing byte after this tag with firmware 5.x and earlier
3960        # (and add large offset to effectively abort processing if unknown firmware)
3961        Hook => '$varSize += ($$self{CanonFirm} ? -1 : 0x10000) if $$self{CanonFirm} < 3',
3962    },
3963    0x23 => { %ciFocalLength,
3964        Hook => q{
3965            $varSize -= 3 if $$self{CanonFirm} == 1;
3966            $varSize -= 2 if $$self{CanonFirm} == 2;
3967            $varSize += 6 if $$self{CanonFirm} >= 4;
3968        },
3969    },
3970    0x7d => {
3971        Name => 'CameraOrientation',
3972        PrintConv => {
3973            0 => 'Horizontal (normal)',
3974            1 => 'Rotate 90 CW',
3975            2 => 'Rotate 270 CW',
3976        },
3977    },
3978    0x8c => {
3979        Name => 'FocusDistanceUpper',
3980        %focusDistanceByteSwap,
3981    },
3982    0x8e => {
3983        Name => 'FocusDistanceLower',
3984        %focusDistanceByteSwap,
3985        Hook => q{
3986            $varSize -= 4 if $$self{CanonFirm} < 3;
3987            $varSize += 5 if $$self{CanonFirm} > 4;
3988        },
3989    },
3990    0xbc => {
3991        Name => 'WhiteBalance',
3992        Format => 'int16u',
3993        SeparateTable => 1,
3994        PrintConv => \%canonWhiteBalance,
3995    },
3996    0xc0 => {
3997        Name => 'ColorTemperature',
3998        Format => 'int16u',
3999    },
4000    0xf4 => {
4001        Name => 'PictureStyle',
4002        Format => 'int8u',
4003        Flags => ['PrintHex','SeparateTable'],
4004        PrintConv => \%pictureStyles,
4005    },
4006    0x153 => {
4007        Name => 'LensType',
4008        Format => 'int16uRev', # value is big-endian
4009        SeparateTable => 1,
4010        ValueConvInv => 'int($val)', # (must truncate decimal part)
4011        PrintConv => \%canonLensTypes,
4012    },
4013    0x155 => { %ciMinFocal },
4014    0x157 => { %ciMaxFocal,
4015        Hook => '$varSize -= 8 if $$self{CanonFirm} < 3',
4016    },
4017    0x164 => {
4018        Name => 'LensSerialNumber',
4019        Format => 'undef[5]',
4020        Priority => 0,
4021        ValueConv => 'unpack("H*",$val)',
4022        ValueConvInv => 'length($val) < 10 and $val = 0 x (10-length($val)) . $val; pack("H*",$val)',
4023    },
4024    0x23c => {
4025        Name => 'FirmwareVersion',
4026        Format => 'string[6]',
4027        Writable => 0,
4028    },
4029    # the 5DmkIII has "User setting1" and "User setting2" file naming options:
4030    # - with "User setting1" 4 characters are selectable
4031    # - with "User setting2", 3 characters are selectable, and the 4th character
4032    # - in the file name corresponds to the image size:
4033    #   L=large, M=medium, S=small1, T=small2, U=small3, _=movie
4034    # - as shipped, the first 4 characters of the file name are unique to the camera
4035    0x28c => { # used for file names like IMG_xxxx.JPG
4036        Name => 'FileIndex',
4037        Groups => { 2 => 'Image' },
4038        Format => 'int32u',
4039        ValueConv => '$val + 1',
4040        ValueConvInv => '$val - 1',
4041    },
4042    0x290 => { # used for file names like 2F0Axxxx.JPG and 6T3Cxxxx.JPG
4043        Name => 'FileIndex2',
4044        Groups => { 2 => 'Image' },
4045        Format => 'int32u',
4046        ValueConv => '$val + 1',
4047        ValueConvInv => '$val - 1',
4048    },
4049    0x298 => { #(NC)
4050        Name => 'DirectoryIndex',
4051        Groups => { 2 => 'Image' },
4052        Format => 'int32u',
4053        ValueConv => '$val - 1',
4054        ValueConvInv => '$val + 1',
4055    },
4056    0x29c => { #(NC)
4057        Name => 'DirectoryIndex2',
4058        Groups => { 2 => 'Image' },
4059        Format => 'int32u',
4060        ValueConv => '$val - 1',
4061        ValueConvInv => '$val + 1',
4062    },
4063    0x3b0 => {
4064        Name => 'PictureStyleInfo',
4065        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
4066    },
4067);
4068
4069# Camera information for 6D (MakerNotes tag 0x0d) (ref PH)
4070%Image::ExifTool::Canon::CameraInfo6D = (
4071    %binaryDataAttrs,
4072    FORMAT => 'int8u',
4073    FIRST_ENTRY => 0,
4074    PRIORITY => 0,
4075    IS_SUBDIR => [ 0x3c6 ],
4076    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4077    NOTES => 'CameraInfo tags for the EOS 6D.',
4078    0x03 => { %ciFNumber },
4079    0x04 => { %ciExposureTime },
4080    0x06 => { %ciISO },
4081    0x1b => { %ciCameraTemperature },
4082    0x23 => { %ciFocalLength },
4083    0x83 => { # (5DmkIII + 6)
4084        Name => 'CameraOrientation',
4085        PrintConv => {
4086            0 => 'Horizontal (normal)',
4087            1 => 'Rotate 90 CW',
4088            2 => 'Rotate 270 CW',
4089        },
4090    },
4091    0x92 => { # (5DmkIII + 6)
4092        Name => 'FocusDistanceUpper',
4093        %focusDistanceByteSwap,
4094    },
4095    0x94 => { # (5DmkIII + 6)
4096        Name => 'FocusDistanceLower',
4097        %focusDistanceByteSwap,
4098    },
4099    0xc2 => { # (5DmkIII + 6)
4100        Name => 'WhiteBalance',
4101        Format => 'int16u',
4102        SeparateTable => 1,
4103        PrintConv => \%canonWhiteBalance,
4104    },
4105    0xc6 => { # (5DmkIII + 6)
4106        Name => 'ColorTemperature',
4107        Format => 'int16u',
4108    },
4109    0xfa => { # (5DmkIII + 6)
4110        Name => 'PictureStyle',
4111        Format => 'int8u',
4112        Flags => ['PrintHex','SeparateTable'],
4113        PrintConv => \%pictureStyles,
4114    },
4115    0x161 => { # (5DmkIII + 0x0e)
4116        Name => 'LensType',
4117        Format => 'int16uRev', # value is big-endian
4118        SeparateTable => 1,
4119        ValueConvInv => 'int($val)', # (must truncate decimal part)
4120        PrintConv => \%canonLensTypes,
4121    },
4122    0x163 => { %ciMinFocal }, # (5DmkIII + 0x0e)
4123    0x165 => { %ciMaxFocal }, # (5DmkIII + 0x0e)
4124    0x256 => { # (5DmkIII + 0x1a)
4125        Name => 'FirmwareVersion',
4126        Format => 'string[6]',
4127        Writable => 0,
4128    },
4129    0x2aa => { # (5DmkIII + 0x16 or 0x1e)
4130        Name => 'FileIndex',
4131        Groups => { 2 => 'Image' },
4132        Format => 'int32u',
4133        ValueConv => '$val + 1',
4134        ValueConvInv => '$val - 1',
4135    },
4136    0x2b6 => { #(NC) (5DmkIII + 0x16 or 0x1e)
4137        Name => 'DirectoryIndex',
4138        Groups => { 2 => 'Image' },
4139        Format => 'int32u',
4140        ValueConv => '$val - 1',
4141        ValueConvInv => '$val + 1',
4142    },
4143    0x3c6 => { # (5DmkIII + 0x16)
4144        Name => 'PictureStyleInfo',
4145        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
4146    },
4147);
4148
4149# Camera information for 7D (MakerNotes tag 0x0d) (ref PH)
4150%Image::ExifTool::Canon::CameraInfo7D = (
4151    %binaryDataAttrs,
4152    FORMAT => 'int8u',
4153    FIRST_ENTRY => 0,
4154    PRIORITY => 0,
4155    DATAMEMBER => [ 0x00, 0x1e ],
4156    IS_SUBDIR => [ 0x327 ],
4157    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4158    NOTES => q{
4159        CameraInfo tags for the EOS 7D.  Indices shown are for firmware versions
4160        1.0.x, but they may be different for other firmware versions.
4161    },
4162    0x00 => {
4163        Name => 'FirmwareVersionLookAhead',
4164        Hidden => 1,
4165        # look ahead to check location of FirmwareVersion string
4166        Format => 'undef[0x1b2]',
4167        RawConv => q{
4168            my $t = substr($val, 0x1a8, 6); # 1 = firmware 3.7.5
4169            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
4170            $t = substr($val, 0x1ac, 6);    # 2 = firmware 1.0.7/1.0.8/1.1.0/1.2.1/1.2.2
4171            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
4172            $self->Warn('Unrecognized CameraInfo7D firmware version');
4173            $$self{CanonFirm} = 0;
4174            return undef;   # not a real tag
4175        },
4176    },
4177    0x03 => { %ciFNumber },
4178    0x04 => { %ciExposureTime },
4179    0x06 => { %ciISO },
4180    0x07 => {
4181        Name => 'HighlightTonePriority',
4182        PrintConv => \%offOn,
4183    },
4184    0x08 => { #37
4185        Name => 'MeasuredEV2',
4186        Description => 'Measured EV 2',
4187        RawConv => '$val ? $val : undef',
4188        ValueConv => '$val / 8 - 6',
4189        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
4190    },
4191    0x09 => { #37
4192        Name => 'MeasuredEV',
4193        Description => 'Measured EV',
4194        RawConv => '$val ? $val : undef',
4195        ValueConv => '$val / 8 - 6',
4196        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
4197    },
4198    0x15 => { #PH (580 EX II)
4199        Name => 'FlashMeteringMode',
4200        PrintConv => {
4201            0 => 'E-TTL',
4202            3 => 'TTL',
4203            4 => 'External Auto',
4204            5 => 'External Manual',
4205            6 => 'Off',
4206        },
4207    },
4208    0x19 => { %ciCameraTemperature },
4209    0x1e => { %ciFocalLength,
4210        Hook => '$varSize += ($$self{CanonFirm} ? -4 : 0x10000) if $$self{CanonFirm} < 2',
4211    },
4212    0x35 => {
4213        Name => 'CameraOrientation',
4214        PrintConv => {
4215            0 => 'Horizontal (normal)',
4216            1 => 'Rotate 90 CW',
4217            2 => 'Rotate 270 CW',
4218        },
4219    },
4220    0x54 => {
4221        Name => 'FocusDistanceUpper',
4222        %focusDistanceByteSwap,
4223    },
4224    0x56 => {
4225        Name => 'FocusDistanceLower',
4226        %focusDistanceByteSwap,
4227    },
4228    0x77 => {
4229        Name => 'WhiteBalance',
4230        Format => 'int16u',
4231        SeparateTable => 1,
4232        PrintConv => \%canonWhiteBalance,
4233    },
4234    0x7b => {
4235        Name => 'ColorTemperature',
4236        Format => 'int16u',
4237    },
4238    0xaf => {
4239        Name => 'CameraPictureStyle',
4240        PrintHex => 1,
4241        PrintConv => {
4242            0x81 => 'Standard',
4243            0x82 => 'Portrait',
4244            0x83 => 'Landscape',
4245            0x84 => 'Neutral',
4246            0x85 => 'Faithful',
4247            0x86 => 'Monochrome',
4248            0x21 => 'User Defined 1',
4249            0x22 => 'User Defined 2',
4250            0x23 => 'User Defined 3',
4251        },
4252    },
4253    0xc9 => {
4254        Name => 'HighISONoiseReduction',
4255        PrintConv => {
4256            0 => 'Standard',
4257            1 => 'Low',
4258            2 => 'Strong',
4259            3 => 'Off',
4260        },
4261    },
4262    0x112 => {
4263        Name => 'LensType',
4264        Format => 'int16uRev', # value is big-endian
4265        SeparateTable => 1,
4266        ValueConvInv => 'int($val)', # (must truncate decimal part)
4267        PrintConv => \%canonLensTypes,
4268    },
4269    0x114 => { %ciMinFocal },
4270    0x116 => { %ciMaxFocal },
4271    0x1ac => {
4272        Name => 'FirmwareVersion',
4273        Format => 'string[6]',
4274        Writable => 0, # not writable for logic reasons
4275        # some firmwares have a null instead of a space after the version number
4276        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
4277    },
4278    0x1eb => {
4279        Name => 'FileIndex',
4280        Groups => { 2 => 'Image' },
4281        Format => 'int32u',
4282        ValueConv => '$val + 1',
4283        ValueConvInv => '$val - 1',
4284    },
4285    0x1f7 => { #(NC)
4286        Name => 'DirectoryIndex',
4287        Groups => { 2 => 'Image' },
4288        Format => 'int32u',
4289        ValueConv => '$val - 1',
4290        ValueConvInv => '$val + 1',
4291    },
4292    0x327 => { #48
4293        Name => 'PictureStyleInfo',
4294        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
4295    },
4296);
4297
4298# Canon camera information for 40D (MakerNotes tag 0x0d) (ref PH)
4299%Image::ExifTool::Canon::CameraInfo40D = (
4300    %binaryDataAttrs,
4301    FORMAT => 'int8u',
4302    FIRST_ENTRY => 0,
4303    PRIORITY => 0,
4304    IS_SUBDIR => [ 0x25b ],
4305    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4306    NOTES => 'CameraInfo tags for the EOS 40D.',
4307    0x03 => { %ciFNumber }, #PH
4308    0x04 => { %ciExposureTime }, #PH
4309    0x06 => { %ciISO }, #PH
4310    0x15 => { #PH (580 EX II)
4311        Name => 'FlashMeteringMode',
4312        PrintConv => {
4313            0 => 'E-TTL',
4314            3 => 'TTL',
4315            4 => 'External Auto',
4316            5 => 'External Manual',
4317            6 => 'Off',
4318        },
4319    },
4320    0x18 => { %ciCameraTemperature }, #36
4321    0x1b => { %ciMacroMagnification }, #PH
4322    0x1d => { %ciFocalLength }, #PH
4323    0x30 => { #20
4324        Name => 'CameraOrientation',
4325        PrintConv => {
4326            0 => 'Horizontal (normal)',
4327            1 => 'Rotate 90 CW',
4328            2 => 'Rotate 270 CW',
4329        },
4330    },
4331    0x43 => { #21/24
4332        Name => 'FocusDistanceUpper',
4333        # this is very odd (little-endian number on odd boundary),
4334        # but it does seem to work better with my sample images - PH
4335        %focusDistanceByteSwap,
4336    },
4337    0x45 => { #21/24
4338        Name => 'FocusDistanceLower',
4339        %focusDistanceByteSwap,
4340    },
4341    0x6f => { #15
4342        Name => 'WhiteBalance',
4343        Format => 'int16u',
4344        PrintConv => \%canonWhiteBalance,
4345        SeparateTable => 1,
4346    },
4347    0x73 => { #15
4348        Name => 'ColorTemperature',
4349        Format => 'int16u',
4350    },
4351    0xd6 => { #15
4352        Name => 'LensType',
4353        Format => 'int16uRev', # value is big-endian
4354        SeparateTable => 1,
4355        ValueConvInv => 'int($val)', # (must truncate decimal part)
4356        PrintConv => \%canonLensTypes,
4357    },
4358    0xd8 => { %ciMinFocal }, #15
4359    0xda => { %ciMaxFocal }, #15
4360    0xff => { #15
4361        Name => 'FirmwareVersion',
4362        Format => 'string[6]',
4363    },
4364    0x133 => { #27
4365        Name => 'FileIndex',
4366        Groups => { 2 => 'Image' },
4367        Format => 'int32u',
4368        Notes => 'combined with DirectoryIndex to give the Composite FileNumber tag',
4369        ValueConv => '$val + 1',
4370        ValueConvInv => '$val - 1',
4371    },
4372    0x13f => { #27
4373        Name => 'DirectoryIndex',
4374        Groups => { 2 => 'Image' },
4375        Format => 'int32u',
4376        ValueConv => '$val - 1', # yes, minus (opposite to FileIndex)
4377        ValueConvInv => '$val + 1',
4378    },
4379    0x25b => {
4380        Name => 'PictureStyleInfo',
4381        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
4382    },
4383    0x92b => { #33
4384        Name => 'LensModel',
4385        Format => 'string[64]',
4386    },
4387);
4388
4389# Canon camera information for 50D (MakerNotes tag 0x0d) (ref PH)
4390%Image::ExifTool::Canon::CameraInfo50D = (
4391    %binaryDataAttrs,
4392    FORMAT => 'int8u',
4393    FIRST_ENTRY => 0,
4394    PRIORITY => 0,
4395    DATAMEMBER => [ 0x00, 0xee ],
4396    IS_SUBDIR => [ 0x2d7 ],
4397    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4398    NOTES => q{
4399        CameraInfo tags for the EOS 50D.  Indices shown are for firmware versions
4400        1.0.x, but they may be different for other firmware versions.
4401    },
4402    0x00 => {
4403        Name => 'FirmwareVersionLookAhead',
4404        Hidden => 1,
4405        # look ahead to check location of FirmwareVersion string
4406        Format => 'undef[0x164]',
4407        RawConv => q{
4408            my $t = substr($val, 0x15a, 6); # 1 = firmware 2.6.1
4409            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
4410            $t = substr($val, 0x15e, 6);    # 2 = firmware 2.9.1/3.1.1/1.0.2/1.0.3
4411            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
4412            $self->Warn('Unrecognized CameraInfo50D firmware version');
4413            $$self{CanonFirm} = 0;
4414            return undef;   # not a real tag
4415        },
4416    },
4417    0x03 => { %ciFNumber },
4418    0x04 => { %ciExposureTime },
4419    0x06 => { %ciISO },
4420    0x07 => {
4421        Name => 'HighlightTonePriority',
4422        PrintConv => \%offOn,
4423    },
4424    0x15 => { #PH (580 EX II)
4425        Name => 'FlashMeteringMode',
4426        PrintConv => {
4427            0 => 'E-TTL',
4428            3 => 'TTL',
4429            4 => 'External Auto',
4430            5 => 'External Manual',
4431            6 => 'Off',
4432        },
4433    },
4434    0x19 => { %ciCameraTemperature }, #36
4435    0x1e => { %ciFocalLength },
4436    0x31 => {
4437        Name => 'CameraOrientation',
4438        PrintConv => {
4439            0 => 'Horizontal (normal)',
4440            1 => 'Rotate 90 CW',
4441            2 => 'Rotate 270 CW',
4442        },
4443    },
4444    0x50 => { #33
4445        Name => 'FocusDistanceUpper',
4446        %focusDistanceByteSwap,
4447    },
4448    0x52 => { #33
4449        Name => 'FocusDistanceLower',
4450        %focusDistanceByteSwap,
4451    },
4452    0x6f => {
4453        Name => 'WhiteBalance',
4454        Format => 'int16u',
4455        SeparateTable => 1,
4456        PrintConv => \%canonWhiteBalance,
4457    },
4458    0x73 => { #33
4459        Name => 'ColorTemperature',
4460        Format => 'int16u',
4461    },
4462    0xa7 => {
4463        Name => 'PictureStyle',
4464        Format => 'int8u',
4465        Flags => ['PrintHex','SeparateTable'],
4466        PrintConv => \%pictureStyles,
4467    },
4468    0xbd => {
4469        Name => 'HighISONoiseReduction',
4470        PrintConv => {
4471            0 => 'Standard',
4472            1 => 'Low',
4473            2 => 'Strong',
4474            3 => 'Off',
4475        },
4476    },
4477    0xbf => {
4478        Name => 'AutoLightingOptimizer',
4479        PrintConv => {
4480            0 => 'Standard',
4481            1 => 'Low',
4482            2 => 'Strong',
4483            3 => 'Off',
4484        },
4485    },
4486    0xea => { #33
4487        Name => 'LensType',
4488        Format => 'int16uRev', # value is big-endian
4489        SeparateTable => 1,
4490        ValueConvInv => 'int($val)', # (must truncate decimal part)
4491        PrintConv => \%canonLensTypes,
4492    },
4493    0xec => { %ciMinFocal },
4494    0xee => { %ciMaxFocal,
4495        Hook => '$varSize += ($$self{CanonFirm} ? -4 : 0x10000) if $$self{CanonFirm} < 2',
4496    },
4497    0x15e => { #33
4498        Name => 'FirmwareVersion',
4499        Format => 'string[6]',
4500        Writable => 0,
4501    },
4502    0x19b => {
4503        Name => 'FileIndex',
4504        Groups => { 2 => 'Image' },
4505        Format => 'int32u',
4506        ValueConv => '$val + 1',
4507        ValueConvInv => '$val - 1',
4508    },
4509    0x1a7 => { #(NC)
4510        Name => 'DirectoryIndex',
4511        Groups => { 2 => 'Image' },
4512        Format => 'int32u',
4513        ValueConv => '$val - 1',
4514        ValueConvInv => '$val + 1',
4515    },
4516    0x2d7 => {
4517        Name => 'PictureStyleInfo',
4518        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
4519    },
4520);
4521
4522# Canon camera information for 60D/1200D (MakerNotes tag 0x0d) (ref PH)
4523# NOTE: Can probably borrow more 50D tags here, possibly with an offset
4524%Image::ExifTool::Canon::CameraInfo60D = (
4525    %binaryDataAttrs,
4526    FORMAT => 'int8u',
4527    FIRST_ENTRY => 0,
4528    PRIORITY => 0,
4529    IS_SUBDIR => [ 0x2f9, 0x321 ],
4530    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4531    NOTES => 'CameraInfo tags for the EOS 60D and 1200D.',
4532    0x03 => { %ciFNumber },
4533    0x04 => { %ciExposureTime },
4534    0x06 => { %ciISO },
4535    0x19 => { %ciCameraTemperature },
4536    0x1e => { %ciFocalLength },
4537    0x36 => {
4538        Name => 'CameraOrientation',
4539        Condition => '$$self{Model} =~ /EOS 60D$/', #(NC)
4540        Notes => '60D only',
4541        PrintConv => {
4542            0 => 'Horizontal (normal)',
4543            1 => 'Rotate 90 CW',
4544            2 => 'Rotate 270 CW',
4545        },
4546    },
4547    0x3a => { #IB
4548        Name => 'CameraOrientation',
4549        Condition => '$$self{Model} =~ /\b(1200D|REBEL T5|Kiss X70)\b/',
4550        Notes => '1200D only',
4551        PrintConv => {
4552            0 => 'Horizontal (normal)',
4553            1 => 'Rotate 90 CW',
4554            2 => 'Rotate 270 CW',
4555        },
4556    },
4557    0x55 => {
4558        Name => 'FocusDistanceUpper',
4559        Condition => '$$self{Model} =~ /EOS 60D$/',
4560        Notes => '60D only',
4561        %focusDistanceByteSwap,
4562    },
4563    0x57 => {
4564        Name => 'FocusDistanceLower',
4565        Condition => '$$self{Model} =~ /EOS 60D$/',
4566        Notes => '60D only',
4567        %focusDistanceByteSwap,
4568    },
4569    0x7d => {
4570        Name => 'ColorTemperature',
4571        Condition => '$$self{Model} =~ /EOS 60D$/',
4572        Notes => '60D only',
4573        Format => 'int16u',
4574    },
4575    0xe8 => {
4576        Name => 'LensType',
4577        Format => 'int16uRev', # value is big-endian
4578        SeparateTable => 1,
4579        ValueConvInv => 'int($val)', # (must truncate decimal part)
4580        PrintConv => \%canonLensTypes,
4581    },
4582    0xea => { %ciMinFocal },
4583    0xec => { %ciMaxFocal },
4584    0x199 => {  # (at this location for 60D firmware 2.8.1/1.0.5, and 1200D 3.3.1/1.0.0)
4585        Name => 'FirmwareVersion',
4586        Format => 'string[6]',
4587        Writable => 0,
4588    },
4589    0x1d9 => {
4590        Name => 'FileIndex',
4591        Condition => '$$self{Model} =~ /EOS 60D$/',
4592        Notes => '60D only',
4593        Groups => { 2 => 'Image' },
4594        Format => 'int32u',
4595        ValueConv => '$val + 1',
4596        ValueConvInv => '$val - 1',
4597    },
4598    0x1e5 => { #(NC)
4599        Name => 'DirectoryIndex',
4600        Condition => '$$self{Model} =~ /EOS 60D$/',
4601        Notes => '60D only',
4602        Groups => { 2 => 'Image' },
4603        Format => 'int32u',
4604        ValueConv => '$val - 1',
4605        ValueConvInv => '$val + 1',
4606    },
4607    0x2f9 => {
4608        Name => 'PictureStyleInfo',
4609        Condition => '$$self{Model} =~ /\b(1200D|REBEL T5|Kiss X70)\b/',
4610        Notes => '1200D',
4611        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
4612    },
4613    0x321 => {
4614        Name => 'PictureStyleInfo',
4615        Condition => '$$self{Model} =~ /EOS 60D$/',
4616        Notes => '60D',
4617        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
4618    },
4619);
4620
4621# Canon camera information for 70D (MakerNotes tag 0x0d) (ref PH)
4622%Image::ExifTool::Canon::CameraInfo70D = (
4623    %binaryDataAttrs,
4624    FORMAT => 'int8u',
4625    FIRST_ENTRY => 0,
4626    PRIORITY => 0,
4627    IS_SUBDIR => [ 0x3cf ],
4628    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4629    NOTES => 'CameraInfo tags for the EOS 70D.',
4630    0x03 => { %ciFNumber },
4631    0x04 => { %ciExposureTime },
4632    0x06 => { %ciISO },
4633    0x1b => { %ciCameraTemperature },
4634    0x23 => { %ciFocalLength },
4635    # 0x36 - focal length again?
4636    0x84 => {
4637        Name => 'CameraOrientation',
4638        PrintConv => {
4639            0 => 'Horizontal (normal)',
4640            1 => 'Rotate 90 CW',
4641            2 => 'Rotate 270 CW',
4642        },
4643    },
4644    0x93 => {
4645        Name => 'FocusDistanceUpper',
4646        %focusDistanceByteSwap,
4647    },
4648    0x95 => {
4649        Name => 'FocusDistanceLower',
4650        %focusDistanceByteSwap,
4651    },
4652    0xc7 => {
4653        Name => 'ColorTemperature',
4654        Format => 'int16u',
4655    },
4656    0x166 => {
4657        Name => 'LensType',
4658        Format => 'int16uRev', # value is big-endian
4659        SeparateTable => 1,
4660        ValueConvInv => 'int($val)', # (must truncate decimal part)
4661        PrintConv => \%canonLensTypes,
4662    },
4663    0x168 => { %ciMinFocal },
4664    0x16a => { %ciMaxFocal },
4665    0x25e => {  # (at this location for firmware 6.1.2, 1.0.4 and 1.1.1)
4666        Name => 'FirmwareVersion',
4667        Format => 'string[6]',
4668        Writable => 0,
4669    },
4670    0x2b3 => {
4671        Name => 'FileIndex',
4672        Groups => { 2 => 'Image' },
4673        Format => 'int32u',
4674        ValueConv => '$val + 1',
4675        ValueConvInv => '$val - 1',
4676    },
4677    0x2bf => { #(NC)
4678        Name => 'DirectoryIndex',
4679        Groups => { 2 => 'Image' },
4680        Format => 'int32u',
4681        ValueConv => '$val - 1',
4682        ValueConvInv => '$val + 1',
4683    },
4684    0x3cf => { #48
4685        Name => 'PictureStyleInfo',
4686        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
4687    },
4688);
4689
4690# Canon camera information for 80D (MakerNotes tag 0x0d) (ref PH)
4691%Image::ExifTool::Canon::CameraInfo80D = (
4692    %binaryDataAttrs,
4693    FORMAT => 'int8u',
4694    FIRST_ENTRY => 0,
4695    PRIORITY => 0,
4696    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4697    NOTES => 'CameraInfo tags for the EOS 80D.',
4698    0x03 => { %ciFNumber },
4699    0x04 => { %ciExposureTime },
4700    0x06 => { %ciISO },
4701    0x1b => { %ciCameraTemperature },
4702    0x23 => { %ciFocalLength },
4703    0x96 => {
4704        Name => 'CameraOrientation',
4705        PrintConv => {
4706            0 => 'Horizontal (normal)',
4707            1 => 'Rotate 90 CW',
4708            2 => 'Rotate 270 CW',
4709        },
4710    },
4711    0xa5 => {
4712        Name => 'FocusDistanceUpper',
4713        %focusDistanceByteSwap,
4714    },
4715    0xa7 => {
4716        Name => 'FocusDistanceLower',
4717        %focusDistanceByteSwap,
4718    },
4719    0x13a => {
4720        Name => 'ColorTemperature',
4721        Format => 'int16u',
4722    },
4723    0x189 => {
4724        Name => 'LensType',
4725        Format => 'int16uRev', # value is big-endian
4726        SeparateTable => 1,
4727        ValueConvInv => 'int($val)', # (must truncate decimal part)
4728        PrintConv => \%canonLensTypes,
4729    },
4730    0x18b => { %ciMinFocal },
4731    0x18d => { %ciMaxFocal },
4732    0x45a => {  # (at this location for firmware 1.0.1)
4733        Name => 'FirmwareVersion',
4734        Format => 'string[6]',
4735        Writable => 0,
4736    },
4737    0x4ae => {
4738        Name => 'FileIndex',
4739        Groups => { 2 => 'Image' },
4740        Format => 'int32u',
4741        ValueConv => '$val + 1',
4742        ValueConvInv => '$val - 1',
4743    },
4744    0x4ba => { #(NC)
4745        Name => 'DirectoryIndex',
4746        Groups => { 2 => 'Image' },
4747        Format => 'int32u',
4748        ValueConv => '$val - 1',
4749        ValueConvInv => '$val + 1',
4750    },
4751);
4752
4753# Canon camera information for 450D (MakerNotes tag 0x0d) (ref PH)
4754%Image::ExifTool::Canon::CameraInfo450D = (
4755    %binaryDataAttrs,
4756    FORMAT => 'int8u',
4757    FIRST_ENTRY => 0,
4758    PRIORITY => 0,
4759    IS_SUBDIR => [ 0x263 ],
4760    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4761    NOTES => 'CameraInfo tags for the EOS 450D.',
4762    0x03 => { %ciFNumber }, #PH
4763    0x04 => { %ciExposureTime }, #PH
4764    0x06 => { %ciISO }, #PH
4765    0x15 => { #PH (580 EX II)
4766        Name => 'FlashMeteringMode',
4767        PrintConv => {
4768            0 => 'E-TTL',
4769            3 => 'TTL',
4770            4 => 'External Auto',
4771            5 => 'External Manual',
4772            6 => 'Off',
4773        },
4774    },
4775    0x18 => { %ciCameraTemperature }, #36
4776    0x1b => { %ciMacroMagnification }, #PH
4777    0x1d => { %ciFocalLength }, #PH
4778    0x30 => { #20
4779        Name => 'CameraOrientation',
4780        PrintConv => {
4781            0 => 'Horizontal (normal)',
4782            1 => 'Rotate 90 CW',
4783            2 => 'Rotate 270 CW',
4784        },
4785    },
4786    0x43 => { #20
4787        Name => 'FocusDistanceUpper',
4788        # this is very odd (little-endian number on odd boundary),
4789        # but it does seem to work better with my sample images - PH
4790        %focusDistanceByteSwap,
4791    },
4792    0x45 => { #20
4793        Name => 'FocusDistanceLower',
4794        %focusDistanceByteSwap,
4795    },
4796    0x6f => { #PH
4797        Name => 'WhiteBalance',
4798        Format => 'int16u',
4799        PrintConv => \%canonWhiteBalance,
4800        SeparateTable => 1,
4801    },
4802    0x73 => { #PH
4803        Name => 'ColorTemperature',
4804        Format => 'int16u',
4805    },
4806    0xde => { #33
4807        Name => 'LensType',
4808        Format => 'int16uRev', # value is big-endian
4809        SeparateTable => 1,
4810        ValueConvInv => 'int($val)', # (must truncate decimal part)
4811        PrintConv => \%canonLensTypes,
4812    },
4813    0x107 => { #PH
4814        Name => 'FirmwareVersion',
4815        Format => 'string[6]',
4816    },
4817    0x10f => { #20
4818        Name => 'OwnerName',
4819        Format => 'string[32]',
4820    },
4821    0x133 => { #20
4822        Name => 'DirectoryIndex',
4823        Groups => { 2 => 'Image' },
4824        Format => 'int32u',
4825    },
4826    0x13f => { #20
4827        Name => 'FileIndex',
4828        Groups => { 2 => 'Image' },
4829        Format => 'int32u',
4830        ValueConv => '$val + 1',
4831        ValueConvInv => '$val - 1',
4832    },
4833    0x263 => { #PH
4834        Name => 'PictureStyleInfo',
4835        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
4836    },
4837    0x933 => { #33
4838        Name => 'LensModel',
4839        Format => 'string[64]',
4840    },
4841);
4842
4843# Canon camera information for 500D (MakerNotes tag 0x0d) (ref PH)
4844%Image::ExifTool::Canon::CameraInfo500D = (
4845    %binaryDataAttrs,
4846    FORMAT => 'int8u',
4847    FIRST_ENTRY => 0,
4848    PRIORITY => 0,
4849    IS_SUBDIR => [ 0x30b ],
4850    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4851    NOTES => 'CameraInfo tags for the EOS 500D.',
4852    0x03 => { %ciFNumber },
4853    0x04 => { %ciExposureTime },
4854    0x06 => { %ciISO },
4855    0x07 => {
4856        Name => 'HighlightTonePriority',
4857        PrintConv => \%offOn,
4858    },
4859    0x15 => { #PH (580 EX II)
4860        Name => 'FlashMeteringMode',
4861        PrintConv => {
4862            0 => 'E-TTL',
4863            3 => 'TTL',
4864            4 => 'External Auto',
4865            5 => 'External Manual',
4866            6 => 'Off',
4867        },
4868    },
4869    0x19 => { %ciCameraTemperature },
4870    0x1e => { %ciFocalLength },
4871    0x31 => {
4872        Name => 'CameraOrientation',
4873        PrintConv => {
4874            0 => 'Horizontal (normal)',
4875            1 => 'Rotate 90 CW',
4876            2 => 'Rotate 270 CW',
4877        },
4878    },
4879    0x50 => {
4880        Name => 'FocusDistanceUpper',
4881        %focusDistanceByteSwap,
4882    },
4883    0x52 => {
4884        Name => 'FocusDistanceLower',
4885        %focusDistanceByteSwap,
4886    },
4887    0x73 => { # (50D + 4)
4888        Name => 'WhiteBalance',
4889        Format => 'int16u',
4890        SeparateTable => 1,
4891        PrintConv => \%canonWhiteBalance,
4892    },
4893    0x77 => { # (50D + 4)
4894        Name => 'ColorTemperature',
4895        Format => 'int16u',
4896    },
4897    0xab => { # (50D + 4)
4898        Name => 'PictureStyle',
4899        Format => 'int8u',
4900        Flags => ['PrintHex','SeparateTable'],
4901        PrintConv => \%pictureStyles,
4902    },
4903    0xbc => {
4904        Name => 'HighISONoiseReduction',
4905        PrintConv => {
4906            0 => 'Standard',
4907            1 => 'Low',
4908            2 => 'Strong',
4909            3 => 'Off',
4910        },
4911    },
4912    0xbe => {
4913        Name => 'AutoLightingOptimizer',
4914        PrintConv => {
4915            0 => 'Standard',
4916            1 => 'Low',
4917            2 => 'Strong',
4918            3 => 'Off',
4919        },
4920    },
4921    0xf6 => {
4922        Name => 'LensType',
4923        Format => 'int16uRev', # value is big-endian
4924        SeparateTable => 1,
4925        ValueConvInv => 'int($val)', # (must truncate decimal part)
4926        PrintConv => \%canonLensTypes,
4927    },
4928    0xf8 => { %ciMinFocal },
4929    0xfa => { %ciMaxFocal },
4930    0x190 => {
4931        Name => 'FirmwareVersion',
4932        Format => 'string[6]',
4933        Writable => 0,
4934        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
4935    },
4936    0x1d3 => {
4937        Name => 'FileIndex',
4938        Groups => { 2 => 'Image' },
4939        Format => 'int32u',
4940        ValueConv => '$val + 1',
4941        ValueConvInv => '$val - 1',
4942    },
4943    0x1df => { #(NC)
4944        Name => 'DirectoryIndex',
4945        Groups => { 2 => 'Image' },
4946        Format => 'int32u',
4947        ValueConv => '$val - 1',
4948        ValueConvInv => '$val + 1',
4949    },
4950    0x30b => {
4951        Name => 'PictureStyleInfo',
4952        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
4953    },
4954);
4955
4956# Canon camera information for 550D (MakerNotes tag 0x0d) (ref PH)
4957%Image::ExifTool::Canon::CameraInfo550D = (
4958    %binaryDataAttrs,
4959    FORMAT => 'int8u',
4960    FIRST_ENTRY => 0,
4961    PRIORITY => 0,
4962    IS_SUBDIR => [ 0x31c ],
4963    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4964    NOTES => 'CameraInfo tags for the EOS 550D.',
4965    0x03 => { %ciFNumber },
4966    0x04 => { %ciExposureTime },
4967    0x06 => { %ciISO },
4968    0x07 => { #(NC)
4969        Name => 'HighlightTonePriority',
4970        PrintConv => \%offOn,
4971    },
4972    0x15 => { #(NC)
4973        Name => 'FlashMeteringMode',
4974        PrintConv => {
4975            0 => 'E-TTL',
4976            3 => 'TTL',
4977            4 => 'External Auto',
4978            5 => 'External Manual',
4979            6 => 'Off',
4980        },
4981    },
4982    0x19 => { %ciCameraTemperature }, # (500D + 0)
4983    0x1e => { %ciFocalLength }, # (500D + 0)
4984    0x35 => { # (500D + 4)
4985        Name => 'CameraOrientation',
4986        PrintConv => {
4987            0 => 'Horizontal (normal)',
4988            1 => 'Rotate 90 CW',
4989            2 => 'Rotate 270 CW',
4990        },
4991    },
4992    0x54 => { # (500D + 4)
4993        Name => 'FocusDistanceUpper',
4994        %focusDistanceByteSwap,
4995    },
4996    0x56 => { # (500D + 4)
4997        Name => 'FocusDistanceLower',
4998        %focusDistanceByteSwap,
4999    },
5000    0x78 => { # (500D + 5) (NC)
5001        Name => 'WhiteBalance',
5002        Format => 'int16u',
5003        SeparateTable => 1,
5004        PrintConv => \%canonWhiteBalance,
5005    },
5006    0x7c => { # (500D + 5)
5007        Name => 'ColorTemperature',
5008        Format => 'int16u',
5009    },
5010    0xb0 => { # (500D + 5)
5011        Name => 'PictureStyle',
5012        Format => 'int8u',
5013        Flags => ['PrintHex','SeparateTable'],
5014        PrintConv => \%pictureStyles,
5015    },
5016    0xff => { # (500D + 9)
5017        Name => 'LensType',
5018        Format => 'int16uRev', # value is big-endian
5019        SeparateTable => 1,
5020        ValueConvInv => 'int($val)', # (must truncate decimal part)
5021        PrintConv => \%canonLensTypes,
5022    },
5023    0x101 => { %ciMinFocal }, # (500D + 9)
5024    0x103 => { %ciMaxFocal }, # (500D + 9)
5025    0x1a4 => { # (500D + 0x11)
5026        Name => 'FirmwareVersion',
5027        Format => 'string[6]',
5028        Writable => 0,
5029        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
5030    },
5031    0x1e4 => { # (500D + 0x11)
5032        Name => 'FileIndex',
5033        Groups => { 2 => 'Image' },
5034        Format => 'int32u',
5035        ValueConv => '$val + 1',
5036        ValueConvInv => '$val - 1',
5037    },
5038    0x1f0 => { # (500D + 0x11) (NC)
5039        Name => 'DirectoryIndex',
5040        Groups => { 2 => 'Image' },
5041        Format => 'int32u',
5042        ValueConv => '$val - 1',
5043        ValueConvInv => '$val + 1',
5044    },
5045    0x31c => { #48
5046        Name => 'PictureStyleInfo',
5047        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
5048    },
5049);
5050
5051# Canon camera information for 600D and 1100D (MakerNotes tag 0x0d) (ref PH)
5052%Image::ExifTool::Canon::CameraInfo600D = (
5053    %binaryDataAttrs,
5054    FORMAT => 'int8u',
5055    FIRST_ENTRY => 0,
5056    PRIORITY => 0,
5057    IS_SUBDIR => [ 0x2fb ],
5058    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5059    NOTES => 'CameraInfo tags for the EOS 600D and 1100D.',
5060    0x03 => { %ciFNumber },
5061    0x04 => { %ciExposureTime },
5062    0x06 => { %ciISO },
5063    0x07 => { #(NC)
5064        Name => 'HighlightTonePriority',
5065        PrintConv => \%offOn,
5066    },
5067    0x15 => { #(NC)
5068        Name => 'FlashMeteringMode',
5069        PrintConv => {
5070            0 => 'E-TTL',
5071            3 => 'TTL',
5072            4 => 'External Auto',
5073            5 => 'External Manual',
5074            6 => 'Off',
5075        },
5076    },
5077    0x19 => { %ciCameraTemperature }, # (60D + 0)
5078    0x1e => { %ciFocalLength }, # (60D + 0)
5079    0x38 => { # (60D + 2)
5080        Name => 'CameraOrientation',
5081        PrintConv => {
5082            0 => 'Horizontal (normal)',
5083            1 => 'Rotate 90 CW',
5084            2 => 'Rotate 270 CW',
5085        },
5086    },
5087    0x57 => { # (60D + 2, 550D + 3)
5088        Name => 'FocusDistanceUpper',
5089        %focusDistanceByteSwap,
5090    },
5091    0x59 => { # (60D + 2, 550D + 3)
5092        Name => 'FocusDistanceLower',
5093        %focusDistanceByteSwap,
5094    },
5095    0x7b => { # (550D + 3)
5096        Name => 'WhiteBalance',
5097        Format => 'int16u',
5098        SeparateTable => 1,
5099        PrintConv => \%canonWhiteBalance,
5100    },
5101    0x7f => { # (60D + 2, 550D + 3)
5102        Name => 'ColorTemperature',
5103        Format => 'int16u',
5104    },
5105    0xb3 => { # (550D + 3)
5106        Name => 'PictureStyle',
5107        Format => 'int8u',
5108        Flags => ['PrintHex','SeparateTable'],
5109        PrintConv => \%pictureStyles,
5110    },
5111    0xea => { # (60D + 2, 550D + 3)
5112        Name => 'LensType',
5113        Format => 'int16uRev', # value is big-endian
5114        SeparateTable => 1,
5115        ValueConvInv => 'int($val)', # (must truncate decimal part)
5116        PrintConv => \%canonLensTypes,
5117    },
5118    0xec => { %ciMinFocal }, # (60D + 2)
5119    0xee => { %ciMaxFocal }, # (60D + 2)
5120    0x19b => { # (60D + 2)
5121        Name => 'FirmwareVersion',
5122        Format => 'string[6]',
5123        Writable => 0,
5124        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
5125    },
5126    0x1db => { # (60D + 2) (NC)
5127        Name => 'FileIndex',
5128        Groups => { 2 => 'Image' },
5129        Format => 'int32u',
5130        ValueConv => '$val + 1',
5131        ValueConvInv => '$val - 1',
5132    },
5133    0x1e7 => { # (60D + 2) (NC)
5134        Name => 'DirectoryIndex',
5135        Groups => { 2 => 'Image' },
5136        Format => 'int32u',
5137        ValueConv => '$val - 1',
5138        ValueConvInv => '$val + 1',
5139    },
5140    0x2fb => {
5141        Name => 'PictureStyleInfo',
5142        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
5143    },
5144);
5145
5146# Canon camera information for 650D/700D (MakerNotes tag 0x0d) (ref PH)
5147%Image::ExifTool::Canon::CameraInfo650D = (
5148    %binaryDataAttrs,
5149    FORMAT => 'int8u',
5150    FIRST_ENTRY => 0,
5151    PRIORITY => 0,
5152    IS_SUBDIR => [ 0x390 ],
5153    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5154    NOTES => 'CameraInfo tags for the EOS 650D and 700D.',
5155    0x03 => { %ciFNumber },
5156    0x04 => { %ciExposureTime },
5157    0x06 => { %ciISO },
5158    0x1b => { %ciCameraTemperature }, # (1DX/5DmkIII + 0)
5159    0x23 => { %ciFocalLength }, # (1DX/5DmkIII + 3)
5160    # 0x35 - seems to be the same as 0x54
5161    0x7d => { # (1DX/5DmkIII + 3)
5162        Name => 'CameraOrientation',
5163        PrintConv => {
5164            0 => 'Horizontal (normal)',
5165            1 => 'Rotate 90 CW',
5166            2 => 'Rotate 270 CW',
5167        },
5168    },
5169    0x8c => { # (1DX + 3)
5170        Name => 'FocusDistanceUpper',
5171        %focusDistanceByteSwap,
5172    },
5173    0x8e => { # (1DX + 3)
5174        Name => 'FocusDistanceLower',
5175        %focusDistanceByteSwap,
5176    },
5177    0xbc => { # (1DX + 7)
5178        Name => 'WhiteBalance',
5179        Format => 'int16u',
5180        SeparateTable => 1,
5181        PrintConv => \%canonWhiteBalance,
5182    },
5183    0xc0 => { # (1DX + 7)
5184        Name => 'ColorTemperature',
5185        Format => 'int16u',
5186    },
5187    0xf4 => { # (1DX + 7)
5188        Name => 'PictureStyle',
5189        Format => 'int8u',
5190        Flags => ['PrintHex','SeparateTable'],
5191        PrintConv => \%pictureStyles,
5192    },
5193    0x127 => {
5194        Name => 'LensType',
5195        Format => 'int16uRev', # value is big-endian
5196        SeparateTable => 1,
5197        ValueConvInv => 'int($val)', # (must truncate decimal part)
5198        PrintConv => \%canonLensTypes,
5199    },
5200    0x129 => { %ciMinFocal },
5201    0x12b => { %ciMaxFocal },
5202    0x21b => { # (650D version 1.0.1)
5203        Name => 'FirmwareVersion',
5204        Condition => '$$self{Model} =~ /(650D|REBEL T4i|Kiss X6i)\b/',
5205        Notes => '650D',
5206        Format => 'string[6]',
5207        Writable => 0,
5208        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
5209    },
5210    0x220 => { # (700D version 1.1.1/2.1.1)
5211        Name => 'FirmwareVersion',
5212        Condition => '$$self{Model} =~ /(700D|REBEL T5i|Kiss X7i)\b/',
5213        Notes => '700D',
5214        Format => 'string[6]',
5215        Writable => 0,
5216        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
5217    },
5218    0x270 => { #(NC)
5219        Name => 'FileIndex',
5220        Condition => '$$self{Model} =~ /(650D|REBEL T4i|Kiss X6i)\b/',
5221        Notes => '650D',
5222        Groups => { 2 => 'Image' },
5223        Format => 'int32u',
5224        ValueConv => '$val + 1',
5225        ValueConvInv => '$val - 1',
5226    },
5227    0x274 => { #(NC)
5228        Name => 'FileIndex',
5229        Condition => '$$self{Model} =~ /(700D|REBEL T5i|Kiss X7i)\b/',
5230        Notes => '700D',
5231        Groups => { 2 => 'Image' },
5232        Format => 'int32u',
5233        ValueConv => '$val + 1',
5234        ValueConvInv => '$val - 1',
5235    },
5236    0x27c => { #(NC)
5237        Name => 'DirectoryIndex',
5238        Condition => '$$self{Model} =~ /(650D|REBEL T4i|Kiss X6i)\b/',
5239        Notes => '650D',
5240        Groups => { 2 => 'Image' },
5241        Format => 'int32u',
5242        ValueConv => '$val - 1',
5243        ValueConvInv => '$val + 1',
5244    },
5245    0x280 => { #(NC)
5246        Name => 'DirectoryIndex',
5247        Condition => '$$self{Model} =~ /(700D|REBEL T5i|Kiss X7i)\b/',
5248        Notes => '700D',
5249        Groups => { 2 => 'Image' },
5250        Format => 'int32u',
5251        ValueConv => '$val - 1',
5252        ValueConvInv => '$val + 1',
5253    },
5254    0x390 => {
5255        Name => 'PictureStyleInfo',
5256        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
5257    },
5258);
5259
5260# Canon camera information for 750D/760D (MakerNotes tag 0x0d) (ref PH)
5261%Image::ExifTool::Canon::CameraInfo750D = (
5262    %binaryDataAttrs,
5263    FORMAT => 'int8u',
5264    FIRST_ENTRY => 0,
5265    PRIORITY => 0,
5266    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5267    NOTES => 'CameraInfo tags for the EOS 750D and 760D.',
5268    0x03 => { %ciFNumber },
5269    0x04 => { %ciExposureTime },
5270    0x06 => { %ciISO },
5271    0x1b => { %ciCameraTemperature }, # (700D + 0)
5272    0x23 => { %ciFocalLength }, # (700D + 0)
5273    0x96 => { #IB (700D + 0x19)
5274        Name => 'CameraOrientation',
5275        PrintConv => {
5276            0 => 'Horizontal (normal)',
5277            1 => 'Rotate 90 CW',
5278            2 => 'Rotate 270 CW',
5279        },
5280    },
5281    0xa5 => { # (700D + 0x19)
5282        Name => 'FocusDistanceUpper',
5283        %focusDistanceByteSwap,
5284    },
5285    0xa7 => { # (700D + 0x19)
5286        Name => 'FocusDistanceLower',
5287        %focusDistanceByteSwap,
5288    },
5289    0x131 => { # (700D + 0x19)
5290        Name => 'WhiteBalance',
5291        Format => 'int16u',
5292        SeparateTable => 1,
5293        PrintConv => \%canonWhiteBalance,
5294    },
5295    0x135 => {
5296        Name => 'ColorTemperature',
5297        Format => 'int16u',
5298    },
5299    0x169 => {
5300        Name => 'PictureStyle',
5301        Format => 'int8u',
5302        Flags => ['PrintHex','SeparateTable'],
5303        PrintConv => \%pictureStyles,
5304    },
5305    0x184 => {
5306        Name => 'LensType',
5307        Format => 'int16uRev', # value is big-endian
5308        SeparateTable => 1,
5309        ValueConvInv => 'int($val)', # (must truncate decimal part)
5310        PrintConv => \%canonLensTypes,
5311    },
5312    0x186 => { %ciMinFocal },
5313    0x188 => { %ciMaxFocal },
5314    0x43d => { # (750D/760D firmware 6.7.2)
5315        Name => 'FirmwareVersion',
5316        Format => 'string[6]',
5317        Writable => 0,
5318        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
5319    },
5320    0x449 => { # (750D/760D firmware 1.0.0)
5321        Name => 'FirmwareVersion',
5322        Format => 'string[6]',
5323        Writable => 0,
5324        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
5325    },
5326);
5327
5328# Canon camera information for 1000D (MakerNotes tag 0x0d) (ref PH)
5329%Image::ExifTool::Canon::CameraInfo1000D = (
5330    %binaryDataAttrs,
5331    FORMAT => 'int8u',
5332    FIRST_ENTRY => 0,
5333    PRIORITY => 0,
5334    IS_SUBDIR => [ 0x267 ],
5335    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5336    NOTES => 'CameraInfo tags for the EOS 1000D.',
5337    0x03 => { %ciFNumber }, #PH
5338    0x04 => { %ciExposureTime }, #PH
5339    0x06 => { %ciISO }, #PH
5340    0x15 => { #PH (580 EX II)
5341        Name => 'FlashMeteringMode',
5342        PrintConv => {
5343            0 => 'E-TTL',
5344            3 => 'TTL',
5345            4 => 'External Auto',
5346            5 => 'External Manual',
5347            6 => 'Off',
5348        },
5349    },
5350    0x18 => { %ciCameraTemperature }, #36
5351    0x1b => { %ciMacroMagnification }, #PH (NC)
5352    0x1d => { %ciFocalLength }, #PH
5353    0x30 => { #20
5354        Name => 'CameraOrientation',
5355        PrintConv => {
5356            0 => 'Horizontal (normal)',
5357            1 => 'Rotate 90 CW',
5358            2 => 'Rotate 270 CW',
5359        },
5360    },
5361    0x43 => { #20
5362        Name => 'FocusDistanceUpper',
5363        %focusDistanceByteSwap,
5364    },
5365    0x45 => { #20
5366        Name => 'FocusDistanceLower',
5367        %focusDistanceByteSwap,
5368    },
5369    0x6f => { #PH
5370        Name => 'WhiteBalance',
5371        Format => 'int16u',
5372        PrintConv => \%canonWhiteBalance,
5373        SeparateTable => 1,
5374    },
5375    0x73 => { #PH
5376        Name => 'ColorTemperature',
5377        Format => 'int16u',
5378    },
5379    0xe2 => { #PH
5380        Name => 'LensType',
5381        Format => 'int16uRev', # value is big-endian
5382        SeparateTable => 1,
5383        ValueConvInv => 'int($val)', # (must truncate decimal part)
5384        PrintConv => \%canonLensTypes,
5385    },
5386    0xe4 => { %ciMinFocal }, #PH
5387    0xe6 => { %ciMaxFocal }, #PH
5388    0x10b => { #PH
5389        Name => 'FirmwareVersion',
5390        Format => 'string[6]',
5391    },
5392    0x137 => { #PH (NC)
5393        Name => 'DirectoryIndex',
5394        Groups => { 2 => 'Image' },
5395        Format => 'int32u',
5396    },
5397    0x143 => { #PH
5398        Name => 'FileIndex',
5399        Groups => { 2 => 'Image' },
5400        Format => 'int32u',
5401        ValueConv => '$val + 1',
5402        ValueConvInv => '$val - 1',
5403    },
5404    0x267 => { #PH
5405        Name => 'PictureStyleInfo',
5406        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
5407    },
5408    0x937 => { #PH
5409        Name => 'LensModel',
5410        Format => 'string[64]',
5411    },
5412);
5413
5414# Canon camera information for PowerShot models (MakerNotes tag 0x0d) - PH
5415%Image::ExifTool::Canon::CameraInfoPowerShot = (
5416    %binaryDataAttrs,
5417    FORMAT => 'int32s',
5418    FIRST_ENTRY => 0,
5419    PRIORITY => 0,
5420    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5421    NOTES => q{
5422        CameraInfo tags for PowerShot models such as the A450, A460, A550, A560,
5423        A570, A630, A640, A650, A710, A720, G7, G9, S5, SD40, SD750, SD800, SD850,
5424        SD870, SD900, SD950, SD1000, SX100 and TX1.
5425    },
5426    0x00 => {
5427        Name => 'ISO',
5428        Groups => { 2 => 'Image' },
5429        ValueConv => '100*exp((($val-411)/96)*log(2))',
5430        ValueConvInv => 'log($val/100)/log(2)*96+411',
5431        PrintConv => 'sprintf("%.0f",$val)',
5432        PrintConvInv => '$val',
5433    },
5434    0x05 => {
5435        Name => 'FNumber',
5436        Groups => { 2 => 'Image' },
5437        ValueConv => 'exp($val/192*log(2))',
5438        ValueConvInv => 'log($val)*192/log(2)',
5439        PrintConv => 'sprintf("%.2g",$val)',
5440        PrintConvInv => '$val',
5441    },
5442    0x06 => {
5443        Name => 'ExposureTime',
5444        Groups => { 2 => 'Image' },
5445        ValueConv => 'exp(-$val/96*log(2))',
5446        ValueConvInv => '-log($val)*96/log(2)',
5447        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
5448        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
5449    },
5450    0x17 => 'Rotation', # usually the same as Orientation (but not always! why?)
5451    # 0x25 - flash fired/not fired (ref 37)
5452    # 0x26 - related to flash mode? (ref 37)
5453    # 0x37 - related to flash strength (ref 37)
5454    # 0x38 - pre-flash fired/no fired or flash data collection (ref 37)
5455    135 => { # [-3] <-- index relative to CameraInfoCount
5456        Name => 'CameraTemperature',
5457        Condition => '$$self{CameraInfoCount} == 138',
5458        Notes => 'A450, A460, A550, A630, A640 and A710',
5459        PrintConv => '"$val C"',
5460        PrintConvInv => '$val=~s/ ?C//; $val',
5461    },
5462    145 => { #37 [-3]
5463        Name => 'CameraTemperature',
5464        Condition => '$$self{CameraInfoCount} == 148',
5465        Notes => q{
5466            A560, A570, A650, A720, G7, G9, S5, SD40, SD750, SD800, SD850, SD870, SD900,
5467            SD950, SD1000, SX100 and TX1
5468        },
5469        PrintConv => '"$val C"',
5470        PrintConvInv => '$val=~s/ ?C//; $val',
5471    },
5472);
5473
5474# Canon camera information for some PowerShot models (MakerNotes tag 0x0d) - PH
5475%Image::ExifTool::Canon::CameraInfoPowerShot2 = (
5476    %binaryDataAttrs,
5477    FORMAT => 'int32s',
5478    FIRST_ENTRY => 0,
5479    PRIORITY => 0,
5480    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5481    NOTES => q{
5482        CameraInfo tags for PowerShot models such as the A470, A480, A490, A495,
5483        A580, A590, A1000, A1100, A2000, A2100, A3000, A3100, D10, E1, G10, G11,
5484        S90, S95, SD770, SD780, SD790, SD880, SD890, SD940, SD960, SD970, SD980,
5485        SD990, SD1100, SD1200, SD1300, SD1400, SD3500, SD4000, SD4500, SX1, SX10,
5486        SX20, SX110, SX120, SX130, SX200 and SX210.
5487    },
5488    0x01 => {
5489        Name => 'ISO',
5490        Groups => { 2 => 'Image' },
5491        ValueConv => '100*exp((($val-411)/96)*log(2))',
5492        ValueConvInv => 'log($val/100)/log(2)*96+411',
5493        PrintConv => 'sprintf("%.0f",$val)',
5494        PrintConvInv => '$val',
5495    },
5496    0x06 => {
5497        Name => 'FNumber',
5498        Groups => { 2 => 'Image' },
5499        ValueConv => 'exp($val/192*log(2))',
5500        ValueConvInv => 'log($val)*192/log(2)',
5501        PrintConv => 'sprintf("%.2g",$val)',
5502        PrintConvInv => '$val',
5503    },
5504    0x07 => {
5505        Name => 'ExposureTime',
5506        Groups => { 2 => 'Image' },
5507        ValueConv => 'exp(-$val/96*log(2))',
5508        ValueConvInv => '-log($val)*96/log(2)',
5509        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
5510        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
5511    },
5512    0x18 => 'Rotation',
5513    153 => { # [-3] <-- index relative to CameraInfoCount
5514        Name => 'CameraTemperature',
5515        Condition => '$$self{CameraInfoCount} == 156',
5516        Notes => 'A470, A580, A590, SD770, SD790, SD890 and SD1100',
5517        PrintConv => '"$val C"',
5518        PrintConvInv => '$val=~s/ ?C//; $val',
5519    },
5520    159 => { # [-3]
5521        Name => 'CameraTemperature',
5522        Condition => '$$self{CameraInfoCount} == 162',
5523        Notes => 'A1000, A2000, E1, G10, SD880, SD990, SX1, SX10 and SX110',
5524        PrintConv => '"$val C"',
5525        PrintConvInv => '$val=~s/ ?C//; $val',
5526    },
5527    164 => { # [-3]
5528        Name => 'CameraTemperature',
5529        Condition => '$$self{CameraInfoCount} == 167',
5530        Notes => 'A480, A1100, A2100, D10, SD780, SD960, SD970, SD1200 and SX200',
5531        PrintConv => '"$val C"',
5532        PrintConvInv => '$val=~s/ ?C//; $val',
5533    },
5534    168 => { # [-3]
5535        Name => 'CameraTemperature',
5536        Condition => '$$self{CameraInfoCount} == 171',
5537        Notes => q{
5538            A490, A495, A3000, A3100, G11, S90, SD940, SD980, SD1300, SD1400, SD3500,
5539            SD4000, SX20, SX120 and SX210
5540        },
5541        PrintConv => '"$val C"',
5542        PrintConvInv => '$val=~s/ ?C//; $val',
5543    },
5544    261 => { # [-3]
5545        Name => 'CameraTemperature',
5546        Condition => '$$self{CameraInfoCount} == 264',
5547        Notes => 'S95, SD4500 and SX130',
5548        PrintConv => '"$val C"',
5549        PrintConvInv => '$val=~s/ ?C//; $val',
5550    },
5551);
5552
5553# unknown Canon camera information (MakerNotes tag 0x0d) - PH
5554%Image::ExifTool::Canon::CameraInfoUnknown32 = (
5555    %binaryDataAttrs,
5556    FORMAT => 'int32s',
5557    FIRST_ENTRY => 0,
5558    PRIORITY => 0,
5559    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5560    NOTES => 'Unknown CameraInfo tags are divided into 3 tables based on format size.',
5561    # This tag may be uncommented, and is useful for generating
5562    # lists of models in the "Notes" below...
5563    # 0 => {
5564    #     Name => 'CameraInfoCount',
5565    #     ValueConv => '$$self{CameraInfoCount}',
5566    # },
5567    71 => { # [-1] <-- index relative to CameraInfoCount
5568        Name => 'CameraTemperature',
5569        Condition => '$$self{CameraInfoCount} == 72',
5570        Notes => 'S1',
5571        PrintConv => '"$val C"',
5572        PrintConvInv => '$val=~s/ ?C//; $val',
5573    },
5574    83 => { # [-2]
5575        Name => 'CameraTemperature',
5576        Condition => '$$self{CameraInfoCount} == 85',
5577        Notes => 'S2',
5578        PrintConv => '"$val C"',
5579        PrintConvInv => '$val=~s/ ?C//; $val',
5580    },
5581    91 => { # [-2 or -3]
5582        Name => 'CameraTemperature',
5583        Condition => '$$self{CameraInfoCount} == 93 or $$self{CameraInfoCount} == 94',
5584        Notes => 'A410, A610, A620, S80, SD30, SD400, SD430, SD450, SD500 and SD550',
5585        PrintConv => '"$val C"',
5586        PrintConvInv => '$val=~s/ ?C//; $val',
5587    },
5588    92 => { # [-4]
5589        Name => 'CameraTemperature',
5590        Condition => '$$self{CameraInfoCount} == 96',
5591        Notes => 'S3',
5592        PrintConv => '"$val C"',
5593        PrintConvInv => '$val=~s/ ?C//; $val',
5594    },
5595    100 => { # [-4]
5596        Name => 'CameraTemperature',
5597        Condition => '$$self{CameraInfoCount} == 104',
5598        Notes => 'A420, A430, A530, A540, A700, SD600, SD630 and SD700',
5599        PrintConv => '"$val C"',
5600        PrintConvInv => '$val=~s/ ?C//; $val',
5601    },
5602    -3 => {
5603        Name => 'CameraTemperature',
5604        Condition => '$$self{CameraInfoCount} > 400',
5605        Notes => '3 entries from end of record for most newer camera models',
5606        PrintConv => '"$val C"',
5607        PrintConvInv => '$val=~s/ ?C//; $val',
5608    },
5609#    466 => { # [-3]
5610#        Name => 'CameraTemperature',
5611#        Condition => '$$self{CameraInfoCount} == 469',
5612#        Notes => '100HS, 300HS, 500HS, A1200, A2200, A3200 and A3300',
5613#        PrintConv => '"$val C"',
5614#        PrintConvInv => '$val=~s/ ?C//; $val',
5615#    },
5616#    503 => { # [-3]
5617#        Name => 'CameraTemperature',
5618#        Condition => '$$self{CameraInfoCount} == 506',
5619#        Notes => 'A800',
5620#        PrintConv => '"$val C"',
5621#        PrintConvInv => '$val=~s/ ?C//; $val',
5622#    },
5623#    506 => { # [-3]
5624#        Name => 'CameraTemperature',
5625#        Condition => '$$self{CameraInfoCount} == 509',
5626#        Notes => 'SX230HS',
5627#        PrintConv => '"$val C"',
5628#        PrintConvInv => '$val=~s/ ?C//; $val',
5629#    },
5630#    520 => { # [-3]
5631#        Name => 'CameraTemperature',
5632#        Condition => '$$self{CameraInfoCount} == 523',
5633#        Notes => '310HS, 510HS, G1X, S100 (new), SX40HS and SX150',
5634#        PrintConv => '"$val C"',
5635#        PrintConvInv => '$val=~s/ ?C//; $val',
5636#    },
5637#    524 => { # [-3]
5638#        Name => 'CameraTemperature',
5639#        Condition => '$$self{CameraInfoCount} == 527',
5640#        Notes => '110HS, 520HS, A2300, A2400, A3400, A4000, D20 and SX260HS',
5641#        PrintConv => '"$val C"',
5642#        PrintConvInv => '$val=~s/ ?C//; $val',
5643#    },
5644#    532 => { # [-3]
5645#        Name => 'CameraTemperature',
5646#        Condition => '$$self{CameraInfoCount} == 535',
5647#        Notes => 'S110 (new), G15, SX50, SX160IS and SX500IS',
5648#        PrintConv => '"$val C"',
5649#        PrintConvInv => '$val=~s/ ?C//; $val',
5650#    },
5651#    547 => { # [-3]
5652#        Name => 'CameraTemperature',
5653#        Condition => '$$self{CameraInfoCount} == 550',
5654#        Notes => '130IS, A1400, A2500 and A2600',
5655#        PrintConv => '"$val C"',
5656#        PrintConvInv => '$val=~s/ ?C//; $val',
5657#    },
5658#    549 => { # [-3]
5659#        Name => 'CameraTemperature',
5660#        Condition => '$$self{CameraInfoCount} == 552',
5661#        Notes => '115IS, 130IS, SX270, SX280, 330HS and A3500',
5662#        PrintConv => '"$val C"',
5663#        PrintConvInv => '$val=~s/ ?C//; $val',
5664#    },
5665#    552 => { # [-3]
5666#        Name => 'CameraTemperature',
5667#        Condition => '$$self{CameraInfoCount} == 555',
5668#        Notes => 'S200 (new)',
5669#        PrintConv => '"$val C"',
5670#        PrintConvInv => '$val=~s/ ?C//; $val',
5671#    },
5672#    850 => { # [-3]
5673#        Name => 'CameraTemperature',
5674#        Condition => '$$self{CameraInfoCount} == 853',
5675#        Notes => 'N',
5676#        PrintConv => '"$val C"',
5677#        PrintConvInv => '$val=~s/ ?C//; $val',
5678#    },
5679#    895 => { # [-3]
5680#        Name => 'CameraTemperature',
5681#        Condition => '$$self{CameraInfoCount} == 898',
5682#        Notes => 'G1XmkII, N100, SX600HS and SX700HS',
5683#        PrintConv => '"$val C"',
5684#        PrintConvInv => '$val=~s/ ?C//; $val',
5685#    },
5686);
5687
5688# unknown Canon camera information (MakerNotes tag 0x0d) - PH
5689%Image::ExifTool::Canon::CameraInfoUnknown16 = (
5690    %binaryDataAttrs,
5691    FORMAT => 'int16s',
5692    FIRST_ENTRY => 0,
5693    PRIORITY => 0,
5694    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5695);
5696
5697# unknown Canon camera information (MakerNotes tag 0x0d) - PH
5698%Image::ExifTool::Canon::CameraInfoUnknown = (
5699    %binaryDataAttrs,
5700    FORMAT => 'int8s',
5701    FIRST_ENTRY => 0,
5702    PRIORITY => 0,
5703    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5704    0x16b => {
5705        Name => 'LensSerialNumber',
5706        Condition => '$$self{Model} =~ /^Canon EOS 5DS/', # (good for 5DS and 5DSR)
5707        Format => 'undef[5]',
5708        Priority => 0,
5709        ValueConv => 'unpack("H*",$val)',
5710        ValueConvInv => 'length($val) < 10 and $val = 0 x (10-length($val)) . $val; pack("H*",$val)',
5711    },
5712    0x5c1 => {
5713        Name => 'FirmwareVersion',
5714        Format => 'string[6]',
5715        Writable => 0,
5716        Condition => '$$valPt =~ /^\d\.\d\.\d\0/',
5717        Notes => 'M50', # (firmware 1.0.0)
5718    },
5719);
5720
5721# Picture Style information for various cameras (ref 48)
5722%Image::ExifTool::Canon::PSInfo = (
5723    %binaryDataAttrs,
5724    FIRST_ENTRY => 0,
5725    PRIORITY => 0,
5726    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5727    NOTES => 'Custom picture style information for various models.',
5728    # (values expected to be "n/a" are flagged as Unknown)
5729    0x00 => { Name => 'ContrastStandard',      %psInfo },
5730    0x04 => { Name => 'SharpnessStandard',     %psInfo },
5731    0x08 => { Name => 'SaturationStandard',    %psInfo },
5732    0x0c => { Name => 'ColorToneStandard',     %psInfo },
5733    0x10 => { Name => 'FilterEffectStandard',  %psInfo, Unknown => 1 },
5734    0x14 => { Name => 'ToningEffectStandard',  %psInfo, Unknown => 1 },
5735    0x18 => { Name => 'ContrastPortrait',      %psInfo },
5736    0x1c => { Name => 'SharpnessPortrait',     %psInfo },
5737    0x20 => { Name => 'SaturationPortrait',    %psInfo },
5738    0x24 => { Name => 'ColorTonePortrait',     %psInfo },
5739    0x28 => { Name => 'FilterEffectPortrait',  %psInfo, Unknown => 1 },
5740    0x2c => { Name => 'ToningEffectPortrait',  %psInfo, Unknown => 1 },
5741    0x30 => { Name => 'ContrastLandscape',     %psInfo },
5742    0x34 => { Name => 'SharpnessLandscape',    %psInfo },
5743    0x38 => { Name => 'SaturationLandscape',   %psInfo },
5744    0x3c => { Name => 'ColorToneLandscape',    %psInfo },
5745    0x40 => { Name => 'FilterEffectLandscape', %psInfo, Unknown => 1 },
5746    0x44 => { Name => 'ToningEffectLandscape', %psInfo, Unknown => 1 },
5747    0x48 => { Name => 'ContrastNeutral',       %psInfo },
5748    0x4c => { Name => 'SharpnessNeutral',      %psInfo },
5749    0x50 => { Name => 'SaturationNeutral',     %psInfo },
5750    0x54 => { Name => 'ColorToneNeutral',      %psInfo },
5751    0x58 => { Name => 'FilterEffectNeutral',   %psInfo, Unknown => 1 },
5752    0x5c => { Name => 'ToningEffectNeutral',   %psInfo, Unknown => 1 },
5753    0x60 => { Name => 'ContrastFaithful',      %psInfo },
5754    0x64 => { Name => 'SharpnessFaithful',     %psInfo },
5755    0x68 => { Name => 'SaturationFaithful',    %psInfo },
5756    0x6c => { Name => 'ColorToneFaithful',     %psInfo },
5757    0x70 => { Name => 'FilterEffectFaithful',  %psInfo, Unknown => 1 },
5758    0x74 => { Name => 'ToningEffectFaithful',  %psInfo, Unknown => 1 },
5759    0x78 => { Name => 'ContrastMonochrome',    %psInfo },
5760    0x7c => { Name => 'SharpnessMonochrome',   %psInfo },
5761    0x80 => { Name => 'SaturationMonochrome',  %psInfo, Unknown => 1 },
5762    0x84 => { Name => 'ColorToneMonochrome',   %psInfo, Unknown => 1 },
5763    0x88 => { Name => 'FilterEffectMonochrome',%psInfo,
5764        PrintConv => {
5765            0 => 'None',
5766            1 => 'Yellow',
5767            2 => 'Orange',
5768            3 => 'Red',
5769            4 => 'Green',
5770            -559038737 => 'n/a', # (0xdeadbeef)
5771        },
5772    },
5773    0x8c => { Name => 'ToningEffectMonochrome',%psInfo,
5774        PrintConv => {
5775            0 => 'None',
5776            1 => 'Sepia',
5777            2 => 'Blue',
5778            3 => 'Purple',
5779            4 => 'Green',
5780            -559038737 => 'n/a', # (0xdeadbeef)
5781        },
5782    },
5783    0x90 => { Name => 'ContrastUserDef1',      %psInfo },
5784    0x94 => { Name => 'SharpnessUserDef1',     %psInfo },
5785    0x98 => { Name => 'SaturationUserDef1',    %psInfo },
5786    0x9c => { Name => 'ColorToneUserDef1',     %psInfo },
5787    0xa0 => { Name => 'FilterEffectUserDef1',  %psInfo,
5788        PrintConv => {
5789            0 => 'None',
5790            1 => 'Yellow',
5791            2 => 'Orange',
5792            3 => 'Red',
5793            4 => 'Green',
5794            -559038737 => 'n/a', # (0xdeadbeef)
5795        },
5796    },
5797    0xa4 => { Name => 'ToningEffectUserDef1',  %psInfo,
5798        PrintConv => {
5799            0 => 'None',
5800            1 => 'Sepia',
5801            2 => 'Blue',
5802            3 => 'Purple',
5803            4 => 'Green',
5804            -559038737 => 'n/a', # (0xdeadbeef)
5805        },
5806    },
5807    0xa8 => { Name => 'ContrastUserDef2',      %psInfo },
5808    0xac => { Name => 'SharpnessUserDef2',     %psInfo },
5809    0xb0 => { Name => 'SaturationUserDef2',    %psInfo },
5810    0xb4 => { Name => 'ColorToneUserDef2',     %psInfo },
5811    0xb8 => { Name => 'FilterEffectUserDef2',  %psInfo,
5812        PrintConv => {
5813            0 => 'None',
5814            1 => 'Yellow',
5815            2 => 'Orange',
5816            3 => 'Red',
5817            4 => 'Green',
5818            -559038737 => 'n/a', # (0xdeadbeef)
5819        },
5820    },
5821    0xbc => { Name => 'ToningEffectUserDef2',  %psInfo,
5822        PrintConv => {
5823            0 => 'None',
5824            1 => 'Sepia',
5825            2 => 'Blue',
5826            3 => 'Purple',
5827            4 => 'Green',
5828            -559038737 => 'n/a', # (0xdeadbeef)
5829        },
5830    },
5831    0xc0 => { Name => 'ContrastUserDef3',      %psInfo },
5832    0xc4 => { Name => 'SharpnessUserDef3',     %psInfo },
5833    0xc8 => { Name => 'SaturationUserDef3',    %psInfo },
5834    0xcc => { Name => 'ColorToneUserDef3',     %psInfo },
5835    0xd0 => { Name => 'FilterEffectUserDef3',  %psInfo,
5836        PrintConv => {
5837            0 => 'None',
5838            1 => 'Yellow',
5839            2 => 'Orange',
5840            3 => 'Red',
5841            4 => 'Green',
5842            -559038737 => 'n/a', # (0xdeadbeef)
5843        },
5844    },
5845    0xd4 => { Name => 'ToningEffectUserDef3',  %psInfo,
5846        PrintConv => {
5847            0 => 'None',
5848            1 => 'Sepia',
5849            2 => 'Blue',
5850            3 => 'Purple',
5851            4 => 'Green',
5852            -559038737 => 'n/a', # (0xdeadbeef)
5853        },
5854    },
5855    # base picture style names:
5856    0xd8 => {
5857        Name => 'UserDef1PictureStyle',
5858        Format => 'int16u',
5859        SeparateTable => 'UserDefStyle',
5860        PrintConv => \%userDefStyles,
5861    },
5862    0xda => {
5863        Name => 'UserDef2PictureStyle',
5864        Format => 'int16u',
5865        SeparateTable => 'UserDefStyle',
5866        PrintConv => \%userDefStyles,
5867    },
5868    0xdc => {
5869        Name => 'UserDef3PictureStyle',
5870        Format => 'int16u',
5871        SeparateTable => 'UserDefStyle',
5872        PrintConv => \%userDefStyles,
5873    },
5874);
5875
5876# Picture Style information for the 60D, etc (ref 48)
5877%Image::ExifTool::Canon::PSInfo2 = (
5878    %binaryDataAttrs,
5879    FIRST_ENTRY => 0,
5880    PRIORITY => 0,
5881    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5882    NOTES => 'Custom picture style information for the EOS 5DmkIII, 60D, 600D and 1100D.',
5883    # (values expected to be "n/a" are flagged as Unknown)
5884    0x00 => { Name => 'ContrastStandard',      %psInfo },
5885    0x04 => { Name => 'SharpnessStandard',     %psInfo },
5886    0x08 => { Name => 'SaturationStandard',    %psInfo },
5887    0x0c => { Name => 'ColorToneStandard',     %psInfo },
5888    0x10 => { Name => 'FilterEffectStandard',  %psInfo, Unknown => 1 },
5889    0x14 => { Name => 'ToningEffectStandard',  %psInfo, Unknown => 1 },
5890    0x18 => { Name => 'ContrastPortrait',      %psInfo },
5891    0x1c => { Name => 'SharpnessPortrait',     %psInfo },
5892    0x20 => { Name => 'SaturationPortrait',    %psInfo },
5893    0x24 => { Name => 'ColorTonePortrait',     %psInfo },
5894    0x28 => { Name => 'FilterEffectPortrait',  %psInfo, Unknown => 1 },
5895    0x2c => { Name => 'ToningEffectPortrait',  %psInfo, Unknown => 1 },
5896    0x30 => { Name => 'ContrastLandscape',     %psInfo },
5897    0x34 => { Name => 'SharpnessLandscape',    %psInfo },
5898    0x38 => { Name => 'SaturationLandscape',   %psInfo },
5899    0x3c => { Name => 'ColorToneLandscape',    %psInfo },
5900    0x40 => { Name => 'FilterEffectLandscape', %psInfo, Unknown => 1 },
5901    0x44 => { Name => 'ToningEffectLandscape', %psInfo, Unknown => 1 },
5902    0x48 => { Name => 'ContrastNeutral',       %psInfo },
5903    0x4c => { Name => 'SharpnessNeutral',      %psInfo },
5904    0x50 => { Name => 'SaturationNeutral',     %psInfo },
5905    0x54 => { Name => 'ColorToneNeutral',      %psInfo },
5906    0x58 => { Name => 'FilterEffectNeutral',   %psInfo, Unknown => 1 },
5907    0x5c => { Name => 'ToningEffectNeutral',   %psInfo, Unknown => 1 },
5908    0x60 => { Name => 'ContrastFaithful',      %psInfo },
5909    0x64 => { Name => 'SharpnessFaithful',     %psInfo },
5910    0x68 => { Name => 'SaturationFaithful',    %psInfo },
5911    0x6c => { Name => 'ColorToneFaithful',     %psInfo },
5912    0x70 => { Name => 'FilterEffectFaithful',  %psInfo, Unknown => 1 },
5913    0x74 => { Name => 'ToningEffectFaithful',  %psInfo, Unknown => 1 },
5914    0x78 => { Name => 'ContrastMonochrome',    %psInfo },
5915    0x7c => { Name => 'SharpnessMonochrome',   %psInfo },
5916    0x80 => { Name => 'SaturationMonochrome',  %psInfo, Unknown => 1 },
5917    0x84 => { Name => 'ColorToneMonochrome',   %psInfo, Unknown => 1 },
5918    0x88 => { Name => 'FilterEffectMonochrome',%psInfo,
5919        PrintConv => {
5920            0 => 'None',
5921            1 => 'Yellow',
5922            2 => 'Orange',
5923            3 => 'Red',
5924            4 => 'Green',
5925            -559038737 => 'n/a', # (0xdeadbeef)
5926        },
5927    },
5928    0x8c => { Name => 'ToningEffectMonochrome',%psInfo,
5929        PrintConv => {
5930            0 => 'None',
5931            1 => 'Sepia',
5932            2 => 'Blue',
5933            3 => 'Purple',
5934            4 => 'Green',
5935            -559038737 => 'n/a', # (0xdeadbeef)
5936        },
5937    },
5938    0x90 => { Name => 'ContrastAuto',          %psInfo },
5939    0x94 => { Name => 'SharpnessAuto',         %psInfo },
5940    0x98 => { Name => 'SaturationAuto',        %psInfo },
5941    0x9c => { Name => 'ColorToneAuto',         %psInfo },
5942    0xa0 => { Name => 'FilterEffectAuto',      %psInfo,
5943        PrintConv => {
5944            0 => 'None',
5945            1 => 'Yellow',
5946            2 => 'Orange',
5947            3 => 'Red',
5948            4 => 'Green',
5949            -559038737 => 'n/a', # (0xdeadbeef)
5950        },
5951    },
5952    0xa4 => { Name => 'ToningEffectAuto',      %psInfo,
5953        PrintConv => {
5954            0 => 'None',
5955            1 => 'Sepia',
5956            2 => 'Blue',
5957            3 => 'Purple',
5958            4 => 'Green',
5959            -559038737 => 'n/a', # (0xdeadbeef)
5960        },
5961    },
5962    0xa8 => { Name => 'ContrastUserDef1',      %psInfo },
5963    0xac => { Name => 'SharpnessUserDef1',     %psInfo },
5964    0xb0 => { Name => 'SaturationUserDef1',    %psInfo },
5965    0xb4 => { Name => 'ColorToneUserDef1',     %psInfo },
5966    0xb8 => { Name => 'FilterEffectUserDef1',  %psInfo,
5967        PrintConv => {
5968            0 => 'None',
5969            1 => 'Yellow',
5970            2 => 'Orange',
5971            3 => 'Red',
5972            4 => 'Green',
5973            -559038737 => 'n/a', # (0xdeadbeef)
5974        },
5975    },
5976    0xbc => { Name => 'ToningEffectUserDef1',  %psInfo,
5977        PrintConv => {
5978            0 => 'None',
5979            1 => 'Sepia',
5980            2 => 'Blue',
5981            3 => 'Purple',
5982            4 => 'Green',
5983            -559038737 => 'n/a', # (0xdeadbeef)
5984        },
5985    },
5986    0xc0 => { Name => 'ContrastUserDef2',      %psInfo },
5987    0xc4 => { Name => 'SharpnessUserDef2',     %psInfo },
5988    0xc8 => { Name => 'SaturationUserDef2',    %psInfo },
5989    0xcc => { Name => 'ColorToneUserDef2',     %psInfo },
5990    0xd0 => { Name => 'FilterEffectUserDef2',  %psInfo,
5991        PrintConv => {
5992            0 => 'None',
5993            1 => 'Yellow',
5994            2 => 'Orange',
5995            3 => 'Red',
5996            4 => 'Green',
5997            -559038737 => 'n/a', # (0xdeadbeef)
5998        },
5999    },
6000    0xd4 => { Name => 'ToningEffectUserDef2',  %psInfo,
6001        PrintConv => {
6002            0 => 'None',
6003            1 => 'Sepia',
6004            2 => 'Blue',
6005            3 => 'Purple',
6006            4 => 'Green',
6007            -559038737 => 'n/a', # (0xdeadbeef)
6008        },
6009    },
6010    0xd8 => { Name => 'ContrastUserDef3',      %psInfo },
6011    0xdc => { Name => 'SharpnessUserDef3',     %psInfo },
6012    0xe0 => { Name => 'SaturationUserDef3',    %psInfo },
6013    0xe4 => { Name => 'ColorToneUserDef3',     %psInfo },
6014    0xe8 => { Name => 'FilterEffectUserDef3',  %psInfo,
6015        PrintConv => {
6016            0 => 'None',
6017            1 => 'Yellow',
6018            2 => 'Orange',
6019            3 => 'Red',
6020            4 => 'Green',
6021            -559038737 => 'n/a', # (0xdeadbeef)
6022        },
6023    },
6024    0xec => { Name => 'ToningEffectUserDef3',  %psInfo,
6025        PrintConv => {
6026            0 => 'None',
6027            1 => 'Sepia',
6028            2 => 'Blue',
6029            3 => 'Purple',
6030            4 => 'Green',
6031            -559038737 => 'n/a', # (0xdeadbeef)
6032        },
6033    },
6034    # base picture style names:
6035    0xf0 => {
6036        Name => 'UserDef1PictureStyle',
6037        Format => 'int16u',
6038        SeparateTable => 'UserDefStyle',
6039        PrintConv => \%userDefStyles,
6040    },
6041    0xf2 => {
6042        Name => 'UserDef2PictureStyle',
6043        Format => 'int16u',
6044        SeparateTable => 'UserDefStyle',
6045        PrintConv => \%userDefStyles,
6046    },
6047    0xf4 => {
6048        Name => 'UserDef3PictureStyle',
6049        Format => 'int16u',
6050        SeparateTable => 'UserDefStyle',
6051        PrintConv => \%userDefStyles,
6052    },
6053);
6054
6055# Movie information (MakerNotes tag 0x11) (ref PH)
6056%Image::ExifTool::Canon::MovieInfo = (
6057    %binaryDataAttrs,
6058    FORMAT => 'int16u',
6059    FIRST_ENTRY => 1,
6060    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
6061    NOTES => 'Tags written by some Canon cameras when recording video.',
6062    1 => { # (older PowerShot AVI)
6063        Name => 'FrameRate',
6064        RawConv => '$val == 65535 ? undef: $val',
6065        ValueConvInv => '$val > 65535 ? 65535 : $val',
6066    },
6067    2 => { # (older PowerShot AVI)
6068        Name => 'FrameCount',
6069        RawConv => '$val == 65535 ? undef: $val',
6070        ValueConvInv => '$val > 65535 ? 65535 : $val',
6071    },
6072    # 3 - values: 0x0001 (older PowerShot AVI), 0x4004, 0x4005
6073    4 => {
6074        Name => 'FrameCount',
6075        Format => 'int32u',
6076    },
6077    6 => {
6078        Name => 'FrameRate',
6079        Format => 'rational32u',
6080        PrintConv => 'int($val * 1000 + 0.5) / 1000',
6081        PrintConvInv => '$val',
6082    },
6083    # 9/10 - same as 6/7 (FrameRate)
6084    106 => {
6085        Name => 'Duration',
6086        Format => 'int32u',
6087        ValueConv => '$val / 1000',
6088        ValueConvInv => '$val * 1000',
6089        PrintConv => 'ConvertDuration($val)',
6090        PrintConvInv => q{
6091            my @a = ($val =~ /\d+(?:\.\d*)?/g);
6092            $val  = pop(@a) || 0;         # seconds
6093            $val += pop(@a) *   60 if @a; # minutes
6094            $val += pop(@a) * 3600 if @a; # hours
6095            return $val;
6096        },
6097    },
6098    108 => {
6099        Name => 'AudioBitrate',
6100        Groups => { 2 => 'Audio' },
6101        Format => 'int32u',
6102        PrintConv => 'ConvertBitrate($val)',
6103        PrintConvInv => q{
6104            $val =~ /^(\d+(?:\.\d*)?) ?([kMG]?bps)?$/ or return undef;
6105            return $1 * {bps=>1,kbps=>1000,Mbps=>1000000,Gbps=>1000000000}->{$2 || 'bps'};
6106        },
6107    },
6108    110 => {
6109        Name => 'AudioSampleRate',
6110        Groups => { 2 => 'Audio' },
6111        Format => 'int32u',
6112    },
6113    112 => { # (guess)
6114        Name => 'AudioChannels',
6115        Groups => { 2 => 'Audio' },
6116        Format => 'int32u',
6117    },
6118    # 114 - values: 0 (60D), 1 (S95)
6119    116 => {
6120        Name => 'VideoCodec',
6121        Format => 'undef[4]',
6122        # swap bytes if little endian
6123        RawConv => 'GetByteOrder() eq "MM" ? $val : pack("N",unpack("V",$val))',
6124        RawConvInv => 'GetByteOrder() eq "MM" ? $val : pack("N",unpack("V",$val))',
6125    },
6126    # 125 - same as 10
6127);
6128
6129# AF information (MakerNotes tag 0x12) - PH
6130%Image::ExifTool::Canon::AFInfo = (
6131    PROCESS_PROC => \&ProcessSerialData,
6132    VARS => { ID_LABEL => 'Sequence' },
6133    FORMAT => 'int16u',
6134    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6135    NOTES => q{
6136        Auto-focus information used by many older Canon models.  The values in this
6137        record are sequential, and some have variable sizes based on the value of
6138        NumAFPoints (which may be 1,5,7,9,15,45 or 53).  The AFArea coordinates are
6139        given in a system where the image has dimensions given by AFImageWidth and
6140        AFImageHeight, and 0,0 is the image center. The direction of the Y axis
6141        depends on the camera model, with positive Y upwards for EOS models, but
6142        apparently downwards for PowerShot models.
6143    },
6144    0 => {
6145        Name => 'NumAFPoints',
6146    },
6147    1 => {
6148        Name => 'ValidAFPoints',
6149        Notes => 'number of AF points valid in the following information',
6150    },
6151    2 => {
6152        Name => 'CanonImageWidth',
6153        Groups => { 2 => 'Image' },
6154    },
6155    3 => {
6156        Name => 'CanonImageHeight',
6157        Groups => { 2 => 'Image' },
6158    },
6159    4 => {
6160        Name => 'AFImageWidth',
6161        Notes => 'size of image in AF coordinates',
6162    },
6163    5 => 'AFImageHeight',
6164    6 => 'AFAreaWidth',
6165    7 => 'AFAreaHeight',
6166    8 => {
6167        Name => 'AFAreaXPositions',
6168        Format => 'int16s[$val{0}]',
6169    },
6170    9 => {
6171        Name => 'AFAreaYPositions',
6172        Format => 'int16s[$val{0}]',
6173    },
6174    10 => {
6175        Name => 'AFPointsInFocus',
6176        Format => 'int16s[int(($val{0}+15)/16)]',
6177        PrintConv => 'Image::ExifTool::DecodeBits($val, undef, 16)',
6178    },
6179    11 => [
6180        {
6181            Name => 'PrimaryAFPoint',
6182            Condition => q{
6183                $$self{Model} !~ /EOS/ and
6184                (not $$self{AFInfoCount} or $$self{AFInfoCount} != 36)
6185            },
6186        },
6187        {
6188            # (some PowerShot 9-point systems put PrimaryAFPoint after 8 unknown values)
6189            Name => 'Canon_AFInfo_0x000b',
6190            Condition => '$$self{Model} !~ /EOS/',
6191            Format => 'int16u[8]',
6192            Unknown => 1,
6193        },
6194        # (serial processing stops here for EOS cameras)
6195    ],
6196    12 => 'PrimaryAFPoint',
6197);
6198
6199# newer AF information (MakerNotes tag 0x26 and 0x32) - PH (A570IS,1DmkIII,40D and G1XmkII)
6200# (Note: this tag is out of sequence in A570IS maker notes)
6201%Image::ExifTool::Canon::AFInfo2 = (
6202    PROCESS_PROC => \&ProcessSerialData,
6203    VARS => { ID_LABEL => 'Sequence' },
6204    FORMAT => 'int16u',
6205    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6206    NOTES => q{
6207        Newer version of the AFInfo record containing much of the same information
6208        (and coordinate confusion) as the older version.  In this record, NumAFPoints
6209        may be 7, 9, 11, 19, 31, 45 or 61, depending on the camera model.
6210    },
6211    0 => {
6212        Name => 'AFInfoSize',
6213        Unknown => 1, # normally don't print this out
6214    },
6215    1 => {
6216        Name => 'AFAreaMode',
6217        PrintConv => {
6218            0 => 'Off (Manual Focus)',
6219            1 => 'AF Point Expansion (surround)', #PH
6220            2 => 'Single-point AF',
6221            # 3 - n/a
6222            4 => 'Auto', #forum6237 (AiAF on A570IS)
6223            5 => 'Face Detect AF',
6224            6 => 'Face + Tracking', #PH (NC, EOS M, live view)
6225            7 => 'Zone AF', #46
6226            8 => 'AF Point Expansion (4 point)', #46/PH/forum6237
6227            9 => 'Spot AF', #46
6228            10 => 'AF Point Expansion (8 point)', #forum6237
6229            11 => 'Flexizone Multi (49 point)', #PH (NC, EOS M, live view; 750D 49 points)
6230            12 => 'Flexizone Multi (9 point)', #PH (750D, 9 points)
6231            13 => 'Flexizone Single', #PH (EOS M default, live view)
6232            14 => 'Large Zone AF', #PH/forum6237 (7DmkII)
6233        },
6234    },
6235    2 => {
6236        Name => 'NumAFPoints',
6237        RawConv => '$$self{NumAFPoints} = $val', # save for later
6238    },
6239    3 => {
6240        Name => 'ValidAFPoints',
6241        Notes => 'number of AF points valid in the following information',
6242    },
6243    4 => {
6244        Name => 'CanonImageWidth',
6245        Groups => { 2 => 'Image' },
6246    },
6247    5 => {
6248        Name => 'CanonImageHeight',
6249        Groups => { 2 => 'Image' },
6250    },
6251    6 => {
6252        Name => 'AFImageWidth',
6253        Notes => 'size of image in AF coordinates',
6254    },
6255    7 => 'AFImageHeight',
6256    8 => {
6257        Name => 'AFAreaWidths',
6258        Format => 'int16s[$val{2}]',
6259    },
6260    9 => {
6261        Name => 'AFAreaHeights',
6262        Format => 'int16s[$val{2}]',
6263    },
6264    10 => {
6265        Name => 'AFAreaXPositions',
6266        Format => 'int16s[$val{2}]',
6267    },
6268    11 => {
6269        Name => 'AFAreaYPositions',
6270        Format => 'int16s[$val{2}]',
6271    },
6272    12 => {
6273        Name => 'AFPointsInFocus',
6274        Format => 'int16s[int(($val{2}+15)/16)]',
6275        PrintConv => 'Image::ExifTool::DecodeBits($val, undef, 16)',
6276    },
6277    13 => [
6278        {
6279            Name => 'AFPointsSelected',
6280            Condition => '$$self{Model} =~ /EOS/',
6281            Format => 'int16s[int(($val{2}+15)/16)]',
6282            PrintConv => 'Image::ExifTool::DecodeBits($val, undef, 16)',
6283        },
6284        {
6285            Name => 'Canon_AFInfo2_0x000d',
6286            Format => 'int16s[int(($val{2}+15)/16)+1]',
6287            Unknown => 1,
6288        },
6289    ],
6290    14 => {
6291        # usually, but not always, the lowest number AF point in focus
6292        Name => 'PrimaryAFPoint',
6293        Condition => '$$self{Model} !~ /EOS/ and not $$self{AFInfo3}', # (not valid for G1XmkII)
6294    },
6295);
6296
6297# contrast information (MakerNotes tag 0x27) - PH
6298%Image::ExifTool::Canon::ContrastInfo = (
6299    %binaryDataAttrs,
6300    FORMAT => 'int16u',
6301    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6302    4 => {
6303        Name => 'IntelligentContrast',
6304        PrintHex => 1,
6305        PrintConv => {
6306            0x00 => 'Off',
6307            0x08 => 'On',
6308            0xffff => 'n/a',
6309            OTHER => sub {
6310                # DPP shows "On" for any value except 0xffff when bit 0x08 is set
6311                my ($val, $inv) = @_;
6312                if ($inv) {
6313                    $val =~ /(0x[0-9a-f]+)/i or $val =~ /(\d+)/ or return undef;
6314                    return $1;
6315                } else {
6316                    return sprintf("On (0x%.2x)",$val) if $val & 0x08;
6317                    return sprintf("Off (0x%.2x)",$val);
6318                }
6319            },
6320        },
6321    },
6322    # 6 - 0=normal, 257=i-Contrast On
6323);
6324
6325# time information (MakerNotes tag 0x35) - PH (1DX, 5DmkIII)
6326%Image::ExifTool::Canon::TimeInfo = (
6327    %binaryDataAttrs,
6328    FORMAT => 'int32s',
6329    FIRST_ENTRY => 1,
6330    GROUPS => { 0 => 'MakerNotes', 2 => 'Time' },
6331    # 0 - size (16 bytes)
6332    1 => {
6333        Name => 'TimeZone',
6334        PrintConv => 'Image::ExifTool::TimeZoneString($val)',
6335        PrintConvInv => sub {
6336            my $val = shift;
6337            $val =~ /^([-+]?)(\d{1,2}):?(\d{2})$/ or return undef;
6338            return(($1 eq '-' ? -1 : 1) * ($2 * 60 + $3));
6339        },
6340    },
6341    2 => {
6342        Name => 'TimeZoneCity',
6343        PrintConvColumns => 3,
6344        PrintConv => {
6345            # [square brackets] = actual time zone for each city
6346            # (round brackets) = observed time zone values from sample images
6347            # --> unobserved entries have not been confirmed!
6348            0 => 'n/a', # (PowerShot models)
6349            1 => 'Chatham Islands', # [+12:45]
6350            2 => 'Wellington',      # [+12] (+12:00,DST+0)
6351            3 => 'Solomon Islands', # [+11]
6352            4 => 'Sydney',          # [+10] (+11:00,DST+1)
6353            5 => 'Adelaide',        # [+9:30]
6354            6 => 'Tokyo',           # [+9] (+09:00,DST+0)
6355            7 => 'Hong Kong',       # [+8] (+08:00,DST+0)
6356            8 => 'Bangkok',         # [+7] (+08:00,DST+1)
6357            9 => 'Yangon',          # [+6:30]
6358            10 => 'Dhaka',          # [+6] (Canon uses old "Dacca" spelling)
6359            11 => 'Kathmandu',      # [+5:45]
6360            12 => 'Delhi',          # [+5:30]
6361            13 => 'Karachi',        # [+5]
6362            14 => 'Kabul',          # [+4:30]
6363            15 => 'Dubai',          # [+4]
6364            16 => 'Tehran',         # [+3:30]
6365            17 => 'Moscow',         # [+4] (+03:00,DST+0) (! changed to +4 permanent DST in 2011)
6366            18 => 'Cairo',          # [+2]
6367            19 => 'Paris',          # [+1] (+01:10,DST+0; +02:00,DST+1)
6368            20 => 'London',         # [0]  (+00:00,DST+0)
6369            21 => 'Azores',         # [-1]
6370            22 => 'Fernando de Noronha', # [-2]
6371            23 => 'Sao Paulo',      # [-3]
6372            24 => 'Newfoundland',   # [-3:30]
6373            25 => 'Santiago',       # [-4]
6374            26 => 'Caracas',        # [-4:30]
6375            27 => 'New York',       # [-5] (-05:00,DST+0; -04:00,DST+1)
6376            28 => 'Chicago',        # [-6]
6377            29 => 'Denver',         # [-7]
6378            30 => 'Los Angeles',    # [-8] (-08:00,DST+0; -07:00,DST+1)
6379            31 => 'Anchorage',      # [-9]
6380            32 => 'Honolulu',       # [-10]
6381            33 => 'Samoa',          # [+13]
6382            32766 => '(not set)',   #(NC)
6383        },
6384    },
6385    3 => {
6386        Name => 'DaylightSavings',
6387        PrintConv => {
6388            0 => 'Off',
6389            60 => 'On',
6390        },
6391    },
6392);
6393
6394# my color mode information (MakerNotes tag 0x1d) - PH (A570IS)
6395%Image::ExifTool::Canon::MyColors = (
6396    %binaryDataAttrs,
6397    FORMAT => 'int16u',
6398    FIRST_ENTRY => 0,
6399    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
6400    0x02 => {
6401        Name => 'MyColorMode',
6402        PrintConvColumns => 2,
6403        PrintConv => {
6404            0 => 'Off',
6405            1 => 'Positive Film', #15 (SD600)
6406            2 => 'Light Skin Tone', #15
6407            3 => 'Dark Skin Tone', #15
6408            4 => 'Vivid Blue', #15
6409            5 => 'Vivid Green', #15
6410            6 => 'Vivid Red', #15
6411            7 => 'Color Accent', #15 (A610) (NC)
6412            8 => 'Color Swap', #15 (A610)
6413            9 => 'Custom',
6414            12 => 'Vivid',
6415            13 => 'Neutral',
6416            14 => 'Sepia',
6417            15 => 'B&W',
6418        },
6419    },
6420);
6421
6422# face detect information (MakerNotes tag 0x24) - PH (A570IS)
6423%Image::ExifTool::Canon::FaceDetect1 = (
6424    %binaryDataAttrs,
6425    FORMAT => 'int16u',
6426    FIRST_ENTRY => 0,
6427    DATAMEMBER => [ 0x02 ],
6428    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
6429    0x02 => {
6430        Name => 'FacesDetected',
6431        DataMember => 'FacesDetected',
6432        RawConv => '$$self{FacesDetected} = $val',
6433    },
6434    0x03 => {
6435        Name => 'FaceDetectFrameSize',
6436        Format => 'int16u[2]',
6437    },
6438    0x08 => {
6439        Name => 'Face1Position',
6440        Format => 'int16s[2]',
6441        RawConv => '$$self{FacesDetected} < 1 ? undef: $val',
6442        Notes => q{
6443            X-Y coordinates for the center of each face in the Face Detect frame at the
6444            time of focus lock. "0 0" is the center, and positive X and Y are to the
6445            right and downwards respectively
6446        },
6447    },
6448    0x0a => {
6449        Name => 'Face2Position',
6450        Format => 'int16s[2]',
6451        RawConv => '$$self{FacesDetected} < 2 ? undef : $val',
6452    },
6453    0x0c => {
6454        Name => 'Face3Position',
6455        Format => 'int16s[2]',
6456        RawConv => '$$self{FacesDetected} < 3 ? undef : $val',
6457    },
6458    0x0e => {
6459        Name => 'Face4Position',
6460        Format => 'int16s[2]',
6461        RawConv => '$$self{FacesDetected} < 4 ? undef : $val',
6462    },
6463    0x10 => {
6464        Name => 'Face5Position',
6465        Format => 'int16s[2]',
6466        RawConv => '$$self{FacesDetected} < 5 ? undef : $val',
6467    },
6468    0x12 => {
6469        Name => 'Face6Position',
6470        Format => 'int16s[2]',
6471        RawConv => '$$self{FacesDetected} < 6 ? undef : $val',
6472    },
6473    0x14 => {
6474        Name => 'Face7Position',
6475        Format => 'int16s[2]',
6476        RawConv => '$$self{FacesDetected} < 7 ? undef : $val',
6477    },
6478    0x16 => {
6479        Name => 'Face8Position',
6480        Format => 'int16s[2]',
6481        RawConv => '$$self{FacesDetected} < 8 ? undef : $val',
6482    },
6483    0x18 => {
6484        Name => 'Face9Position',
6485        Format => 'int16s[2]',
6486        RawConv => '$$self{FacesDetected} < 9 ? undef : $val',
6487    },
6488);
6489
6490# more face detect information (MakerNotes tag 0x25) - PH (A570IS)
6491%Image::ExifTool::Canon::FaceDetect2 = (
6492    %binaryDataAttrs,
6493    FORMAT => 'int8u',
6494    FIRST_ENTRY => 0,
6495    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
6496    0x01 => 'FaceWidth',
6497    0x02 => 'FacesDetected',
6498);
6499
6500# G9 white balance information (MakerNotes tag 0x29) (ref IB)
6501%Image::ExifTool::Canon::WBInfo = (
6502    %binaryDataAttrs,
6503    NOTES => 'WB tags for the Canon G9.',
6504    FORMAT => 'int32u',
6505    FIRST_ENTRY => 1,
6506    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
6507    0x02 => { Name => 'WB_GRGBLevelsAuto',        Format => 'int32s[4]' },
6508    0x0a => { Name => 'WB_GRGBLevelsDaylight',    Format => 'int32s[4]' },
6509    0x12 => { Name => 'WB_GRGBLevelsCloudy',      Format => 'int32s[4]' },
6510    0x1a => { Name => 'WB_GRGBLevelsTungsten',    Format => 'int32s[4]' },
6511    0x22 => { Name => 'WB_GRGBLevelsFluorescent', Format => 'int32s[4]' },
6512    0x2a => { Name => 'WB_GRGBLevelsFluorHigh',   Format => 'int32s[4]' },
6513    0x32 => { Name => 'WB_GRGBLevelsFlash',       Format => 'int32s[4]' },
6514    0x3a => { Name => 'WB_GRGBLevelsUnderwater',  Format => 'int32s[4]' },
6515    0x42 => { Name => 'WB_GRGBLevelsCustom1',     Format => 'int32s[4]' },
6516    0x4a => { Name => 'WB_GRGBLevelsCustom2',     Format => 'int32s[4]' },
6517);
6518
6519# yet more face detect information (MakerNotes tag 0x2f) - PH (G12)
6520%Image::ExifTool::Canon::FaceDetect3 = (
6521    %binaryDataAttrs,
6522    FORMAT => 'int16u',
6523    FIRST_ENTRY => 1,
6524    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
6525    # 0 - size (34 bytes)
6526    # 1 - 1=4:3/16:9,2=1:1/3:2/4:5
6527    # 2 - normally 1 if faces detected, but sometimes 0 (maybe if face wasn't in captured image?)
6528    3 => 'FacesDetected',
6529    # 4 - 240=4:3/4:5/1:1,180=16:9,212=3:2
6530);
6531
6532# File number information (MakerNotes tag 0x93)
6533%Image::ExifTool::Canon::FileInfo = (
6534    %binaryDataAttrs,
6535    FORMAT => 'int16s',
6536    FIRST_ENTRY => 1,
6537    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
6538    DATAMEMBER => [ 20 ],
6539    1 => [
6540        { #5
6541            Name => 'FileNumber',
6542            Condition => '$$self{Model} =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
6543            Format => 'int32u',
6544            # Thanks to Juha Eskelinen for figuring this out:
6545            # [this is an odd bit mapping -- it looks like the file number exists as
6546            # a 16-bit integer containing the high bits, followed by an 8-bit integer
6547            # with the low bits.  But it is more convenient to have this in a single
6548            # word, so some bit manipulations are necessary... - PH]
6549            # The bit pattern of the 32-bit word is:
6550            #   31....24 23....16 15.....8 7......0
6551            #   00000000 ffffffff DDDDDDDD ddFFFFFF
6552            #     0 = zero bits (not part of the file number?)
6553            #     f/F = low/high bits of file number
6554            #     d/D = low/high bits of directory number
6555            # The directory and file number are then converted into decimal
6556            # and separated by a '-' to give the file number used in the 20D
6557            ValueConv => '(($val&0xffc0)>>6)*10000+(($val>>16)&0xff)+(($val&0x3f)<<8)',
6558            ValueConvInv => q{
6559                my $d = int($val/10000);
6560                my $f = $val - $d * 10000;
6561                return (($d<<6) & 0xffc0) + (($f & 0xff)<<16) + (($f>>8) & 0x3f);
6562            },
6563            PrintConv => '$_=$val,s/(\d+)(\d{4})/$1-$2/,$_',
6564            PrintConvInv => '$val=~s/-//g;$val',
6565        },
6566        { #16
6567            Name => 'FileNumber',
6568            Condition => '$$self{Model} =~ /\b(30D|400D|REBEL XTi|Kiss Digital X|K236)\b/',
6569            Format => 'int32u',
6570            Notes => q{
6571                the location of the upper 4 bits of the directory number is a mystery for
6572                the EOS 30D, so the reported directory number will be incorrect for original
6573                images with a directory number of 164 or greater
6574            },
6575            # Thanks to Emil Sit for figuring this out:
6576            # [more insane bit maniplations like the 20D/350D above, but this time we
6577            # appear to have lost the upper 4 bits of the directory number (this was
6578            # verified through tests with directory numbers 100, 222, 801 and 999) - PH]
6579            # The bit pattern for the 30D is: (see 20D notes above for more information)
6580            #   31....24 23....16 15.....8 7......0
6581            #   00000000 ffff0000 ddddddFF FFFFFFFF
6582            # [NOTE: the 4 high order directory bits don't appear in this record, but
6583            # I have chosen to write them into bits 16-19 since these 4 zero bits look
6584            # very suspicious, and are a convenient place to store this information - PH]
6585            ValueConv  => q{
6586                my $d = ($val & 0xffc00) >> 10;
6587                # we know there are missing bits if directory number is < 100
6588                $d += 0x40 while $d < 100;  # (repair the damage as best we can)
6589                return $d*10000 + (($val&0x3ff)<<4) + (($val>>20)&0x0f);
6590            },
6591            ValueConvInv => q{
6592                my $d = int($val/10000);
6593                my $f = $val - $d * 10000;
6594                return ($d << 10) + (($f>>4)&0x3ff) + (($f&0x0f)<<20);
6595            },
6596            PrintConv => '$_=$val,s/(\d+)(\d{4})/$1-$2/,$_',
6597            PrintConvInv => '$val=~s/-//g;$val',
6598        },
6599        { #7 (1D, 1Ds)
6600            Name => 'ShutterCount',
6601            Condition => 'GetByteOrder() eq "MM"',
6602            Format => 'int32u',
6603        },
6604        { #7 (1DmkII, 1DSmkII, 1DSmkIIN)
6605            Name => 'ShutterCount',
6606            # ref http://www.luminous-landscape.com/forum/index.php?topic=36469 :
6607            Notes => q{
6608                there are reports that the ShutterCount changed when loading a settings file
6609                on the 1DSmkII
6610            },
6611            Condition => '$$self{Model} =~ /\b1Ds? Mark II\b/',
6612            Format => 'int32u',
6613            ValueConv => '($val>>16)|(($val&0xffff)<<16)',
6614            ValueConvInv => '($val>>16)|(($val&0xffff)<<16)',
6615        },
6616        # 5D gives a single byte value (unknown)
6617        # 40D stores all zeros
6618    ],
6619    3 => { #PH
6620        Name => 'BracketMode',
6621        PrintConv => {
6622            0 => 'Off',
6623            1 => 'AEB',
6624            2 => 'FEB',
6625            3 => 'ISO',
6626            4 => 'WB',
6627        },
6628    },
6629    4 => 'BracketValue', #PH
6630    5 => 'BracketShotNumber', #PH
6631    6 => { #PH
6632        Name => 'RawJpgQuality',
6633        RawConv => '$val<=0 ? undef : $val',
6634        PrintConv => \%canonQuality,
6635    },
6636    7 => { #PH
6637        Name => 'RawJpgSize',
6638        RawConv => '$val<0 ? undef : $val',
6639        PrintConv => \%canonImageSize,
6640    },
6641    8 => { #PH
6642        Name => 'LongExposureNoiseReduction2',
6643        Notes => q{
6644            for some modules this gives the long exposure noise reduction applied to the
6645            image, but for other models this just reflects the setting independent of
6646            whether or not it was applied
6647        },
6648        RawConv => '$val<0 ? undef : $val',
6649        PrintConv => {
6650            0 => 'Off',
6651            1 => 'On (1D)',
6652            3 => 'On',
6653            4 => 'Auto',
6654        },
6655    },
6656    9 => { #PH
6657        Name => 'WBBracketMode',
6658        PrintConv => {
6659            0 => 'Off',
6660            1 => 'On (shift AB)',
6661            2 => 'On (shift GM)',
6662        },
6663    },
6664    12 => 'WBBracketValueAB', #PH
6665    13 => 'WBBracketValueGM', #PH
6666    14 => { #PH
6667        Name => 'FilterEffect',
6668        RawConv => '$val==-1 ? undef : $val',
6669        PrintConv => {
6670            0 => 'None',
6671            1 => 'Yellow',
6672            2 => 'Orange',
6673            3 => 'Red',
6674            4 => 'Green',
6675        },
6676    },
6677    15 => { #PH
6678        Name => 'ToningEffect',
6679        RawConv => '$val==-1 ? undef : $val',
6680        PrintConv => {
6681            0 => 'None',
6682            1 => 'Sepia',
6683            2 => 'Blue',
6684            3 => 'Purple',
6685            4 => 'Green',
6686        },
6687    },
6688    16 => { #PH
6689        %ciMacroMagnification,
6690        # MP-E 65mm on 5DmkII: 44=5x,52~=3.9x,56~=3.3x,62~=2.6x,75=1x
6691        # ME-E 65mm on 40D/450D: 72 for all samples (not valid)
6692        Condition => q{
6693            $$self{LensType} and $$self{LensType} == 124 and
6694            $$self{Model} !~ /\b(40D|450D|REBEL XSi|Kiss X2)\b/
6695        },
6696        Notes => q{
6697            currently decoded only for the MP-E 65mm f/2.8 1-5x Macro Photo, and not
6698            valid for all camera models
6699        },
6700    },
6701    # 17 - values: 0, 3, 4
6702    # 18 - same as LiveViewShooting for all my samples (5DmkII, 50D) - PH
6703    19 => { #PH
6704        # Note: this value is not displayed by Canon ImageBrowser for the following
6705        # models with the live view feature:  1DmkIII, 1DSmkIII, 40D, 450D, 1000D
6706        # (this tag could be valid only for some firmware versions:
6707        # http://www.breezesys.com/forum/showthread.php?p=16980)
6708        Name => 'LiveViewShooting',
6709        PrintConv => \%offOn,
6710    },
6711    20 => { #47
6712        Name => 'FocusDistanceUpper',
6713        DataMember => 'FocusDistanceUpper2',
6714        Format => 'int16u',
6715        RawConv => '($$self{FocusDistanceUpper2} = $val) || undef',
6716        ValueConv => '$val / 100',
6717        ValueConvInv => '$val * 100',
6718        PrintConv => '$val > 655.345 ? "inf" : "$val m"',
6719        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
6720    },
6721    21 => { #47
6722        Name => 'FocusDistanceLower',
6723        Condition => '$$self{FocusDistanceUpper2}',
6724        Format => 'int16u',
6725        ValueConv => '$val / 100',
6726        ValueConvInv => '$val * 100',
6727        PrintConv => '$val > 655.345 ? "inf" : "$val m"',
6728        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
6729    },
6730    # 22 - values: 0, 1
6731    # 23 - values: 0, 21, 22
6732    25 => { #PH
6733        Name => 'FlashExposureLock',
6734        PrintConv => \%offOn,
6735    },
6736    0x3d => { #IB
6737        Name => 'RFLensType',
6738        Format => 'int16u',
6739        PrintConv => {
6740            0 => 'n/a',
6741            257 => 'Canon RF 50mm F1.2L USM',
6742            258 => 'Canon RF 24-105mm F4L IS USM',
6743            259 => 'Canon RF 28-70mm F2L USM',
6744            260 => 'Canon RF 35mm F1.8 MACRO IS STM',
6745            261 => 'Canon RF 85mm F1.2L USM',
6746            262 => 'Canon RF 85mm F1.2L USM DS',
6747            263 => 'Canon RF 24-70mm F2.8L IS USM',
6748            264 => 'Canon RF 15-35mm F2.8L IS USM',
6749            265 => 'Canon RF 24-240mm F4-6.3 IS USM',
6750            266 => 'Canon RF 70-200mm F2.8L IS USM',
6751            267 => 'Canon RF 85mm F2 MACRO IS STM',
6752            268 => 'Canon RF 600mm F11 IS STM',
6753            269 => 'Canon RF 600mm F11 IS STM + RF1.4x',
6754            270 => 'Canon RF 600mm F11 IS STM + RF2x',
6755            271 => 'Canon RF 800mm F11 IS STM',
6756            272 => 'Canon RF 800mm F11 IS STM + RF1.4x',
6757            273 => 'Canon RF 800mm F11 IS STM + RF2x',
6758            274 => 'Canon RF 24-105mm F4-7.1 IS STM',
6759            275 => 'Canon RF 100-500mm F4.5-7.1L IS USM',
6760            276 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF1.4x',
6761            277 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
6762            278 => 'Canon RF 70-200mm F4L IS USM', #42
6763            280 => 'Canon RF 50mm F1.8 STM', #42
6764            # Note: add new RF lenses to %canonLensTypes with ID 61182
6765        },
6766    },
6767);
6768
6769# Internal serial number information (MakerNotes tag 0x96) (ref PH)
6770%Image::ExifTool::Canon::SerialInfo = (
6771    %binaryDataAttrs,
6772    FIRST_ENTRY => 0,
6773    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6774    9 => {
6775        Name => 'InternalSerialNumber',
6776        Format => 'string',
6777    },
6778);
6779
6780# Cropping information (MakerNotes tag 0x98) (ref PH)
6781%Image::ExifTool::Canon::CropInfo = (
6782    %binaryDataAttrs,
6783    FORMAT => 'int16u',
6784    FIRST_ENTRY => 0,
6785    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6786    0 => 'CropLeftMargin',  # (NC, may be right)
6787    1 => 'CropRightMargin',
6788    2 => 'CropTopMargin',   # (NC, may be bottom)
6789    3 => 'CropBottomMargin',
6790);
6791
6792# Aspect ratio information (MakerNotes tag 0x9a) (ref PH)
6793%Image::ExifTool::Canon::AspectInfo = (
6794    %binaryDataAttrs,
6795    FORMAT => 'int32u',
6796    FIRST_ENTRY => 0,
6797    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6798    0 => {
6799        Name => 'AspectRatio',
6800        PrintConv => {
6801            0 => '3:2',
6802            1 => '1:1',
6803            2 => '4:3',
6804            7 => '16:9',
6805            8 => '4:5',
6806            12 => '3:2 (APS-H crop)', #IB
6807            13 => '3:2 (APS-C crop)', #IB
6808        },
6809    },
6810    # (could use better names for these, or the Crop tags above, or both)
6811    1 => 'CroppedImageWidth',
6812    2 => 'CroppedImageHeight',
6813    3 => 'CroppedImageLeft', #forum4138
6814    4 => 'CroppedImageTop', #ditto
6815);
6816
6817# Color information (MakerNotes tag 0xa0)
6818%Image::ExifTool::Canon::Processing = (
6819    %binaryDataAttrs,
6820    FORMAT => 'int16s',
6821    FIRST_ENTRY => 1,
6822    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
6823    1 => { #PH
6824        Name => 'ToneCurve',
6825        PrintConv => {
6826            0 => 'Standard',
6827            1 => 'Manual',
6828            2 => 'Custom',
6829        },
6830    },
6831    2 => { #12
6832        Name => 'Sharpness',
6833        Notes => 'all models except the 20D and 350D',
6834        Condition => '$$self{Model} !~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
6835        Priority => 0,  # (maybe not as reliable as other sharpness values)
6836    },
6837    3 => { #PH
6838        Name => 'SharpnessFrequency', # PatternSharpness?
6839        PrintConvColumns => 2,
6840        PrintConv => {
6841            0 => 'n/a',
6842            1 => 'Lowest',
6843            2 => 'Low',
6844            3 => 'Standard',
6845            4 => 'High',
6846            5 => 'Highest',
6847        },
6848    },
6849    4 => 'SensorRedLevel', #PH
6850    5 => 'SensorBlueLevel', #PH
6851    6 => 'WhiteBalanceRed', #PH
6852    7 => 'WhiteBalanceBlue', #PH
6853    8 => { #PH
6854        Name => 'WhiteBalance',
6855        RawConv => '$val < 0 ? undef : $val',
6856        PrintConv => \%canonWhiteBalance,
6857        SeparateTable => 1,
6858    },
6859    9 => 'ColorTemperature', #6
6860    10 => { #12
6861        Name => 'PictureStyle',
6862        Flags => ['PrintHex','SeparateTable'],
6863        PrintConv => \%pictureStyles,
6864    },
6865    11 => { #PH
6866        Name => 'DigitalGain',
6867        ValueConv => '$val / 10',
6868        ValueConvInv => '$val * 10',
6869    },
6870    12 => { #PH
6871        Name => 'WBShiftAB',
6872        Notes => 'positive is a shift toward amber',
6873    },
6874    13 => { #PH
6875        Name => 'WBShiftGM',
6876        Notes => 'positive is a shift toward green',
6877    },
6878);
6879
6880# Color balance information (MakerNotes tag 0xa9) (ref PH)
6881%Image::ExifTool::Canon::ColorBalance = (
6882    %binaryDataAttrs,
6883    NOTES => 'These tags are used by the 10D and 300D.',
6884    FORMAT => 'int16s',
6885    FIRST_ENTRY => 0,
6886    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6887    # red,green1,green2,blue (ref 2)
6888    1  => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
6889    5  => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
6890    9  => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
6891    13 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
6892    17 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
6893    21 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
6894    25 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
6895    29 => [{
6896        Name => 'WB_RGGBLevelsCustom',
6897        Notes => 'black levels for the D60',
6898        Condition => '$$self{Model} !~ /EOS D60\b/',
6899        Format => 'int16s[4]',
6900    },{ # (black levels for D60, ref IB)
6901        Name => 'BlackLevels',
6902        Format => 'int16s[4]',
6903    }],
6904    33 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
6905    37 => { Name => 'WB_RGGBBlackLevels',      Format => 'int16s[4]' }, #IB
6906);
6907
6908# Measured color levels (MakerNotes tag 0xaa) (ref 37)
6909%Image::ExifTool::Canon::MeasuredColor = (
6910    %binaryDataAttrs,
6911    FORMAT => 'int16u',
6912    FIRST_ENTRY => 1,
6913    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6914    1 => {
6915        # this is basically the inverse of WB_RGGBLevelsMeasured (ref 37)
6916        Name => 'MeasuredRGGB',
6917        Format => 'int16u[4]',
6918    },
6919    # 5 - observed values: 0, 1 - PH
6920);
6921
6922# Flags information (MakerNotes tag 0xb0) (ref PH)
6923%Image::ExifTool::Canon::Flags = (
6924    %binaryDataAttrs,
6925    FORMAT => 'int16s',
6926    FIRST_ENTRY => 1,
6927    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6928    1 => 'ModifiedParamFlag',
6929);
6930
6931# Modified information (MakerNotes tag 0xb1) (ref PH)
6932%Image::ExifTool::Canon::ModifiedInfo = (
6933    %binaryDataAttrs,
6934    FORMAT => 'int16s',
6935    FIRST_ENTRY => 1,
6936    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6937    1 => {
6938        Name => 'ModifiedToneCurve',
6939        PrintConv => {
6940            0 => 'Standard',
6941            1 => 'Manual',
6942            2 => 'Custom',
6943        },
6944    },
6945    2 => {
6946        Name => 'ModifiedSharpness',
6947        Notes => '1D and 5D only',
6948        Condition => '$$self{Model} =~ /\b(1D|5D)/',
6949    },
6950    3 => {
6951        Name => 'ModifiedSharpnessFreq', # ModifiedPatternSharpness?
6952        PrintConv => {
6953            0 => 'n/a',
6954            1 => 'Lowest',
6955            2 => 'Low',
6956            3 => 'Standard',
6957            4 => 'High',
6958            5 => 'Highest',
6959        },
6960    },
6961    4 => 'ModifiedSensorRedLevel',
6962    5 => 'ModifiedSensorBlueLevel',
6963    6 => 'ModifiedWhiteBalanceRed',
6964    7 => 'ModifiedWhiteBalanceBlue',
6965    8 => {
6966        Name => 'ModifiedWhiteBalance',
6967        PrintConv => \%canonWhiteBalance,
6968        SeparateTable => 'WhiteBalance',
6969    },
6970    9 => 'ModifiedColorTemp',
6971    10 => {
6972        Name => 'ModifiedPictureStyle',
6973        PrintHex => 1,
6974        SeparateTable => 'PictureStyle',
6975        PrintConv => \%pictureStyles,
6976    },
6977    11 => {
6978        Name => 'ModifiedDigitalGain',
6979        ValueConv => '$val / 10',
6980        ValueConvInv => '$val * 10',
6981    },
6982);
6983
6984# Preview image information (MakerNotes tag 0xb6)
6985# - The 300D writes a 1536x1024 preview image that is accessed
6986#   through this information - decoded by PH 12/14/03
6987%Image::ExifTool::Canon::PreviewImageInfo = (
6988    %binaryDataAttrs,
6989    FORMAT => 'int32u',
6990    FIRST_ENTRY => 1,
6991    IS_OFFSET => [ 5 ],   # tag 5 is 'IsOffset'
6992    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
6993# the size of the preview block in 2-byte increments
6994#    0 => {
6995#        Name => 'PreviewImageInfoWords',
6996#    },
6997    1 => {
6998        Name => 'PreviewQuality',
6999        PrintConv => \%canonQuality,
7000    },
7001    2 => {
7002        Name => 'PreviewImageLength',
7003        OffsetPair => 5,   # point to associated offset
7004        DataTag => 'PreviewImage',
7005        WriteGroup => 'MakerNotes',
7006        Protected => 2,
7007    },
7008    3 => 'PreviewImageWidth',
7009    4 => 'PreviewImageHeight',
7010    5 => {
7011        Name => 'PreviewImageStart',
7012        Flags => 'IsOffset',
7013        OffsetPair => 2,  # associated byte count tagID
7014        DataTag => 'PreviewImage',
7015        WriteGroup => 'MakerNotes',
7016        Protected => 2,
7017    },
7018    # NOTE: The size of the PreviewImageInfo structure is incorrectly
7019    # written as 48 bytes (Count=12, Format=int32u), but only the first
7020    # 6 int32u values actually exist
7021);
7022
7023# Sensor information (MakerNotes tag 0xe0) (ref 12)
7024%Image::ExifTool::Canon::SensorInfo = (
7025    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
7026    FORMAT => 'int16s',
7027    FIRST_ENTRY => 1,
7028    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
7029    # Note: Don't make these writable because it confuses Canon decoding software
7030    # if these are changed
7031    1 => 'SensorWidth',
7032    2 => 'SensorHeight',
7033    5 => 'SensorLeftBorder', #2
7034    6 => 'SensorTopBorder', #2
7035    7 => 'SensorRightBorder', #2
7036    8 => 'SensorBottomBorder', #2
7037    9 => { #22
7038        Name => 'BlackMaskLeftBorder',
7039        Notes => q{
7040            coordinates for the area to the left or right of the image used to calculate
7041            the average black level
7042        },
7043    },
7044    10 => 'BlackMaskTopBorder', #22
7045    11 => 'BlackMaskRightBorder', #22
7046    12 => 'BlackMaskBottomBorder', #22
7047);
7048
7049# Color data (MakerNotes tag 0x4001, count=582) (ref 12)
7050%Image::ExifTool::Canon::ColorData1 = (
7051    %binaryDataAttrs,
7052    NOTES => 'These tags are used by the 20D and 350D.',
7053    FORMAT => 'int16s',
7054    FIRST_ENTRY => 0,
7055    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7056    IS_SUBDIR => [ 0x4b ],
7057    # 0x00: size of record in bytes - PH
7058    # (dcraw 8.81 uses index 0x19 for WB)
7059    0x19 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16s[4]' },
7060    0x1d => 'ColorTempAsShot',
7061    0x1e => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16s[4]' },
7062    0x22 => 'ColorTempAuto',
7063    0x23 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16s[4]' },
7064    0x27 => 'ColorTempDaylight',
7065    0x28 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16s[4]' },
7066    0x2c => 'ColorTempShade',
7067    0x2d => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16s[4]' },
7068    0x31 => 'ColorTempCloudy',
7069    0x32 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16s[4]' },
7070    0x36 => 'ColorTempTungsten',
7071    0x37 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16s[4]' },
7072    0x3b => 'ColorTempFluorescent',
7073    0x3c => { Name => 'WB_RGGBLevelsFlash',       Format => 'int16s[4]' },
7074    0x40 => 'ColorTempFlash',
7075    0x41 => { Name => 'WB_RGGBLevelsCustom1',     Format => 'int16s[4]' },
7076    0x45 => 'ColorTempCustom1',
7077    0x46 => { Name => 'WB_RGGBLevelsCustom2',     Format => 'int16s[4]' },
7078    0x4a => 'ColorTempCustom2',
7079    0x4b => { #PH
7080        Name => 'ColorCalib',
7081        Format => 'undef[120]',
7082        Unknown => 1, # (all tags are unknown, so we can avoid processing entire directory)
7083        Notes => 'A, B, C, Temperature',
7084        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
7085    },
7086);
7087
7088# Color data (MakerNotes tag 0x4001, count=653) (ref 12)
7089%Image::ExifTool::Canon::ColorData2 = (
7090    %binaryDataAttrs,
7091    NOTES => 'These tags are used by the 1DmkII and 1DSmkII.',
7092    FORMAT => 'int16s',
7093    FIRST_ENTRY => 0,
7094    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7095    IS_SUBDIR => [ 0xa4 ],
7096    0x18 => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
7097    0x1c => 'ColorTempAuto',
7098    0x1d => { Name => 'WB_RGGBLevelsUnknown',    Format => 'int16s[4]', Unknown => 1 },
7099    0x21 => { Name => 'ColorTempUnknown', Unknown => 1 },
7100    # (dcraw 8.81 uses index 0x22 for WB)
7101    0x22 => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
7102    0x26 => 'ColorTempAsShot',
7103    0x27 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
7104    0x2b => 'ColorTempDaylight',
7105    0x2c => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
7106    0x30 => 'ColorTempShade',
7107    0x31 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
7108    0x35 => 'ColorTempCloudy',
7109    0x36 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
7110    0x3a => 'ColorTempTungsten',
7111    0x3b => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
7112    0x3f => 'ColorTempFluorescent',
7113    0x40 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
7114    0x44 => 'ColorTempKelvin',
7115    0x45 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
7116    0x49 => 'ColorTempFlash',
7117    0x4a => { Name => 'WB_RGGBLevelsUnknown2',   Format => 'int16s[4]', Unknown => 1 },
7118    0x4e => { Name => 'ColorTempUnknown2', Unknown => 1 },
7119    0x4f => { Name => 'WB_RGGBLevelsUnknown3',   Format => 'int16s[4]', Unknown => 1 },
7120    0x53 => { Name => 'ColorTempUnknown3', Unknown => 1 },
7121    0x54 => { Name => 'WB_RGGBLevelsUnknown4',   Format => 'int16s[4]', Unknown => 1 },
7122    0x58 => { Name => 'ColorTempUnknown4', Unknown => 1 },
7123    0x59 => { Name => 'WB_RGGBLevelsUnknown5',   Format => 'int16s[4]', Unknown => 1 },
7124    0x5d => { Name => 'ColorTempUnknown5', Unknown => 1 },
7125    0x5e => { Name => 'WB_RGGBLevelsUnknown6',   Format => 'int16s[4]', Unknown => 1 },
7126    0x62 => { Name => 'ColorTempUnknown6', Unknown => 1 },
7127    0x63 => { Name => 'WB_RGGBLevelsUnknown7',   Format => 'int16s[4]', Unknown => 1 },
7128    0x67 => { Name => 'ColorTempUnknown7', Unknown => 1 },
7129    0x68 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16s[4]', Unknown => 1 },
7130    0x6c => { Name => 'ColorTempUnknown8', Unknown => 1 },
7131    0x6d => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16s[4]', Unknown => 1 },
7132    0x71 => { Name => 'ColorTempUnknown9', Unknown => 1 },
7133    0x72 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
7134    0x76 => { Name => 'ColorTempUnknown10', Unknown => 1 },
7135    0x77 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
7136    0x7b => { Name => 'ColorTempUnknown11', Unknown => 1 },
7137    0x7c => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
7138    0x80 => { Name => 'ColorTempUnknown12', Unknown => 1 },
7139    0x81 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
7140    0x85 => { Name => 'ColorTempUnknown13', Unknown => 1 },
7141    0x86 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
7142    0x8a => { Name => 'ColorTempUnknown14', Unknown => 1 },
7143    0x8b => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
7144    0x8f => { Name => 'ColorTempUnknown15', Unknown => 1 },
7145    0x90 => { Name => 'WB_RGGBLevelsPC1',        Format => 'int16s[4]' },
7146    0x94 => 'ColorTempPC1',
7147    0x95 => { Name => 'WB_RGGBLevelsPC2',        Format => 'int16s[4]' },
7148    0x99 => 'ColorTempPC2',
7149    0x9a => { Name => 'WB_RGGBLevelsPC3',        Format => 'int16s[4]' },
7150    0x9e => 'ColorTempPC3',
7151    0x9f => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
7152    0xa3 => { Name => 'ColorTempUnknown16', Unknown => 1 },
7153    0xa4 => { #PH
7154        Name => 'ColorCalib',
7155        Format => 'undef[120]',
7156        Unknown => 1,
7157        Notes => 'A, B, C, Temperature',
7158        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
7159    },
7160    0x26a => { #PH
7161        Name => 'RawMeasuredRGGB',
7162        Format => 'int32u[4]',
7163        Notes => 'raw MeasuredRGGB values, before normalization',
7164        # swap words because the word ordering is big-endian, opposite to the byte ordering
7165        ValueConv => \&SwapWords,
7166        ValueConvInv => \&SwapWords,
7167    },
7168);
7169
7170# Color data (MakerNotes tag 0x4001, count=796) (ref 12)
7171%Image::ExifTool::Canon::ColorData3 = (
7172    %binaryDataAttrs,
7173    NOTES => 'These tags are used by the 1DmkIIN, 5D, 30D and 400D.',
7174    FORMAT => 'int16s',
7175    FIRST_ENTRY => 0,
7176    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7177    IS_SUBDIR => [ 0x85 ],
7178    0x00 => { #PH
7179        Name => 'ColorDataVersion',
7180        PrintConv => {
7181            1 => '1 (1DmkIIN/5D/30D/400D)',
7182        },
7183    },
7184    # 0x01-0x3e: RGGB coefficients, apparently specific to the
7185    # individual camera and possibly used for color calibration (ref 37)
7186    # (dcraw 8.81 uses index 0x3f for WB)
7187    0x3f => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16s[4]' },
7188    0x43 => 'ColorTempAsShot',
7189    0x44 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16s[4]' },
7190    0x48 => 'ColorTempAuto',
7191    # not sure exactly what 'Measured' values mean...
7192    0x49 => { Name => 'WB_RGGBLevelsMeasured',    Format => 'int16s[4]' },
7193    0x4d => 'ColorTempMeasured',
7194    0x4e => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16s[4]' },
7195    0x52 => 'ColorTempDaylight',
7196    0x53 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16s[4]' },
7197    0x57 => 'ColorTempShade',
7198    0x58 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16s[4]' },
7199    0x5c => 'ColorTempCloudy',
7200    0x5d => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16s[4]' },
7201    0x61 => 'ColorTempTungsten',
7202    0x62 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16s[4]' },
7203    0x66 => 'ColorTempFluorescent',
7204    0x67 => { Name => 'WB_RGGBLevelsKelvin',      Format => 'int16s[4]' },
7205    0x6b => 'ColorTempKelvin',
7206    0x6c => { Name => 'WB_RGGBLevelsFlash',       Format => 'int16s[4]' },
7207    0x70 => 'ColorTempFlash',
7208    0x71 => { Name => 'WB_RGGBLevelsPC1',         Format => 'int16s[4]' },
7209    0x75 => 'ColorTempPC1',
7210    0x76 => { Name => 'WB_RGGBLevelsPC2',         Format => 'int16s[4]' },
7211    0x7a => 'ColorTempPC2',
7212    0x7b => { Name => 'WB_RGGBLevelsPC3',         Format => 'int16s[4]' },
7213    0x7f => 'ColorTempPC3',
7214    0x80 => { Name => 'WB_RGGBLevelsCustom',      Format => 'int16s[4]' },
7215    0x84 => 'ColorTempCustom',
7216    0x85 => { #37
7217        Name => 'ColorCalib',
7218        Format => 'undef[120]',
7219        Unknown => 1,
7220        Notes => 'B, C, A, Temperature',
7221        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
7222    },
7223    0xc4 => { #IB
7224        Name => 'PerChannelBlackLevel',
7225        Format => 'int16u[4]',
7226    },
7227    # 0xc8-0x1c7: some sort of color table (ref 37)
7228    0x248 => { #37
7229        Name => 'FlashOutput',
7230        ValueConv => '$val >= 255 ? 255 : exp(($val-200)/16*log(2))',
7231        ValueConvInv => '$val == 255 ? 255 : 200 + log($val)*16/log(2)',
7232        PrintConv => '$val == 255 ? "Strobe or Misfire" : sprintf("%.0f%%", $val * 100)',
7233        PrintConvInv => '$val =~ /^(\d(\.?\d*))/ ? $1 / 100 : 255',
7234    },
7235    0x249 => { #37
7236        Name => 'FlashBatteryLevel',
7237        # calibration points for external flash: 144=3.76V (almost empty), 192=5.24V (full)
7238        # - have seen a value of 201 with internal flash
7239        PrintConv => '$val ? sprintf("%.2fV", $val * 5 / 186) : "n/a"',
7240        PrintConvInv => '$val=~/^(\d+\.\d+)\s*V?$/i ? int($val*186/5+0.5) : 0',
7241    },
7242    0x24a => { #37
7243        Name => 'ColorTempFlashData',
7244        # 0 for no external flash, 35980 for 'Strobe or Misfire'
7245        # (lower than ColorTempFlash by up to 200 degrees)
7246        RawConv => '($val < 2000 or $val > 12000) ? undef : $val',
7247    },
7248    # 0x24b: inverse relationship with flash power (ref 37)
7249    # 0x286: has value 256 for correct exposure, less for under exposure (seen 96 minimum) (ref 37)
7250    0x287 => { #37
7251        Name => 'MeasuredRGGBData',
7252        Format => 'int32u[4]',
7253        Notes => 'MeasuredRGGB may be derived from these data values',
7254        # swap words because the word ordering is big-endian, opposite to the byte ordering
7255        ValueConv => \&SwapWords,
7256        ValueConvInv => \&SwapWords,
7257    },
7258    # 0x297: ranges from -10 to 30, higher for high ISO (ref 37)
7259);
7260
7261# Color data (MakerNotes tag 0x4001, count=674|692|702|1227|1250|1251|1337|1338|1346) (ref PH)
7262%Image::ExifTool::Canon::ColorData4 = (
7263    %binaryDataAttrs,
7264    NOTES => q{
7265        These tags are used by the 1DmkIII, 1DSmkIII, 1DmkIV, 5DmkII, 7D, 40D, 50D,
7266        60D, 450D, 500D, 550D, 1000D and 1100D.
7267    },
7268    FORMAT => 'int16s',
7269    FIRST_ENTRY => 0,
7270    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7271    IS_SUBDIR => [ 0x3f, 0xa8 ],
7272    DATAMEMBER => [ 0x00 ],
7273    0x00 => {
7274        Name => 'ColorDataVersion',
7275        DataMember => 'ColorDataVersion',
7276        RawConv => '$$self{ColorDataVersion} = $val',
7277        PrintConv => {
7278            2 => '2 (1DmkIII)',
7279            3 => '3 (40D)',
7280            4 => '4 (1DSmkIII)',
7281            5 => '5 (450D/1000D)',
7282            6 => '6 (50D/5DmkII)',
7283            7 => '7 (500D/550D/7D/1DmkIV)',
7284            9 => '9 (60D/1100D)',
7285        },
7286    },
7287    # 0x01-0x18: unknown RGGB coefficients (int16s[4]) (50D)
7288    # (dcraw 8.81 uses index 0x3f for WB)
7289    0x3f => {
7290        Name => 'ColorCoefs',
7291        Format => 'undef[210]', # ColorTempUnknown11 is last entry
7292        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCoefs' }
7293    },
7294    0xa8 => {
7295        Name => 'ColorCalib',
7296        Format => 'undef[120]',
7297        Unknown => 1,
7298        Notes => 'B, C, A, Temperature',
7299        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
7300    },
7301    0x0e7 => { Name => 'AverageBlackLevel',     Format => 'int16u[4]' }, #IB
7302    0x280 => { #PH
7303        Name => 'RawMeasuredRGGB',
7304        Format => 'int32u[4]',
7305        Notes => 'raw MeasuredRGGB values, before normalization',
7306        # swap words because the word ordering is big-endian, opposite to the byte ordering
7307        ValueConv => \&SwapWords,
7308        ValueConvInv => \&SwapWords,
7309    },
7310    0x2b4 => { #IB
7311        Name => 'PerChannelBlackLevel',
7312        Condition => '$$self{ColorDataVersion} == 4 or $$self{ColorDataVersion} == 5',
7313        Format => 'int16u[4]',
7314    },
7315    0x2b8 => { #IB
7316        Name => 'NormalWhiteLevel',
7317        Condition => '$$self{ColorDataVersion} == 4 or $$self{ColorDataVersion} == 5',
7318        Format => 'int16u',
7319        RawConv => '$val || undef',
7320    },
7321    0x2b9 => { #IB
7322        Name => 'SpecularWhiteLevel',
7323        Condition => '$$self{ColorDataVersion} == 4 or $$self{ColorDataVersion} == 5',
7324        Format => 'int16u',
7325    },
7326    0x2ba => { #IB
7327        Name => 'LinearityUpperMargin',
7328        Condition => '$$self{ColorDataVersion} == 4 or $$self{ColorDataVersion} == 5',
7329        Format => 'int16u',
7330    },
7331    0x2cb => { #IB
7332        Name => 'PerChannelBlackLevel',
7333        Condition => '$$self{ColorDataVersion} == 6 or $$self{ColorDataVersion} == 7',
7334        Format => 'int16u[4]',
7335    },
7336    0x2cf => [{ #IB
7337        Name => 'NormalWhiteLevel',
7338        Condition => '$$self{ColorDataVersion} == 6 or $$self{ColorDataVersion} == 7',
7339        Format => 'int16u',
7340        RawConv => '$val || undef',
7341    },{
7342        Name => 'PerChannelBlackLevel',
7343        Condition => '$$self{ColorDataVersion} == 9',
7344        Format => 'int16u[4]',
7345    }],
7346    0x2d0 => { #IB
7347        Name => 'SpecularWhiteLevel',
7348        Condition => '$$self{ColorDataVersion} == 6 or $$self{ColorDataVersion} == 7',
7349        Format => 'int16u',
7350    },
7351    0x2d1 => { #IB
7352        Name => 'LinearityUpperMargin',
7353        Condition => '$$self{ColorDataVersion} == 6 or $$self{ColorDataVersion} == 7',
7354        Format => 'int16u',
7355    },
7356    0x2d3 => { #IB
7357        Name => 'NormalWhiteLevel',
7358        Condition => '$$self{ColorDataVersion} == 9',
7359        Format => 'int16u',
7360        RawConv => '$val || undef',
7361    },
7362    0x2d4 => { #IB
7363        Name => 'SpecularWhiteLevel',
7364        Condition => '$$self{ColorDataVersion} == 9',
7365        Format => 'int16u',
7366    },
7367    0x2d5 => { #IB
7368        Name => 'LinearityUpperMargin',
7369        Condition => '$$self{ColorDataVersion} == 9',
7370        Format => 'int16u',
7371    },
7372);
7373
7374# color coefficients (ref PH)
7375%Image::ExifTool::Canon::ColorCoefs = (
7376    %binaryDataAttrs,
7377    FORMAT => 'int16s',
7378    FIRST_ENTRY => 0,
7379    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7380    0x00 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16s[4]' },
7381    0x04 => 'ColorTempAsShot',
7382    0x05 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16s[4]' },
7383    0x09 => 'ColorTempAuto',
7384    0x0a => { Name => 'WB_RGGBLevelsMeasured',    Format => 'int16s[4]' },
7385    0x0e => 'ColorTempMeasured',
7386    # the following Unknown values are set for the 50D and 5DmkII, and the
7387    # SRAW images of the 40D, and affect thumbnail display for the 50D/5DmkII
7388    # and conversion for all modes of the 40D
7389    0x0f => { Name => 'WB_RGGBLevelsUnknown',     Format => 'int16s[4]', Unknown => 1 },
7390    0x13 => { Name => 'ColorTempUnknown', Unknown => 1 },
7391    0x14 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16s[4]' },
7392    0x18 => 'ColorTempDaylight',
7393    0x19 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16s[4]' },
7394    0x1d => 'ColorTempShade',
7395    0x1e => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16s[4]' },
7396    0x22 => 'ColorTempCloudy',
7397    0x23 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16s[4]' },
7398    0x27 => 'ColorTempTungsten',
7399    0x28 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
7400    0x2c => 'ColorTempFluorescent',
7401    # (changing the Kelvin values has no effect on image in DPP... why not?)
7402    0x2d => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
7403    0x31 => 'ColorTempKelvin',
7404    0x32 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
7405    0x36 => 'ColorTempFlash',
7406    0x37 => { Name => 'WB_RGGBLevelsUnknown2',   Format => 'int16s[4]', Unknown => 1 },
7407    0x3b => { Name => 'ColorTempUnknown2', Unknown => 1 },
7408    0x3c => { Name => 'WB_RGGBLevelsUnknown3',   Format => 'int16s[4]', Unknown => 1 },
7409    0x40 => { Name => 'ColorTempUnknown3', Unknown => 1 },
7410    0x41 => { Name => 'WB_RGGBLevelsUnknown4',   Format => 'int16s[4]', Unknown => 1 },
7411    0x45 => { Name => 'ColorTempUnknown4', Unknown => 1 },
7412    0x46 => { Name => 'WB_RGGBLevelsUnknown5',   Format => 'int16s[4]', Unknown => 1 },
7413    0x4a => { Name => 'ColorTempUnknown5', Unknown => 1 },
7414    0x4b => { Name => 'WB_RGGBLevelsUnknown6',   Format => 'int16s[4]', Unknown => 1 },
7415    0x4f => { Name => 'ColorTempUnknown6', Unknown => 1 },
7416    0x50 => { Name => 'WB_RGGBLevelsUnknown7',   Format => 'int16s[4]', Unknown => 1 },
7417    0x54 => { Name => 'ColorTempUnknown7', Unknown => 1 },
7418    0x55 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16s[4]', Unknown => 1 },
7419    0x59 => { Name => 'ColorTempUnknown8', Unknown => 1 },
7420    0x5a => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16s[4]', Unknown => 1 },
7421    0x5e => { Name => 'ColorTempUnknown9', Unknown => 1 },
7422    0x5f => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
7423    0x63 => { Name => 'ColorTempUnknown10', Unknown => 1 },
7424    0x64 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
7425    0x68 => { Name => 'ColorTempUnknown11', Unknown => 1 },
7426    0x69 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
7427    0x6d => { Name => 'ColorTempUnknown12', Unknown => 1 },
7428    0x6e => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
7429    0x72 => { Name => 'ColorTempUnknown13', Unknown => 1 },
7430);
7431
7432# color coefficients (ref PH/IB)
7433%Image::ExifTool::Canon::ColorCoefs2 = (
7434    %binaryDataAttrs,
7435    FORMAT => 'int16s',
7436    FIRST_ENTRY => 0,
7437    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7438    0x00 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16s[4]' },
7439    0x07 => 'ColorTempAsShot',
7440    0x08 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16s[4]' },
7441    0x0f => 'ColorTempAuto',
7442    0x10 => { Name => 'WB_RGGBLevelsMeasured',    Format => 'int16s[4]' },
7443    0x17 => 'ColorTempMeasured',
7444    0x18 => { Name => 'WB_RGGBLevelsUnknown',     Format => 'int16s[4]', Unknown => 1 },
7445    0x1f => { Name => 'ColorTempUnknown', Unknown => 1 },
7446    0x20 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16s[4]' },
7447    0x27 => 'ColorTempDaylight',
7448    0x28 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16s[4]' },
7449    0x2f => 'ColorTempShade',
7450    0x30 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16s[4]' },
7451    0x37 => 'ColorTempCloudy',
7452    0x38 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16s[4]' },
7453    0x3f => 'ColorTempTungsten',
7454    0x40 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
7455    0x47 => 'ColorTempFluorescent',
7456    0x48 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
7457    0x4f => 'ColorTempKelvin',
7458    0x50 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
7459    0x57 => 'ColorTempFlash',
7460    0x58 => { Name => 'WB_RGGBLevelsUnknown2',   Format => 'int16s[4]', Unknown => 1 },
7461    0x5f => { Name => 'ColorTempUnknown2', Unknown => 1 },
7462    0x60 => { Name => 'WB_RGGBLevelsUnknown3',   Format => 'int16s[4]', Unknown => 1 },
7463    0x67 => { Name => 'ColorTempUnknown3', Unknown => 1 },
7464    0x68 => { Name => 'WB_RGGBLevelsUnknown4',   Format => 'int16s[4]', Unknown => 1 },
7465    0x6f => { Name => 'ColorTempUnknown4', Unknown => 1 },
7466    0x70 => { Name => 'WB_RGGBLevelsUnknown5',   Format => 'int16s[4]', Unknown => 1 },
7467    0x77 => { Name => 'ColorTempUnknown5', Unknown => 1 },
7468    0x78 => { Name => 'WB_RGGBLevelsUnknown6',   Format => 'int16s[4]', Unknown => 1 },
7469    0x7f => { Name => 'ColorTempUnknown6', Unknown => 1 },
7470    0x80 => { Name => 'WB_RGGBLevelsUnknown7',   Format => 'int16s[4]', Unknown => 1 },
7471    0x87 => { Name => 'ColorTempUnknown7', Unknown => 1 },
7472    0x88 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16s[4]', Unknown => 1 },
7473    0x8f => { Name => 'ColorTempUnknown8', Unknown => 1 },
7474    0x90 => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16s[4]', Unknown => 1 },
7475    0x97 => { Name => 'ColorTempUnknown9', Unknown => 1 },
7476    0x98 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
7477    0x9f => { Name => 'ColorTempUnknown10', Unknown => 1 },
7478    0xa0 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
7479    0xa7 => { Name => 'ColorTempUnknown11', Unknown => 1 },
7480    0xa8 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
7481    0xaf => { Name => 'ColorTempUnknown12', Unknown => 1 },
7482    0xb0 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
7483    0xb7 => { Name => 'ColorTempUnknown13', Unknown => 1 },
7484);
7485
7486# color calibration (ref 37)
7487%Image::ExifTool::Canon::ColorCalib = (
7488    %binaryDataAttrs,
7489    FORMAT => 'int16s',
7490    FIRST_ENTRY => 0,
7491    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7492    # these coefficients are in a different order compared to older
7493    # models (A,B,C in ColorData1/2 vs. C,A,B in ColorData3/4) - PH
7494    # Coefficient A most closely matches the blue curvature, and
7495    # coefficient B most closely matches the red curvature, but the match
7496    # is not perfect, and I don't know what coefficient C is for (certainly
7497    # not a green coefficient) - PH
7498    NOTES => q{
7499        Camera color calibration data.  For the 20D, 350D, 1DmkII and 1DSmkII the
7500        order of the coefficients is A, B, C, Temperature, but for newer models it
7501        is B, C, A, Temperature.  These tags are extracted only when the L<Unknown|../ExifTool.html#Unknown>
7502        option is used.
7503    },
7504    0x00 => { Name => 'CameraColorCalibration01', %cameraColorCalibration },
7505    0x04 => { Name => 'CameraColorCalibration02', %cameraColorCalibration },
7506    0x08 => { Name => 'CameraColorCalibration03', %cameraColorCalibration },
7507    0x0c => { Name => 'CameraColorCalibration04', %cameraColorCalibration },
7508    0x10 => { Name => 'CameraColorCalibration05', %cameraColorCalibration },
7509    0x14 => { Name => 'CameraColorCalibration06', %cameraColorCalibration },
7510    0x18 => { Name => 'CameraColorCalibration07', %cameraColorCalibration },
7511    0x1c => { Name => 'CameraColorCalibration08', %cameraColorCalibration },
7512    0x20 => { Name => 'CameraColorCalibration09', %cameraColorCalibration },
7513    0x24 => { Name => 'CameraColorCalibration10', %cameraColorCalibration },
7514    0x28 => { Name => 'CameraColorCalibration11', %cameraColorCalibration },
7515    0x2c => { Name => 'CameraColorCalibration12', %cameraColorCalibration },
7516    0x30 => { Name => 'CameraColorCalibration13', %cameraColorCalibration },
7517    0x34 => { Name => 'CameraColorCalibration14', %cameraColorCalibration },
7518    0x38 => { Name => 'CameraColorCalibration15', %cameraColorCalibration },
7519);
7520
7521# color calibration2
7522%Image::ExifTool::Canon::ColorCalib2 = (
7523    %binaryDataAttrs,
7524    FORMAT => 'int16s',
7525    FIRST_ENTRY => 0,
7526    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7527    NOTES => 'B, C, A, D, Temperature.',
7528    0x00 => { Name => 'CameraColorCalibration01', %cameraColorCalibration2 },
7529    0x05 => { Name => 'CameraColorCalibration02', %cameraColorCalibration2 },
7530    0x0a => { Name => 'CameraColorCalibration03', %cameraColorCalibration2 },
7531    0x0f => { Name => 'CameraColorCalibration04', %cameraColorCalibration2 },
7532    0x14 => { Name => 'CameraColorCalibration05', %cameraColorCalibration2 },
7533    0x19 => { Name => 'CameraColorCalibration06', %cameraColorCalibration2 },
7534    0x1e => { Name => 'CameraColorCalibration07', %cameraColorCalibration2 },
7535    0x23 => { Name => 'CameraColorCalibration08', %cameraColorCalibration2 },
7536    0x28 => { Name => 'CameraColorCalibration09', %cameraColorCalibration2 },
7537    0x2d => { Name => 'CameraColorCalibration10', %cameraColorCalibration2 },
7538    0x32 => { Name => 'CameraColorCalibration11', %cameraColorCalibration2 },
7539    0x37 => { Name => 'CameraColorCalibration12', %cameraColorCalibration2 },
7540    0x3c => { Name => 'CameraColorCalibration13', %cameraColorCalibration2 },
7541    0x41 => { Name => 'CameraColorCalibration14', %cameraColorCalibration2 },
7542    0x46 => { Name => 'CameraColorCalibration15', %cameraColorCalibration2 },
7543);
7544
7545# Color data (MakerNotes tag 0x4001, count=5120) (ref PH)
7546%Image::ExifTool::Canon::ColorData5 = (
7547    %binaryDataAttrs,
7548    NOTES => 'These tags are used by many EOS M and PowerShot models.',
7549    FORMAT => 'int16s',
7550    FIRST_ENTRY => 0,
7551    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7552    DATAMEMBER => [ 0x00 ],
7553    IS_SUBDIR => [ 0x47, 0xba, 0xff ],
7554    0x00 => {
7555        Name => 'ColorDataVersion',
7556        DataMember => 'ColorDataVersion',
7557        RawConv => '$$self{ColorDataVersion} = $val',
7558        PrintConv => {
7559            -3 => '-3 (M10/M3)', # (and PowerShot G1X/G1XmkII/G10/G11/G12/G15/G16/G3X/G5X/G7X/G9X/S100/S110/S120/S90/S95/SX1IS/SX50HS/SX60HS)
7560            -4 => '-4 (M100/M5/M6)', # (and PowerShot G1XmkIII/G7XmkII/G9XmkII)
7561        },
7562    },
7563    0x47 => [{
7564        Name => 'ColorCoefs',
7565        Condition => '$$self{ColorDataVersion} == -3',
7566        Format => 'undef[230]', # ColorTempUnknown13 is last entry
7567        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCoefs' }
7568    },{
7569        Name => 'ColorCoefs2',
7570        Condition => '$$self{ColorDataVersion} == -4',
7571        Format => 'undef[368]',
7572        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCoefs2' }
7573    }],
7574    0xba => {
7575        Name => 'ColorCalib2',
7576        Condition => '$$self{ColorDataVersion} == -3',
7577        Format => 'undef[150]',
7578        Unknown => 1,
7579        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib2' }
7580    },
7581    0xff => {
7582        Name => 'ColorCalib2',
7583        Condition => '$$self{ColorDataVersion} == -4',
7584        Format => 'undef[150]',
7585        Unknown => 1,
7586        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib2' }
7587    },
7588    0x108=> { #IB
7589        Name => 'PerChannelBlackLevel',
7590        Condition => '$$self{ColorDataVersion} == -3',
7591        Format => 'int16s[4]',
7592    },
7593    0x14d=> { #IB
7594        Name => 'PerChannelBlackLevel',
7595        Condition => '$$self{ColorDataVersion} == -4',
7596        Format => 'int16s[4]',
7597    },
7598    0x0569 => { #PH (NC)
7599        Name => 'NormalWhiteLevel',
7600        Condition => '$$self{ColorDataVersion} == -4',
7601        Format => 'int16u',
7602    },
7603    0x056a => { #PH (NC)
7604        Name => 'SpecularWhiteLevel',
7605        Condition => '$$self{ColorDataVersion} == -4',
7606        Format => 'int16u',
7607    },
7608);
7609
7610# Color data (MakerNotes tag 0x4001, count=1273|1275) (ref PH)
7611%Image::ExifTool::Canon::ColorData6 = (
7612    %binaryDataAttrs,
7613    NOTES => 'These tags are used by the EOS 600D and 1200D.',
7614    FORMAT => 'int16s',
7615    FIRST_ENTRY => 0,
7616    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7617    IS_SUBDIR => [ 0xbc ],
7618    0x00 => {
7619        Name => 'ColorDataVersion',
7620        PrintConv => {
7621            10 => '10 (600D/1200D)',
7622        },
7623    },
7624    0x3f => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
7625    0x43 => 'ColorTempAsShot',
7626    0x44 => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
7627    0x48 => 'ColorTempAuto',
7628    0x49 => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
7629    0x4d => 'ColorTempMeasured',
7630    0x4e => { Name => 'WB_RGGBLevelsUnknown',    Format => 'int16s[4]', Unknown => 1 },
7631    0x52 => { Name => 'ColorTempUnknown', Unknown => 1 },
7632    0x53 => { Name => 'WB_RGGBLevelsUnknown2',   Format => 'int16s[4]', Unknown => 1 },
7633    0x57 => { Name => 'ColorTempUnknown2', Unknown => 1 },
7634    0x58 => { Name => 'WB_RGGBLevelsUnknown3',   Format => 'int16s[4]', Unknown => 1 },
7635    0x5c => { Name => 'ColorTempUnknown3', Unknown => 1 },
7636    0x5d => { Name => 'WB_RGGBLevelsUnknown4',   Format => 'int16s[4]', Unknown => 1 },
7637    0x61 => { Name => 'ColorTempUnknown4', Unknown => 1 },
7638    0x62 => { Name => 'WB_RGGBLevelsUnknown5',   Format => 'int16s[4]', Unknown => 1 },
7639    0x66 => { Name => 'ColorTempUnknown5', Unknown => 1 },
7640    0x67 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
7641    0x6b => 'ColorTempDaylight',
7642    0x6c => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
7643    0x70 => 'ColorTempShade',
7644    0x71 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
7645    0x75 => 'ColorTempCloudy',
7646    0x76 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
7647    0x7a => 'ColorTempTungsten',
7648    0x7b => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
7649    0x7f => 'ColorTempFluorescent',
7650    0x80 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
7651    0x84 => 'ColorTempKelvin',
7652    0x85 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
7653    0x89 => 'ColorTempFlash',
7654    0x8a => { Name => 'WB_RGGBLevelsUnknown6',   Format => 'int16s[4]', Unknown => 1 },
7655    0x8e => { Name => 'ColorTempUnknown6', Unknown => 1 },
7656    0x8f => { Name => 'WB_RGGBLevelsUnknown7',   Format => 'int16s[4]', Unknown => 1 },
7657    0x93 => { Name => 'ColorTempUnknown7', Unknown => 1 },
7658    0x94 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16s[4]', Unknown => 1 },
7659    0x98 => { Name => 'ColorTempUnknown8', Unknown => 1 },
7660    0x99 => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16s[4]', Unknown => 1 },
7661    0x9d => { Name => 'ColorTempUnknown9', Unknown => 1 },
7662    0x9e => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
7663    0xa2 => { Name => 'ColorTempUnknown10', Unknown => 1 },
7664    0xa3 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
7665    0xa7 => { Name => 'ColorTempUnknown11', Unknown => 1 },
7666    0xa8 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
7667    0xac => { Name => 'ColorTempUnknown12', Unknown => 1 },
7668    0xad => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
7669    0xb1 => { Name => 'ColorTempUnknown13', Unknown => 1 },
7670    0xb2 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
7671    0xb6 => { Name => 'ColorTempUnknown14', Unknown => 1 },
7672    0xb7 => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
7673    0xbb => { Name => 'ColorTempUnknown15', Unknown => 1 },
7674    0xbc => {
7675        Name => 'ColorCalib',
7676        Format => 'undef[120]',
7677        Unknown => 1,
7678        Notes => 'B, C, A, Temperature',
7679        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
7680    },
7681    0x0fb => { Name => 'AverageBlackLevel',     Format => 'int16u[4]' }, #IB
7682    0x194 => { #PH
7683        Name => 'RawMeasuredRGGB',
7684        Format => 'int32u[4]',
7685        Notes => 'raw MeasuredRGGB values, before normalization',
7686        # swap words because the word ordering is big-endian, opposite to the byte ordering
7687        ValueConv => \&SwapWords,
7688        ValueConvInv => \&SwapWords,
7689    },
7690    0x1df => { Name => 'PerChannelBlackLevel',  Format => 'int16u[4]' }, #IB
7691    0x1e3 => { Name => 'NormalWhiteLevel',      Format => 'int16u',  RawConv => '$val || undef' }, #IB
7692    0x1e4 => { Name => 'SpecularWhiteLevel',    Format => 'int16u' }, #IB
7693    0x1e5 => { Name => 'LinearityUpperMargin',  Format => 'int16u' }, #IB
7694);
7695
7696# Color data (MakerNotes tag 0x4001, count=1312,1313,1316) (ref PH)
7697%Image::ExifTool::Canon::ColorData7 = (
7698    %binaryDataAttrs,
7699    NOTES => 'These tags are used by the EOS 1DX, 5DmkIII, 6D, 100D, 650D, 700D, M and 7DmkII.',
7700    FORMAT => 'int16s',
7701    FIRST_ENTRY => 0,
7702    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7703    DATAMEMBER => [ 0x00 ],
7704    IS_SUBDIR => [ 0xd5 ],
7705    0x00 => {
7706        Name => 'ColorDataVersion',
7707        DataMember => 'ColorDataVersion',
7708        RawConv => '$$self{ColorDataVersion} = $val',
7709        PrintConv => {
7710            10 => '10 (1DX/5DmkIII/6D/70D/100D/650D/700D/M)',
7711            11 => '11 (7DmkII/750D/760D)',
7712        },
7713    },
7714    # not really sure about the AsShot, Auto and Measured values any more - PH
7715    0x3f => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
7716    0x43 => 'ColorTempAsShot',
7717    0x44 => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
7718    0x48 => 'ColorTempAuto',
7719    0x49 => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
7720    0x4d => 'ColorTempMeasured',
7721    0x4e => { Name => 'WB_RGGBLevelsUnknown',   Format => 'int16s[4]', Unknown => 1 },
7722    0x52 => { Name => 'ColorTempUnknown',  Unknown => 1 },
7723    0x53 => { Name => 'WB_RGGBLevelsUnknown2',  Format => 'int16s[4]', Unknown => 1 },
7724    0x57 => { Name => 'ColorTempUnknown2', Unknown => 1 },
7725    0x58 => { Name => 'WB_RGGBLevelsUnknown3',  Format => 'int16s[4]', Unknown => 1 },
7726    0x5c => { Name => 'ColorTempUnknown3', Unknown => 1 },
7727    0x5d => { Name => 'WB_RGGBLevelsUnknown4',  Format => 'int16s[4]', Unknown => 1 },
7728    0x61 => { Name => 'ColorTempUnknown4', Unknown => 1 },
7729    0x62 => { Name => 'WB_RGGBLevelsUnknown5',  Format => 'int16s[4]', Unknown => 1 },
7730    0x66 => { Name => 'ColorTempUnknown5', Unknown => 1 },
7731    0x67 => { Name => 'WB_RGGBLevelsUnknown6',  Format => 'int16s[4]', Unknown => 1 },
7732    0x6b => { Name => 'ColorTempUnknown6', Unknown => 1 },
7733    0x6c => { Name => 'WB_RGGBLevelsUnknown7',  Format => 'int16s[4]', Unknown => 1 },
7734    0x70 => { Name => 'ColorTempUnknown7', Unknown => 1 },
7735    0x71 => { Name => 'WB_RGGBLevelsUnknown8',  Format => 'int16s[4]', Unknown => 1 },
7736    0x75 => { Name => 'ColorTempUnknown8', Unknown => 1 },
7737    0x76 => { Name => 'WB_RGGBLevelsUnknown9',  Format => 'int16s[4]', Unknown => 1 },
7738    0x7a => { Name => 'ColorTempUnknown9', Unknown => 1 },
7739    0x7b => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
7740    0x7f => { Name => 'ColorTempUnknown10', Unknown => 1 },
7741    0x80 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
7742    0x84 => 'ColorTempDaylight',
7743    0x85 => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
7744    0x89 => 'ColorTempShade',
7745    0x8a => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
7746    0x8e => 'ColorTempCloudy',
7747    0x8f => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
7748    0x93 => 'ColorTempTungsten',
7749    0x94 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
7750    0x98 => 'ColorTempFluorescent',
7751    0x99 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
7752    0x9d => 'ColorTempKelvin',
7753    0x9e => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
7754    0xa2 => 'ColorTempFlash',
7755    0xa3 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
7756    0xa7 => { Name => 'ColorTempUnknown11', Unknown => 1 },
7757    0xa8 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
7758    0xac => { Name => 'ColorTempUnknown12', Unknown => 1 },
7759    0xad => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
7760    0xb1 => { Name => 'ColorTempUnknown13', Unknown => 1 },
7761    0xb2 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
7762    0xb6 => { Name => 'ColorTempUnknown14', Unknown => 1 },
7763    0xb7 => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
7764    0xbb => { Name => 'ColorTempUnknown15', Unknown => 1 },
7765    0xbc => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
7766    0xc0 => { Name => 'ColorTempUnknown16', Unknown => 1 },
7767    0xc1 => { Name => 'WB_RGGBLevelsUnknown17',  Format => 'int16s[4]', Unknown => 1 },
7768    0xc5 => { Name => 'ColorTempUnknown17', Unknown => 1 },
7769    0xc6 => { Name => 'WB_RGGBLevelsUnknown18',  Format => 'int16s[4]', Unknown => 1 },
7770    0xca => { Name => 'ColorTempUnknown18', Unknown => 1 },
7771    0xcb => { Name => 'WB_RGGBLevelsUnknown19',  Format => 'int16s[4]', Unknown => 1 },
7772    0xcf => { Name => 'ColorTempUnknown19', Unknown => 1 },
7773    0xd0 => { Name => 'WB_RGGBLevelsUnknown20',  Format => 'int16s[4]', Unknown => 1 },
7774    0xd4 => { Name => 'ColorTempUnknown20', Unknown => 1 },
7775    0xd5 => {
7776        Name => 'ColorCalib',
7777        Format => 'undef[120]',
7778        Unknown => 1,
7779        Notes => 'B, C, A, Temperature',
7780        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
7781    },
7782    0x114 => { Name => 'AverageBlackLevel',     Format => 'int16u[4]' }, #IB
7783    0x1ad => {
7784        Name => 'RawMeasuredRGGB',
7785        Condition => '$$self{ColorDataVersion} == 10',
7786        Format => 'int32u[4]',
7787        Notes => 'raw MeasuredRGGB values, before normalization',
7788        # swap words because the word ordering is big-endian, opposite to the byte ordering
7789        ValueConv => \&SwapWords,
7790        ValueConvInv => \&SwapWords,
7791    },
7792    0x1f8 => { #IB
7793        Name => 'PerChannelBlackLevel',
7794        Condition => '$$self{ColorDataVersion} == 10',
7795        Format => 'int16u[4]',
7796    },
7797    0x1fc => { #IB
7798        Name => 'NormalWhiteLevel',
7799        Condition => '$$self{ColorDataVersion} == 10',
7800        Format => 'int16u',
7801        RawConv => '$val || undef',
7802    },
7803    0x1fd => { #IB
7804        Name => 'SpecularWhiteLevel',
7805        Condition => '$$self{ColorDataVersion} == 10',
7806        Format => 'int16u',
7807    },
7808    0x1fe => { #IB
7809        Name => 'LinearityUpperMargin',
7810        Condition => '$$self{ColorDataVersion} == 10',
7811        Format => 'int16u',
7812    },
7813    0x26b => {
7814        Name => 'RawMeasuredRGGB',
7815        Condition => '$$self{ColorDataVersion} == 11',
7816        Format => 'int32u[4]',
7817        ValueConv => \&SwapWords,
7818        ValueConvInv => \&SwapWords,
7819    },
7820    0x2d8 => {
7821        Name => 'PerChannelBlackLevel',
7822        Condition => '$$self{ColorDataVersion} == 11',
7823        Format => 'int16u[4]',
7824    },
7825    0x2dc => {
7826        Name => 'NormalWhiteLevel',
7827        Condition => '$$self{ColorDataVersion} == 11',
7828        Format => 'int16u',
7829        RawConv => '$val || undef',
7830    },
7831    0x2dd => {
7832        Name => 'SpecularWhiteLevel',
7833        Condition => '$$self{ColorDataVersion} == 11',
7834        Format => 'int16u',
7835    },
7836    0x2de => {
7837        Name => 'LinearityUpperMargin',
7838        Condition => '$$self{ColorDataVersion} == 11',
7839        Format => 'int16u',
7840    },
7841);
7842
7843# Color data (MakerNotes tag 0x4001, count=1560,etc) (ref IB)
7844%Image::ExifTool::Canon::ColorData8 = (
7845    %binaryDataAttrs,
7846    FORMAT => 'int16s',
7847    FIRST_ENTRY => 0,
7848    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7849    DATAMEMBER => [ 0 ],
7850    IS_SUBDIR => [ 0x107 ],
7851    0x00 => {
7852        Name => 'ColorDataVersion',
7853        DataMember => 'ColorDataVersion',
7854        RawConv => '$$self{ColorDataVersion} = $val',
7855        PrintConv => {
7856            12 => '12 (5DS/5DSR)',
7857            13 => '13 (80D)', #PH
7858            14 => '14 (1300D/2000D/4000D)', #IB
7859            15 => '15 (6DmkII/77D/200D/800D)', #IB
7860        },
7861    },
7862    0x3f => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
7863    0x43 => 'ColorTempAsShot',
7864    0x44 => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
7865    0x48 => 'ColorTempAuto',
7866    0x49 => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
7867    0x4d => 'ColorTempMeasured',
7868    0x4e => { Name => 'WB_RGGBLevelsUnknown',   Format => 'int16s[4]', Unknown => 1 },
7869    0x52 => { Name => 'ColorTempUnknown',  Unknown => 1 },
7870    0x53 => { Name => 'WB_RGGBLevelsUnknown2',  Format => 'int16s[4]', Unknown => 1 },
7871    0x57 => { Name => 'ColorTempUnknown2', Unknown => 1 },
7872    0x58 => { Name => 'WB_RGGBLevelsUnknown3',  Format => 'int16s[4]', Unknown => 1 },
7873    0x5c => { Name => 'ColorTempUnknown3', Unknown => 1 },
7874    0x5d => { Name => 'WB_RGGBLevelsUnknown4',  Format => 'int16s[4]', Unknown => 1 },
7875    0x61 => { Name => 'ColorTempUnknown4', Unknown => 1 },
7876    0x62 => { Name => 'WB_RGGBLevelsUnknown5',  Format => 'int16s[4]', Unknown => 1 },
7877    0x66 => { Name => 'ColorTempUnknown5', Unknown => 1 },
7878    0x67 => { Name => 'WB_RGGBLevelsUnknown6',  Format => 'int16s[4]', Unknown => 1 },
7879    0x6b => { Name => 'ColorTempUnknown6', Unknown => 1 },
7880    0x6c => { Name => 'WB_RGGBLevelsUnknown7',  Format => 'int16s[4]', Unknown => 1 },
7881    0x70 => { Name => 'ColorTempUnknown7', Unknown => 1 },
7882    0x71 => { Name => 'WB_RGGBLevelsUnknown8',  Format => 'int16s[4]', Unknown => 1 },
7883    0x75 => { Name => 'ColorTempUnknown8', Unknown => 1 },
7884    0x76 => { Name => 'WB_RGGBLevelsUnknown9',  Format => 'int16s[4]', Unknown => 1 },
7885    0x7a => { Name => 'ColorTempUnknown9', Unknown => 1 },
7886    0x7b => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
7887    0x7f => { Name => 'ColorTempUnknown10', Unknown => 1 },
7888    0x80 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
7889    0x84 => { Name => 'ColorTempUnknown11', Unknown => 1 },
7890    0x85 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
7891    0x89 => 'ColorTempDaylight',
7892    0x8a => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
7893    0x8e => 'ColorTempShade',
7894    0x8f => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
7895    0x93 => 'ColorTempCloudy',
7896    0x94 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
7897    0x98 => 'ColorTempTungsten',
7898    0x99 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
7899    0x9d => 'ColorTempFluorescent',
7900    0x9e => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
7901    0xa2 => 'ColorTempKelvin',
7902    0xa3 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
7903    0xa7 => 'ColorTempFlash',
7904    0xa8 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
7905    0xac => { Name => 'ColorTempUnknown12', Unknown => 1 },
7906    0xad => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
7907    0xb1 => { Name => 'ColorTempUnknown13', Unknown => 1 },
7908    0xb2 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
7909    0xb6 => { Name => 'ColorTempUnknown14', Unknown => 1 },
7910    0xb7 => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
7911    0xbb => { Name => 'ColorTempUnknown15', Unknown => 1 },
7912    0xbc => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
7913    0xc0 => { Name => 'ColorTempUnknown16', Unknown => 1 },
7914    0xc1 => { Name => 'WB_RGGBLevelsUnknown17',  Format => 'int16s[4]', Unknown => 1 },
7915    0xc5 => { Name => 'ColorTempUnknown17', Unknown => 1 },
7916    0xc6 => { Name => 'WB_RGGBLevelsUnknown18',  Format => 'int16s[4]', Unknown => 1 },
7917    0xca => { Name => 'ColorTempUnknown18', Unknown => 1 },
7918    0xcb => { Name => 'WB_RGGBLevelsUnknown19',  Format => 'int16s[4]', Unknown => 1 },
7919    0xcf => { Name => 'ColorTempUnknown19', Unknown => 1 },
7920    0xd0 => { Name => 'WB_RGGBLevelsUnknown20',  Format => 'int16s[4]', Unknown => 1 },
7921    0xd4 => { Name => 'ColorTempUnknown20', Unknown => 1 },
7922    0xd5 => { Name => 'WB_RGGBLevelsUnknown21',  Format => 'int16s[4]', Unknown => 1 },
7923    0xd9 => { Name => 'ColorTempUnknown21', Unknown => 1 },
7924    0xda => { Name => 'WB_RGGBLevelsUnknown22',  Format => 'int16s[4]', Unknown => 1 },
7925    0xde => { Name => 'ColorTempUnknown22', Unknown => 1 },
7926    0xdf => { Name => 'WB_RGGBLevelsUnknown23',  Format => 'int16s[4]', Unknown => 1 },
7927    0xe3 => { Name => 'ColorTempUnknown23', Unknown => 1 },
7928    0xe4 => { Name => 'WB_RGGBLevelsUnknown24',  Format => 'int16s[4]', Unknown => 1 },
7929    0xe8 => { Name => 'ColorTempUnknown24', Unknown => 1 },
7930    0xe9 => { Name => 'WB_RGGBLevelsUnknown25',  Format => 'int16s[4]', Unknown => 1 },
7931    0xed => { Name => 'ColorTempUnknown25', Unknown => 1 },
7932    0xee => { Name => 'WB_RGGBLevelsUnknown26',  Format => 'int16s[4]', Unknown => 1 },
7933    0xf2 => { Name => 'ColorTempUnknown26', Unknown => 1 },
7934    0xf3 => { Name => 'WB_RGGBLevelsUnknown27',  Format => 'int16s[4]', Unknown => 1 },
7935    0xf7 => { Name => 'ColorTempUnknown27', Unknown => 1 },
7936    0xf8 => { Name => 'WB_RGGBLevelsUnknown28',  Format => 'int16s[4]', Unknown => 1 },
7937    0xfc => { Name => 'ColorTempUnknown28', Unknown => 1 },
7938    0xfd => { Name => 'WB_RGGBLevelsUnknown29',  Format => 'int16s[4]', Unknown => 1 },
7939    0x101 => { Name => 'ColorTempUnknown29', Unknown => 1 },
7940    0x102 => { Name => 'WB_RGGBLevelsUnknown30',  Format => 'int16s[4]', Unknown => 1 },
7941    0x106 => { Name => 'ColorTempUnknown30', Unknown => 1 },
7942
7943    0x107 => {
7944        Name => 'ColorCalib',
7945        Format => 'undef[120]',
7946        Unknown => 1,
7947        Notes => 'B, C, A, Temperature',
7948        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
7949    },
7950    0x146 => { Name => 'AverageBlackLevel', Format => 'int16u[4]' },
7951    0x22c => {
7952        Name => 'PerChannelBlackLevel',
7953        Condition => '$$self{ColorDataVersion} == 14',
7954        Format => 'int16u[4]',
7955        Notes => '1300D',
7956    },
7957    0x230 => {
7958        Name => 'NormalWhiteLevel',
7959        Condition => '$$self{ColorDataVersion} == 14',
7960        Format => 'int16u',
7961        Notes => '1300D',
7962        RawConv => '$val || undef',
7963    },
7964    0x231 => {
7965        Name => 'SpecularWhiteLevel',
7966        Condition => '$$self{ColorDataVersion} == 14',
7967        Format => 'int16u',
7968        Notes => '1300D',
7969    },
7970    0x232 => {
7971        Name => 'LinearityUpperMargin',
7972        Condition => '$$self{ColorDataVersion} == 14',
7973        Format => 'int16u',
7974        Notes => '1300D',
7975    },
7976    0x30a => {
7977        Name => 'PerChannelBlackLevel',
7978        Condition => '$$self{ColorDataVersion} < 14 or $$self{ColorDataVersion} == 15',
7979        Format => 'int16u[4]',
7980        Notes => '5DS, 5DS R, 77D, 80D and 800D',
7981    },
7982    0x30e => {
7983        Name => 'NormalWhiteLevel',
7984        Condition => '$$self{ColorDataVersion} < 14 or $$self{ColorDataVersion} == 15',
7985        Format => 'int16u',
7986        Notes => '5DS, 5DS R, 77D, 80D and 800D',
7987        RawConv => '$val || undef',
7988    },
7989    0x30f => {
7990        Name => 'SpecularWhiteLevel',
7991        Condition => '$$self{ColorDataVersion} < 14 or $$self{ColorDataVersion} == 15',
7992        Format => 'int16u',
7993        Notes => '5DS, 5DS R, 77D, 80D and 800D',
7994    },
7995    0x310 => {
7996        Name => 'LinearityUpperMargin',
7997        Condition => '$$self{ColorDataVersion} < 14 or $$self{ColorDataVersion} == 15',
7998        Format => 'int16u',
7999        Notes => '5DS, 5DS R, 77D, 80D and 800D',
8000    },
8001);
8002
8003# Color data (MakerNotes tag 0x4001, count=1820,etc) (ref PH)
8004%Image::ExifTool::Canon::ColorData9 = (
8005    %binaryDataAttrs,
8006    FORMAT => 'int16s',
8007    FIRST_ENTRY => 0,
8008    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8009    DATAMEMBER => [ 0 ],
8010    IS_SUBDIR => [ 0x10a ],
8011    0x00 => {
8012        Name => 'ColorDataVersion',
8013        DataMember => 'ColorDataVersion',
8014        RawConv => '$$self{ColorDataVersion} = $val',
8015        PrintConv => {
8016            16 => '16 (M50)',
8017            17 => '17 (EOS R)',     # (and PowerShot SX740HS)
8018            18 => '18 (EOS RP)',    # (and PowerShot SX70HS)
8019            19 => '19 (90D/M6mkII/M200)',# (and PowerShot G7XmkIII)
8020        },
8021    },
8022    0x47 => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
8023    0x4b => 'ColorTempAsShot',
8024    0x4c => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
8025    0x50 => 'ColorTempAuto',
8026    0x51 => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
8027    0x55 => 'ColorTempMeasured',
8028    0x56 => { Name => 'WB_RGGBLevelsUnknown',   Format => 'int16s[4]', Unknown => 1 },
8029    0x5a => { Name => 'ColorTempUnknown',  Unknown => 1 },
8030    0x5b => { Name => 'WB_RGGBLevelsUnknown2',  Format => 'int16s[4]', Unknown => 1 },
8031    0x5f => { Name => 'ColorTempUnknown2', Unknown => 1 },
8032    0x60 => { Name => 'WB_RGGBLevelsUnknown3',  Format => 'int16s[4]', Unknown => 1 },
8033    0x64 => { Name => 'ColorTempUnknown3', Unknown => 1 },
8034    0x65 => { Name => 'WB_RGGBLevelsUnknown4',  Format => 'int16s[4]', Unknown => 1 },
8035    0x69 => { Name => 'ColorTempUnknown4', Unknown => 1 },
8036    0x6a => { Name => 'WB_RGGBLevelsUnknown5',  Format => 'int16s[4]', Unknown => 1 },
8037    0x6e => { Name => 'ColorTempUnknown5', Unknown => 1 },
8038    0x6f => { Name => 'WB_RGGBLevelsUnknown6',  Format => 'int16s[4]', Unknown => 1 },
8039    0x73 => { Name => 'ColorTempUnknown6', Unknown => 1 },
8040    0x74 => { Name => 'WB_RGGBLevelsUnknown7',  Format => 'int16s[4]', Unknown => 1 },
8041    0x78 => { Name => 'ColorTempUnknown7', Unknown => 1 },
8042    0x79 => { Name => 'WB_RGGBLevelsUnknown8',  Format => 'int16s[4]', Unknown => 1 },
8043    0x7d => { Name => 'ColorTempUnknown8', Unknown => 1 },
8044    0x7e => { Name => 'WB_RGGBLevelsUnknown9',  Format => 'int16s[4]', Unknown => 1 },
8045    0x82 => { Name => 'ColorTempUnknown9', Unknown => 1 },
8046    0x83 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
8047    0x87 => { Name => 'ColorTempUnknown10', Unknown => 1 },
8048    0x88 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
8049    0x8c => 'ColorTempDaylight',
8050    0x8d => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
8051    0x91 => 'ColorTempShade',
8052    0x92 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
8053    0x96 => 'ColorTempCloudy',
8054    0x97 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
8055    0x9b => 'ColorTempTungsten',
8056    0x9c => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
8057    0xa0 => 'ColorTempFluorescent',
8058    0xa1 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
8059    0xa5 => 'ColorTempKelvin',
8060    0xa6 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
8061    0xaa => 'ColorTempFlash',
8062    0xab => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
8063    0xaf => { Name => 'ColorTempUnknown11', Unknown => 1 },
8064    0xb0 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
8065    0xb4 => { Name => 'ColorTempUnknown12', Unknown => 1 },
8066    0xb5 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
8067    0xb9 => { Name => 'ColorTempUnknown13', Unknown => 1 },
8068    0xba => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
8069    0xbe => { Name => 'ColorTempUnknown14', Unknown => 1 },
8070    0xbf => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
8071    0xc3 => { Name => 'ColorTempUnknown15', Unknown => 1 },
8072    0xc4 => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
8073    0xc8 => { Name => 'ColorTempUnknown16', Unknown => 1 },
8074    0xc9 => { Name => 'WB_RGGBLevelsUnknown17',  Format => 'int16s[4]', Unknown => 1 },
8075    0xcd => { Name => 'ColorTempUnknown17', Unknown => 1 },
8076    0xce => { Name => 'WB_RGGBLevelsUnknown18',  Format => 'int16s[4]', Unknown => 1 },
8077    0xd2 => { Name => 'ColorTempUnknown18', Unknown => 1 },
8078    0xd3 => { Name => 'WB_RGGBLevelsUnknown19',  Format => 'int16s[4]', Unknown => 1 },
8079    0xd7 => { Name => 'ColorTempUnknown19', Unknown => 1 },
8080    0xd8 => { Name => 'WB_RGGBLevelsUnknown20',  Format => 'int16s[4]', Unknown => 1 },
8081    0xdc => { Name => 'ColorTempUnknown20', Unknown => 1 },
8082    0xdd => { Name => 'WB_RGGBLevelsUnknown21',  Format => 'int16s[4]', Unknown => 1 },
8083    0xe1 => { Name => 'ColorTempUnknown21', Unknown => 1 },
8084    0xe2 => { Name => 'WB_RGGBLevelsUnknown22',  Format => 'int16s[4]', Unknown => 1 },
8085    0xe6 => { Name => 'ColorTempUnknown22', Unknown => 1 },
8086    0xe7 => { Name => 'WB_RGGBLevelsUnknown23',  Format => 'int16s[4]', Unknown => 1 },
8087    0xeb => { Name => 'ColorTempUnknown23', Unknown => 1 },
8088    0xec => { Name => 'WB_RGGBLevelsUnknown24',  Format => 'int16s[4]', Unknown => 1 },
8089    0xf0 => { Name => 'ColorTempUnknown24', Unknown => 1 },
8090    0xf1 => { Name => 'WB_RGGBLevelsUnknown25',  Format => 'int16s[4]', Unknown => 1 },
8091    0xf5 => { Name => 'ColorTempUnknown25', Unknown => 1 },
8092    0xf6 => { Name => 'WB_RGGBLevelsUnknown26',  Format => 'int16s[4]', Unknown => 1 },
8093    0xfa => { Name => 'ColorTempUnknown26', Unknown => 1 },
8094    0xfb => { Name => 'WB_RGGBLevelsUnknown27',  Format => 'int16s[4]', Unknown => 1 },
8095    0xff => { Name => 'ColorTempUnknown27', Unknown => 1 },
8096    0x100=> { Name => 'WB_RGGBLevelsUnknown28',  Format => 'int16s[4]', Unknown => 1 },
8097    0x104=> { Name => 'ColorTempUnknown28', Unknown => 1 },
8098    0x105=> { Name => 'WB_RGGBLevelsUnknown29',  Format => 'int16s[4]', Unknown => 1 },
8099    0x109=> { Name => 'ColorTempUnknown29', Unknown => 1 },
8100    0x10a => { #IB
8101        Name => 'ColorCalib',
8102        Format => 'undef[120]',
8103        Unknown => 1,
8104        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
8105    },
8106    0x149 => { #IB
8107        Name => 'PerChannelBlackLevel',
8108        Format => 'int16u[4]',
8109    },
8110    # 0x318 - PerChannelBlackLevel again (ref IB)
8111    0x31c => { #IB
8112        Name => 'NormalWhiteLevel',
8113        Format => 'int16u',
8114        RawConv => '$val || undef',
8115    },
8116    0x31d => { #IB
8117        Name => 'SpecularWhiteLevel',
8118        Format => 'int16u',
8119    },
8120    0x31e => { #IB
8121        Name => 'LinearityUpperMargin',
8122        Format => 'int16u',
8123    },
8124);
8125
8126# Color data (MakerNotes tag 0x4001, count=2024,3656)
8127# (same as ColorData9 but shifted up by 0x0e, ref PH)
8128%Image::ExifTool::Canon::ColorData10 = (
8129    %binaryDataAttrs,
8130    FORMAT => 'int16s',
8131    FIRST_ENTRY => 0,
8132    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8133    DATAMEMBER => [ 0 ],
8134    IS_SUBDIR => [ 0x118 ],
8135    0x00 => {
8136        Name => 'ColorDataVersion',
8137        DataMember => 'ColorDataVersion',
8138        RawConv => '$$self{ColorDataVersion} = $val',
8139        PrintConv => {
8140            32 => '32 (1DXmkIII)', #IB
8141            33 => '33 (R5/R6)',
8142        },
8143    },
8144    0x55 => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
8145    0x59 => 'ColorTempAsShot',
8146    0x5a => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
8147    0x5e => 'ColorTempAuto',
8148    0x5f => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
8149    0x63 => 'ColorTempMeasured',
8150    0x64 => { Name => 'WB_RGGBLevelsUnknown',   Format => 'int16s[4]', Unknown => 1 },
8151    0x68 => { Name => 'ColorTempUnknown',  Unknown => 1 },
8152    0x69 => { Name => 'WB_RGGBLevelsUnknown2',  Format => 'int16s[4]', Unknown => 1 },
8153    0x6d => { Name => 'ColorTempUnknown2', Unknown => 1 },
8154    0x6e => { Name => 'WB_RGGBLevelsUnknown3',  Format => 'int16s[4]', Unknown => 1 },
8155    0x72 => { Name => 'ColorTempUnknown3', Unknown => 1 },
8156    0x73 => { Name => 'WB_RGGBLevelsUnknown4',  Format => 'int16s[4]', Unknown => 1 },
8157    0x77 => { Name => 'ColorTempUnknown4', Unknown => 1 },
8158    0x78 => { Name => 'WB_RGGBLevelsUnknown5',  Format => 'int16s[4]', Unknown => 1 },
8159    0x7c => { Name => 'ColorTempUnknown5', Unknown => 1 },
8160    0x7d => { Name => 'WB_RGGBLevelsUnknown6',  Format => 'int16s[4]', Unknown => 1 },
8161    0x81 => { Name => 'ColorTempUnknown6', Unknown => 1 },
8162    0x82 => { Name => 'WB_RGGBLevelsUnknown7',  Format => 'int16s[4]', Unknown => 1 },
8163    0x86 => { Name => 'ColorTempUnknown7', Unknown => 1 },
8164    0x87 => { Name => 'WB_RGGBLevelsUnknown8',  Format => 'int16s[4]', Unknown => 1 },
8165    0x8b => { Name => 'ColorTempUnknown8', Unknown => 1 },
8166    0x8c => { Name => 'WB_RGGBLevelsUnknown9',  Format => 'int16s[4]', Unknown => 1 },
8167    0x90 => { Name => 'ColorTempUnknown9', Unknown => 1 },
8168    0x91 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
8169    0x95 => { Name => 'ColorTempUnknown10', Unknown => 1 },
8170    0x96 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
8171    0x9a => 'ColorTempDaylight',
8172    0x9b => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
8173    0x9f => 'ColorTempShade',
8174    0xa0 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
8175    0xa4 => 'ColorTempCloudy',
8176    0xa5 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
8177    0xa9 => 'ColorTempTungsten',
8178    0xaa => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
8179    0xae => 'ColorTempFluorescent',
8180    0xaf => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
8181    0xb3 => 'ColorTempKelvin',
8182    0xb4 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
8183    0xb8 => 'ColorTempFlash',
8184    0xb9 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
8185    0xbd => { Name => 'ColorTempUnknown11', Unknown => 1 },
8186    0xbe => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
8187    0xc2 => { Name => 'ColorTempUnknown12', Unknown => 1 },
8188    0xc3 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
8189    0xc7 => { Name => 'ColorTempUnknown13', Unknown => 1 },
8190    0xc8 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
8191    0xcc => { Name => 'ColorTempUnknown14', Unknown => 1 },
8192    0xcd => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
8193    0xd1 => { Name => 'ColorTempUnknown15', Unknown => 1 },
8194    0xd2 => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
8195    0xd6 => { Name => 'ColorTempUnknown16', Unknown => 1 },
8196    0xd7 => { Name => 'WB_RGGBLevelsUnknown17',  Format => 'int16s[4]', Unknown => 1 },
8197    0xdb => { Name => 'ColorTempUnknown17', Unknown => 1 },
8198    0xdc => { Name => 'WB_RGGBLevelsUnknown18',  Format => 'int16s[4]', Unknown => 1 },
8199    0xe0 => { Name => 'ColorTempUnknown18', Unknown => 1 },
8200    0xe1 => { Name => 'WB_RGGBLevelsUnknown19',  Format => 'int16s[4]', Unknown => 1 },
8201    0xe5 => { Name => 'ColorTempUnknown19', Unknown => 1 },
8202    0xe6 => { Name => 'WB_RGGBLevelsUnknown20',  Format => 'int16s[4]', Unknown => 1 },
8203    0xea => { Name => 'ColorTempUnknown20', Unknown => 1 },
8204    0xeb => { Name => 'WB_RGGBLevelsUnknown21',  Format => 'int16s[4]', Unknown => 1 },
8205    0xef => { Name => 'ColorTempUnknown21', Unknown => 1 },
8206    0xf0 => { Name => 'WB_RGGBLevelsUnknown22',  Format => 'int16s[4]', Unknown => 1 },
8207    0xf4 => { Name => 'ColorTempUnknown22', Unknown => 1 },
8208    0xf5 => { Name => 'WB_RGGBLevelsUnknown23',  Format => 'int16s[4]', Unknown => 1 },
8209    0xf9 => { Name => 'ColorTempUnknown23', Unknown => 1 },
8210    0xfa => { Name => 'WB_RGGBLevelsUnknown24',  Format => 'int16s[4]', Unknown => 1 },
8211    0xfe => { Name => 'ColorTempUnknown24', Unknown => 1 },
8212    0xff => { Name => 'WB_RGGBLevelsUnknown25',  Format => 'int16s[4]', Unknown => 1 },
8213    0x103=> { Name => 'ColorTempUnknown25', Unknown => 1 },
8214    0x104=> { Name => 'WB_RGGBLevelsUnknown26',  Format => 'int16s[4]', Unknown => 1 },
8215    0x108=> { Name => 'ColorTempUnknown26', Unknown => 1 },
8216    0x109=> { Name => 'WB_RGGBLevelsUnknown27',  Format => 'int16s[4]', Unknown => 1 },
8217    0x10d=> { Name => 'ColorTempUnknown27', Unknown => 1 },
8218    0x10e=> { Name => 'WB_RGGBLevelsUnknown28',  Format => 'int16s[4]', Unknown => 1 },
8219    0x112=> { Name => 'ColorTempUnknown28', Unknown => 1 },
8220    0x113=> { Name => 'WB_RGGBLevelsUnknown29',  Format => 'int16s[4]', Unknown => 1 },
8221    0x117=> { Name => 'ColorTempUnknown29', Unknown => 1 },
8222    0x118 => {
8223        Name => 'ColorCalib',
8224        Format => 'undef[120]',
8225        Unknown => 1,
8226        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
8227    },
8228    0x157 => {
8229        Name => 'PerChannelBlackLevel',
8230        Format => 'int16u[4]',
8231    },
8232    # 0x326 - PerChannelBlackLevel again
8233    0x32a => {
8234        Name => 'NormalWhiteLevel',
8235        Format => 'int16u',
8236        RawConv => '$val || undef',
8237    },
8238    0x32b => {
8239        Name => 'SpecularWhiteLevel',
8240        Format => 'int16u',
8241    },
8242    0x32c => {
8243        Name => 'LinearityUpperMargin',
8244        Format => 'int16u',
8245    },
8246);
8247
8248# Unknown color data (MakerNotes tag 0x4001)
8249%Image::ExifTool::Canon::ColorDataUnknown = (
8250    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
8251    FORMAT => 'int16s',
8252    FIRST_ENTRY => 0,
8253    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8254    0x00 => 'ColorDataVersion',
8255);
8256
8257# Color information (MakerNotes tag 0x4003) (ref PH)
8258%Image::ExifTool::Canon::ColorInfo = (
8259    %binaryDataAttrs,
8260    FORMAT => 'int16s',
8261    FIRST_ENTRY => 1,
8262    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8263    1 => {
8264        Condition => '$$self{Model} =~ /EOS-1D/',
8265        Name => 'Saturation',
8266        %Image::ExifTool::Exif::printParameter,
8267    },
8268    2 => {
8269        Name => 'ColorTone',
8270        %Image::ExifTool::Exif::printParameter,
8271    },
8272    3 => {
8273        Name => 'ColorSpace',
8274        RawConv => '$val ? $val : undef', # ignore tag if zero
8275        PrintConv => {
8276            1 => 'sRGB',
8277            2 => 'Adobe RGB',
8278        },
8279    },
8280);
8281
8282# AF micro-adjustment information (MakerNotes tag 0x4013) (ref PH)
8283%Image::ExifTool::Canon::AFMicroAdj = (
8284    %binaryDataAttrs,
8285    FORMAT => 'int32s',
8286    FIRST_ENTRY => 1,
8287    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8288    1 => {
8289        Name => 'AFMicroAdjMode',
8290        PrintConv => {
8291            0 => 'Disable',
8292            1 => 'Adjust all by the same amount',
8293            2 => 'Adjust by lens',
8294          # 3 - seen this for EOS 77D, which doesn't have an AF Micro Adjust feature - PH
8295        },
8296    },
8297    2 => {
8298        Name => 'AFMicroAdjValue',
8299        Format => 'rational64s',
8300    },
8301);
8302
8303# Vignetting correction information (MakerNotes tag 0x4015)
8304%Image::ExifTool::Canon::VignettingCorr = (
8305    %binaryDataAttrs,
8306    FORMAT => 'int16s',
8307    FIRST_ENTRY => 1,
8308    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8309    NOTES => 'This information is found in images from newer EOS models.',
8310    0 => {
8311        Name => 'VignettingCorrVersion',
8312        Format => 'int8u',
8313        Writable => 0,
8314    },
8315    2 => {
8316        Name => 'PeripheralLighting',
8317        PrintConv => \%offOn,
8318    },
8319    3 => {
8320        Name => 'DistortionCorrection',
8321        PrintConv => \%offOn,
8322    },
8323    4 => {
8324        Name => 'ChromaticAberrationCorr',
8325        PrintConv => \%offOn,
8326    },
8327    5 => {
8328        Name => 'ChromaticAberrationCorr',
8329        PrintConv => \%offOn,
8330    },
8331    6 => 'PeripheralLightingValue',
8332    9 => 'DistortionCorrectionValue',
8333    # 10 - flags?
8334    11 => {
8335        Name => 'OriginalImageWidth',
8336        Notes => 'full size of original image before being rotated or scaled in camera',
8337    },
8338    12 => 'OriginalImageHeight',
8339);
8340
8341%Image::ExifTool::Canon::VignettingCorrUnknown = (
8342    %binaryDataAttrs,
8343    FORMAT => 'int16s',
8344    FIRST_ENTRY => 1,
8345    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8346    NOTES => 'Vignetting correction from PowerShot models.',
8347    0 => {
8348        Name => 'VignettingCorrVersion',
8349        Format => 'int8u',
8350        Writable => 0,
8351    },
8352);
8353
8354# More Vignetting correction information (MakerNotes tag 0x4016)
8355%Image::ExifTool::Canon::VignettingCorr2 = (
8356    %binaryDataAttrs,
8357    FORMAT => 'int32s',
8358    FIRST_ENTRY => 1,
8359    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8360    5 => {
8361        Name => 'PeripheralLightingSetting',
8362        PrintConv => \%offOn,
8363    },
8364    6 => {
8365        Name => 'ChromaticAberrationSetting',
8366        PrintConv => \%offOn,
8367    },
8368    7 => {
8369        Name => 'DistortionCorrectionSetting',
8370        PrintConv => \%offOn,
8371    },
8372);
8373
8374# Auto Lighting Optimizater information (MakerNotes tag 0x4018) (ref PH)
8375%Image::ExifTool::Canon::LightingOpt = (
8376    %binaryDataAttrs,
8377    FORMAT => 'int32s',
8378    FIRST_ENTRY => 1,
8379    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8380    NOTES => 'This information is new in images from the EOS 7D.',
8381    1 => {
8382        Name => 'PeripheralIlluminationCorr',
8383        PrintConv => \%offOn,
8384    },
8385    2 => {
8386        Name => 'AutoLightingOptimizer',
8387        PrintConv => {
8388            0 => 'Standard',
8389            1 => 'Low',
8390            2 => 'Strong',
8391            3 => 'Off',
8392        },
8393    },
8394    3 => {
8395        Name => 'HighlightTonePriority',
8396        PrintConv => \%offOn,
8397    },
8398    4 => {
8399        Name => 'LongExposureNoiseReduction',
8400        PrintConv => {
8401            0 => 'Off',
8402            1 => 'Auto',
8403            2 => 'On',
8404        },
8405    },
8406    5 => {
8407        Name => 'HighISONoiseReduction',
8408        PrintConv => {
8409            0 => 'Standard',
8410            1 => 'Low',
8411            2 => 'Strong',
8412            3 => 'Off',
8413        },
8414    },
8415    # 6 - related to ChromaticAberrationCorr
8416    # 7 - related to DistortionCorrection (0=off, 1=On in a 5DmkIV sample)
8417    # 8 - related to PeripheralIlluminationCorr and ChromaticAberrationCorr
8418);
8419
8420# Lens information (MakerNotes tag 0x4019) (ref 20)
8421%Image::ExifTool::Canon::LensInfo = (
8422    %binaryDataAttrs,
8423    FIRST_ENTRY => 0,
8424    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8425    0 => { # this doesn't seem to be valid for some models (eg. 550D, 7D?, 1DmkIV?)
8426        Name => 'LensSerialNumber',
8427        Notes => q{
8428            apparently this is an internal serial number because it doesn't correspond
8429            to the one printed on the lens
8430        },
8431        Format => 'undef[5]',
8432        Priority => 0,
8433        RawConv => '$val=~/^\0\0\0\0/ ? undef : $val', # (rules out 550D and older lenses)
8434        ValueConv => 'unpack("H*", $val)',
8435        ValueConvInv => 'length($val) < 10 and $val = 0 x (10-length($val)) . $val; pack("H*",$val)',
8436    },
8437);
8438
8439# Subject mode ambience information (MakerNotes tag 0x4020) (ref PH)
8440%Image::ExifTool::Canon::Ambience = (
8441    %binaryDataAttrs,
8442    FORMAT => 'int32s',
8443    FIRST_ENTRY => 1,
8444    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8445    1 => {
8446        Name => 'AmbienceSelection',
8447        PrintConv => {
8448            0 => 'Standard',
8449            1 => 'Vivid',
8450            2 => 'Warm',
8451            3 => 'Soft',
8452            4 => 'Cool',
8453            5 => 'Intense',
8454            6 => 'Brighter',
8455            7 => 'Darker',
8456            8 => 'Monochrome',
8457        },
8458    },
8459);
8460
8461# Multi-exposure information (MakerNotes tag 0x4021) (ref PH)
8462%Image::ExifTool::Canon::MultiExp = (
8463    %binaryDataAttrs,
8464    FORMAT => 'int32s',
8465    FIRST_ENTRY => 1,
8466    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
8467    1 => {
8468        Name => 'MultiExposure',
8469        PrintConv => {
8470            0 => 'Off',
8471            1 => 'On',
8472            2 => 'On (RAW)', #IB
8473        },
8474    },
8475    2 => {
8476        Name => 'MultiExposureControl',
8477        PrintConv => {
8478            0 => 'Additive',
8479            1 => 'Average',
8480            2 => 'Bright (comparative)',
8481            3 => 'Dark (comparative)',
8482        },
8483    },
8484    3 => 'MultiExposureShots',
8485);
8486
8487my %filterConv = (
8488    PrintConv => {
8489        -1 => 'Off',
8490        OTHER => sub { my $val=shift; return "On ($val)" },
8491    },
8492);
8493# Creative filter information (MakerNotes tag 0x4024) (ref PH)
8494%Image::ExifTool::Canon::FilterInfo = (
8495    PROCESS_PROC => \&ProcessFilters,
8496    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8497    NOTES => 'Information about creative filter settings.',
8498    0x101 => {
8499        Name => 'GrainyBWFilter',
8500        Description => 'Grainy B/W Filter',
8501        %filterConv,
8502    },
8503    0x201 => { Name => 'SoftFocusFilter',   %filterConv },
8504    0x301 => { Name => 'ToyCameraFilter',   %filterConv },
8505    0x401 => { Name => 'MiniatureFilter',   %filterConv },
8506    0x402 => {
8507        Name => 'MiniatureFilterOrientation',
8508        PrintConv => {
8509            0 => 'Horizontal',
8510            1 => 'Vertical',
8511        },
8512    },
8513    0x403 => 'MiniatureFilterPosition',
8514    0x404 => 'MiniatureFilterParameter', # but what is the meaning?
8515    0x501 => { Name => 'FisheyeFilter',     %filterConv }, # (M2)
8516    0x601 => { Name => 'PaintingFilter',    %filterConv }, # (M2)
8517    0x701 => { Name => 'WatercolorFilter',  %filterConv }, # (M2)
8518);
8519
8520# HDR information (MakerNotes tag 0x4025) (ref PH)
8521%Image::ExifTool::Canon::HDRInfo = (
8522    %binaryDataAttrs,
8523    FORMAT => 'int32s',
8524    FIRST_ENTRY => 1,
8525    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
8526    1 => {
8527        Name => 'HDR',
8528        PrintConv => {
8529            0 => 'Off',
8530            1 => 'Auto',
8531            2 => 'On',
8532        },
8533    },
8534    2 => {
8535        Name => 'HDREffect',
8536        PrintConv => {
8537            0 => 'Natural',
8538            1 => 'Art (standard)',
8539            2 => 'Art (vivid)',
8540            3 => 'Art (bold)',
8541            4 => 'Art (embossed)',
8542        },
8543    },
8544    # 3 - maybe related to AutoImageAlign?
8545);
8546
8547# AF configuration info (MakerNotes tag 0x4028) (ref PH)
8548%Image::ExifTool::Canon::AFConfig = (
8549    %binaryDataAttrs,
8550    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8551    FORMAT => 'int32s',
8552    FIRST_ENTRY => 1,
8553    1 => {
8554        Name => 'AFConfigTool',
8555        ValueConv => '$val + 1',
8556        ValueConvInv => '$val - 1',
8557        PrintConv => '"Case $val"',
8558        PrintConvInv => '$val=~/(\d+)/ ? $1 : undef',
8559    },
8560    2 => 'AFTrackingSensitivity',
8561    3 => {
8562        Name => 'AFAccelDecelTracking',
8563        Description => 'AF Accel/Decel Tracking',
8564    },
8565    4 => 'AFPointSwitching',
8566    5 => { #52
8567        Name => 'AIServoFirstImage',
8568        PrintConv => {
8569             0 => 'Equal Priority',
8570             1 => 'Release Priority',
8571             2 => 'Focus Priority',
8572        },
8573    },
8574    6 => { #52
8575        Name => 'AIServoSecondImage',
8576        PrintConv => {
8577             0 => 'Equal Priority',
8578             1 => 'Release Priority',
8579             2 => 'Focus Priority',
8580             3 => 'Release High Priority',
8581             4 => 'Focus High Priority',
8582        },
8583    },
8584    7 => { #52
8585        Name => 'USMLensElectronicMF',
8586        PrintConv => {
8587             0 => 'Enable After AF',
8588             1 => 'Disable After AF',
8589             2 => 'Disable in AF Mode',
8590        },
8591    },
8592    8 => { #52
8593        Name => 'AFAssistBeam',
8594        PrintConv => {
8595             0 => 'Enable',
8596             1 => 'Disable',
8597             2 => 'IR AF Assist Beam Only',
8598        },
8599    },
8600    9 => { #52
8601        Name => 'OneShotAFRelease',
8602        PrintConv => {
8603             0 => 'Focus Priority',
8604             1 => 'Release Priority',
8605        },
8606    },
8607    10 => { #52
8608        Name => 'AutoAFPointSelEOSiTRAF',
8609        Description => 'Auto AF Point Sel EOS iTR AF',
8610        # valid for: 1DX, 1DXmkII, 7DmkII, 5DS, 5DSR
8611        # not valid for: 5DmkIII
8612        Notes => 'only valid for some models',
8613        Condition => '$$self{Model} !~ /5D /',
8614        PrintConv => {
8615             0 => 'Enable',
8616             1 => 'Disable',
8617        },
8618    },
8619    11 => { #52
8620        Name => 'LensDriveWhenAFImpossible',
8621        PrintConv => {
8622             0 => 'Continue Focus Search',
8623             1 => 'Stop Focus Search',
8624        },
8625    },
8626    12 => { #52
8627        Name => 'SelectAFAreaSelectionMode',
8628        PrintConv => { BITMASK => {
8629            0 => 'Single-point AF',
8630            1 => 'Auto', # (61 point)
8631            2 => 'Zone AF',
8632            3 => 'AF Point Expansion (4 point)',
8633            4 => 'Spot AF',
8634            5 => 'AF Point Expansion (8 point)',
8635        }},
8636    },
8637    13 => { #52
8638        Name => 'AFAreaSelectionMethod',
8639        PrintConv => {
8640             0 => 'M-Fn Button',
8641             1 => 'Main Dial',
8642        },
8643    },
8644    14 => { #52
8645        Name => 'OrientationLinkedAF',
8646        PrintConv => { # Covers both 1Dx (0-2) and 5D3 (0-1)
8647             0 => 'Same for Vert/Horiz Points',
8648             1 => 'Separate Vert/Horiz Points',
8649             2 => 'Separate Area+Points',
8650        },
8651    },
8652    15 => { #52
8653        Name => 'ManualAFPointSelPattern',
8654        PrintConv => {
8655             0 => 'Stops at AF Area Edges',
8656             1 => 'Continuous',
8657        },
8658    },
8659    16 => { #52
8660        Name => 'AFPointDisplayDuringFocus',
8661        PrintConv => {
8662             0 => 'Selected (constant)',
8663             1 => 'All (constant)',
8664             2 => 'Selected (pre-AF, focused)',
8665             3 => 'Selected (focused)',
8666             4 => 'Disabled',
8667        },
8668    },
8669    17 => { #52
8670        Name => 'VFDisplayIllumination',
8671        PrintConv => {
8672             0 => 'Auto',
8673             1 => 'Enable',
8674             2 => 'Disable',
8675        },
8676    },
8677    18 => { #52
8678        Name => 'AFStatusViewfinder',
8679        Condition => '$$self{Model} =~ /1D X/',
8680        Notes => '1D X only',
8681        PrintConv => {
8682             0 => 'Show in Field of View',
8683             1 => 'Show Outside View',
8684        },
8685    },
8686    19 => { #52
8687        Name => 'InitialAFPointInServo',
8688        Condition => '$$self{Model} =~ /1D X/',
8689        Notes => '1D X only',
8690        PrintConv => {
8691             0 => 'Initial AF Point Selected',
8692             1 => 'Manual AF Point',
8693             2 => 'Auto', #PH (1DXmkII)
8694        },
8695    },
8696);
8697
8698# RAW burst mode info (MakerNotes tag 0x403f) (ref 25)
8699%Image::ExifTool::Canon::RawBurstInfo = (
8700    %binaryDataAttrs,
8701    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8702    FORMAT => 'int32u',
8703    FIRST_ENTRY => 1,
8704    1 => 'RawBurstImageNum',
8705    2 => 'RawBurstImageCount',
8706);
8707
8708# Canon UUID atoms (ref PH, SX280)
8709%Image::ExifTool::Canon::uuid = (
8710    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
8711    WRITE_PROC => 'Image::ExifTool::QuickTime::WriteQuickTime',
8712    NOTES => q{
8713        Tags extracted from the uuid atom of MP4 videos from cameras such as the
8714        SX280, and CR3 images from cameras such as the EOS M50.
8715    },
8716    CNCV => {
8717        Name => 'CompressorVersion',
8718        # use this to recognize the specific type of Canon RAW (CR3 or CRM)
8719        RawConv => '$self->OverrideFileType($1) if $val =~ /^Canon(\w{3})/i; $val',
8720    },
8721    # CNDM - 4 bytes - 0xff,0xd8,0xff,0xd9
8722    CNTH => {
8723        Name => 'CanonCNTH',
8724        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CNTH' },
8725    },
8726    CCTP => { # (CR3 files)
8727        Name => 'CanonCCTP',
8728        SubDirectory => {
8729            TagTable => 'Image::ExifTool::Canon::CCTP',
8730            Start => '12',
8731        },
8732    },
8733    # CTBO - (CR3 files) int32u entry count N, N x (int32u index, int64u offset, int64u size)
8734    #        index: 1=XMP, 2=PRVW, 3=mdat, 4=?, 5=?
8735    #        --> ignored when reading, but offsets are updated when writing
8736    CMT1 => { # (CR3 files)
8737        Name => 'IFD0',
8738        SubDirectory => {
8739            TagTable => 'Image::ExifTool::Exif::Main',
8740            ProcessProc => \&Image::ExifTool::ProcessTIFF,
8741            WriteProc => \&Image::ExifTool::WriteTIFF,
8742        },
8743    },
8744    CMT2 => { # (CR3 files)
8745        Name => 'ExifIFD',
8746        SubDirectory => {
8747            TagTable => 'Image::ExifTool::Exif::Main',
8748            ProcessProc => \&Image::ExifTool::ProcessTIFF,
8749            WriteProc => \&Image::ExifTool::WriteTIFF,
8750        },
8751    },
8752    CMT3 => { # (CR3 files)
8753        Name => 'MakerNoteCanon',
8754        SubDirectory => {
8755            TagTable => 'Image::ExifTool::Canon::Main',
8756            ProcessProc => \&ProcessCMT3,
8757            WriteProc => \&Image::ExifTool::WriteTIFF,
8758        },
8759    },
8760    CMT4 => { # (CR3 files)
8761        Name => 'GPSInfo',
8762        SubDirectory => {
8763            TagTable => 'Image::ExifTool::GPS::Main',
8764            ProcessProc => \&Image::ExifTool::ProcessTIFF,
8765            WriteProc => \&Image::ExifTool::WriteTIFF,
8766            DirName => 'GPS',
8767        },
8768    },
8769    THMB => {
8770        Name => 'ThumbnailImage',
8771        Groups => { 2 => 'Preview' },
8772        RawConv => 'substr($val, 16)',
8773        Binary => 1,
8774    },
8775    CNOP => { #PH (M50)
8776        Name => 'CanonCNOP',
8777        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CNOP' },
8778    },
8779);
8780
8781# Canon top-level uuid atoms (ref PH, written by DPP4)
8782%Image::ExifTool::Canon::uuid2 = (
8783    WRITE_PROC => 'Image::ExifTool::QuickTime::WriteQuickTime',
8784    CNOP => {
8785        Name => 'CanonVRD',
8786        SubDirectory => {
8787            TagTable => 'Image::ExifTool::CanonVRD::Main',
8788            WriteProc => 'Image::ExifTool::CanonVRD::WriteCanonDR4',
8789        },
8790    },
8791);
8792
8793%Image::ExifTool::Canon::UnknownIFD = (
8794    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8795);
8796
8797# Canon CCTP atoms (ref PH, CR3 files)
8798%Image::ExifTool::Canon::CCTP = (
8799    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
8800    # CCDT - int32u[3]: 0. 0, 1. decoder type?, 2. 0, 3. index
8801);
8802
8803# 'CMP1' atom information (ref 54, CR3 files)
8804%Image::ExifTool::Canon::CMP1 = (
8805    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
8806    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
8807    FORMAT => 'int16u',
8808    FIRST_ENTRY => 0,
8809    PRIORITY => 0,
8810    8  => { Name => 'ImageWidth',  Format => 'int32u' },
8811    10 => { Name => 'ImageHeight', Format => 'int32u' },
8812    # (the rest of the documented tags don't seem to produced good values with my samples - PH)
8813);
8814
8815# 'CDI1' atom information (ref PH, CR3 files)
8816%Image::ExifTool::Canon::CDI1 = (
8817    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
8818    IAD1 => { Name => 'IAD1', SubDirectory => { TagTable => 'Image::ExifTool::Canon::IAD1' } },
8819);
8820
8821# 'IAD1' atom information (ref 54, CR3 files)
8822%Image::ExifTool::Canon::IAD1 = (
8823    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
8824    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
8825    FORMAT => 'int16u',
8826    FIRST_ENTRY => 0,
8827);
8828
8829# Canon Timed MetaData (ref PH, CR3 files)
8830%Image::ExifTool::Canon::CTMD = (
8831    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
8832    PROCESS_PROC => \&ProcessCTMD,
8833    NOTES => q{
8834        Canon Timed MetaData tags found in CR3 images.  The L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option
8835        is automatically applied when reading CR3 files to be able to extract this
8836        information.
8837    },
8838    1 => {
8839        Name => 'TimeStamp',
8840        Groups => { 2 => 'Time' },
8841        RawConv => q{
8842            my $fmt = GetByteOrder() eq 'MM' ? 'x2nCCCCCC' : 'x2vCCCCCC';
8843            sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d.%.2d', unpack($fmt, $val));
8844        },
8845        PrintConv => '$self->ConvertDateTime($val)',
8846    },
8847  # 3 - 4 bytes, seen: ff ff ff ff
8848    4 => {
8849        Name => 'FocalInfo',
8850        SubDirectory => { TagTable => 'Image::ExifTool::Canon::FocalInfo' },
8851    },
8852    5 => {
8853        Name => 'ExposureInfo',
8854        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ExposureInfo' },
8855    },
8856    7 => {
8857        Name => 'ExifInfo7',
8858        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ExifInfo' },
8859    },
8860    8 => {
8861        Name => 'ExifInfo8',
8862        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ExifInfo' },
8863    },
8864    9 => {
8865        Name => 'ExifInfo9',
8866        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ExifInfo' },
8867    },
8868  # 10 - 60 bytes: all zeros with a pair of 0xff's at offset 0x02 (C200 CRM)
8869  # 11 - 612 bytes: all zero with pairs of 0xff's at offset 0x6e and 0x116 (C200 CRM)
8870);
8871
8872# Canon Timed MetaData (ref PH, CR3 files)
8873%Image::ExifTool::Canon::ExifInfo = (
8874    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
8875    PROCESS_PROC => \&ProcessExifInfo,
8876    0x8769 => {
8877        Name => 'ExifIFD',
8878        SubDirectory => {
8879            TagTable => 'Image::ExifTool::Exif::Main',
8880            ProcessProc => \&Image::ExifTool::ProcessTIFF,
8881        },
8882    },
8883    0x927c => {
8884        Name => 'MakerNoteCanon',
8885        SubDirectory => {
8886            TagTable => 'Image::ExifTool::Canon::Main',
8887            ProcessProc => \&Image::ExifTool::ProcessTIFF,
8888        },
8889    },
8890);
8891
8892# timed focal length information (ref PH, CR3 files)
8893%Image::ExifTool::Canon::FocalInfo = (
8894    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
8895    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
8896    FORMAT => 'int32u',
8897    FIRST_ENTRY => 0,
8898    0 => {
8899        Name => 'FocalLength',
8900        Format => 'rational32u',
8901        PrintConv => 'sprintf("%.1f mm",$val)',
8902    },
8903);
8904
8905# timed exposure information (ref PH, CR3 files)
8906%Image::ExifTool::Canon::ExposureInfo = (
8907    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
8908    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
8909    FORMAT => 'int32u',
8910    FIRST_ENTRY => 0,
8911    0 => {
8912        Name => 'FNumber',
8913        Format => 'rational32u',
8914        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
8915    },
8916    1 => {
8917        Name => 'ExposureTime',
8918        Format => 'rational32u',
8919        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
8920    },
8921    2 => {
8922        Name => 'ISO',
8923        Format => 'int32u',
8924        ValueConv => '$val & 0x7fffffff',   # (not sure what high bit indicates)
8925    },
8926);
8927
8928%Image::ExifTool::Canon::CNTH = (
8929    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
8930    VARS => { ATOM_COUNT => 1 },    # only one contained atom
8931    WRITABLE => 1,
8932    WRITE_PROC => 'Image::ExifTool::QuickTime::WriteQuickTime',
8933    NOTES => q{
8934        Canon-specific QuickTime tags found in the CNTH atom of MOV/MP4 videos from
8935        some cameras.
8936    },
8937    CNDA => {
8938        Name => 'ThumbnailImage',
8939        Groups => { 2 => 'Preview' },
8940        Format => 'undef',
8941        Notes => 'the full THM image, embedded metadata is extracted as the first sub-document',
8942        SetBase => 1,
8943        RawConv => q{
8944            $$self{DOC_NUM} = ++$$self{DOC_COUNT};
8945            $self->ExtractInfo(\$val, { ReEntry => 1 });
8946            $$self{DOC_NUM} = 0;
8947            return \$val;
8948        },
8949        RawConvInv => '$val',
8950    },
8951);
8952
8953# Canon CNOP atoms (ref PH)
8954%Image::ExifTool::Canon::CNOP = (
8955    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
8956    # CNFB - 52 bytes (7DmkII,M50,C200)
8957    # CNMI - 4 bytes: "0x20000001" (C200)
8958    # CNCM - 48 bytes: original file name in bytes 24-31 (C200)
8959);
8960
8961# 'skip' atom of Canon MOV videos (ref PH)
8962%Image::ExifTool::Canon::Skip = (
8963    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
8964    NOTES => 'Information found in the "skip" atom of Canon MOV videos.',
8965    CNDB => { Name => 'Unknown_CNDB', Unknown => 1, Binary => 1 },
8966);
8967
8968# Canon composite tags
8969%Image::ExifTool::Canon::Composite = (
8970    GROUPS => { 2 => 'Camera' },
8971    DriveMode => {
8972        Require => {
8973            0 => 'ContinuousDrive',
8974            1 => 'SelfTimer',
8975        },
8976        ValueConv => '$val[0] ? 0 : ($val[1] ? 1 : 2)',
8977        PrintConv => {
8978            0 => 'Continuous Shooting',
8979            1 => 'Self-timer Operation',
8980            2 => 'Single-frame Shooting',
8981        },
8982    },
8983    Lens => {
8984        Require => {
8985            0 => 'Canon:MinFocalLength',
8986            1 => 'Canon:MaxFocalLength',
8987        },
8988        ValueConv => '$val[0]',
8989        PrintConv => 'Image::ExifTool::Canon::PrintFocalRange(@val)',
8990    },
8991    Lens35efl => {
8992        Description => 'Lens',
8993        Require => {
8994            0 => 'Canon:MinFocalLength',
8995            1 => 'Canon:MaxFocalLength',
8996            3 => 'Lens',
8997        },
8998        Desire => {
8999            2 => 'ScaleFactor35efl',
9000        },
9001        ValueConv => '$val[3] * ($val[2] ? $val[2] : 1)',
9002        PrintConv => '$prt[3] . ($val[2] ? sprintf(" (35 mm equivalent: %s)",Image::ExifTool::Canon::PrintFocalRange(@val)) : "")',
9003    },
9004    ShootingMode => {
9005        Require => {
9006            0 => 'CanonExposureMode',
9007            1 => 'EasyMode',
9008        },
9009        Desire => {
9010            2 => 'BulbDuration',
9011        },
9012        # most Canon models set CanonExposureMode to Manual (4) for Bulb shots,
9013        # but the 1DmkIII uses a value of 7 for Bulb, so use this for other
9014        # models too (Note that Canon DPP reports "Manual Exposure" here)
9015        ValueConv => '$val[0] ? (($val[0] eq "4" and $val[2]) ? 7 : $val[0]) : $val[1] + 10',
9016        PrintConv => '$val eq "7" ? "Bulb" : ($val[0] ? $prt[0] : $prt[1])',
9017    },
9018    FlashType => {
9019        Notes => q{
9020            may report "Built-in Flash" for some Canon cameras with external flash in
9021            manual mode
9022        },
9023        Require => {
9024            0 => 'FlashBits',
9025        },
9026        RawConv => '$val[0] ? $val : undef',
9027        ValueConv => '$val[0]&(1<<14)? 1 : 0',
9028        PrintConv => {
9029            0 => 'Built-In Flash',
9030            1 => 'External',
9031        },
9032    },
9033    RedEyeReduction => {
9034        Require => {
9035            0 => 'CanonFlashMode',
9036            1 => 'FlashBits',
9037        },
9038        RawConv => '$val[1] ? $val : undef',
9039        ValueConv => '($val[0]==3 or $val[0]==4 or $val[0]==6) ? 1 : 0',
9040        PrintConv => {
9041            0 => 'Off',
9042            1 => 'On',
9043        },
9044    },
9045    # same as FlashExposureComp, but undefined if no flash
9046    ConditionalFEC => {
9047        Description => 'Flash Exposure Compensation',
9048        Require => {
9049            0 => 'FlashExposureComp',
9050            1 => 'FlashBits',
9051        },
9052        RawConv => '$val[1] ? $val : undef',
9053        ValueConv => '$val[0]',
9054        PrintConv => '$prt[0]',
9055    },
9056    # hack to assume 1st curtain unless we see otherwise
9057    ShutterCurtainHack => {
9058        Description => 'Shutter Curtain Sync',
9059        Desire => {
9060            0 => 'ShutterCurtainSync',
9061        },
9062        Require => {
9063            1 => 'FlashBits',
9064        },
9065        RawConv => '$val[1] ? $val : undef',
9066        ValueConv => 'defined($val[0]) ? $val[0] : 0',
9067        PrintConv => {
9068            0 => '1st-curtain sync',
9069            1 => '2nd-curtain sync',
9070        },
9071    },
9072    WB_RGGBLevels => {
9073        Require => {
9074            0 => 'Canon:WhiteBalance',
9075        },
9076        Desire => {
9077            1 => 'WB_RGGBLevelsAsShot',
9078            # indices of the following entries correspond to Canon:WhiteBalance + 2
9079            2 => 'WB_RGGBLevelsAuto',
9080            3 => 'WB_RGGBLevelsDaylight',
9081            4 => 'WB_RGGBLevelsCloudy',
9082            5 => 'WB_RGGBLevelsTungsten',
9083            6 => 'WB_RGGBLevelsFluorescent',
9084            7 => 'WB_RGGBLevelsFlash',
9085            8 => 'WB_RGGBLevelsCustom',
9086           10 => 'WB_RGGBLevelsShade',
9087           11 => 'WB_RGGBLevelsKelvin',
9088        },
9089        ValueConv => '$val[1] ? $val[1] : $val[($val[0] || 0) + 2]',
9090    },
9091    ISO => {
9092        Priority => 0,  # let EXIF:ISO take priority
9093        Desire => {
9094            0 => 'Canon:CameraISO',
9095            1 => 'Canon:BaseISO',
9096            2 => 'Canon:AutoISO',
9097        },
9098        Notes => 'use CameraISO if numerical, otherwise calculate as BaseISO * AutoISO / 100',
9099        ValueConv => q{
9100            return $val[0] if $val[0] and $val[0] =~ /^\d+$/;
9101            return undef unless $val[1] and $val[2];
9102            return $val[1] * $val[2] / 100;
9103        },
9104        PrintConv => 'sprintf("%.0f",$val)',
9105    },
9106    DigitalZoom => {
9107        Require => {
9108            0 => 'Canon:ZoomSourceWidth',
9109            1 => 'Canon:ZoomTargetWidth',
9110            2 => 'Canon:DigitalZoom',
9111        },
9112        RawConv => q{
9113            ToFloat(@val);
9114            return undef unless $val[2] and $val[2] == 3 and $val[0] and $val[1];
9115            return $val[1] / $val[0];
9116        },
9117        PrintConv => 'sprintf("%.2fx",$val)',
9118    },
9119    OriginalDecisionData => {
9120        Flags => ['Writable','Protected'],
9121        WriteGroup => 'MakerNotes',
9122        Require => 'OriginalDecisionDataOffset',
9123        RawConv => 'Image::ExifTool::Canon::ReadODD($self,$val[0])',
9124    },
9125    FileNumber => {
9126        Groups => { 2 => 'Image' },
9127        Writable => 1,
9128        WriteCheck => '$val=~/\d+-\d+/ ? undef : "Invalid format"',
9129        DelCheck => '"Can\'t delete"',
9130        Require => {
9131            0 => 'DirectoryIndex',
9132            1 => 'FileIndex',
9133        },
9134        WriteAlso => {
9135            DirectoryIndex => '$val=~/(\d+)-(\d+)/; $1',
9136            FileIndex => '$val=~/(\d+)-(\d+)/; $2',
9137        },
9138        ValueConv => q{
9139            # fix the funny things that these numbers do when they wrap over 9999
9140            # (it seems that FileIndex and DirectoryIndex actually store the
9141            #  numbers from the previous image, so we need special logic
9142            #  to handle the FileIndex wrap properly)
9143            $val[1] == 10000 and $val[1] = 1, ++$val[0];
9144            return sprintf("%.3d-%.4d",@val);
9145        },
9146    },
9147);
9148
9149# add our composite tags
9150Image::ExifTool::AddCompositeTags('Image::ExifTool::Canon');
9151
9152#------------------------------------------------------------------------------
9153# Return lens name with teleconverter if applicable
9154# Inputs: 0) lens name string, 1) short focal length
9155# Returns: lens string with tc if appropriate
9156sub LensWithTC($$)
9157{
9158    my ($lens, $shortFocal) = @_;
9159
9160    # add teleconverter multiplication factor if applicable
9161    # (and if the LensType doesn't already include one)
9162    if (not $lens =~ /x$/ and $lens =~ /(\d+)/) {
9163        my $sf = $1;    # short focal length
9164        my $tc;
9165        foreach $tc (1, 1.4, 2, 2.8) {
9166            next if abs($shortFocal - $sf * $tc) > 0.9;
9167            $lens .= " + ${tc}x" if $tc > 1;
9168            last;
9169        }
9170    }
9171    return $lens;
9172}
9173
9174#------------------------------------------------------------------------------
9175# Attempt to calculate sensor size for Canon cameras
9176# Inputs: 0/1) rational values for FocalPlaneX/YResolution
9177# Returns: Sensor diagonal size in mm, or undef
9178# Notes: This algorithm is fairly reliable, but has been found to give incorrect
9179#        values for some firmware versions of the EOS 20D, A310, SD40 and IXUS 65
9180# (ref http://wyw.dcweb.cn/download.asp?path=&file=jhead-2.96-ccdwidth_hack.zip)
9181sub CalcSensorDiag($$)
9182{
9183    my ($xres, $yres) = @_;
9184    # most Canon cameras store the sensor size in the denominator
9185    if ($xres and $yres) {
9186        # assumptions: 1) numerators are image width/height * 1000
9187        # 2) denominators are sensor width/height in inches * 1000
9188        my @xres = split /[ \/]/, $xres;
9189        my @yres = split /[ \/]/, $yres;
9190        # verify assumptions as best we can:
9191            # numerators are always divisible by 1000
9192        if ($xres[0] % 1000 == 0 and $yres[0] % 1000 == 0 and
9193            # at least 640x480 pixels (DC models - PH)
9194            $xres[0] >= 640000 and $yres[0] >= 480000 and
9195            # ... but not too big!
9196            $xres[0] < 10000000 and $yres[0] < 10000000 and
9197            # minimum sensor size is 0.061 inches (DC models - PH)
9198            $xres[1] >= 61 and $xres[1] < 1500 and
9199            $yres[1] >= 61 and $yres[1] < 1000 and
9200            # sensor isn't square (may happen if rationals have been reduced)
9201            $xres[1] != $yres[1])
9202        {
9203            return sqrt($xres[1]*$xres[1] + $yres[1]*$yres[1]) * 0.0254;
9204        }
9205    }
9206    return undef;
9207}
9208
9209#------------------------------------------------------------------------------
9210# Attempt to identify the specific lens if multiple lenses have the same LensType
9211# Inputs: 0) PrintConv hash ref, 1) LensType, 2) MinFocalLength, 3) MaxFocalLength
9212#         4) MaxAperture, 5) LensModel
9213# Notes: PrintConv, LensType, MinFocalLength and MaxFocalLength must be defined.
9214#        Other inputs are optional.
9215sub PrintLensID(@)
9216{
9217    my ($printConv, $lensType, $shortFocal, $longFocal, $maxAperture, $lensModel) = @_;
9218    my $lens;
9219    $lens = $$printConv{$lensType} unless $lensType eq '-1' or $lensType eq '65535';
9220    if ($lens) {
9221        # return this lens unless other lenses have the same LensType
9222        return LensWithTC($lens, $shortFocal) unless $$printConv{"$lensType.1"};
9223        $lens =~ s/ or .*//s;    # remove everything after "or"
9224        # make list of all possible matching lenses
9225        my @lenses = ( $lens );
9226        my $i;
9227        for ($i=1; $$printConv{"$lensType.$i"}; ++$i) {
9228            push @lenses, $$printConv{"$lensType.$i"};
9229        }
9230        my ($tc, @user, @maybe, @likely, @matches);
9231        # look for lens in user-defined lenses
9232        foreach $lens (@lenses) {
9233            push @user, $lens if $Image::ExifTool::userLens{$lens};
9234        }
9235        # attempt to determine actual lens
9236        foreach $tc (1, 1.4, 2, 2.8) {  # loop through teleconverter scaling factors
9237            foreach $lens (@lenses) {
9238                next unless $lens =~ /(\d+)(?:-(\d+))?mm.*?(?:[fF]\/?)(\d+(?:\.\d+)?)(?:-(\d+(?:\.\d+)?))?/;
9239                # ($1=short focal, $2=long focal, $3=max aperture wide, $4=max aperture tele)
9240                my ($sf, $lf, $sa, $la) = ($1, $2, $3, $4);
9241                # see if we can rule out this lens by focal length or aperture
9242                $lf = $sf if $sf and not $lf;
9243                $la = $sa if $sa and not $la;
9244                # account for converter-specific LensType's (ie. end with " + #.#x")
9245                if ($lens =~ / \+ (\d+(\.\d+)?)x$/) {
9246                    $sf *= $1;  $lf *= $1;
9247                    $sa *= $1;  $la *= $1;
9248                }
9249                next if abs($shortFocal - $sf * $tc) > 0.9;
9250                my $tclens = $lens;
9251                $tclens .= " + ${tc}x" if $tc > 1;
9252                push @maybe, $tclens;
9253                next if abs($longFocal  - $lf * $tc) > 0.9;
9254                push @likely, $tclens;
9255                if ($maxAperture) {
9256                    # (not 100% sure that TC affects MaxAperture, but it should!)
9257                    # (RF 24-105mm F4L IS USM shows a MaxAperture of 4.177)
9258                    next if $maxAperture < $sa * $tc - 0.18;
9259                    next if $maxAperture > $la * $tc + 0.18;
9260                }
9261                push @matches, $tclens;
9262            }
9263            last if @maybe;
9264        }
9265        if (@user) {
9266            # choose the best match if we have more than one
9267            if (@user > 1) {
9268                my ($try, @good);
9269                foreach $try (\@matches, \@likely, \@maybe) {
9270                    foreach (@$try) {
9271                        $Image::ExifTool::userLens{$_} and push(@good, $_), next;
9272                        # check for match with TC string removed
9273                        next unless /^(.*) \+ \d+(\.\d+)?x$/;
9274                        $Image::ExifTool::userLens{$1} and push(@good, $_);
9275                    }
9276                    return join(' or ', @good) if @good;
9277                }
9278            }
9279            # default to returning the first user-defined lens
9280            return LensWithTC($user[0], $shortFocal);
9281        }
9282        # differentiate Sigma Art/Contemporary/Sports models
9283        if (@matches > 1 and $lensModel and $lensModel =~ /(\| [ACS])/) {
9284            my $type = $1;
9285            my @best;
9286            foreach $lens (@matches) {
9287                push @best, $lens if $lens =~ /\Q$type/;
9288            }
9289            @matches = @best if @best;
9290        }
9291        @matches = @likely unless @matches;
9292        @matches = @maybe unless @matches;
9293        Image::ExifTool::Exif::MatchLensModel(\@matches, $lensModel);
9294        return join(' or ', @matches) if @matches;
9295    } elsif ($lensModel and $lensModel =~ /\d/) {
9296        # use lens model as written by the camera
9297        if ($printConv eq \%canonLensTypes) {
9298            # add "Canon" to the start since the Canon cameras only understand Canon lenses
9299            return "Canon $lensModel";
9300        } else {
9301            return $lensModel;
9302        }
9303    }
9304    my $str = '';
9305    if ($shortFocal) {
9306        $str .= sprintf(' %d', $shortFocal);
9307        $str .= sprintf('-%d', $longFocal) if $longFocal and $longFocal != $shortFocal;
9308        $str .= 'mm';
9309    }
9310    # (careful because Sigma LensType's may not be integer, so use string comparison)
9311    return "Unknown$str" if $lensType eq '-1' or $lensType eq '65535';
9312    return "Unknown ($lensType)$str";
9313}
9314
9315#------------------------------------------------------------------------------
9316# Swap 16-bit words in 32-bit integers
9317# Inputs: 0) string of integers
9318# Returns: string of word-swapped integers
9319sub SwapWords($)
9320{
9321    my @a = split(' ', shift);
9322    $_ = (($_ >> 16) | ($_ << 16)) & 0xffffffff foreach @a;
9323    return "@a";
9324}
9325
9326#------------------------------------------------------------------------------
9327# Validate first word of Canon binary data
9328# Inputs: 0) data pointer, 1) offset, 2-N) list of valid values
9329# Returns: true if data value is the same
9330sub Validate($$@)
9331{
9332    my ($dataPt, $offset, @vals) = @_;
9333    # the first 16-bit value is the length of the data in bytes
9334    my $dataVal = Image::ExifTool::Get16u($dataPt, $offset);
9335    my $val;
9336    foreach $val (@vals) {
9337        return 1 if $val == $dataVal;
9338    }
9339    return undef;
9340}
9341
9342#------------------------------------------------------------------------------
9343# Validate CanonAFInfo
9344# Inputs: 0) data pointer, 1) offset, 2) size
9345# Returns: true if data appears valid
9346sub ValidateAFInfo($$$)
9347{
9348    my ($dataPt, $offset, $size) = @_;
9349    return 0 if $size < 24; # must be at least 24 bytes long (PowerShot Pro1)
9350    my $af = Get16u($dataPt, $offset);
9351    return 0 if $af !~ /^(1|5|7|9|15|45|53)$/; # check NumAFPoints
9352    my $w1 = Get16u($dataPt, $offset + 4);
9353    my $h1 = Get16u($dataPt, $offset + 6);
9354    return 0 unless $h1 and $w1;
9355    my $f1 = $w1 / $h1;
9356    # check for normal aspect ratio
9357    return 1 if abs($f1 - 1.33) < 0.01 or abs($f1 - 1.67) < 0.01;
9358    # ZoomBrowser can modify this for rotated images (ref Joshua Bixby)
9359    return 1 if abs($f1 - 0.75) < 0.01 or abs($f1 - 0.60) < 0.01;
9360    my $w2 = Get16u($dataPt, $offset + 8);
9361    my $h2 = Get16u($dataPt, $offset + 10);
9362    return 0 unless $h2 and $w2;
9363    # compare aspect ratio with AF image size
9364    # (but the Powershot AFImageHeight is odd, hence the test above)
9365    return 0 if $w1 eq $h1;
9366    my $f2 = $w2 / $h2;
9367    return 1 if abs(1-$f1/$f2) < 0.01;
9368    return 1 if abs(1-$f1*$f2) < 0.01;
9369    return 0;
9370}
9371
9372#------------------------------------------------------------------------------
9373# Read original decision data from file (variable length)
9374# Inputs: 0) ExifTool object ref, 1) offset in file
9375# Returns: reference to original decision data (or undef if no data)
9376sub ReadODD($$)
9377{
9378    my ($et, $offset) = @_;
9379    return undef unless $offset;
9380    my ($raf, $buff, $buf2, $i, $warn);
9381    return undef unless defined($raf = $$et{RAF});
9382    # the data block is a variable length and starts with 0xffffffff
9383    # followed a 4-byte (int32u) version number
9384    my $pos = $raf->Tell();
9385    if ($raf->Seek($offset, 0) and $raf->Read($buff, 8)==8 and $buff=~/^\xff{4}.\0\0/s) {
9386        my $err = 1;
9387        # must set byte order in case it is different than current byte order
9388        # (we could be reading this after byte order was changed)
9389        my $oldOrder = GetByteOrder();
9390        my $version = Get32u(\$buff, 4);
9391        if ($version > 20) {
9392            ToggleByteOrder();
9393            $version = unpack('N',pack('V',$version));
9394        }
9395        if ($version == 1 or   # 1Ds (big endian)
9396            $version == 2)     # 5D/20D (little endian)
9397        {
9398            # this data is structured as follows:
9399            #  4 bytes: all 0xff
9400            #  4 bytes: version number (=1 or 2)
9401            # 20 bytes: sha1
9402            #  4 bytes: record count
9403            # for each record:
9404            # |  4 bytes: record number (beginning at 0)
9405            # |  4 bytes: block offset
9406            # |  4 bytes: block length
9407            # | 20 bytes: block sha1
9408            if ($raf->Read($buf2, 24) == 24) {
9409                $buff .= $buf2;
9410                my $count = Get32u(\$buf2, 20);
9411                # read all records if the count is reasonable
9412                if ($count and $count < 20 and
9413                    $raf->Read($buf2, $count * 32) == $count * 32)
9414                {
9415                    $buff .= $buf2;
9416                    undef $err;
9417                }
9418            }
9419        } elsif ($version == 3) { # newer models (little endian)
9420            # this data is structured as follows:
9421            #  4 bytes: all 0xff
9422            #  4 bytes: version number (=3)
9423            # 24 bytes: sha1 A length (=20) + sha1 A
9424            # 24 bytes: sha1 B length (=20) + sha1 B
9425            #  4 bytes: length of remaining data (including this length word!)
9426            #  8 bytes: salt length (=4) + salt ?
9427            #  4 bytes: unknown (=3)
9428            #  4 bytes: size of file
9429            #  4 bytes: unknown (=1 for most models, 2 for 5DmkII)
9430            #  4 bytes: unknown (=1)
9431            #  4 bytes: unknown (always the same for a given firmware version)
9432            #  4 bytes: unknown (random)
9433            #  4 bytes: record count
9434            # for each record:
9435            # |  4 bytes: record number (beginning at 1)
9436            # |  8 bytes: salt length (=4) + salt ?
9437            # | 24 bytes: sha1 length (=20) + sha1
9438            # |  4 bytes: block count
9439            # | for each block:
9440            # | |  4 bytes: block offset
9441            # | |  4 bytes: block length
9442            # followed by zero padding to end of ODD data (~72 bytes)
9443            for ($i=0; ; ++$i) {
9444                $i == 3 and undef $err, last; # success!
9445                $raf->Read($buf2, 4) == 4 or last;
9446                $buff .= $buf2;
9447                my $len = Get32u(\$buf2, 0);
9448                # (the data length includes the length word itself - doh!)
9449                $len -= 4 if $i == 2 and $len >= 4;
9450                # make sure records are a reasonable size (<= 64kB)
9451                $len <= 0x10000 and $raf->Read($buf2, $len) == $len or last;
9452                $buff .= $buf2;
9453            }
9454        } else {
9455            $warn = "Unsupported original decision data version $version";
9456        }
9457        SetByteOrder($oldOrder);
9458        unless ($err) {
9459            if ($et->Options('HtmlDump')) {
9460                $et->HDump($offset, length $buff, '[OriginalDecisionData]', undef);
9461            }
9462            $raf->Seek($pos, 0);    # restore original file position
9463            return \$buff;
9464        }
9465    }
9466    $et->Warn($warn || 'Invalid original decision data');
9467    $raf->Seek($pos, 0);    # restore original file position
9468    return undef;
9469}
9470
9471#------------------------------------------------------------------------------
9472# Convert the CameraISO value
9473# Inputs: 0) value, 1) set for inverse conversion
9474sub CameraISO($;$)
9475{
9476    my ($val, $inv) = @_;
9477    my $rtnVal;
9478    my %isoLookup = (
9479         0 => 'n/a',
9480        14 => 'Auto High', #PH (S3IS)
9481        15 => 'Auto',
9482        16 => 50,
9483        17 => 100,
9484        18 => 200,
9485        19 => 400,
9486        20 => 800, #PH
9487    );
9488    if ($inv) {
9489        $rtnVal = Image::ExifTool::ReverseLookup($val, \%isoLookup);
9490        if (not defined $rtnVal and Image::ExifTool::IsInt($val)) {
9491            $rtnVal = ($val & 0x3fff) | 0x4000;
9492        }
9493    } elsif ($val != 0x7fff) {
9494        if ($val & 0x4000) {
9495            $rtnVal = $val & 0x3fff;
9496        } else {
9497            $rtnVal = $isoLookup{$val} || "Unknown ($val)";
9498        }
9499    }
9500    return $rtnVal;
9501}
9502
9503#------------------------------------------------------------------------------
9504# Print range of focal lengths
9505# Inputs: 0) short focal, 1) long focal, 2) optional scaling factor
9506sub PrintFocalRange(@)
9507{
9508    my ($short, $long, $scale) = @_;
9509
9510    $scale or $scale = 1;
9511    if ($short == $long) {
9512        return sprintf("%.1f mm", $short * $scale);
9513    } else {
9514        return sprintf("%.1f - %.1f mm", $short * $scale, $long * $scale);
9515    }
9516}
9517
9518#------------------------------------------------------------------------------
9519# Process a serial stream of binary data
9520# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
9521# Returns: 1 on success
9522# Notes: The tagID's for serial stream tags are consecutive indices beginning
9523#        at 0, and the corresponding values must be contiguous in memory.
9524#        "Unknown" tags must be used to skip padding or unknown values.
9525# (does not yet extract Rational values)
9526sub ProcessSerialData($$$)
9527{
9528    my ($et, $dirInfo, $tagTablePtr) = @_;
9529    my $dataPt = $$dirInfo{DataPt};
9530    my $offset = $$dirInfo{DirStart};
9531    my $size = $$dirInfo{DirLen};
9532    my $base = $$dirInfo{Base} || 0;
9533    my $verbose = $et->Options('Verbose');
9534    my $dataPos = $$dirInfo{DataPos} || 0;
9535
9536    # temporarily set Unknown option so GetTagInfo() will return existing unknown tags
9537    # (require to maintain serial data synchronization)
9538    my $unknown = $et->Options(Unknown => 1);
9539    # but disable unknown tag generation (because processing ends when we run out of tags)
9540    $$et{NO_UNKNOWN} = 1;
9541
9542    $verbose and $et->VerboseDir('SerialData', undef, $size);
9543
9544    # get default format ('int8u' unless specified)
9545    my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u';
9546
9547    my ($index, %val);
9548    my $pos = 0;
9549    for ($index=0; $$tagTablePtr{$index} and $pos <= $size; ++$index) {
9550        my $tagInfo = $et->GetTagInfo($tagTablePtr, $index) or last;
9551        my $format = $$tagInfo{Format};
9552        my $count = 1;
9553        if ($format) {
9554            if ($format =~ /(.*)\[(.*)\]/) {
9555                $format = $1;
9556                $count = $2;
9557                # evaluate count to allow count to be based on previous values
9558                #### eval Format (%val, $size)
9559                $count = eval $count;
9560                $@ and warn("Format $$tagInfo{Name}: $@"), last;
9561            } elsif ($format eq 'string') {
9562                # allow string with no specified count to run to end of block
9563                $count = ($size > $pos) ? $size - $pos : 0;
9564            }
9565        } else {
9566            $format = $defaultFormat;
9567        }
9568        my $len = (Image::ExifTool::FormatSize($format) || 1) * $count;
9569        last if $pos + $len > $size;
9570        my $val = ReadValue($dataPt, $pos+$offset, $format, $count, $size-$pos);
9571        last unless defined $val;
9572        if ($verbose) {
9573            $et->VerboseInfo($index, $tagInfo,
9574                Index  => $index,
9575                Table  => $tagTablePtr,
9576                Value  => $val,
9577                DataPt => $dataPt,
9578                Size   => $len,
9579                Start  => $pos+$offset,
9580                Addr   => $pos+$offset+$base+$dataPos,
9581                Format => $format,
9582                Count  => $count,
9583            );
9584        }
9585        $val{$index} = $val;
9586        if ($$tagInfo{SubDirectory}) {
9587            my $subTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
9588            my %dirInfo = (
9589                DataPt => \$val,
9590                DataPos => $dataPos + $pos,
9591                DirStart => 0,
9592                DirLen => length($val),
9593            );
9594            $et->ProcessDirectory(\%dirInfo, $subTablePtr);
9595        } elsif (not $$tagInfo{Unknown} or $unknown) {
9596            # don't extract zero-length information
9597            $et->FoundTag($tagInfo, $val) if $count;
9598        }
9599        $pos += $len;
9600    }
9601    $et->Options(Unknown => $unknown);    # restore Unknown option
9602    delete $$et{NO_UNKNOWN};
9603    return 1;
9604}
9605
9606#------------------------------------------------------------------------------
9607# Print 1D AF points
9608# Inputs: 0) value to convert
9609# Focus point pattern:
9610#            A1  A2  A3  A4  A5  A6  A7
9611#      B1  B2  B3  B4  B5  B6  B7  B8  B9  B10
9612#    C1  C2  C3  C4  C5  C6  C7  C9  C9  C10  C11
9613#      D1  D2  D3  D4  D5  D6  D7  D8  D9  D10
9614#            E1  E2  E3  E4  E5  E6  E7
9615sub PrintAFPoints1D($)
9616{
9617    my $val = shift;
9618    return 'Unknown' unless length $val == 8;
9619    # list of focus point values for decoding the first byte of the 8-byte record.
9620    # they are the x/y positions of each bit in the AF point mask
9621    # (y is upper 3 bits / x is lower 5 bits)
9622    my @focusPts = (0,0,
9623              0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,         0,0,
9624      0x21,0x23,0x25,0x27,0x29,0x2b,0x2d,0x2f,0x31,0x33,
9625    0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4d,0x50,0x52,0x54,
9626      0x61,0x63,0x65,0x67,0x69,0x6b,0x6d,0x6f,0x71,0x73,  0,0,
9627              0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,   0,0,0,0,0
9628    );
9629    my $focus = unpack('C',$val);
9630    my @bits = split //, unpack('b*',substr($val,1));
9631    my @rows = split //, '  AAAAAAA  BBBBBBBBBBCCCCCCCCCCCDDDDDDDDDD  EEEEEEE     ';
9632    my ($focusing, $focusPt, @points);
9633    my $lastRow = '';
9634    my $col = 0;
9635    foreach $focusPt (@focusPts) {
9636        my $row = shift @rows;
9637        $col = ($row eq $lastRow) ? $col + 1 : 1;
9638        $lastRow = $row;
9639        $focusing = "$row$col" if $focus eq $focusPt;
9640        push @points, "$row$col" if shift @bits;
9641    }
9642    $focusing or $focusing = ($focus == 0xff) ? 'Auto' : sprintf('Unknown (0x%.2x)',$focus);
9643    return "$focusing (" . join(',',@points) . ')';
9644}
9645
9646#------------------------------------------------------------------------------
9647# Convert Canon hex-based EV (modulo 0x20) to real number
9648# Inputs: 0) value to convert
9649# eg) 0x00 -> 0
9650#     0x0c -> 0.33333
9651#     0x10 -> 0.5
9652#     0x14 -> 0.66666
9653#     0x20 -> 1   ...  etc
9654sub CanonEv($)
9655{
9656    my $val = shift;
9657    my $sign;
9658    # temporarily make the number positive
9659    if ($val < 0) {
9660        $val = -$val;
9661        $sign = -1;
9662    } else {
9663        $sign = 1;
9664    }
9665    my $frac = $val & 0x1f;
9666    $val -= $frac;      # remove fraction
9667    # Convert 1/3 and 2/3 codes
9668    if ($frac == 0x0c) {
9669        $frac = 0x20 / 3;
9670    } elsif ($frac == 0x14) {
9671        $frac = 0x40 / 3;
9672    }
9673    return $sign * ($val + $frac) / 0x20;
9674}
9675
9676#------------------------------------------------------------------------------
9677# Convert number to Canon hex-based EV (modulo 0x20)
9678# Inputs: 0) number
9679# Returns: Canon EV code
9680sub CanonEvInv($)
9681{
9682    my $num = shift;
9683    my $sign;
9684    # temporarily make the number positive
9685    if ($num < 0) {
9686        $num = -$num;
9687        $sign = -1;
9688    } else {
9689        $sign = 1;
9690    }
9691    my $val = int($num);
9692    my $frac = $num - $val;
9693    if (abs($frac - 0.33) < 0.05) {
9694        $frac = 0x0c
9695    } elsif (abs($frac - 0.67) < 0.05) {
9696        $frac = 0x14;
9697    } else {
9698        $frac = int($frac * 0x20 + 0.5);
9699    }
9700    return $sign * ($val * 0x20 + $frac);
9701}
9702
9703#------------------------------------------------------------------------------
9704# Read CMT3 maker notes from CR3 file
9705# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table ref
9706# Returns: data block (may be empty if no Exif data) or undef on error
9707sub ProcessCMT3($$$)
9708{
9709    my ($et, $dirInfo, $tagTablePtr) = @_;
9710
9711    # extract the static maker notes to copying to other file types if requested
9712    # Note: this won't copy makernotes in the timed metadata since these are stored
9713    # separately, but the only records they have that aren't in the static maker notes
9714    # (for the M50) are: ColorData9, Flavor, CanonCameraInfoUnknown,
9715    # VignettingCorrUnknown1, Canon_0x4033 and Canon_0x402e
9716    if (($et->Options('MakerNotes') or $$et{REQ_TAG_LOOKUP}{makernotecanon}) and
9717        $$dirInfo{DirLen} > 8)
9718    {
9719        my $dataPt = $$dirInfo{DataPt};
9720        # remove old (unused) trailer
9721        $$dataPt =~ s/(II\x2a\0|MM\0\x2a)\0{4,10}$//;
9722        # remove TIFF header and append as the Canon makernote trailer
9723        # (so offsets will be interpreted correctly)
9724        my $val = substr($$dataPt,8) . substr($$dataPt,0,8);
9725        $et->FoundTag($Image::ExifTool::Canon::uuid{CMT3}, \$val);
9726    }
9727    return $et->ProcessTIFF($dirInfo, $tagTablePtr);
9728}
9729
9730#------------------------------------------------------------------------------
9731# Process CTMD EXIF information
9732# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
9733# Returns: 1 on success
9734sub ProcessExifInfo($$$)
9735{
9736    my ($et, $dirInfo, $tagTablePtr) = @_;
9737    my $dataPt = $$dirInfo{DataPt};
9738    my $start = $$dirInfo{DirStart} || 0;
9739    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $start);
9740    my $dirEnd = $start + $dirLen;
9741    # loop through TIFF-format EXIF/MakerNote records
9742    my ($pos, $len, $tag);
9743    for ($pos = $start; $pos + 8 < $dirEnd; $pos += $len) {
9744        $len = Get32u($dataPt, $pos);
9745        $tag = Get32u($dataPt, $pos + 4);
9746        # test size/tag for valid ExifInfo (not EXIF in CRM files)
9747        last if $len < 8 or $pos + $len > $dirEnd or not $$tagTablePtr{$tag};
9748        $et->VerboseDir('ExifInfo', undef, $dirLen) if $pos == $start;
9749        $et->HandleTag($tagTablePtr, $tag, undef,
9750            DataPt  => $dataPt,
9751            Base    => $$dirInfo{Base} + $pos + 8, # base for TIFF pointers
9752            DataPos => -($pos + 8), # (relative to Base)
9753            Start   => $pos + 8,
9754            Size    => $len - 8,
9755        );
9756    }
9757    return 1;
9758}
9759
9760#------------------------------------------------------------------------------
9761# Process Canon Timed MetaData (ref PH)
9762# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
9763# Returns: 1 on success
9764sub ProcessCTMD($$$)
9765{
9766    my ($et, $dirInfo, $tagTablePtr) = @_;
9767    my $dataPt = $$dirInfo{DataPt};
9768    my $verbose = $et->Options('Verbose');
9769    my $dirLen = length $$dataPt;
9770    my $pos = 0;
9771    SetByteOrder('II');
9772    while ($pos + 6 < $dirLen) {
9773        my $size = Get32u($dataPt, $pos);
9774        my $type = Get16u($dataPt, $pos + 4);
9775        # what is the meaning of the 6-byte header of these records?:
9776        #  type 1 - 00 00 00 01 zz zz - TimeStamp(CR3/CRM); zz=00(CR3),ff(CRM)
9777        #  type 3 - 00 00 00 01 zz zz - ? "ff ff ff ff"; zz=00(CR3),ff(CRM)
9778        #  type 4 - 00 00 00 01 ff ff - FocalInfo(CR3/CRM)
9779        #  type 5 - 00 00 00 01 ff ff - ExposureInfo(CR3/CRM)
9780        #  type 6 - 00 04 00 01 ff ff - ? "03 04 00 80 e0 15 ff ff"(CRM) [0x15e0 = ColorTemperature?]
9781        #  type 7 - xx yy 00 01 ff ff - ExifIFD + MakerNotes(CR3), ?(CRM); xxyy=0101(CR3),0004(CRM)
9782        #  type 8 - 01 yy 00 01 ff ff - MakerNotes(CR3), ?(CRM); yy=01(CR3),04(CRM)
9783        #  type 9 - 01 yy 00 01 ff ff - MakerNotes(CR3), ?(CRM); yy=01(CR3),00(CRM)
9784        #  type 10- 01 00 00 01 ff ff - ? (CRM)
9785        #  type 11- 01 00 00 01 ff ff - ? (CRM)
9786        # --> maybe yy == 01 for ExifInfo?
9787        $size < 12 and $et->Warn('Short CTMD record'), last;
9788        $pos + $size > $dirLen and $et->Warn('Truncated CTMD record'), last;
9789        $et->VerboseDir("CTMD type $type", undef, $size - 6);
9790        HexDump($dataPt, 6,     # dump 6-byte header
9791            Start  => $pos + 6,
9792            Addr   => $$dirInfo{Base} + $pos + 6,
9793            Prefix => $$et{INDENT},
9794        ) if $verbose > 2;
9795        if ($$tagTablePtr{$type}) {
9796            $et->HandleTag($tagTablePtr, $type, undef,
9797                DataPt  => $dataPt,
9798                Base    => $$dirInfo{Base},
9799                Start   => $pos + 12,
9800                Size    => $size - 12,
9801            );
9802        } elsif ($verbose) {
9803            $et->VerboseDump($dataPt, Len=>$size-12, Start=>$pos+12, DataPos=>$$dirInfo{Base});
9804        }
9805        $pos += $size;
9806    }
9807    $et->Warn('Error parsing Canon CTMD data', 1) if $pos != $dirLen;
9808    return 1;
9809}
9810
9811#------------------------------------------------------------------------------
9812# Process a creative filter data
9813# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
9814# Returns: 1 on success
9815sub ProcessFilters($$$)
9816{
9817    my ($et, $dirInfo, $tagTablePtr) = @_;
9818    my $dataPt = $$dirInfo{DataPt};
9819    my $pos = $$dirInfo{DirStart};
9820    my $dirLen = $$dirInfo{DirLen};
9821    my $dataPos = $$dirInfo{DataPos} || 0;
9822    my $end = $pos + $dirLen;
9823    my $verbose = $et->Options('Verbose');
9824
9825    return 0 if $dirLen < 8;
9826    my $numFilters = Get32u($dataPt, $pos + 4);
9827    $verbose and $et->VerboseDir('Creative Filter', $numFilters);
9828    $pos += 8;
9829    my ($i, $j, $err);
9830    for ($i=0; $i<$numFilters; ++$i) {
9831        # read filter structure:
9832        # 4 bytes - filter number
9833        # 4 bytes - filter data length
9834        # 4 bytes - number of parameters:
9835        # |  4 bytes - parameter ID
9836        # |  4 bytes - parameter value count
9837        # |  4 bytes * count - parameter values (NC)
9838        $pos + 12 > $end and $err = "Truncated data for filter $i", last;
9839        my $fnum = Get32u($dataPt, $pos); # (is this an index or an ID?)
9840        my $size = Get32u($dataPt, $pos + 4);
9841        my $nparm = Get32u($dataPt, $pos + 8);
9842        my $nxt = $pos + 4 + $size;
9843        $nxt > $end and $err = "Invalid size ($size) for filter $i", last;
9844        $verbose and $et->VerboseDir("Filter $fnum", $nparm, $size);
9845        $pos += 12;
9846        for ($j=0; $j<$nparm; ++$j) {
9847            $pos + 12 > $end and $err = "Truncated data for filter $i param $j", last;
9848            my $tag = Get32u($dataPt, $pos);
9849            my $count = Get32u($dataPt, $pos + 4);
9850            $pos += 8;
9851            $pos + 4 * $count > $end and $err = "Truncated value for filter $i param $j", last;
9852            my $val = ReadValue($dataPt, $pos, 'int32s', $count, 4 * $count);
9853            $et->HandleTag($tagTablePtr, $tag, $val,
9854                DataPt  => $dataPt,
9855                DataPos => $dataPos,
9856                Start   => $pos,
9857                Size    => 4 * $count,
9858            );
9859            $pos += 4 * $count;
9860        }
9861        $pos = $nxt;    # step to next filter
9862    }
9863    $err and $et->Warn($err, 1);
9864    return 1;
9865}
9866
9867#------------------------------------------------------------------------------
9868# Write Canon maker notes
9869# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table ref
9870# Returns: data block (may be empty if no Exif data) or undef on error
9871sub WriteCanon($$$)
9872{
9873    my ($et, $dirInfo, $tagTablePtr) = @_;
9874    $et or return 1;    # allow dummy access to autoload this package
9875    my $dirData = Image::ExifTool::Exif::WriteExif($et, $dirInfo, $tagTablePtr);
9876    # add footer which is written by some Canon models (format of a TIFF header)
9877    if (defined $dirData and length $dirData and $$dirInfo{Fixup}) {
9878        $dirData .= GetByteOrder() . Set16u(42) . Set32u(0);
9879        $$dirInfo{Fixup}->AddFixup(length($dirData) - 4);
9880    }
9881    return $dirData;
9882}
9883
9884#------------------------------------------------------------------------------
98851;  # end
9886
9887__END__
9888
9889=head1 NAME
9890
9891Image::ExifTool::Canon - Canon EXIF maker notes tags
9892
9893=head1 SYNOPSIS
9894
9895This module is loaded automatically by Image::ExifTool when required.
9896
9897=head1 DESCRIPTION
9898
9899This module contains definitions required by Image::ExifTool to interpret
9900Canon maker notes in EXIF information.
9901
9902=head1 AUTHOR
9903
9904Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
9905
9906This library is free software; you can redistribute it and/or modify it
9907under the same terms as Perl itself.
9908
9909=head1 REFERENCES
9910
9911=over 4
9912
9913=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
9914
9915=item L<http://www.wonderland.org/crw/>
9916
9917=item L<http://www.cybercom.net/~dcoffin/dcraw/>
9918
9919=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm>
9920
9921=item (...plus lots of testing with my 300D, A570IS and G12!)
9922
9923=back
9924
9925=head1 ACKNOWLEDGEMENTS
9926
9927Thanks Michael Rommel and Daniel Pittman for information they provided about
9928the Digital Ixus and PowerShot S70 cameras, Juha Eskelinen and Emil Sit for
9929figuring out the 20D and 30D FileNumber, Denny Priebe for figuring out a
9930couple of 1D tags, and Michael Tiemann, Rainer Honle, Dave Nicholson, Chris
9931Huebsch, Ger Vermeulen, Darryl Zurn, D.J. Cristi, Bogdan, Vesa Kivisto and
9932Kai Harrekilde-Petersen for decoding a number of new tags.  Also thanks to
9933everyone who made contributions to the LensType lookup list or the meanings
9934of other tag values.
9935
9936=head1 SEE ALSO
9937
9938L<Image::ExifTool::TagNames/Canon Tags>,
9939L<Image::ExifTool(3pm)|Image::ExifTool>
9940
9941=cut
9942