source: main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Panasonic.pm@ 34921

Last change on this file since 34921 was 34921, checked in by anupama, 3 years ago

Committing the improvements to EmbeddedMetaPlugin's processing of Keywords vs other metadata fields. Keywords were literally stored as arrays of words rather than phrases in PDFs (at least in Diego's sample PDF), whereas other meta fields like Subjects and Creators stored them as arrays of phrases. To get both to work, Kathy updated EXIF to a newer version, to retrieve the actual EXIF values stored in the PDF. And Kathy and Dr Bainbridge came up with a new option that I added called apply_join_before_split_to_metafields that's a regex which can list the metadata fields to apply the join_before_split to and whcih previously always got applied to all metadata fields. Now it's applied to any *Keywords metafields by default, as that's the metafield we have experience of that behaves differently to the others, as it stores by word instead of phrases. Tested on Diego's sample PDF. Diego has double-checked it to works on his sample PDF too, setting the split char to ; and turning on the join_before_split and leaving apply_join_before_split_to_metafields at its default of .*Keywords. File changes are strings.properties for the tooltip, the plugin introducing the option and working with it and Kathy's EXIF updates affecting cpan/File and cpan/Image.

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