File Coverage

blib/lib/Image/ExifTool/Panasonic.pm
Criterion Covered Total %
statement 16 139 11.5
branch 2 78 2.5
condition 0 44 0.0
subroutine 5 8 62.5
pod 0 4 0.0
total 23 273 8.4


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------
2             # File: Panasonic.pm
3             #
4             # Description: Panasonic/Leica maker notes tags
5             #
6             # Revisions: 11/10/2004 - P. Harvey Created
7             #
8             # References: 1) http://www.compton.nu/panasonic.html (based on FZ10)
9             # 2) Derived from DMC-FZ3 samples from dpreview.com
10             # 3) http://johnst.org/sw/exiftags/
11             # 4) Tels (http://bloodgate.com/) private communication (tests with FZ5)
12             # 7) http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm (2007/10/02)
13             # 8) Marcel Coenen private communication (DMC-FZ50)
14             # 9) http://forums.dpreview.com/forums/read.asp?forum=1033&message=22756430
15             # 10) http://bretteville.com/pdfs/M8Metadata_v2.pdf
16             # 11) http://www.digital-leica.com/lens_codes/index.html
17             # (now https://www.l-camera-forum.com/leica-news/leica-lens-codes/)
18             # 12) Joerg - http://www.cpanforum.com/threads/11602 (LX3 firmware 2.0)
19             # 13) Michael Byczkowski private communication (Leica M9)
20             # 14) Carl Bretteville private communication (M9)
21             # 15) Zdenek Mihula private communication (TZ8)
22             # 16) Olaf Ulrich private communication
23             # 17) https://exiftool.org/forum/index.php/topic,4922.0.html
24             # 18) Thomas Modes private communication (G6)
25             # 19) https://exiftool.org/forum/index.php/topic,5533.0.html
26             # 20) Bernd-Michael Kemper private communication (DMC-GX80/85)
27             # 21) Klaus Homeister forum post
28             # 22) Daniel Beichl private communication (G9)
29             # 23) Tim Gray private communication (M10 Monochrom)
30             # JD) Jens Duttke private communication (TZ3,FZ30,FZ50)
31             #------------------------------------------------------------------------------
32              
33             package Image::ExifTool::Panasonic;
34              
35 29     29   5189 use strict;
  29         88  
  29         1194  
36 29     29   188 use vars qw($VERSION %leicaLensTypes);
  29         90  
  29         1784  
37 29     29   212 use Image::ExifTool qw(:DataAccess :Utils);
  29         66  
  29         6965  
38 29     29   1701 use Image::ExifTool::Exif;
  29         173  
  29         186196  
39              
40             $VERSION = '2.18';
41              
42             sub ProcessLeicaLEIC($$$);
43             sub WhiteBalanceConv($;$$);
44              
45             # Leica lens types (ref 10)
46             %leicaLensTypes = (
47             OTHER => sub {
48             my ($val, $inv, $conv) = @_;
49             return undef if $inv or not $val =~ s/ .*//;
50             return $$conv{$val};
51             },
52             Notes => q{
53             the LensType value is obtained by splitting the stored value into 2
54             integers: The stored value divided by 4, and its lower 2 bits. The second
55             number is used only if necessary to identify certain manually coded lenses
56             on the M9, or the focal length of some multi-focal lenses.
57             },
58             # All M9 codes (two numbers: first the LensID then the lower 2 bits)
59             # are ref PH with samples from ref 13. From ref 10, the lower 2 bits of
60             # the LensType value give the frame selector position for most lenses,
61             # although for the 28-35-50mm (at least) it gives the focal length selection.
62             # The M9 also gives the focal length selection but for other lenses the
63             # lower 3 bits don't change with frame selector position except for the lens
64             # shows as uncoded for certain lenses and some incorrect positions of the
65             # frame selector. The bits are zero for uncoded lenses when manually coding
66             # from the menu on the M9. - PH
67             # Frame selector bits (from ref 10, M8):
68             # 1 => '28/90mm frame lines engaged',
69             # 2 => '24/35mm frame lines engaged',
70             # 3 => '50/75mm frame lines engaged',
71             '0 0' => 'Uncoded lens',
72             #
73             # NOTE: MUST ADD ENTRY TO %frameSelectorBits below when a new lens is added!!!!
74             #
75             # model number(s):
76             1 => 'Elmarit-M 21mm f/2.8', # 11134
77             3 => 'Elmarit-M 28mm f/2.8 (III)', # 11804
78             4 => 'Tele-Elmarit-M 90mm f/2.8 (II)', # 11800
79             5 => 'Summilux-M 50mm f/1.4 (II)', # 11868/11856/11114
80             6 => 'Summicron-M 35mm f/2 (IV)', # 11310/11311
81             '6 0' => 'Summilux-M 35mm f/1.4', # 11869/11870/11860
82             7 => 'Summicron-M 90mm f/2 (II)', # 11136/11137
83             9 => 'Elmarit-M 135mm f/2.8 (I/II)', # 11829
84             '9 0' => 'Apo-Telyt-M 135mm f/3.4', # 11889
85             11 => 'Summaron-M 28mm f/5.6', # ? (ref IB)
86             12 => 'Thambar-M 90mm f/2.2', # ? (ref IB)
87             16 => 'Tri-Elmar-M 16-18-21mm f/4 ASPH.',# 11626
88             '16 1' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 16mm)',
89             '16 2' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 18mm)',
90             '16 3' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 21mm)',
91             23 => 'Summicron-M 50mm f/2 (III)', # 11817, version (I) in camera menu
92             24 => 'Elmarit-M 21mm f/2.8 ASPH.', # 11135/11897
93             25 => 'Elmarit-M 24mm f/2.8 ASPH.', # 11878/11898
94             26 => 'Summicron-M 28mm f/2 ASPH.', # 11604
95             27 => 'Elmarit-M 28mm f/2.8 (IV)', # 11809
96             28 => 'Elmarit-M 28mm f/2.8 ASPH.', # 11606
97             29 => 'Summilux-M 35mm f/1.4 ASPH.', # 11874/11883
98             '29 0' => 'Summilux-M 35mm f/1.4 ASPHERICAL', # 11873 (different from "ASPH." model!)
99             30 => 'Summicron-M 35mm f/2 ASPH.', # 11879/11882
100             31 => 'Noctilux-M 50mm f/1', # 11821/11822
101             '31 0' => 'Noctilux-M 50mm f/1.2', # 11820
102             32 => 'Summilux-M 50mm f/1.4 ASPH.', # 11891/11892
103             33 => 'Summicron-M 50mm f/2 (IV, V)', # 11819/11825/11826/11816, version (II,III) in camera menu
104             34 => 'Elmar-M 50mm f/2.8', # 11831/11823/11825
105             35 => 'Summilux-M 75mm f/1.4', # 11814/11815/11810
106             36 => 'Apo-Summicron-M 75mm f/2 ASPH.', # 11637
107             37 => 'Apo-Summicron-M 90mm f/2 ASPH.', # 11884/11885
108             38 => 'Elmarit-M 90mm f/2.8', # 11807/11808, version (II) in camera menu
109             39 => 'Macro-Elmar-M 90mm f/4', # 11633/11634
110             '39 0' => 'Tele-Elmar-M 135mm f/4 (II)',# 11861
111             40 => 'Macro-Adapter M', # 14409
112             41 => 'Apo-Summicron-M 50mm f/2 ASPH.', #IB
113             '41 3' => 'Apo-Summicron-M 50mm f/2 ASPH.', #16
114             42 => 'Tri-Elmar-M 28-35-50mm f/4 ASPH.',# 11625
115             '42 1' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 28mm)',
116             '42 2' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 35mm)',
117             '42 3' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 50mm)',
118             43 => 'Summarit-M 35mm f/2.5', # ? (ref PH)
119             44 => 'Summarit-M 50mm f/2.5', # ? (ref PH)
120             45 => 'Summarit-M 75mm f/2.5', # ? (ref PH)
121             46 => 'Summarit-M 90mm f/2.5', # ?
122             47 => 'Summilux-M 21mm f/1.4 ASPH.', # ? (ref 11)
123             48 => 'Summilux-M 24mm f/1.4 ASPH.', # ? (ref 11)
124             49 => 'Noctilux-M 50mm f/0.95 ASPH.', # ? (ref 11)
125             50 => 'Elmar-M 24mm f/3.8 ASPH.', # ? (ref 11)
126             51 => 'Super-Elmar-M 21mm f/3.4 Asph', # ? (ref 16, frameSelectorBits=1)
127             '51 2' => 'Super-Elmar-M 14mm f/3.8 Asph', # ? (ref 16)
128             52 => 'Apo-Telyt-M 18mm f/3.8 ASPH.', # ? (ref PH/11)
129             53 => 'Apo-Telyt-M 135mm f/3.4', #IB
130             '53 2' => 'Apo-Telyt-M 135mm f/3.4', #16
131             '53 3' => 'Apo-Summicron-M 50mm f/2 (VI)', #LR
132             58 => 'Noctilux-M 75mm f/1.25 ASPH.', # ? (ref IB)
133             );
134              
135             # M9 frame selector bits for each lens
136             # 1 = towards lens = 28/90mm or 21mm or Adapter (or Elmarit-M 135mm f/2.8)
137             # 2 = away from lens = 24/35mm (or 35/135mm on the M9)
138             # 3 = middle position = 50/75mm or 18mm
139             my %frameSelectorBits = (
140             1 => 1,
141             3 => 1,
142             4 => 1,
143             5 => 3,
144             6 => 2,
145             7 => 1,
146             9 => 1, # (because lens has special magnifier for the rangefinder)
147             16 => 1, # or 2 or 3
148             23 => 3,
149             24 => 1,
150             25 => 2,
151             26 => 1,
152             27 => 1,
153             28 => 1,
154             29 => 2,
155             30 => 2,
156             31 => 3,
157             32 => 3,
158             33 => 3,
159             34 => 3,
160             35 => 3,
161             36 => 3,
162             37 => 1,
163             38 => 1,
164             39 => 1,
165             40 => 1,
166             42 => 1, # or 2 or 3
167             43 => 2, # (NC)
168             44 => 3, # (NC)
169             45 => 3,
170             46 => 1, # (NC)
171             47 => 1, # (NC)
172             48 => 2, # (NC)
173             49 => 3, # (NC)
174             50 => 2, # (NC)
175             51 => 1, # or 2 (ref 16)
176             52 => 3,
177             53 => 2, #16
178             );
179              
180             # conversions for ShootingMode and SceneMode
181             my %shootingMode = (
182             1 => 'Normal',
183             2 => 'Portrait',
184             3 => 'Scenery',
185             4 => 'Sports',
186             5 => 'Night Portrait',
187             6 => 'Program',
188             7 => 'Aperture Priority',
189             8 => 'Shutter Priority',
190             9 => 'Macro',
191             10 => 'Spot', #7
192             11 => 'Manual',
193             12 => 'Movie Preview', #PH (LZ6)
194             13 => 'Panning',
195             14 => 'Simple', #PH (LZ6)
196             15 => 'Color Effects', #7
197             16 => 'Self Portrait', #PH (TZ5)
198             17 => 'Economy', #7
199             18 => 'Fireworks',
200             19 => 'Party',
201             20 => 'Snow',
202             21 => 'Night Scenery',
203             22 => 'Food', #7
204             23 => 'Baby', #JD
205             24 => 'Soft Skin', #PH (LZ6)
206             25 => 'Candlelight', #PH (LZ6)
207             26 => 'Starry Night', #PH (LZ6)
208             27 => 'High Sensitivity', #7 (LZ6)
209             28 => 'Panorama Assist', #7
210             29 => 'Underwater', #7
211             30 => 'Beach', #PH (LZ6)
212             31 => 'Aerial Photo', #PH (LZ6)
213             32 => 'Sunset', #PH (LZ6)
214             33 => 'Pet', #JD
215             34 => 'Intelligent ISO', #PH (LZ6)
216             35 => 'Clipboard', #7
217             36 => 'High Speed Continuous Shooting', #7
218             37 => 'Intelligent Auto', #7
219             39 => 'Multi-aspect', #PH (TZ5)
220             41 => 'Transform', #PH (FS7)
221             42 => 'Flash Burst', #PH (FZ28)
222             43 => 'Pin Hole', #PH (FZ28)
223             44 => 'Film Grain', #PH (FZ28)
224             45 => 'My Color', #PH (GF1)
225             46 => 'Photo Frame', #PH (FS7)
226             48 => 'Movie', #PH (GM1)
227             # 49 - seen for FS4 (snow?)
228             51 => 'HDR', #12
229             52 => 'Peripheral Defocus', #Horst Wandres
230             55 => 'Handheld Night Shot', #PH (FZ47)
231             57 => '3D', #PH (3D1)
232             59 => 'Creative Control', #PH (FZ47)
233             60 => 'Intelligent Auto Plus', #20
234             62 => 'Panorama', #17
235             63 => 'Glass Through', #17
236             64 => 'HDR', #17
237             66 => 'Digital Filter', #PH (GF5 "Impressive Art", "Cross Process", "Color Select", "Star")
238             67 => 'Clear Portrait', #18
239             68 => 'Silky Skin', #18
240             69 => 'Backlit Softness', #18
241             70 => 'Clear in Backlight', #18
242             71 => 'Relaxing Tone', #18
243             72 => "Sweet Child's Face", #18
244             73 => 'Distinct Scenery', #18
245             74 => 'Bright Blue Sky', #18
246             75 => 'Romantic Sunset Glow', #18
247             76 => 'Vivid Sunset Glow', #18
248             77 => 'Glistening Water', #18
249             78 => 'Clear Nightscape', #18
250             79 => 'Cool Night Sky', #18
251             80 => 'Warm Glowing Nightscape', #18
252             81 => 'Artistic Nightscape', #18
253             82 => 'Glittering Illuminations', #18
254             83 => 'Clear Night Portrait', #18
255             84 => 'Soft Image of a Flower', #18
256             85 => 'Appetizing Food', #18
257             86 => 'Cute Dessert', #18
258             87 => 'Freeze Animal Motion', #18
259             88 => 'Clear Sports Shot', #18
260             89 => 'Monochrome', #18
261             90 => 'Creative Control', #18
262             92 => 'Handheld Night Shot', #forum11523
263             );
264              
265             %Image::ExifTool::Panasonic::Main = (
266             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
267             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
268             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
269             WRITABLE => 1,
270             0x01 => {
271             Name => 'ImageQuality',
272             Writable => 'int16u',
273             Notes => 'quality of the main image, which may be in a different file',
274             PrintConv => {
275             1 => 'TIFF', #PH (FZ20)
276             2 => 'High',
277             3 => 'Normal',
278             # 5 - seen this for 1920x1080, 30fps SZ7 video - PH
279             6 => 'Very High', #3 (Leica)
280             7 => 'RAW', #3 (Leica)
281             9 => 'Motion Picture', #PH (LZ6)
282             11 => 'Full HD Movie', #PH (V-LUX)
283             12 => '4k Movie', #PH (V-LUX)
284             },
285             },
286             0x02 => {
287             Name => 'FirmwareVersion',
288             Writable => 'undef',
289             Notes => q{
290             for some camera models such as the FZ30 this may be an internal production
291             reference number and not the actual firmware version
292             }, # (ref http://www.stevesforums.com/forums/view_topic.php?id=87764&forum_id=23&)
293             # (can be either binary or ascii -- add decimal points if binary)
294             ValueConv => '$val=~/[\0-\x2f]/ ? join(" ",unpack("C*",$val)) : $val',
295             ValueConvInv => q{
296             $val =~ /(\d+ ){3}\d+/ and $val = pack('C*',split(' ', $val));
297             length($val) == 4 or warn "Version must be 4 numbers\n";
298             return $val;
299             },
300             PrintConv => '$val=~tr/ /./; $val',
301             PrintConvInv => '$val=~tr/./ /; $val',
302             },
303             0x03 => {
304             Name => 'WhiteBalance',
305             Writable => 'int16u',
306             PrintConv => {
307             1 => 'Auto',
308             2 => 'Daylight',
309             3 => 'Cloudy',
310             4 => 'Incandescent', #PH
311             5 => 'Manual',
312             8 => 'Flash',
313             10 => 'Black & White', #3 (Leica)
314             11 => 'Manual 2', #PH (FZ8)
315             12 => 'Shade', #PH (FS7)
316             13 => 'Kelvin', #PeterK (NC)
317             14 => 'Manual 3', #forum9296
318             15 => 'Manual 4', #forum9296
319             # also seen 18,26 (forum9296)
320             19 => 'Auto (cool)', #PH (Leica C-Lux)
321             },
322             },
323             0x07 => {
324             Name => 'FocusMode',
325             Writable => 'int16u',
326             PrintConv => {
327             1 => 'Auto',
328             2 => 'Manual',
329             4 => 'Auto, Focus button', #4
330             5 => 'Auto, Continuous', #4
331             6 => 'AF-S', #18 (also seen for GF1 - PH)
332             7 => 'AF-C', #18
333             8 => 'AF-F', #18 (auto-focus flexible)
334             },
335             },
336             0x0f => [
337             {
338             Name => 'AFAreaMode',
339             Condition => '$$self{Model} =~ /DMC-FZ10\b/', #JD
340             Writable => 'int8u',
341             Count => 2,
342             Notes => 'DMC-FZ10',
343             PrintConv => {
344             '0 1' => 'Spot Mode On',
345             '0 16' => 'Spot Mode Off',
346             },
347             },{
348             Name => 'AFAreaMode',
349             Writable => 'int8u',
350             Count => 2,
351             Notes => 'other models',
352             PrintConv => { #PH
353             '0 1' => '9-area', # (FS7)
354             '0 16' => '3-area (high speed)', # (FZ8)
355             '0 23' => '23-area', #PH (FZ47,NC)
356             '0 49' => '49-area', #20
357             '0 225' => '225-area', #22
358             '1 0' => 'Spot Focusing', # (FZ8)
359             '1 1' => '5-area', # (FZ8)
360             '16' => 'Normal?', # (only mode for DMC-LC20)
361             '16 0' => '1-area', # (FZ8)
362             '16 16' => '1-area (high speed)', # (FZ8)
363             # '32 0' is Face Detect for FS7, and Face Detect or Focus Tracking
364             # for the DMC-FZ200 (ref 17), and Auto is DMC-L1 guess,
365             '32 0' => 'Tracking',
366             '32 1' => '3-area (left)?', # (DMC-L1 guess)
367             '32 2' => '3-area (center)?', # (DMC-L1 guess)
368             '32 3' => '3-area (right)?', # (DMC-L1 guess)
369             '64 0' => 'Face Detect',
370             '64 1' => 'Face Detect (animal detect on)', #forum11194
371             '64 2' => 'Face Detect (animal detect off)', #forum11194
372             '128 0' => 'Pinpoint focus', #18/forum11194
373             '240 0' => 'Tracking', #22
374             },
375             },
376             ],
377             0x1a => {
378             Name => 'ImageStabilization',
379             Writable => 'int16u',
380             PrintConv => {
381             2 => 'On, Optical',
382             3 => 'Off',
383             4 => 'On, Mode 2',
384             5 => 'On, Optical Panning', #18
385             # GF1 also has a "Mode 3" - PH
386             6 => 'On, Body-only', #PH (GX7, sensor shift?)
387             7 => 'On, Body-only Panning', #forum11194
388             9 => 'Dual IS', #20
389             10 => 'Dual IS Panning', #forum11194
390             11 => 'Dual2 IS', #forum9298
391             12 => 'Dual2 IS Panning', #forum11194
392             },
393             },
394             0x1c => {
395             Name => 'MacroMode',
396             Writable => 'int16u',
397             PrintConv => {
398             1 => 'On',
399             2 => 'Off',
400             0x101 => 'Tele-Macro', #7
401             0x201 => 'Macro Zoom', #PH (FS7)
402             },
403             },
404             0x1f => {
405             Name => 'ShootingMode',
406             Writable => 'int16u',
407             PrintConvColumns => 2,
408             PrintConv => \%shootingMode,
409             },
410             0x20 => {
411             Name => 'Audio',
412             Writable => 'int16u',
413             PrintConv => {
414             1 => 'Yes',
415             2 => 'No',
416             3 => 'Stereo', #PH (NC)
417             },
418             },
419             0x21 => { #2
420             Name => 'DataDump',
421             Writable => 0,
422             Binary => 1,
423             },
424             # 0x22 - normally 0, but 2 for 'Simple' ShootingMode in LZ6 sample - PH
425             0x23 => {
426             Name => 'WhiteBalanceBias',
427             Format => 'int16s',
428             Writable => 'int16s',
429             ValueConv => '$val / 3',
430             ValueConvInv => '$val * 3',
431             PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
432             PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
433             },
434             0x24 => {
435             Name => 'FlashBias',
436             Format => 'int16s',
437             Writable => 'int16s',
438             ValueConv => '$val / 3', #17 (older models may not have factor of 3? - PH)
439             ValueConvInv => '$val * 3',
440             PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
441             PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
442             },
443             0x25 => { #PH
444             Name => 'InternalSerialNumber',
445             Writable => 'undef',
446             Count => 16,
447             Notes => q{
448             this number is unique, and contains the date of manufacture, but is not the
449             same as the number printed on the camera body
450             },
451             PrintConv => q{
452             return $val unless $val=~/^([A-Z][0-9A-Z]{2})(\d{2})(\d{2})(\d{2})(\d{4})/;
453             my $yr = $2 + ($2 < 70 ? 2000 : 1900);
454             return "($1) $yr:$3:$4 no. $5";
455             },
456             PrintConvInv => '$_=$val; tr/A-Z0-9//dc; s/(.{3})(19|20)/$1/; $_',
457             },
458             0x26 => { #PH
459             Name => 'PanasonicExifVersion',
460             Writable => 'undef',
461             },
462             0x27 => {
463             Name => 'VideoFrameRate',
464             Writable => 'int16u',
465             Notes => 'only valid for older models',
466             PrintConv => {
467             OTHER => sub { shift },
468             0 => 'n/a',
469             },
470             },
471             0x28 => {
472             Name => 'ColorEffect',
473             Writable => 'int16u',
474             # FX30 manual: (ColorMode) natural, vivid, cool, warm, b/w, sepia
475             PrintConv => {
476             1 => 'Off',
477             2 => 'Warm',
478             3 => 'Cool',
479             4 => 'Black & White',
480             5 => 'Sepia',
481             6 => 'Happy', #PH (FX70) (yes, really. you wouldn't want sad colors now would you?)
482             8 => 'Vivid', #PH (SZ3)
483             },
484             },
485             0x29 => { #JD
486             Name => 'TimeSincePowerOn',
487             Writable => 'int32u',
488             Notes => q{
489             time in 1/100 s from when the camera was powered on to when the image is
490             written to memory card
491             },
492             ValueConv => '$val / 100',
493             ValueConvInv => '$val * 100',
494             PrintConv => sub { # convert to format "[DD days ]HH:MM:SS.ss"
495             my $val = shift;
496             my $str = '';
497             if ($val >= 24 * 3600) {
498             my $d = int($val / (24 * 3600));
499             $str .= "$d days ";
500             $val -= $d * 24 * 3600;
501             }
502             my $h = int($val / 3600);
503             $val -= $h * 3600;
504             my $m = int($val / 60);
505             $val -= $m * 60;
506             my $ss = sprintf('%05.2f', $val);
507             if ($ss >= 60) {
508             $ss = '00.00';
509             ++$m >= 60 and $m -= 60, ++$h;
510             }
511             return sprintf("%s%.2d:%.2d:%s",$str,$h,$m,$ss);
512             },
513             PrintConvInv => sub {
514             my $val = shift;
515             my @vals = ($val =~ /\d+(?:\.\d*)?/g);
516             my $sec = 0;
517             $sec += 24 * 3600 * shift(@vals) if @vals > 3;
518             $sec += 3600 * shift(@vals) if @vals > 2;
519             $sec += 60 * shift(@vals) if @vals > 1;
520             $sec += shift(@vals) if @vals;
521             return $sec;
522             },
523             },
524             0x2a => { #4
525             Name => 'BurstMode',
526             Writable => 'int16u',
527             Notes => 'decoding may be different for some models',
528             PrintConv => {
529             0 => 'Off',
530             1 => 'On', #PH (TZ5) [was "Low/High Quality" from ref 4]
531             2 => 'Auto Exposure Bracketing (AEB)', #17
532             3 => 'Focus Bracketing', #forum11194
533             4 => 'Unlimited', #PH (TZ5)
534             8 => 'White Balance Bracketing', #18
535             17 => 'On (with flash)', #forum5597
536             18 => 'Aperture Bracketing', #forum11194
537             },
538             },
539             0x2b => { #4
540             Name => 'SequenceNumber',
541             Writable => 'int32u',
542             },
543             0x2c => [
544             {
545             Name => 'ContrastMode',
546             Condition => q{
547             $$self{Model} !~ /^DMC-(FX10|G1|L1|L10|LC80|GF\d+|G2|TZ10|ZS7)$/ and
548             # tested for DC-GH6, but rule out other DC- models just in case - PH
549             $$self{Model} !~ /^DC-/
550             },
551             Flags => 'PrintHex',
552             Writable => 'int16u',
553             Notes => q{
554             this decoding seems to work for some models such as the LC1, LX2, FZ7, FZ8,
555             FZ18 and FZ50, but may not be correct for other models such as the FX10, G1, L1,
556             L10 and LC80
557             },
558             PrintConv => {
559             0x00 => 'Normal',
560             0x01 => 'Low',
561             0x02 => 'High',
562             # 0x03 - observed with LZ6 and TZ5 in Fireworks mode
563             # and GX7 in Fantasy/Retro/OldDays/HighKey - PH
564             # 0x04 - observed in MP4 movie with GM1 (EXIF and 0x39 Contrast "Normal") - PH
565             0x05 => 'Normal 2', #forum1194
566             0x06 => 'Medium Low', #PH (FZ18)
567             0x07 => 'Medium High', #PH (FZ18)
568             # 0x08 - GX7 in DynamicMonochrome mode
569             0x0d => 'High Dynamic', #PH (FZ47 in ?)
570             # 0x13 - seen for LX100 (PH)
571             0x18 => 'Dynamic Range (film-like)', #forum11194
572             0x2e => 'Match Filter Effects Toy', #forum11194
573             0x37 => 'Match Photo Style L. Monochrome', #forum11194
574             # DMC-LC1 values:
575             0x100 => 'Low',
576             0x110 => 'Normal',
577             0x120 => 'High',
578             }
579             },{
580             Name => 'ContrastMode',
581             Condition => '$$self{Model} =~ /^DMC-(GF\d+|G2)$/',
582             Notes => 'these values are used by the G2, GF1, GF2, GF3, GF5 and GF6',
583             Writable => 'int16u',
584             PrintConv => { # (decoded for GF1 unless otherwise noted)
585             0 => '-2',
586             1 => '-1',
587             2 => 'Normal',
588             3 => '+1',
589             4 => '+2',
590             # Note: Other Contrast tags will be "Normal" in any of these modes:
591             5 => 'Normal 2', # 5 - seen for Portrait (FX80) and Normal (GF6)
592             7 => 'Nature (Color Film)', # (GF1,G2; GF3 "Miniature")
593             9 => 'Expressive', #(GF3)
594             12 => 'Smooth (Color Film) or Pure (My Color)', #(GF1,G2 "Smooth Color")
595             17 => 'Dynamic (B&W Film)', #(GF1,G2)
596             22 => 'Smooth (B&W Film)', #(GF1,G2)
597             25 => 'High Dynamic', #(GF5)
598             26 => 'Retro', #(GF5)
599             27 => 'Dynamic (Color Film)', #(GF1,G2) (GF3 "High Key")
600             28 => 'Low Key', #(GF5)
601             29 => 'Toy Effect', #(GF5)
602             32 => 'Vibrant (Color Film) or Expressive (My Color)', # (GF1; G2 "Vibrant"; GF2,GF5 "Expressive")
603             33 => 'Elegant (My Color)',
604             37 => 'Nostalgic (Color Film)', # (GF1,G2; GF5 "Sepia")
605             41 => 'Dynamic Art (My Color)', # (GF5 "High Key")
606             42 => 'Retro (My Color)',
607             45 => 'Cinema', #(GF2)
608             47 => 'Dynamic Mono', #(GF5)
609             50 => 'Impressive Art', #(GF5)
610             51 => 'Cross Process', #(GF5)
611             100 => 'High Dynamic 2', #Exiv2 (G6)
612             101 => 'Retro 2', #Exiv2 (G6)
613             102 => 'High Key 2', #Exiv2 (G6)
614             103 => 'Low Key 2', #Exiv2 (G6)
615             104 => 'Toy Effect 2', #Exiv2 (G6)
616             107 => 'Expressive 2', #(GF6)
617             112 => 'Sepia', #Exiv2 (G6)
618             117 => 'Miniature', #Exiv2 (G6)
619             122 => 'Dynamic Monochrome', #(GF6)
620             127 => 'Old Days', #Exiv2 (G6)
621             132 => 'Dynamic Monochrome 2', #Exiv2 (G6)
622             135 => 'Impressive Art 2', #Exiv2 (G6)
623             136 => 'Cross Process 2', #Exiv2 (G6)
624             137 => 'Toy Pop', #Exiv2 (G6)
625             138 => 'Fantasy', #Exiv2 (G6)
626             256 => 'Normal 3', #Exiv2 (G6)
627             272 => 'Standard', #Exiv2 (G6)
628             288 => 'High', #Exiv2 (G6)
629             # more new modes for GF6:
630             # ? => 'Old Days',
631             # ? => 'Toy Pop',
632             # ? => 'Bleach Bypass',
633             # ? => 'Fantasy',
634             # ? => 'Star Filter',
635             # ? => 'One Point Color',
636             # ? => 'Sunshine',
637             },
638             },{
639             Name => 'ContrastMode',
640             Condition => '$$self{Model} =~ /^DMC-(TZ10|ZS7)$/',
641             Notes => 'these values are used by the TZ10 and ZS7',
642             Writable => 'int16u',
643             PrintConv => {
644             0 => 'Normal',
645             1 => '-2',
646             2 => '+2',
647             5 => '-1',
648             6 => '+1',
649             },
650             },{
651             Name => 'ContrastMode',
652             Writable => 'int16u',
653             },
654             ],
655             0x2d => {
656             Name => 'NoiseReduction',
657             Writable => 'int16u',
658             Notes => 'the encoding for this value is not consistent between models',
659             PrintConv => {
660             0 => 'Standard',
661             1 => 'Low (-1)',
662             2 => 'High (+1)',
663             3 => 'Lowest (-2)', #JD
664             4 => 'Highest (+2)', #JD
665             5 => '+5', #PH (NC)
666             6 => '+6', # (NC) seen for DC-S1/S1R (IB)
667             65531 => '-5', # LX100/FZ2500 "NR1" test shots at imaging-resource (PH)
668             65532 => '-4',
669             65533 => '-3',
670             65534 => '-2',
671             65535 => '-1',
672             },
673             },
674             0x2e => { #4
675             Name => 'SelfTimer',
676             Writable => 'int16u',
677             PrintConv => {
678             0 => 'Off (0)', #forum11529
679             1 => 'Off',
680             2 => '10 s',
681             3 => '2 s',
682             4 => '10 s / 3 pictures', #17
683             258 => '2 s after shutter pressed', #forum11194
684             266 => '10 s after shutter pressed', #forum11194
685             778 => '3 photos after 10 s', #forum11194
686             },
687             },
688             # 0x2f - values: 1 (LZ6,FX10K)
689             0x30 => { #7
690             Name => 'Rotation',
691             Writable => 'int16u',
692             PrintConv => {
693             1 => 'Horizontal (normal)',
694             3 => 'Rotate 180', #PH
695             6 => 'Rotate 90 CW', #PH (ref 7 gives 270 CW)
696             8 => 'Rotate 270 CW', #PH (ref 7 gives 90 CW)
697             },
698             },
699             0x31 => { #PH (FS7)
700             Name => 'AFAssistLamp',
701             Writable => 'int16u',
702             PrintConv => {
703             1 => 'Fired',
704             2 => 'Enabled but Not Used',
705             3 => 'Disabled but Required',
706             4 => 'Disabled and Not Required',
707             # have seen a value of 5 - PH
708             # values possibly related to FOC-L? - JD
709             },
710             },
711             0x32 => { #7
712             Name => 'ColorMode',
713             Writable => 'int16u',
714             PrintConv => {
715             0 => 'Normal',
716             1 => 'Natural',
717             2 => 'Vivid',
718             # have seen 3 for GF2 - PH
719             },
720             },
721             0x33 => { #JD
722             Name => 'BabyAge',
723             Writable => 'string',
724             Notes => 'or pet age', #PH
725             PrintConv => '$val eq "9999:99:99 00:00:00" ? "(not set)" : $val',
726             PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
727             },
728             0x34 => { #7/PH
729             Name => 'OpticalZoomMode',
730             Writable => 'int16u',
731             PrintConv => {
732             1 => 'Standard',
733             2 => 'Extended',
734             },
735             },
736             0x35 => { #9
737             Name => 'ConversionLens',
738             Writable => 'int16u',
739             PrintConv => { #PH (unconfirmed)
740             1 => 'Off',
741             2 => 'Wide',
742             3 => 'Telephoto',
743             4 => 'Macro',
744             },
745             },
746             0x36 => { #8
747             Name => 'TravelDay',
748             Writable => 'int16u',
749             PrintConv => '$val == 65535 ? "n/a" : $val',
750             PrintConvInv => '$val =~ /(\d+)/ ? $1 : $val',
751             },
752             # 0x37 - values: 0,1,2 (LZ6, 0 for movie preview); 257 (FX10K); 0,256 (TZ5, 0 for movie preview)
753             # --> may indicate battery power (forum11388)
754             0x38 => { #forum11388
755             Name => 'BatteryLevel',
756             Writable => 'int16u',
757             PrintConv => {
758             1 => 'Full',
759             2 => 'Medium',
760             3 => 'Low',
761             4 => 'Near Empty',
762             7 => 'Near Full',
763             8 => 'Medium Low',
764             256 => 'n/a',
765             },
766             },
767             0x39 => { #7 (L1/L10)
768             Name => 'Contrast',
769             Format => 'int16s',
770             Writable => 'int16u',
771             %Image::ExifTool::Exif::printParameter,
772             },
773             0x3a => {
774             Name => 'WorldTimeLocation',
775             Writable => 'int16u',
776             PrintConv => {
777             1 => 'Home',
778             2 => 'Destination',
779             },
780             },
781             0x3b => { #PH (TZ5/FS7)
782             # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
783             Name => 'TextStamp',
784             Writable => 'int16u',
785             PrintConv => { 1 => 'Off', 2 => 'On' },
786             },
787             0x3c => { #PH
788             Name => 'ProgramISO', # (maybe should rename this ISOSetting?)
789             Writable => 'int16u', # (new models store a long here)
790             PrintConv => {
791             OTHER => sub { shift },
792             65534 => 'Intelligent ISO', #PH (FS7)
793             65535 => 'n/a',
794             -1 => 'n/a',
795             },
796             },
797             0x3d => { #PH
798             Name => 'AdvancedSceneType',
799             Writable => 'int16u',
800             Notes => 'used together with SceneMode to derive Composite AdvancedSceneMode',
801             # see forum11194 for more info
802             },
803             0x3e => { #PH (TZ5/FS7)
804             # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
805             Name => 'TextStamp',
806             Writable => 'int16u',
807             PrintConv => { 1 => 'Off', 2 => 'On' },
808             },
809             0x3f => { #PH (TZ7)
810             Name => 'FacesDetected',
811             Writable => 'int16u',
812             },
813             0x40 => { #7 (L1/L10)
814             Name => 'Saturation',
815             Format => 'int16s',
816             Writable => 'int16u',
817             %Image::ExifTool::Exif::printParameter,
818             },
819             0x41 => { #7 (L1/L10)
820             Name => 'Sharpness',
821             Format => 'int16s',
822             Writable => 'int16u',
823             %Image::ExifTool::Exif::printParameter,
824             },
825             0x42 => { #7 (DMC-L1)
826             Name => 'FilmMode',
827             Writable => 'int16u',
828             PrintConv => {
829             0 => 'n/a', #PH (eg. FZ100 "Photo Frame" ShootingMode)
830             1 => 'Standard (color)',
831             2 => 'Dynamic (color)',
832             3 => 'Nature (color)',
833             4 => 'Smooth (color)',
834             5 => 'Standard (B&W)',
835             6 => 'Dynamic (B&W)',
836             7 => 'Smooth (B&W)',
837             # 8 => 'My Film 1'? (from owner manual)
838             # 9 => 'My Film 2'?
839             10 => 'Nostalgic', #(GH1)
840             11 => 'Vibrant', #(GH1)
841             # 12 => 'Multi Film'? (in the GH1 specs)
842             },
843             },
844             0x43 => { #forum9369
845             Name => 'JPEGQuality',
846             Writable => 'int16u',
847             PrintConv => {
848             0 => 'n/a (Movie)',
849             2 => 'High',
850             3 => 'Standard',
851             6 => 'Very High',
852             255 => 'n/a (RAW only)',
853             },
854             },
855             0x44 => {
856             Name => 'ColorTempKelvin',
857             Format => 'int16u',
858             },
859             0x45 => { #19
860             Name => 'BracketSettings',
861             Writable => 'int16u',
862             PrintConv => {
863             0 => 'No Bracket',
864             1 => '3 Images, Sequence 0/-/+',
865             2 => '3 Images, Sequence -/0/+',
866             3 => '5 Images, Sequence 0/-/+',
867             4 => '5 Images, Sequence -/0/+',
868             5 => '7 Images, Sequence 0/-/+',
869             6 => '7 Images, Sequence -/0/+',
870             },
871             },
872             0x46 => { #PH/JD
873             Name => 'WBShiftAB',
874             Format => 'int16s',
875             Writable => 'int16u',
876             Notes => 'positive is a shift toward blue',
877             },
878             0x47 => { #PH/JD
879             Name => 'WBShiftGM',
880             Format => 'int16s',
881             Writable => 'int16u',
882             Notes => 'positive is a shift toward green',
883             },
884             0x48 => { #17
885             Name => 'FlashCurtain',
886             Writable => 'int16u',
887             PrintConv => {
888             0 => 'n/a',
889             1 => '1st',
890             2 => '2nd',
891             },
892             },
893             0x49 => { #19
894             Name => 'LongExposureNoiseReduction', # (indicates availability, forum11194)
895             Writable => 'int16u',
896             PrintConv => {
897             1 => 'Off',
898             2 => 'On'
899             }
900             },
901             # 0x4a - int16u: 0
902             0x4b => { #PH
903             Name => 'PanasonicImageWidth',
904             Writable => 'int32u',
905             },
906             0x4c => { #PH
907             Name => 'PanasonicImageHeight',
908             Writable => 'int32u',
909             },
910             0x4d => { #PH (FS7)
911             Name => 'AFPointPosition',
912             Writable => 'rational64u',
913             Count => 2,
914             Notes => 'X Y coordinates of primary AF area center, in the range 0.0 to 1.0',
915             PrintConv => q{
916             return 'none' if $val eq '16777216 16777216';
917             my @a = split ' ', $val;
918             sprintf("%.2g %.2g",@a);
919             },
920             PrintConvInv => '$val eq "none" ? "16777216 16777216" : $val',
921             },
922             0x4e => { #PH
923             Name => 'FaceDetInfo',
924             PrintConv => 'length $val',
925             SubDirectory => {
926             TagTable => 'Image::ExifTool::Panasonic::FaceDetInfo',
927             },
928             },
929             # 0x4f,0x50 - int16u: 0
930             0x51 => {
931             Name => 'LensType',
932             Writable => 'string',
933             ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
934             ValueConvInv => '$val',
935             },
936             0x52 => { #7 (DMC-L1)
937             Name => 'LensSerialNumber',
938             Writable => 'string',
939             ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
940             ValueConvInv => '$val',
941             },
942             0x53 => { #7 (DMC-L1)
943             Name => 'AccessoryType',
944             Writable => 'string',
945             ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
946             ValueConvInv => '$val',
947             },
948             0x54 => { #19
949             Name => 'AccessorySerialNumber',
950             Writable => 'string',
951             ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
952             ValueConvInv => '$val',
953             },
954             # 0x55 - int16u: 1 (see forum9372)
955             # 0x57 - int16u: 0
956             0x59 => { #PH (FS7)
957             Name => 'Transform',
958             Writable => 'undef',
959             Notes => 'decoded as two 16-bit signed integers',
960             Format => 'int16s',
961             Count => 2,
962             PrintConv => {
963             '-3 2' => 'Slim High',
964             '-1 1' => 'Slim Low',
965             '0 0' => 'Off',
966             '1 1' => 'Stretch Low',
967             '3 2' => 'Stretch High',
968             },
969             },
970             # 0x5a - int16u: 0,2
971             # 0x5b - int16u: 0
972             # 0x5c - int16u: 0,2
973             0x5d => { #PH (GF1, FZ35)
974             Name => 'IntelligentExposure',
975             Notes => 'not valid for some models', # (doesn't change in ZS7 and GH1 images)
976             Writable => 'int16u',
977             PrintConv => {
978             0 => 'Off',
979             1 => 'Low',
980             2 => 'Standard',
981             3 => 'High',
982             },
983             },
984             # 0x5e,0x5f - undef[4]
985             0x60 => { #18
986             Name => 'LensFirmwareVersion',
987             Writable => 'undef',
988             Format => 'int8u',
989             Count => 4,
990             PrintConv => '$val=~tr/ /./; $val',
991             PrintConvInv => '$val=~tr/./ /; $val',
992             },
993             0x61 => { #PH
994             Name => 'FaceRecInfo',
995             SubDirectory => {
996             TagTable => 'Image::ExifTool::Panasonic::FaceRecInfo',
997             },
998             },
999             0x62 => { #PH (FS7)
1000             Name => 'FlashWarning',
1001             Writable => 'int16u',
1002             PrintConv => { 0 => 'No', 1 => 'Yes (flash required but disabled)' },
1003             },
1004             0x63 => { #PH
1005             # not sure exactly what this means, but in my samples this is
1006             # FacesRecognized bytes of 0x01, padded with 0x00 to a length of 4 - PH
1007             Name => 'RecognizedFaceFlags',
1008             Format => 'int8u',
1009             Count => 4,
1010             Writable => 'undef',
1011             Unknown => 1,
1012             },
1013             0x65 => { #15
1014             Name => 'Title',
1015             Format => 'string',
1016             Writable => 'undef', # (Count 64)
1017             },
1018             0x66 => { #15
1019             Name => 'BabyName',
1020             Notes => 'or pet name',
1021             Format => 'string',
1022             Writable => 'undef', # (Count 64)
1023             },
1024             0x67 => { #15
1025             Name => 'Location',
1026             Groups => { 2 => 'Location' },
1027             Format => 'string',
1028             Writable => 'undef', # (Count 64)
1029             },
1030             # 0x68 - int8u: 1
1031             0x69 => { #PH (ZS7)
1032             Name => 'Country', # (Country/Region)
1033             Groups => { 2 => 'Location' },
1034             Format => 'string',
1035             Writable => 'undef', # (Count 72)
1036             },
1037             # 0x6a - int8u: 1
1038             0x6b => { #PH (ZS7)
1039             Name => 'State', # (State/Province/Count -- what is Count?)
1040             Groups => { 2 => 'Location' },
1041             Format => 'string',
1042             Writable => 'undef', # (Count 72)
1043             },
1044             # 0x6c - int8u: 1
1045             0x6d => { #PH (ZS7) (also see forum5997)
1046             Name => 'City', # (City/Town)
1047             Groups => { 2 => 'Location' },
1048             Format => 'string',
1049             Writable => 'undef', # (Count 72)
1050             Notes => 'City/Town as stored by some models, or County/Township for others',
1051             },
1052             # 0x6e - int8u: 1
1053             0x6f => { #PH (ZS7)
1054             Name => 'Landmark', # (Landmark)
1055             Groups => { 2 => 'Location' },
1056             Format => 'string',
1057             Writable => 'undef', # (Count 128)
1058             },
1059             0x70 => { #PH (ZS7)
1060             Name => 'IntelligentResolution',
1061             Writable => 'int8u',
1062             PrintConv => {
1063             0 => 'Off',
1064             # Note: I think these values make sense for the GH2, but meanings
1065             # may be different for other models
1066             1 => 'Low',
1067             2 => 'Standard',
1068             3 => 'High',
1069             4 => 'Extended',
1070             },
1071             },
1072             # 0x71 - undef[128] (maybe text stamp text?)
1073             0x77 => { #18
1074             Name => 'BurstSpeed',
1075             Writable => 'int16u',
1076             Notes => 'images per second',
1077             },
1078             # 0x72,0x73,0x74,0x75,0x77,0x78: 0
1079             # 0x76: 0, (3 for G6 with HDR on, ref 18)
1080             0x76 => { #18/21
1081             Name => 'HDRShot',
1082             Writable => 'int16u',
1083             PrintConv => { 0 => 'Off', 3 => 'On' },
1084             },
1085             0x79 => { #PH (GH2)
1086             Name => 'IntelligentD-Range',
1087             Writable => 'int16u',
1088             PrintConv => {
1089             0 => 'Off',
1090             1 => 'Low',
1091             2 => 'Standard',
1092             3 => 'High',
1093             },
1094             },
1095             # 0x7a,0x7b: 0
1096             0x7c => { #18
1097             Name => 'ClearRetouch',
1098             Writable => 'int16u',
1099             PrintConv => { 0 => 'Off', 1 => 'On' },
1100             },
1101             0x80 => { #forum5997 (seen garbage here for SZ5 - PH)
1102             Name => 'City2', # (City/Town/Village)
1103             Groups => { 2 => 'Location' },
1104             Format => 'string',
1105             Writable => 'undef', # (Count 72)
1106             Notes => 'City/Town/Village as stored by some models',
1107             },
1108             # 0x81 - undef[72]: "---"
1109             # 0x82 - undef[72]: "---"
1110             # 0x83 - undef[72]: "---"
1111             # 0x84 - undef[72]: "---"
1112             # 0x85 - undef[128]: "---"
1113             0x86 => { #http://dev.exiv2.org/issues/825
1114             Name => 'ManometerPressure',
1115             Writable => 'int16u',
1116             RawConv => '$val==65535 ? undef : $val',
1117             ValueConv => '$val / 10',
1118             ValueConvInv => '$val * 10',
1119             PrintConv => 'sprintf("%.1f kPa",$val)',
1120             PrintConvInv => '$val=~s/ ?kPa//i; $val',
1121             },
1122             0x89 => {
1123             Name => 'PhotoStyle',
1124             Writable => 'int16u',
1125             PrintConv => {
1126             0 => 'Auto',
1127             1 => 'Standard or Custom',
1128             2 => 'Vivid',
1129             3 => 'Natural',
1130             4 => 'Monochrome',
1131             5 => 'Scenery',
1132             6 => 'Portrait',
1133             8 => 'Cinelike D', #forum11194
1134             9 => 'Cinelike V', #forum11194
1135             11 => 'L. Monochrome', #forum11194
1136             12 => 'Like709', #forum14033
1137             15 => 'L. Monochrome D', #forum11194
1138             17 => 'V-Log', #forum14033
1139             18 => 'Cinelike D2', #forum14033
1140             },
1141             },
1142             0x8a => { #18
1143             Name => 'ShadingCompensation',
1144             Writable => 'int16u',
1145             PrintConv => {
1146             0 => 'Off',
1147             1 => 'On'
1148             }
1149             },
1150             0x8b => { #21
1151             Name => 'WBShiftIntelligentAuto',
1152             Writable => 'int16u',
1153             Format => 'int16s',
1154             Notes => 'value is -9 for blue to +9 for amber. Valid for Intelligent-Auto modes',
1155             },
1156             0x8c => {
1157             Name => 'AccelerometerZ',
1158             Writable => 'int16u',
1159             Format => 'int16s',
1160             Notes => 'positive is acceleration upwards',
1161             },
1162             0x8d => {
1163             Name => 'AccelerometerX',
1164             Writable => 'int16u',
1165             Format => 'int16s',
1166             Notes => 'positive is acceleration to the left',
1167             },
1168             0x8e => {
1169             Name => 'AccelerometerY',
1170             Writable => 'int16u',
1171             Format => 'int16s',
1172             Notes => 'positive is acceleration backwards',
1173             },
1174             0x8f => { #18
1175             Name => 'CameraOrientation',
1176             Writable => 'int8u',
1177             PrintConv => {
1178             0 => 'Normal',
1179             1 => 'Rotate CW',
1180             2 => 'Rotate 180',
1181             3 => 'Rotate CCW',
1182             4 => 'Tilt Upwards',
1183             5 => 'Tilt Downwards'
1184             }
1185             },
1186             0x90 => {
1187             Name => 'RollAngle',
1188             Writable => 'int16u',
1189             Format => 'int16s',
1190             Notes => 'converted to degrees of clockwise camera rotation',
1191             ValueConv => '$val / 10',
1192             ValueConvInv => '$val * 10',
1193             },
1194             0x91 => {
1195             Name => 'PitchAngle',
1196             Writable => 'int16u',
1197             Format => 'int16s',
1198             Notes => 'converted to degrees of upward camera tilt',
1199             ValueConv => '-$val / 10',
1200             ValueConvInv => '-$val * 10',
1201             },
1202             0x92 => { #21 (forum9453) (more to decode in forum11194)
1203             Name => 'WBShiftCreativeControl',
1204             Writable => 'int8u',
1205             Format => 'int8s',
1206             Notes => 'WB shift or style strength. Valid for Creative-Control modes',
1207             },
1208             0x93 => { #18
1209             Name => 'SweepPanoramaDirection',
1210             Writable => 'int8u',
1211             PrintConv => {
1212             0 => 'Off',
1213             1 => 'Left to Right',
1214             2 => 'Right to Left',
1215             3 => 'Top to Bottom',
1216             4 => 'Bottom to Top'
1217             }
1218             },
1219             0x94 => { #18
1220             Name => 'SweepPanoramaFieldOfView',
1221             Writable => 'int16u'
1222             },
1223             0x96 => { #18
1224             Name => 'TimerRecording',
1225             Writable => 'int8u',
1226             PrintConv => {
1227             0 => 'Off',
1228             1 => 'Time Lapse',
1229             2 => 'Stop-motion Animation',
1230             3 => 'Focus Bracketing', #forum11194
1231             },
1232             },
1233             0x9d => { #18
1234             Name => 'InternalNDFilter',
1235             Writable => 'rational64u'
1236             },
1237             0x9e => { #18
1238             Name => 'HDR',
1239             Writable => 'int16u',
1240             PrintConv => {
1241             0 => 'Off',
1242             100 => '1 EV',
1243             200 => '2 EV',
1244             300 => '3 EV',
1245             32868 => '1 EV (Auto)',
1246             32968 => '2 EV (Auto)',
1247             33068 => '3 EV (Auto)',
1248             },
1249             },
1250             0x9f => { #18
1251             Name => 'ShutterType',
1252             Writable => 'int16u',
1253             PrintConv => {
1254             0 => 'Mechanical',
1255             1 => 'Electronic',
1256             2 => 'Hybrid', #PH (GM1, 1st curtain electronic, 2nd curtain mechanical)
1257             },
1258             },
1259             # 0xa0 - undef[32]: AWB gains and black levels (ref forum9303)
1260             0xa1 => { #forum11194
1261             Name => 'FilterEffect',
1262             Writable => 'rational64u',
1263             Format => 'int32u',
1264             PrintConv => {
1265             # '0 0' => 'Expressive', #forum11194
1266             '0 0' => 'Off', #forum14033 (GH6)
1267             '0 1' => 'Expressive', #forum14033 (GH6) (have also seen this for XS1)
1268             '0 2' => 'Retro',
1269             '0 4' => 'High Key',
1270             '0 8' => 'Sepia',
1271             '0 16' => 'High Dynamic',
1272             '0 32' => 'Miniature Effect',
1273             '0 256' => 'Low Key',
1274             '0 512' => 'Toy Effect',
1275             '0 1024' => 'Dynamic Monochrome',
1276             '0 2048' => 'Soft Focus',
1277             '0 4096' => 'Impressive Art',
1278             '0 8192' => 'Cross Process',
1279             '0 16384' => 'One Point Color',
1280             '0 32768' => 'Star Filter',
1281             '0 524288' => 'Old Days',
1282             '0 1048576' => 'Sunshine',
1283             '0 2097152' => 'Bleach Bypass',
1284             '0 4194304' => 'Toy Pop',
1285             '0 8388608' => 'Fantasy',
1286             '0 33554432' => 'Monochrome',
1287             '0 67108864' => 'Rough Monochrome',
1288             '0 134217728' => 'Silky Monochrome',
1289             },
1290             },
1291             0xa3 => { #18
1292             Name => 'ClearRetouchValue',
1293             Writable => 'rational64u',
1294             # undef if ClearRetouch is off, 0 if it is on
1295             },
1296             0xa7 => { #forum9374 (conversion table for 14- to 16-bit mapping)
1297             Name => 'OutputLUT',
1298             Binary => 1,
1299             Notes => q{
1300             2-column by 432-row binary lookup table of unsigned short values for
1301             converting to 16-bit output (1st column) from 14 bits (2nd column) with
1302             camera contrast
1303             },
1304             },
1305             0xab => { #18
1306             Name => 'TouchAE',
1307             Writable => 'int16u',
1308             PrintConv => { 0 => 'Off', 1 => 'On' },
1309             },
1310             0xac => { #forum11194
1311             Name => 'MonochromeFilterEffect',
1312             Writable => 'int16u',
1313             PrintConv => { 0 => 'Off', 1 => 'Yellow', 2 => 'Orange', 3 => 'Red', 4 => 'Green' },
1314             },
1315             0xad => { #forum9360
1316             Name => 'HighlightShadow',
1317             Writable => 'int16u',
1318             Format => 'int16s', #forum11194
1319             Count => 2,
1320             },
1321             0xaf => { #PH (is this in UTC maybe? -- sometimes different time zone other times)
1322             Name => 'TimeStamp',
1323             Writable => 'string',
1324             Groups => { 2 => 'Time' },
1325             Shift => 'Time',
1326             PrintConv => '$self->ConvertDateTime($val)',
1327             PrintConvInv => '$self->InverseDateTime($val)',
1328             },
1329             0xb3 => { #forum11194
1330             Name => 'VideoBurstResolution',
1331             Writable => 'int16u',
1332             PrintConv => { 1 => 'Off or 4K', 4 => '6K' },
1333             },
1334             0xb4 => { #forum9429
1335             Name => 'MultiExposure',
1336             Writable => 'int16u',
1337             PrintConv => { 0 => 'n/a', 1 => 'Off', 2 => 'On' },
1338             },
1339             0xb9 => { #forum9425
1340             Name => 'RedEyeRemoval',
1341             Writable => 'int16u',
1342             PrintConv => { 0 => 'Off', 1 => 'On' },
1343             },
1344             0xbb => { #forum9282
1345             Name => 'VideoBurstMode',
1346             Writable => 'int32u',
1347             PrintHex => 1,
1348             PrintConv => {
1349             0x01 => 'Off',
1350             0x04 => 'Post Focus',
1351             0x18 => '4K Burst',
1352             0x28 => '4K Burst (Start/Stop)',
1353             0x48 => '4K Pre-burst',
1354             0x108 => 'Loop Recording',
1355             0x810 => '6K Burst',
1356             0x820 => '6K Burst (Start/Stop)',
1357             0x408 => 'Focus Stacking', #forum11563
1358             0x1001 => 'High Resolution Mode',
1359             },
1360             },
1361             0xbc => { #forum9282
1362             Name => 'DiffractionCorrection',
1363             Writable => 'int16u',
1364             PrintConv => { 0 => 'Off', 1 => 'Auto' },
1365             },
1366             0xbd => { #forum11194
1367             Name => 'FocusBracket',
1368             Notes => 'positive is further, negative is closer',
1369             Writable => 'int16u',
1370             Format => 'int16s',
1371             },
1372             0xbe => { #forum11194
1373             Name => 'LongExposureNRUsed',
1374             Writable => 'int16u',
1375             PrintConv => { 0 => 'No', 1 => 'Yes' },
1376             },
1377             0xbf => { #forum11194
1378             Name => 'PostFocusMerging',
1379             Format => 'int32u',
1380             Count => 2,
1381             PrintConv => { '0 0' => 'Post Focus Auto Merging or None' },
1382             },
1383             0xc1 => { #forum11194
1384             Name => 'VideoPreburst',
1385             Writable => 'int16u',
1386             PrintConv => { 0 => 'No', 1 => '4K or 6K' },
1387             },
1388             0xca => { #forum11459
1389             Name => 'SensorType',
1390             Writable => 'int16u',
1391             PrintConv => {
1392             0 => 'Multi-aspect',
1393             1 => 'Standard',
1394             },
1395             },
1396             # Note: LensTypeMake and LensTypeModel are combined into a Composite LensType tag
1397             # defined in Olympus.pm which has the same values as Olympus:LensType
1398             0xc4 => { #PH
1399             Name => 'LensTypeMake',
1400             Condition => '$format eq "int16u" and $$valPt ne "\xff\xff"', # (ignore make 65535 for now)
1401             Writable => 'int16u',
1402             },
1403             0xc5 => { #PH
1404             Name => 'LensTypeModel',
1405             Condition => '$format eq "int16u"',
1406             Writable => 'int16u',
1407             RawConv => q{
1408             return undef unless $val;
1409             require Image::ExifTool::Olympus; # (to load Composite LensID)
1410             return $val;
1411             },
1412             ValueConv => '$_=sprintf("%.4x",$val); s/(..)(..)/$2 $1/; $_',
1413             ValueConvInv => '$val =~ s/(..) (..)/$2$1/; hex($val)',
1414             },
1415             0xd1 => { #PH
1416             Name => 'ISO',
1417             RawConv => '$val > 0xfffffff0 ? undef : $val',
1418             Writable => 'int32u',
1419             },
1420             0xd2 => { #forum11194
1421             Name => 'MonochromeGrainEffect',
1422             Writable => 'int16u',
1423             PrintConv => {
1424             0 => 'Off',
1425             1 => 'Low',
1426             2 => 'Standard',
1427             3 => 'High',
1428             },
1429             },
1430             0xd6 => { #PH (DC-S1)
1431             Name => 'NoiseReductionStrength',
1432             Writable => 'rational64s',
1433             },
1434             0xe4 => { #IB
1435             Name => 'LensTypeModel',
1436             Condition => '$format eq "int16u"',
1437             Writable => 'int16u',
1438             RawConv => q{
1439             return undef unless $val;
1440             require Image::ExifTool::Olympus; # (to load Composite LensID)
1441             return $val;
1442             },
1443             ValueConv => '$_=sprintf("%.4x",$val); s/(..)(..)/$2 $1/; $_',
1444             ValueConvInv => '$val =~ s/(..) (..)/$2$1/; hex($val)',
1445             },
1446             0xe8 => { #PH (DC-GH6)
1447             Name => 'MinimumISO',
1448             Writable => 'int32u',
1449             },
1450             0xee => { #PH (DC-GH6)
1451             Name => 'DynamicRangeBoost',
1452             Writable => 'int16u',
1453             PrintConv => { 0 => 'Off', 1 => 'On' },
1454             },
1455             0x0e00 => {
1456             Name => 'PrintIM',
1457             Description => 'Print Image Matching',
1458             Writable => 0,
1459             SubDirectory => { TagTable => 'Image::ExifTool::PrintIM::Main' },
1460             },
1461             0x2003 => { #21
1462             Name => 'TimeInfo',
1463             SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::TimeInfo' },
1464             },
1465             0x8000 => { #PH
1466             Name => 'MakerNoteVersion',
1467             Format => 'undef',
1468             },
1469             0x8001 => { #7/PH/JD
1470             Name => 'SceneMode',
1471             Writable => 'int16u',
1472             PrintConvColumns => 2,
1473             PrintConv => {
1474             0 => 'Off',
1475             %shootingMode,
1476             },
1477             },
1478             0x8002 => { #21
1479             Name => 'HighlightWarning',
1480             Writable => 'int16u',
1481             PrintConv => { 0 => 'Disabled', 1 => 'No', 2 => 'Yes' },
1482             },
1483             0x8003 => { #21
1484             Name => 'DarkFocusEnvironment',
1485             Writable => 'int16u',
1486             PrintConv => { 1 => 'No', 2 => 'Yes' },
1487             },
1488             0x8004 => { #PH/JD
1489             Name => 'WBRedLevel',
1490             Writable => 'int16u',
1491             },
1492             0x8005 => { #PH/JD
1493             Name => 'WBGreenLevel',
1494             Writable => 'int16u',
1495             },
1496             0x8006 => { #PH/JD
1497             Name => 'WBBlueLevel',
1498             Writable => 'int16u',
1499             },
1500             #0x8007 => { #PH - questionable [disabled because it conflicts with EXIF in too many samples]
1501             # Name => 'FlashFired',
1502             # Writable => 'int16u',
1503             # PrintConv => { 0 => 'Yes', 1 => 'No' },
1504             #},
1505             0x8008 => { #PH (TZ5/FS7)
1506             # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
1507             Name => 'TextStamp',
1508             Writable => 'int16u',
1509             PrintConv => { 1 => 'Off', 2 => 'On' },
1510             },
1511             0x8009 => { #PH (TZ5/FS7)
1512             # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
1513             Name => 'TextStamp',
1514             Writable => 'int16u',
1515             PrintConv => { 1 => 'Off', 2 => 'On' },
1516             },
1517             0x8010 => { #PH
1518             Name => 'BabyAge',
1519             Writable => 'string',
1520             Notes => 'or pet age',
1521             PrintConv => '$val eq "9999:99:99 00:00:00" ? "(not set)" : $val',
1522             PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
1523             },
1524             0x8012 => { #PH (FS7)
1525             Name => 'Transform',
1526             Writable => 'undef',
1527             Notes => 'decoded as two 16-bit signed integers',
1528             Format => 'int16s',
1529             Count => 2,
1530             PrintConv => {
1531             '-3 2' => 'Slim High',
1532             '-1 1' => 'Slim Low',
1533             '0 0' => 'Off',
1534             '1 1' => 'Stretch Low',
1535             '3 2' => 'Stretch High',
1536             },
1537             },
1538             );
1539              
1540             # Leica type2 maker notes (ref 10)
1541             %Image::ExifTool::Panasonic::Leica2 = (
1542             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
1543             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1544             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
1545             WRITABLE => 1,
1546             NOTES => 'These tags are used by the Leica M8.',
1547             0x300 => {
1548             Name => 'Quality',
1549             Writable => 'int16u',
1550             PrintConv => {
1551             1 => 'Fine',
1552             2 => 'Basic',
1553             },
1554             },
1555             0x302 => {
1556             Name => 'UserProfile',
1557             Writable => 'int32u',
1558             PrintConv => {
1559             1 => 'User Profile 1',
1560             2 => 'User Profile 2',
1561             3 => 'User Profile 3',
1562             4 => 'User Profile 0 (Dynamic)',
1563             },
1564             },
1565             0x303 => {
1566             Name => 'SerialNumber',
1567             Writable => 'int32u',
1568             PrintConv => 'sprintf("%.7d", $val)',
1569             PrintConvInv => '$val',
1570             },
1571             0x304 => {
1572             Name => 'WhiteBalance',
1573             Writable => 'int16u',
1574             Notes => 'values above 0x8000 are converted to Kelvin color temperatures',
1575             PrintConv => {
1576             0 => 'Auto or Manual',
1577             1 => 'Daylight',
1578             2 => 'Fluorescent',
1579             3 => 'Tungsten',
1580             4 => 'Flash',
1581             10 => 'Cloudy',
1582             11 => 'Shade',
1583             OTHER => \&WhiteBalanceConv,
1584             },
1585             },
1586             0x310 => {
1587             Name => 'LensType',
1588             Writable => 'int32u',
1589             SeparateTable => 1,
1590             ValueConv => '($val >> 2) . " " . ($val & 0x3)',
1591             ValueConvInv => \&LensTypeConvInv,
1592             PrintConv => \%leicaLensTypes,
1593             },
1594             0x311 => {
1595             Name => 'ExternalSensorBrightnessValue',
1596             Format => 'rational64s', # (incorrectly unsigned in JPEG images)
1597             Writable => 'rational64s',
1598             Notes => '"blue dot" measurement',
1599             PrintConv => 'sprintf("%.2f", $val)',
1600             PrintConvInv => '$val',
1601             },
1602             0x312 => {
1603             Name => 'MeasuredLV',
1604             Format => 'rational64s', # (incorrectly unsigned in JPEG images)
1605             Writable => 'rational64s',
1606             Notes => 'imaging sensor or TTL exposure meter measurement',
1607             PrintConv => 'sprintf("%.2f", $val)',
1608             PrintConvInv => '$val',
1609             },
1610             0x313 => {
1611             Name => 'ApproximateFNumber',
1612             Writable => 'rational64u',
1613             PrintConv => 'sprintf("%.1f", $val)',
1614             PrintConvInv => '$val',
1615             },
1616             0x320 => {
1617             Name => 'CameraTemperature',
1618             Writable => 'int32s',
1619             PrintConv => '"$val C"',
1620             PrintConvInv => '$val=~s/ ?C//; $val',
1621             },
1622             0x321 => { Name => 'ColorTemperature', Writable => 'int32u' },
1623             0x322 => { Name => 'WBRedLevel', Writable => 'rational64u' },
1624             0x323 => { Name => 'WBGreenLevel', Writable => 'rational64u' },
1625             0x324 => { Name => 'WBBlueLevel', Writable => 'rational64u' },
1626             0x325 => {
1627             Name => 'UV-IRFilterCorrection',
1628             Description => 'UV/IR Filter Correction',
1629             Writable => 'int32u',
1630             PrintConv => {
1631             0 => 'Not Active',
1632             1 => 'Active',
1633             },
1634             },
1635             0x330 => { Name => 'CCDVersion', Writable => 'int32u' },
1636             0x331 => { Name => 'CCDBoardVersion', Writable => 'int32u' },
1637             0x332 => { Name => 'ControllerBoardVersion', Writable => 'int32u' },
1638             0x333 => { Name => 'M16CVersion', Writable => 'int32u' },
1639             0x340 => { Name => 'ImageIDNumber', Writable => 'int32u' },
1640             );
1641              
1642             # Leica type3 maker notes (ref PH)
1643             %Image::ExifTool::Panasonic::Leica3 = (
1644             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
1645             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1646             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
1647             WRITABLE => 1,
1648             NOTES => 'These tags are used by the Leica R8 and R9 digital backs.',
1649             0x0b => { #IB
1650             Name => 'SerialInfo',
1651             SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::SerialInfo' },
1652             },
1653             0x0d => {
1654             Name => 'WB_RGBLevels',
1655             Writable => 'int16u',
1656             Count => 3,
1657             },
1658             );
1659              
1660             # Leica serial number info (ref IB)
1661             %Image::ExifTool::Panasonic::SerialInfo = (
1662             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
1663             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
1664             TAG_PREFIX => 'Leica_SerialInfo',
1665             FIRST_ENTRY => 0,
1666             4 => {
1667             Name => 'SerialNumber',
1668             Format => 'string[8]',
1669             }
1670             );
1671              
1672             # Leica type4 maker notes (ref PH) (M9)
1673             %Image::ExifTool::Panasonic::Leica4 = (
1674             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
1675             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1676             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
1677             WRITABLE => 1,
1678             NOTES => 'This information is written by the M9.',
1679             0x3000 => {
1680             Name => 'Subdir3000',
1681             SubDirectory => {
1682             TagTable => 'Image::ExifTool::Panasonic::Subdir',
1683             ByteOrder => 'Unknown',
1684             },
1685             },
1686             0x3100 => {
1687             Name => 'Subdir3100',
1688             SubDirectory => {
1689             TagTable => 'Image::ExifTool::Panasonic::Subdir',
1690             ByteOrder => 'Unknown',
1691             },
1692             },
1693             0x3400 => {
1694             Name => 'Subdir3400',
1695             SubDirectory => {
1696             TagTable => 'Image::ExifTool::Panasonic::Subdir',
1697             ByteOrder => 'Unknown',
1698             },
1699             },
1700             0x3900 => {
1701             Name => 'Subdir3900',
1702             SubDirectory => {
1703             TagTable => 'Image::ExifTool::Panasonic::Subdir',
1704             ByteOrder => 'Unknown',
1705             },
1706             },
1707             );
1708              
1709             # Leica M9 SubDirectory tags (ref PH)
1710             %Image::ExifTool::Panasonic::Subdir = (
1711             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
1712             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1713             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
1714             TAG_PREFIX => 'Leica_Subdir',
1715             WRITABLE => 1,
1716             # 0x3001 - normally 0 but value of 2 when manual coding is used
1717             # with a coded lens (but only tested with Elmar-M 50mm f/2.8) - PH
1718             0x300a => {
1719             Name => 'Contrast',
1720             Writable => 'int32u',
1721             PrintConv => {
1722             0 => 'Low',
1723             1 => 'Medium Low',
1724             2 => 'Normal',
1725             3 => 'Medium High',
1726             4 => 'High',
1727             },
1728             },
1729             0x300b => {
1730             Name => 'Sharpening',
1731             Writable => 'int32u',
1732             PrintConv => {
1733             0 => 'Off',
1734             1 => 'Low',
1735             2 => 'Normal',
1736             3 => 'Medium High',
1737             4 => 'High',
1738             },
1739             },
1740             0x300d => {
1741             Name => 'Saturation',
1742             Writable => 'int32u',
1743             PrintConv => {
1744             0 => 'Low',
1745             1 => 'Medium Low',
1746             2 => 'Normal',
1747             3 => 'Medium High',
1748             4 => 'High',
1749             5 => 'Black & White',
1750             6 => 'Vintage B&W',
1751             },
1752             },
1753             # 0x3032 - some sort of RGB coefficients? (zeros unless Kelvin WB, but same for all Color Temps)
1754             0x3033 => {
1755             Name => 'WhiteBalance',
1756             Writable => 'int32u',
1757             PrintConv => { #13
1758             0 => 'Auto',
1759             1 => 'Tungsten',
1760             2 => 'Fluorescent',
1761             3 => 'Daylight Fluorescent',
1762             4 => 'Daylight',
1763             5 => 'Flash',
1764             6 => 'Cloudy',
1765             7 => 'Shade',
1766             8 => 'Manual',
1767             9 => 'Kelvin',
1768             },
1769             },
1770             0x3034 => {
1771             Name => 'JPEGQuality',
1772             Writable => 'int32u',
1773             PrintConv => {
1774             94 => 'Basic',
1775             97 => 'Fine',
1776             },
1777             },
1778             # 0x3035 (int32u): -1 unless Manual WB (2 in my Manual sample)
1779             0x3036 => {
1780             Name => 'WB_RGBLevels',
1781             Writable => 'rational64u',
1782             Count => 3,
1783             },
1784             0x3038 => {
1785             Name => 'UserProfile', # (CameraProfile according to ref 14)
1786             Writable => 'string',
1787             },
1788             0x303a => {
1789             Name => 'JPEGSize',
1790             Writable => 'int32u',
1791             PrintConv => {
1792             0 => '5216x3472',
1793             1 => '3840x2592',
1794             2 => '2592x1728',
1795             3 => '1728x1152',
1796             4 => '1280x864',
1797             },
1798             },
1799             0x3103 => { #13 (valid for FW 1.116 and later)
1800             Name => 'SerialNumber',
1801             Writable => 'string',
1802             },
1803             # 0x3104 body-dependent string ("00012905000000") (not serial number)
1804             # 0x3105 body-dependent string ("00012905000000")
1805             # 0x3107 - body-dependent string ("4H205800116800") (not serial number)
1806             0x3109 => {
1807             Name => 'FirmwareVersion',
1808             Writable => 'string',
1809             },
1810             0x312a => { #14 (NC)
1811             Name => 'BaseISO',
1812             Writable => 'int32u',
1813             },
1814             0x312b => {
1815             Name => 'SensorWidth',
1816             Writable => 'int32u',
1817             },
1818             0x312c => {
1819             Name => 'SensorHeight',
1820             Writable => 'int32u',
1821             },
1822             0x312d => { #14 (NC)
1823             Name => 'SensorBitDepth',
1824             Writable => 'int32u',
1825             },
1826             0x3402 => { #PH/13
1827             Name => 'CameraTemperature',
1828             Writable => 'int32s',
1829             PrintConv => '"$val C"',
1830             PrintConvInv => '$val=~s/ ?C//; $val',
1831             },
1832             0x3405 => {
1833             Name => 'LensType',
1834             Writable => 'int32u',
1835             SeparateTable => 1,
1836             ValueConv => '($val >> 2) . " " . ($val & 0x3)',
1837             ValueConvInv => \&LensTypeConvInv,
1838             PrintConv => \%leicaLensTypes,
1839             },
1840             0x3406 => { #PH/13
1841             Name => 'ApproximateFNumber',
1842             Writable => 'rational64u',
1843             PrintConv => 'sprintf("%.1f", $val)',
1844             PrintConvInv => '$val',
1845             },
1846             0x3407 => { #14
1847             Name => 'MeasuredLV',
1848             Writable => 'int32s',
1849             Notes => 'imaging sensor or TTL exposure meter measurement',
1850             ValueConv => '$val / 1e5', #PH (NC)
1851             ValueConvInv => '$val * 1e5', #PH (NC)
1852             PrintConv => 'sprintf("%.2f", $val)',
1853             PrintConvInv => '$val',
1854             },
1855             0x3408 => { #14
1856             Name => 'ExternalSensorBrightnessValue',
1857             Writable => 'int32s',
1858             Notes => '"blue dot" measurement',
1859             ValueConv => '$val / 1e5', #PH (NC)
1860             ValueConvInv => '$val * 1e5', #PH (NC)
1861             PrintConv => 'sprintf("%.2f", $val)',
1862             PrintConvInv => '$val',
1863             },
1864             0x3901 => {
1865             Name => 'Data1',
1866             SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::Data1' },
1867             },
1868             0x3902 => {
1869             Name => 'Data2',
1870             SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::Data2' },
1871             },
1872             # 0x3903 - larger binary data block
1873             );
1874              
1875             # time stamp information (ref 21)
1876             %Image::ExifTool::Panasonic::TimeInfo = (
1877             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
1878             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
1879             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
1880             GROUPS => { 0 => 'MakerNotes', 1 => 'Panasonic', 2 => 'Image' },
1881             FIRST_ENTRY => 0,
1882             WRITABLE => 1,
1883             0 => {
1884             Name => 'PanasonicDateTime',
1885             Groups => { 2 => 'Time' },
1886             Shift => 'Time',
1887             Format => 'undef[8]',
1888             RawConv => '$val =~ /^\0/ ? undef : $val',
1889             ValueConv => 'sprintf("%s:%s:%s %s:%s:%s.%s", unpack "H4H2H2H2H2H2H2", $val)',
1890             ValueConvInv => q{
1891             $val =~ s/[-+].*//; # remove time zone
1892             $val =~ tr/0-9//dc; # remove non-digits
1893             $val = pack("H*",$val);
1894             $val .= "\0" while length $val < 8;
1895             return $val;
1896             },
1897             PrintConv => '$self->ConvertDateTime($val)',
1898             PrintConvInv => '$self->InverseDateTime($val)',
1899             },
1900             # 8 - 8 bytes usually 8 x 0xff (spot for another date/time?)
1901             16 => {
1902             Name => 'TimeLapseShotNumber',
1903             Format => 'int32u',
1904             },
1905             );
1906              
1907             %Image::ExifTool::Panasonic::Data1 = (
1908             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
1909             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
1910             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
1911             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
1912             WRITABLE => 1,
1913             TAG_PREFIX => 'Leica_Data1',
1914             FIRST_ENTRY => 0,
1915             0x0016 => {
1916             Name => 'LensType',
1917             Format => 'int32u',
1918             Priority => 0,
1919             SeparateTable => 1,
1920             ValueConv => '(($val >> 2) & 0xffff) . " " . ($val & 0x3)',
1921             ValueConvInv => \&LensTypeConvInv,
1922             PrintConv => \%leicaLensTypes,
1923             },
1924             );
1925              
1926             %Image::ExifTool::Panasonic::Data2 = (
1927             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
1928             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
1929             TAG_PREFIX => 'Leica_Data2',
1930             FIRST_ENTRY => 0,
1931             );
1932              
1933             # Leica type5 maker notes (ref PH) (X1)
1934             %Image::ExifTool::Panasonic::Leica5 = (
1935             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
1936             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1937             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
1938             WRITABLE => 1,
1939             PRIORITY => 0,
1940             NOTES => 'This information is written by the X1, X2, X VARIO and T.',
1941             0x0303 => {
1942             Name => 'LensType',
1943             Condition => '$format eq "string"',
1944             Notes => 'Leica T only',
1945             Writable => 'string',
1946             },
1947             # 0x0304 - int8u[1]: may be M-lens ID for Leica SL, mounted through "M-adapter L" (ref IB)
1948             # --> int8u[4] for some models (maybe not lens ID for these?) - PH
1949             # (see http://us.leica-camera.com/Photography/Leica-APS-C/Lenses-for-Leica-TL/L-Adapters/M-Adapter-L)
1950             # 58 = 'Leica Noctilux-M 75mm F1.25 ASPH (Typ 601) on Leica SL
1951             0x0305 => { #IB
1952             Name => 'SerialNumber',
1953             Writable => 'int32u',
1954             },
1955             # 0x0406 - saturation or sharpness
1956             0x0407 => { Name => 'OriginalFileName', Writable => 'string' },
1957             0x0408 => { Name => 'OriginalDirectory',Writable => 'string' },
1958             0x040a => { #IB
1959             Name => 'FocusInfo',
1960             SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::FocusInfo' },
1961             },
1962             # 0x040b - related to white balance
1963             0x040d => {
1964             Name => 'ExposureMode',
1965             Format => 'int8u',
1966             Count => 4,
1967             PrintConv => {
1968             '0 0 0 0' => 'Program AE',
1969             # '0 1 0 0' - seen for X (Typ 113) - PH
1970             '1 0 0 0' => 'Aperture-priority AE',
1971             '1 1 0 0' => 'Aperture-priority AE (1)', # (see for Leica T)
1972             '2 0 0 0' => 'Shutter speed priority AE', #(guess)
1973             '3 0 0 0' => 'Manual',
1974             },
1975             },
1976             0x0410 => {
1977             Name => 'ShotInfo',
1978             SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::ShotInfo' },
1979             },
1980             # 0x0410 - int8u[16]: first byte is FileNumber
1981             # 0x0411 - int8u[4]: first number is FilmMode (1=Standard,2=Vivid,3=Natural,4=BW Natural,5=BW High Contrast)
1982             0x0412 => { Name => 'FilmMode', Writable => 'string' },
1983             0x0413 => { Name => 'WB_RGBLevels', Writable => 'rational64u', Count => 3 },
1984             0x0500 => {
1985             Name => 'InternalSerialNumber',
1986             Writable => 'undef',
1987             PrintConv => q{
1988             return $val unless $val=~/^(.{3})(\d{2})(\d{2})(\d{2})(\d{4})/;
1989             my $yr = $2 + ($2 < 70 ? 2000 : 1900);
1990             return "($1) $yr:$3:$4 no. $5";
1991             },
1992             PrintConvInv => '$_=$val; tr/A-Z0-9//dc; s/(.{3})(19|20)/$1/; $_',
1993             },
1994             );
1995              
1996             # Leica type5 ShotInfo (ref PH) (X2)
1997             %Image::ExifTool::Panasonic::ShotInfo = (
1998             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
1999             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
2000             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
2001             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
2002             TAG_PREFIX => 'Leica_ShotInfo',
2003             FIRST_ENTRY => 0,
2004             WRITABLE => 1,
2005             0 => {
2006             Name => 'FileIndex',
2007             Format => 'int16u',
2008             },
2009             );
2010              
2011             # Leica type5 FocusInfo (ref IB)
2012             %Image::ExifTool::Panasonic::FocusInfo = (
2013             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
2014             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
2015             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
2016             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
2017             TAG_PREFIX => 'Leica_FocusInfo',
2018             FIRST_ENTRY => 0,
2019             WRITABLE => 1,
2020             FORMAT => 'int16u',
2021             0 => {
2022             Name => 'FocusDistance',
2023             ValueConv => '$val / 1000',
2024             ValueConvInv => '$val * 1000',
2025             PrintConv => '$val < 65535 ? "$val m" : "inf"',
2026             PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 65535',
2027             },
2028             1 => {
2029             Name => 'FocalLength',
2030             Priority => 0,
2031             RawConv => '$val ? $val : undef',
2032             ValueConv => '$val / 1000',
2033             ValueConvInv => '$val * 1000',
2034             PrintConv => 'sprintf("%.1f mm",$val)',
2035             PrintConvInv => '$val=~s/\s*mm$//;$val',
2036             },
2037             );
2038              
2039             # Leica type6 maker notes (ref PH) (S2)
2040             %Image::ExifTool::Panasonic::Leica6 = (
2041             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
2042             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
2043             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
2044             NOTES => q{
2045             This information is written by the S2 and M (Typ 240), as a trailer in JPEG
2046             images.
2047             },
2048             0x300 => {
2049             Name => 'PreviewImage',
2050             Groups => { 2 => 'Preview' },
2051             Writable => 'undef',
2052             Notes => 'S2 and M (Typ 240)',
2053             DataTag => 'PreviewImage',
2054             RawConv => q{
2055             return \$val if $val =~ /^Binary/;
2056             return \$val if $val =~ /^\xff\xd8\xff/;
2057             $$self{PreviewError} = 1 unless $val eq 'none';
2058             return undef;
2059             },
2060             ValueConvInv => '$val || "none"',
2061             WriteCheck => 'return $val=~/^(none|\xff\xd8\xff)/s ? undef : "Not a valid image"',
2062             ChangeBase => '$dirStart + $dataPos - 8',
2063             },
2064             0x301 => {
2065             Name => 'UnknownBlock',
2066             Notes => 'unknown 320kB block, not copied to JPEG images',
2067             Flags => [ 'Unknown', 'Binary', 'Drop' ],
2068             },
2069             # 0x302 - same value as 4 unknown bytes at the end of JPEG or after the DNG TIFF header (ImageID, ref IB)
2070             0x303 => {
2071             Name => 'LensType',
2072             Writable => 'string',
2073             ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
2074             ValueConvInv => '$val',
2075             },
2076             0x304 => { #IB
2077             Name => 'FocusDistance',
2078             Notes => 'focus distance in mm for most models, but cm for others',
2079             Writable => 'int32u',
2080             },
2081             0x311 => {
2082             Name => 'ExternalSensorBrightnessValue',
2083             Condition => '$$self{Model} =~ /Typ 006/',
2084             Notes => 'Leica S only',
2085             Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
2086             Writable => 'rational64s',
2087             PrintConv => 'sprintf("%.2f", $val)',
2088             PrintConvInv => '$val',
2089             },
2090             0x312 => {
2091             Name => 'MeasuredLV',
2092             Condition => '$$self{Model} =~ /Typ 006/',
2093             Notes => 'Leica S only',
2094             Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
2095             Writable => 'rational64s',
2096             PrintConv => 'sprintf("%.2f", $val)',
2097             PrintConvInv => '$val',
2098             },
2099             0x320 => {
2100             Name => 'FirmwareVersion',
2101             Condition => '$$self{Model} =~ /Typ 006/',
2102             Notes => 'Leica S only',
2103             Writable => 'int8u',
2104             Count => 4,
2105             PrintConv => '$val=~tr/ /./; $val',
2106             PrintConvInv => '$val=~tr/./ /; $val',
2107             },
2108             0x321 => { #IB
2109             Name => 'LensSerialNumber',
2110             Condition => '$$self{Model} =~ /Typ 006/',
2111             Notes => 'Leica S only',
2112             Writable => 'int32u',
2113             PrintConv => 'sprintf("%.10d",$val)',
2114             PrintConvInv => '$val',
2115             },
2116             # 0x321 - SerialNumber for Leica S? (ref IB)
2117             # 0x340 - same as 0x302 (ImageID, ref IB)
2118             );
2119              
2120             # Leica type9 maker notes (ref IB) (S)
2121             %Image::ExifTool::Panasonic::Leica9 = (
2122             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
2123             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
2124             GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
2125             NOTES => 'This information is written by the Leica S (Typ 007) and M10 models.',
2126             0x304 => {
2127             Name => 'FocusDistance',
2128             Notes => 'focus distance in mm for most models, but cm for others',
2129             Writable => 'int32u',
2130             },
2131             0x311 => {
2132             Name => 'ExternalSensorBrightnessValue',
2133             Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
2134             Writable => 'rational64s',
2135             PrintConv => 'sprintf("%.2f", $val)',
2136             PrintConvInv => '$val',
2137             },
2138             0x312 => {
2139             Name => 'MeasuredLV',
2140             Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
2141             Writable => 'rational64s',
2142             PrintConv => 'sprintf("%.2f", $val)',
2143             PrintConvInv => '$val',
2144             },
2145             # 0x340 - ImageUniqueID
2146             0x34c => { #23
2147             Name => 'UserProfile',
2148             Writable => 'string',
2149             },
2150             # 0x357 int32u - 0=DNG, 3162=JPG (ref 23)
2151             0x359 => { #23
2152             Name => 'ISOSelected',
2153             Writable => 'int32s',
2154             PrintConv => {
2155             0 => 'Auto',
2156             OTHER => sub { return shift; },
2157             },
2158             },
2159             0x35a => { #23
2160             Name => 'FNumber',
2161             Writable => 'int32s',
2162             ValueConv => '$val / 1000',
2163             ValueConvInv => '$val * 1000',
2164             PrintConv => 'sprintf("%.1f", $val)',
2165             PrintConvInv => '$val',
2166             },
2167             0x035b => { #IB
2168             Name => 'CorrelatedColorTemp', # (in Kelvin)
2169             Writable => 'int16u',
2170             },
2171             0x035c => { #IB
2172             Name => 'ColorTint', # (same units as Adobe is using)
2173             Writable => 'int16s',
2174             },
2175             0x035d => { #IB
2176             Name => 'WhitePoint', # (x/y)
2177             Writable => 'rational64u',
2178             Count => 2,
2179             },
2180             );
2181              
2182             # Type 2 tags (ref PH)
2183             %Image::ExifTool::Panasonic::Type2 = (
2184             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
2185             GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2186             FIRST_ENTRY => 0,
2187             FORMAT => 'int16u',
2188             NOTES => q{
2189             This type of maker notes is used by models such as the NV-DS65, PV-D2002,
2190             PV-DC3000, PV-DV203, PV-DV401, PV-DV702, PV-L2001, PV-SD4090, PV-SD5000 and
2191             iPalm.
2192             },
2193             0 => {
2194             Name => 'MakerNoteType',
2195             Format => 'string[4]',
2196             },
2197             # seems to vary inversely with amount of light, so I'll call it 'Gain' - PH
2198             # (minimum is 16, maximum is 136. Value is 0 for pictures captured from video)
2199             3 => 'Gain',
2200             );
2201              
2202             # Face detection position information (ref PH)
2203             %Image::ExifTool::Panasonic::FaceDetInfo = (
2204             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
2205             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
2206             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
2207             GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2208             WRITABLE => 1,
2209             FORMAT => 'int16u',
2210             FIRST_ENTRY => 0,
2211             DATAMEMBER => [ 0 ],
2212             NOTES => 'Face detection position information.',
2213             0 => {
2214             Name => 'NumFacePositions',
2215             Format => 'int16u',
2216             DataMember => 'NumFacePositions',
2217             RawConv => '$$self{NumFacePositions} = $val',
2218             Notes => q{
2219             number of detected face positions stored in this record. May be less than
2220             FacesDetected
2221             },
2222             },
2223             1 => {
2224             Name => 'Face1Position',
2225             Format => 'int16u[4]',
2226             RawConv => '$$self{NumFacePositions} < 1 ? undef : $val',
2227             Notes => q{
2228             4 numbers: X/Y coordinates of the face center and width/height of face.
2229             Coordinates are relative to an image twice the size of the thumbnail, or 320
2230             pixels wide
2231             },
2232             },
2233             5 => {
2234             Name => 'Face2Position',
2235             Format => 'int16u[4]',
2236             RawConv => '$$self{NumFacePositions} < 2 ? undef : $val',
2237             },
2238             9 => {
2239             Name => 'Face3Position',
2240             Format => 'int16u[4]',
2241             RawConv => '$$self{NumFacePositions} < 3 ? undef : $val',
2242             },
2243             13 => {
2244             Name => 'Face4Position',
2245             Format => 'int16u[4]',
2246             RawConv => '$$self{NumFacePositions} < 4 ? undef : $val',
2247             },
2248             17 => {
2249             Name => 'Face5Position',
2250             Format => 'int16u[4]',
2251             RawConv => '$$self{NumFacePositions} < 5 ? undef : $val',
2252             },
2253             );
2254              
2255             # Face recognition information from DMC-TZ7 (ref PH)
2256             %Image::ExifTool::Panasonic::FaceRecInfo = (
2257             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
2258             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
2259             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
2260             GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2261             WRITABLE => 1,
2262             FIRST_ENTRY => 0,
2263             DATAMEMBER => [ 0 ],
2264             NOTES => q{
2265             Tags written by cameras with facial recognition. These cameras not only
2266             detect faces in an image, but also recognize specific people based a
2267             user-supplied set of known faces.
2268             },
2269             0 => {
2270             Name => 'FacesRecognized',
2271             Format => 'int16u',
2272             DataMember => 'FacesRecognized',
2273             RawConv => '$$self{FacesRecognized} = $val',
2274             },
2275             4 => {
2276             Name => 'RecognizedFace1Name',
2277             Format => 'string[20]',
2278             RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
2279             },
2280             24 => {
2281             Name => 'RecognizedFace1Position',
2282             Format => 'int16u[4]',
2283             RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
2284             Notes => 'coordinates in same format as face detection tags above',
2285             },
2286             32 => {
2287             Name => 'RecognizedFace1Age',
2288             Format => 'string[20]',
2289             RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
2290             },
2291             52 => {
2292             Name => 'RecognizedFace2Name',
2293             Format => 'string[20]',
2294             RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
2295             },
2296             72 => {
2297             Name => 'RecognizedFace2Position',
2298             Format => 'int16u[4]',
2299             RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
2300             },
2301             80 => {
2302             Name => 'RecognizedFace2Age',
2303             Format => 'string[20]',
2304             RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
2305             },
2306             100 => {
2307             Name => 'RecognizedFace3Name',
2308             Format => 'string[20]',
2309             RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
2310             },
2311             120 => {
2312             Name => 'RecognizedFace3Position',
2313             Format => 'int16u[4]',
2314             RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
2315             },
2316             128 => {
2317             Name => 'RecognizedFace3Age',
2318             Format => 'string[20]',
2319             RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
2320             },
2321             );
2322              
2323             # PANA atom found in user data of MP4 videos (ref PH)
2324             %Image::ExifTool::Panasonic::PANA = (
2325             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
2326             GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2327             NOTES => q{
2328             Tags extracted from the PANA and LEIC user data found in MP4 videos from
2329             various Panasonic and Leica models.
2330             },
2331             0x00 => {
2332             Name => 'Make',
2333             Condition => '$$valPt =~ /^(LEICA|Panasonic)/', # (only seen "LEICA")
2334             Groups => { 2 => 'Camera' },
2335             Format => 'string[22]',
2336             RawConv => '$$self{LeicaLEIC} = 1;$$self{Make} = $val',
2337             },
2338             0x04 => {
2339             Name => 'Model',
2340             Condition => '$$valPt =~ /^[^\0]{6}/ and not $$self{LeicaLEIC}',
2341             Description => 'Camera Model Name',
2342             Groups => { 2 => 'Camera' },
2343             Format => 'string[16]',
2344             RawConv => '$$self{Model} = $val',
2345             },
2346             0x0c => { # (FZ1000)
2347             Name => 'Model',
2348             Condition => '$$valPt =~ /^[^\0]{6}/ and not $$self{LeicaLEIC} and not $$self{Model}',
2349             Description => 'Camera Model Name',
2350             Groups => { 2 => 'Camera' },
2351             Format => 'string[16]',
2352             RawConv => '$$self{Model} = $val',
2353             },
2354             0x10 => { # (DC-FT7)
2355             Name => 'JPEG-likeData',
2356             # looks like a JPEG preview, but not a well-formed JPEG file
2357             Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
2358             Format => 'undef[$size-0x10]',
2359             SubDirectory => {
2360             TagTable => 'Image::ExifTool::Exif::Main',
2361             ProcessProc => \&Image::ExifTool::ProcessTIFF,
2362             Start => 12,
2363             },
2364             },
2365             0x16 => {
2366             Name => 'Model',
2367             Condition => '$$self{LeicaLEIC}',
2368             Description => 'Camera Model Name',
2369             Groups => { 2 => 'Camera' },
2370             Format => 'string[30]',
2371             RawConv => '$$self{Model} = $val',
2372             },
2373             0x40 => {
2374             Name => 'ThumbnailTest',
2375             Format => 'undef[0x600]',
2376             Hidden => 1,
2377             RawConv => q{
2378             if (substr($val,0x1c,3) eq "\xff\xd8\xff") { # offset 0x5c
2379             $$self{ThumbType} = 1;
2380             } elsif (substr($val,0x506,3) eq "\xff\xd8\xff") { # offset 0x546
2381             $$self{ThumbType} = 2;
2382             } elsif (substr($val,0x51e,3) eq "\xff\xd8\xff") { # offset 0x55e (Leica T)
2383             $$self{ThumbType} = 3;
2384             } else {
2385             $$self{ThumbType} = 0;
2386             }
2387             return undef;
2388             },
2389             },
2390             0x34 => {
2391             Name => 'Version1',
2392             Condition => '$$self{LeicaLEIC}',
2393             Format => 'string[14]',
2394             },
2395             0x3e => {
2396             Name => 'Version2',
2397             Condition => '$$self{LeicaLEIC}',
2398             Format => 'string[14]',
2399             },
2400             0x50 => {
2401             Name => 'MakerNoteLeica5',
2402             Condition => '$$self{LeicaLEIC}',
2403             SubDirectory => {
2404             TagTable => 'Image::ExifTool::Panasonic::Leica5',
2405             ProcessProc => \&ProcessLeicaLEIC,
2406             },
2407             },
2408             0x58 => {
2409             Name => 'ThumbnailWidth',
2410             Condition => '$$self{ThumbType} == 1',
2411             Notes => 'Panasonic models',
2412             Format => 'int16u',
2413             },
2414             0x5a => {
2415             Name => 'ThumbnailHeight',
2416             Condition => '$$self{ThumbType} == 1',
2417             Format => 'int16u',
2418             },
2419             0x5c => {
2420             Name => 'ThumbnailImage',
2421             Condition => '$$self{ThumbType} == 1',
2422             Groups => { 2 => 'Preview' },
2423             Format => 'undef[16384]',
2424             ValueConv => '$val=~s/\0*$//; \$val', # remove trailing zeros
2425             },
2426             # 0x5c - there is some messed-up EXIF-IFD-looking data starting here in
2427             # Leica X VARIO MP4 videos, but it doesn't quite make sense
2428             0x536 => { # (Leica X VARIO)
2429             Name => 'ThumbnailWidth',
2430             Condition => '$$self{ThumbType} == 2',
2431             Notes => 'Leica X Vario',
2432             Format => 'int32uRev', # (little-endian)
2433             },
2434             0x53a => { # (Leica X VARIO)
2435             Name => 'ThumbnailHeight',
2436             Condition => '$$self{ThumbType} == 2',
2437             Format => 'int32uRev', # (little-endian)
2438             },
2439             0x53e => { # (Leica X VARIO)
2440             Name => 'ThumbnailLength',
2441             Condition => '$$self{ThumbType} == 2',
2442             Format => 'int32uRev', # (little-endian)
2443             },
2444             0x546 => { # (Leica X VARIO)
2445             Name => 'ThumbnailImage',
2446             Condition => '$$self{ThumbType} == 2',
2447             Groups => { 2 => 'Preview' },
2448             Format => 'undef[$val{0x53e}]',
2449             Binary => 1,
2450             },
2451             0x54e => { # (Leica T)
2452             Name => 'ThumbnailWidth',
2453             Condition => '$$self{ThumbType} == 3',
2454             Notes => 'Leica X Vario',
2455             Format => 'int32uRev', # (little-endian)
2456             },
2457             0x552 => { # (Leica T)
2458             Name => 'ThumbnailHeight',
2459             Condition => '$$self{ThumbType} == 3',
2460             Format => 'int32uRev', # (little-endian)
2461             },
2462             0x556 => { # (Leica T)
2463             Name => 'ThumbnailLength',
2464             Condition => '$$self{ThumbType} == 3',
2465             Format => 'int32uRev', # (little-endian)
2466             },
2467             0x55e => { # (Leica T)
2468             Name => 'ThumbnailImage',
2469             Condition => '$$self{ThumbType} == 3',
2470             Groups => { 2 => 'Preview' },
2471             Format => 'undef[$val{0x556}]',
2472             Binary => 1,
2473             },
2474             0x4068 => {
2475             Name => 'ExifData',
2476             Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
2477             SubDirectory => {
2478             TagTable => 'Image::ExifTool::Exif::Main',
2479             ProcessProc => \&Image::ExifTool::ProcessTIFF,
2480             Start => 12,
2481             },
2482             },
2483             0x4080 => { # (FZ1000)
2484             Name => 'ExifData',
2485             Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
2486             SubDirectory => {
2487             TagTable => 'Image::ExifTool::Exif::Main',
2488             ProcessProc => \&Image::ExifTool::ProcessTIFF,
2489             Start => 12,
2490             },
2491             },
2492             0x200080 => { # (GH6)
2493             Name => 'ExifData',
2494             Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
2495             SubDirectory => {
2496             TagTable => 'Image::ExifTool::Exif::Main',
2497             ProcessProc => \&Image::ExifTool::ProcessTIFF,
2498             Start => 12,
2499             },
2500             },
2501             );
2502              
2503             # Panasonic Composite tags
2504             %Image::ExifTool::Panasonic::Composite = (
2505             GROUPS => { 2 => 'Camera' },
2506             AdvancedSceneMode => {
2507             SeparateTable => 'Panasonic AdvancedSceneMode', # print values in a separate table
2508             Require => {
2509             0 => 'Model',
2510             1 => 'SceneMode',
2511             2 => 'AdvancedSceneType',
2512             },
2513             ValueConv => '"$val[0] $val[1] $val[2]"',
2514             PrintConv => { #PH
2515             OTHER => sub {
2516             my ($val,$flag,$conv) = @_;
2517             $val =~ s/.* (\d+ \d+)/$1/; # drop model name
2518             return $$conv{$val} if $$conv{$val};
2519             my @v = split ' ', $val;
2520             my $prt = $shootingMode{$v[0]};
2521             # AdvancedSceneType=1 for non-automatic modes P,A,S,SCN (ref 19)
2522             # AdvancedSceneType=5 for automatic mode iA (ref 19)
2523             if ($prt) {
2524             return $prt if $v[1] == 1;
2525             return "$prt (intelligent auto)" if $v[1] == 5; #forum11523
2526             return "$prt (intelligent auto plus)" if $v[1] == 7; #forum11523
2527             return "$prt ($v[1])";
2528             }
2529             return "Unknown ($val)";
2530             },
2531             Notes => 'A Composite tag derived from Model, SceneMode and AdvancedSceneType.',
2532             '0 1' => 'Off',
2533             # '0 7' - seen this for V-LUX movies (PH)
2534             # '0 8' - seen for D-LUX(Typ104) movies (PH)
2535             '2 2' => 'Outdoor Portrait', #(FZ28)
2536             '2 3' => 'Indoor Portrait', #(FZ28)
2537             '2 4' => 'Creative Portrait', #(FZ28)
2538             '3 2' => 'Nature', #(FZ28)
2539             '3 3' => 'Architecture', #(FZ28)
2540             '3 4' => 'Creative Scenery', #(FZ28)
2541             #'3 5' - ? (FT1)
2542             '4 2' => 'Outdoor Sports', #(FZ28)
2543             '4 3' => 'Indoor Sports', #(FZ28)
2544             '4 4' => 'Creative Sports', #(FZ28)
2545             '9 2' => 'Flower', #(FZ28)
2546             '9 3' => 'Objects', #(FZ28)
2547             '9 4' => 'Creative Macro', #(FZ28)
2548             #'9 5' - ? (GF3)
2549             '18 1' => 'High Sensitivity', #forum11523 (TZ5)
2550             '20 1' => 'Fireworks', #forum11523 (TZ5)
2551             '21 2' => 'Illuminations', #(FZ28)
2552             '21 4' => 'Creative Night Scenery', #(FZ28)
2553             #'21 5' - ? (LX3)
2554             '26 1' => 'High-speed Burst (shot 1)', #forum11523 (TZ5)
2555             '27 1' => 'High-speed Burst (shot 2)', #forum11523 (TZ5)
2556             '29 1' => 'Snow', #forum11523 (TZ5)
2557             '30 1' => 'Starry Sky', #forum11523 (TZ5)
2558             '31 1' => 'Beach', #forum11523 (TZ5)
2559             '36 1' => 'High-speed Burst (shot 3)', #forum11523 (TZ5)
2560             #'37 5' - ? (various)
2561             '39 1' => 'Aerial Photo / Underwater / Multi-aspect', #forum11523 (TZ5)
2562             '45 2' => 'Cinema', #(GF2)
2563             '45 7' => 'Expressive', #(GF1,GF2)
2564             '45 8' => 'Retro', #(GF1,GF2)
2565             '45 9' => 'Pure', #(GF1,GF2)
2566             '45 10' => 'Elegant', #(GF1,GF2)
2567             '45 12' => 'Monochrome', #(GF1,GF2)
2568             '45 13' => 'Dynamic Art', #(GF1,GF2)
2569             '45 14' => 'Silhouette', #(GF1,GF2)
2570             '51 2' => 'HDR Art', #12
2571             '51 3' => 'HDR B&W', #12
2572             '59 1' => 'Expressive', #(GF5)
2573             '59 2' => 'Retro', #(GF5)
2574             '59 3' => 'High Key', #(GF5)
2575             '59 4' => 'Sepia', #(GF3,GF5)
2576             '59 5' => 'High Dynamic', #(GF3,GF5)
2577             '59 6' => 'Miniature', #(GF3)
2578             '59 9' => 'Low Key', #(GF5)
2579             '59 10' => 'Toy Effect', #(GF5)
2580             '59 11' => 'Dynamic Monochrome', #(GF5)
2581             '59 12' => 'Soft', #(GF5)
2582             '66 1' => 'Impressive Art', #19
2583             '66 2' => 'Cross Process', #(GF5)
2584             '66 3' => 'Color Select', #(GF5) (called "One Point Color" by some other models - PH)
2585             '66 4' => 'Star', #(GF5)
2586             '90 3' => 'Old Days', #18
2587             '90 4' => 'Sunshine', #18
2588             '90 5' => 'Bleach Bypass', #18
2589             '90 6' => 'Toy Pop', #18
2590             '90 7' => 'Fantasy', #18
2591             '90 8' => 'Monochrome', #PH (GX7)
2592             '90 9' => 'Rough Monochrome', #PH (GX7)
2593             '90 10' => 'Silky Monochrome', #PH (GX7)
2594             '92 1' => 'Handheld Night Shot', #Horst Wandres (FZ1000)
2595             # TZ40 Creative Control modes (ref 19)
2596             'DMC-TZ40 90 1' => 'Expressive',
2597             'DMC-TZ40 90 2' => 'Retro',
2598             'DMC-TZ40 90 3' => 'High Key',
2599             'DMC-TZ40 90 4' => 'Sepia',
2600             'DMC-TZ40 90 5' => 'High Dynamic',
2601             'DMC-TZ40 90 6' => 'Miniature',
2602             'DMC-TZ40 90 9' => 'Low Key',
2603             'DMC-TZ40 90 10' => 'Toy Effect',
2604             'DMC-TZ40 90 11' => 'Dynamic Monochrome',
2605             'DMC-TZ40 90 12' => 'Soft',
2606             },
2607             },
2608             );
2609              
2610             # add our composite tags
2611             Image::ExifTool::AddCompositeTags('Image::ExifTool::Panasonic');
2612              
2613             #------------------------------------------------------------------------------
2614             # Inverse conversion for Leica M9 lens codes
2615             # Inputs: 0) value
2616             # Returns: Converted value, or undef on error
2617             sub LensTypeConvInv($)
2618             {
2619 0     0 0 0 my $val = shift;
2620 0 0       0 if ($val =~ /^(\d+) (\d+)$/) {
    0          
2621 0         0 return ($1 << 2) + ($2 & 0x03);
2622             } elsif ($val =~ /^\d+$/) {
2623 0         0 my $bits = $frameSelectorBits{$val};
2624 0 0       0 return undef unless defined $bits;
2625 0         0 return ($val << 2) | $bits;
2626             } else {
2627 0         0 return undef;
2628             }
2629             }
2630              
2631             #------------------------------------------------------------------------------
2632             # Convert Leica Kelvin white balance
2633             # Inputs: 0) value, 1) flag to perform inverse conversion
2634             # Returns: Converted value, or undef on error
2635             sub WhiteBalanceConv($;$$)
2636             {
2637 2     2 0 11 my ($val, $inv) = @_;
2638 2 50       12 if ($inv) {
2639 2 50       14 return $1 + 0x8000 if $val =~ /(\d+)/;
2640             } else {
2641 0 0       0 return ($val - 0x8000) . ' Kelvin' if $val > 0x8000;
2642             }
2643 2         13 return undef;
2644             }
2645              
2646             #------------------------------------------------------------------------------
2647             # Process Leica makernotes in LEIC atom of MP4 videos (Leica T and X Vario)
2648             # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
2649             # Returns: 1 on success
2650             sub ProcessLeicaLEIC($$$)
2651             {
2652 0     0 0   my ($et, $dirInfo, $tagTablePtr) = @_;
2653 0           my $dataPt = $$dirInfo{DataPt};
2654 0   0       my $dirStart = $$dirInfo{DirStart} || 0;
2655 0   0       my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
2656 0 0         return 0 if $dirLen < 6;
2657 0           SetByteOrder('II');
2658 0           my $numEntries = Get16u($dataPt, $dirStart);
2659 0 0 0       return 0 if $numEntries < 1 or $numEntries > 255;
2660 0           my $size = Get32u($dataPt, $dirStart + 2);
2661 0 0 0       return 0 if $size < $numEntries * 12 or $size + 6 > $dirLen;
2662             # the Leica programmers want to make things difficult, so they store
2663             # the entry count before the directory size, making it impossible to
2664             # process as a standard TIFF IFD without a bit of reorganization...
2665 0           Set16u($numEntries, $dataPt, $dirStart + 4);
2666 0           my %dirInfo = %$dirInfo;
2667 0           $dirInfo{DirStart} = $dirStart + 4;
2668 0           $dirInfo{DirLen} = $size - 4;
2669 0           $dirInfo{DataPos} -= $dirStart;
2670 0           $dirInfo{Base} += $dirStart;
2671 0           return Image::ExifTool::Exif::ProcessExif($et, \%dirInfo, $tagTablePtr);
2672 0           return 1;
2673             }
2674              
2675             #------------------------------------------------------------------------------
2676             # Process MakerNote trailer written by Leica S2
2677             # Inputs: 0) ExifTool object ref, 1) new absolute position of Leica trailer when writing
2678             # Returns: On success: 1 when reading, directory data when writing; otherwise undef
2679             # Notes:
2680             # - may be called twice for a file if the first call doesn't succeed
2681             # - must leave RAF position unchanged
2682             # - uses information from LeicaTrailer member:
2683             # TagInfo = tag info ref for MakerNote SubDirectory
2684             # Offset/Size = value offset/size from MakerNote IFD
2685             # TrailStart/TrailLen = actual JPEG trailer position/size (2nd call only)
2686             # - deletes LeicaTrailer member and sets LeicaTrailerPos when successful
2687             sub ProcessLeicaTrailer($;$)
2688             {
2689 0     0 0   my ($et, $newPos) = @_;
2690 0           my $trail = $$et{LeicaTrailer};
2691 0           my $raf = $$et{RAF};
2692 0           my $trailPos = $$trail{TrailPos};
2693 0   0       my $pos = $trailPos || $$trail{Offset};
2694 0   0       my $len = $$trail{TrailLen} || $$trail{Size};
2695 0           my ($buff, $result, %tagPtr);
2696              
2697 0 0         delete $$et{LeicaTrailer} if $trailPos; # done after this
2698 0 0         unless ($len > 0) {
2699 0 0         $et->Warn('Missing Leica MakerNote trailer', 1) if $trailPos;
2700 0           delete $$et{LeicaTrailer};
2701 0           return undef;
2702             }
2703 0           my $oldPos = $raf->Tell();
2704 0   0       my $ok = ($raf->Seek($pos, 0) and $raf->Read($buff, $len) == $len);
2705 0           $raf->Seek($oldPos, 0);
2706 0 0         unless ($ok) {
2707 0 0         $et->Warn('Error reading Leica MakerNote trailer', 1) if $trailPos;
2708 0           return undef;
2709             }
2710             # look for Leica MakerNote header (should be at start of
2711             # trailer, but allow up to 256 bytes of garbage just in case)
2712 0 0         if ($buff !~ /^(.{0,256})LEICA\0..../sg) {
2713 0 0         my $what = $trailPos ? 'trailer' : 'offset';
2714 0           $et->Warn("Invalid Leica MakerNote $what", 1);
2715 0           return undef;
2716             }
2717 0           my $junk = $1;
2718 0           my $start = pos($buff) - 10;
2719 0 0 0       if ($start and not $trailPos) {
2720 0           $et->Warn('Invalid Leica MakerNote offset', 1);
2721 0           return undef;
2722             }
2723             #
2724             # all checks passed -- go ahead and process the trailer now
2725             #
2726 0           my $hdrLen = 8;
2727 0           my $dirStart = $start + $hdrLen;
2728 0           my $tagInfo = $$trail{TagInfo};
2729 0 0         if ($$et{HTML_DUMP}) {
    0          
2730 0           my $name = $$tagInfo{Name};
2731 0           $et->HDump($pos+$start, $len-$start, "$name value", 'Leica MakerNote trailer', 4);
2732 0           $et->HDump($pos+$start, $hdrLen, "MakerNotes header", $name);
2733             } elsif ($et->Options('Verbose')) {
2734 0           my $where = sprintf('at offset 0x%x', $pos);
2735 0           $et->VPrint(0, "Leica MakerNote trailer ($len bytes $where):\n");
2736             }
2737             # delete LeicaTrailer member so we don't try to process it again
2738 0           delete $$et{LeicaTrailer};
2739 0           $$et{LeicaTrailerPos} = $pos + $start; # return actual start position of Leica trailer
2740              
2741 0           my $oldOrder = GetByteOrder();
2742 0           my $num = Get16u(\$buff, $dirStart); # get entry count
2743 0 0         ToggleByteOrder() if ($num>>8) > ($num&0xff); # set byte order
2744              
2745             # use specialized algorithm to automatically fix offsets
2746 0           my $valStart = $dirStart + 2 + 12 * $num + 4;
2747 0           my $fix = 0;
2748 0 0         if ($valStart < $len) {
2749 0           my $valBlock = Image::ExifTool::MakerNotes::GetValueBlocks(\$buff, $dirStart, \%tagPtr);
2750             # find the minimum offset (excluding the PreviewImage tag 0x300 and 0x301)
2751 0           my $minPtr;
2752 0           foreach (keys %tagPtr) {
2753 0           my $ptr = $tagPtr{$_};
2754 0 0 0       next if $_ == 0x300 or $_ == 0x301 or not $ptr or $ptr == 0xffffffff;
      0        
      0        
2755 0 0 0       $minPtr = $ptr if not defined $minPtr or $minPtr > $ptr;
2756             }
2757 0 0         if ($minPtr) {
2758 0           my $diff = $minPtr - ($valStart + $pos);
2759 0           pos($buff) = $valStart;
2760 0           my $expect;
2761 0 0         if ($$et{Model} eq 'S2') {
2762             # scan value data for the first non-zero byte
2763 0 0         if ($buff =~ /[^\0]/g) {
2764 0           my $n = pos($buff) - 1 - $valStart; # number of zero bytes
2765             # S2 writes 282 bytes of zeros, exiftool writes none
2766 0 0         $expect = $n >= 282 ? 282 : 0;
2767             }
2768             } else { # M (Type 240)
2769             # scan for the lens type (M writes 114 bytes of garbage first)
2770 0 0 0       if ($buff =~ /\G.{114}([\x20-\x7f]*\0*)/sg and length($1) >= 50) {
2771 0           $expect = 114;
2772             }
2773             }
2774 0           my $fixBase = $et->Options('FixBase');
2775 0 0 0       if (not defined $expect) {
    0          
2776 0           $et->Warn('Unrecognized Leica trailer structure');
2777             } elsif ($diff != $expect or defined $fixBase) {
2778 0           $fix = $expect - $diff;
2779 0 0         if (defined $fixBase) {
2780 0 0         $fix = $fixBase if $fixBase ne '';
2781 0           $et->Warn("Adjusted MakerNotes base by $fix",1);
2782             } else {
2783 0           $et->Warn("Possibly incorrect maker notes offsets (fixed by $fix)",1);
2784             }
2785             }
2786             }
2787             }
2788             # generate dirInfo for Leica MakerNote directory
2789             my %dirInfo = (
2790             Name => $$tagInfo{Name},
2791 0           Base => $fix,
2792             DataPt => \$buff,
2793             DataPos => $pos - $fix,
2794             DataLen => $len,
2795             DirStart => $dirStart,
2796             DirLen => $len - $dirStart,
2797             DirName => 'MakerNotes',
2798             Parent => 'ExifIFD',
2799             TagInfo => $tagInfo,
2800             );
2801 0           my $tagTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
2802 0 0         if ($newPos) { # are we writing?
2803 0 0         if ($$et{Model} ne 'S2') {
2804 0           $et->Warn('Leica MakerNote trailer too messed up to edit. Copying as a block', 1);
2805 0           return $buff;
2806             }
2807             # set position of new MakerNote IFD (+ 8 for Leica MakerNote header)
2808 0           $dirInfo{NewDataPos} = $newPos + $start + 8;
2809 0           $result = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
2810             # write preview image last if necessary and fix up the preview offsets
2811 0           my $previewInfo = $$et{PREVIEW_INFO};
2812 0           delete $$et{PREVIEW_INFO};
2813 0 0         if ($result) {
2814 0 0         if ($previewInfo) {
2815 0           my $fixup = $previewInfo->{Fixup};
2816             # set preview offset (relative to start of makernotes, + 8 for makernote header)
2817 0           $fixup->SetMarkerPointers(\$result, 'PreviewImage', length($result) + 8);
2818 0           $result .= $$previewInfo{Data};
2819             }
2820 0           return $junk . substr($buff, $start, $hdrLen) . $result;
2821             }
2822             } else {
2823             # extract information
2824 0           $result = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
2825             # also extract as a block if necessary
2826 0 0 0       if ($et->Options('MakerNotes') or
2827             $$et{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})})
2828             {
2829             # makernote header must be included in RebuildMakerNotes call
2830 0           $dirInfo{DirStart} -= 8;
2831 0           $dirInfo{DirLen} += 8;
2832 0           $$et{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
2833             # rebuild maker notes (creates $$et{MAKER_NOTE_FIXUP})
2834 0           my $val = Image::ExifTool::Exif::RebuildMakerNotes($et, \%dirInfo, $tagTablePtr);
2835 0 0         unless (defined $val) {
2836 0 0         $et->Warn('Error rebuilding maker notes (may be corrupt)') if $len > 4;
2837 0           $val = $buff,
2838             }
2839 0           my $key = $et->FoundTag($tagInfo, $val);
2840 0           $et->SetGroup($key, 'ExifIFD');
2841             }
2842             }
2843 0           SetByteOrder($oldOrder);
2844 0           return $result;
2845             }
2846              
2847             1; # end
2848              
2849             __END__