source: gsdl/trunk/perllib/cpan/Image/ExifTool/Panasonic.pm@ 16842

Last change on this file since 16842 was 16842, checked in by davidb, 16 years ago

ExifTool added to cpan area to support metadata extraction from files such as JPEG. Primarily targetted as Image files (hence the Image folder name decided upon by the ExifTool author) it also can handle video such as flash and audio such as Wav

File size: 18.1 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# 5) CPAN forum post by 'hardloaf' (http://www.cpanforum.com/threads/2183)
13# 6) http://www.cybercom.net/~dcoffin/dcraw/
14# 7) http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm
15# 8) Marcel Coenen private communication (DMC-FZ50)
16# 9) http://forums.dpreview.com/forums/read.asp?forum=1033&message=22756430
17# 10) Jens Duttke private communication (TZ3,FZ30,FZ50)
18#------------------------------------------------------------------------------
19
20package Image::ExifTool::Panasonic;
21
22use strict;
23use vars qw($VERSION);
24use Image::ExifTool::Exif;
25
26$VERSION = '1.26';
27
28sub ProcessPanasonicType2($$$);
29
30# conversions for ShootingMode and SceneMode
31my %shootingMode = (
32 1 => 'Normal',
33 2 => 'Portrait',
34 3 => 'Scenery',
35 4 => 'Sports',
36 5 => 'Night Portrait',
37 6 => 'Program',
38 7 => 'Aperture Priority',
39 8 => 'Shutter Priority',
40 9 => 'Macro',
41 11 => 'Manual',
42 12 => 'Movie Preview', #PH (LZ6)
43 13 => 'Panning',
44 14 => 'Simple', #PH (LZ6)
45 18 => 'Fireworks',
46 19 => 'Party',
47 20 => 'Snow',
48 21 => 'Night Scenery',
49 22 => 'Food', #7
50 23 => 'Baby', #10
51 24 => 'Soft Skin', #PH (LZ6)
52 25 => 'Candlelight', #PH (LZ6)
53 26 => 'Starry Night', #PH (LZ6)
54 27 => 'High Sensitivity', #7 (LZ6)
55 29 => 'Underwater', #7
56 30 => 'Beach', #PH (LZ6)
57 31 => 'Aerial Photo', #PH (LZ6)
58 32 => 'Sunset', #PH (LZ6)
59 33 => 'Pet', #10
60 34 => 'Intelligent ISO', #PH (LZ6)
61);
62
63%Image::ExifTool::Panasonic::Main = (
64 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
65 CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
66 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
67 WRITABLE => 1,
68 0x01 => {
69 Name => 'ImageQuality',
70 Writable => 'int16u',
71 PrintConv => {
72 2 => 'High',
73 3 => 'Normal',
74 6 => 'Very High', #3 (Leica)
75 7 => 'Raw', #3 (Leica)
76 9 => 'Motion Picture', #PH (LZ6)
77 },
78 },
79 0x02 => {
80 Name => 'FirmwareVersion',
81 Writable => 'undef',
82 Notes => q{
83 for some camera models such as the FZ30 this may be an internal production
84 reference number and not the actual firmware version
85 }, # (ref http://www.stevesforums.com/forums/view_topic.php?id=87764&forum_id=23&)
86 # (can be either binary or ascii -- add decimal points if binary)
87 ValueConv => '$val=~/[\0-\x2f]/ ? join(" ",unpack("C*",$val)) : $val',
88 ValueConvInv => q{
89 $val =~ /(\d+ ){3}\d+/ and $val = pack('C*',split(' ', $val));
90 length($val) == 4 or warn "Version must be 4 numbers\n";
91 return $val;
92 },
93 PrintConv => '$val=~tr/ /./; $val',
94 PrintConvInv => '$val=~tr/./ /; $val',
95 },
96 0x03 => {
97 Name => 'WhiteBalance',
98 Writable => 'int16u',
99 PrintConv => {
100 1 => 'Auto',
101 2 => 'Daylight',
102 3 => 'Cloudy',
103 4 => 'Halogen',
104 5 => 'Manual',
105 8 => 'Flash',
106 10 => 'Black & White', #3 (Leica)
107 11 => 'Manual', #PH (FZ8)
108 },
109 },
110 0x07 => {
111 Name => 'FocusMode',
112 Writable => 'int16u',
113 PrintConv => {
114 1 => 'Auto',
115 2 => 'Manual',
116 4 => 'Auto, Focus button', #4
117 5 => 'Auto, Continuous', #4
118 },
119 },
120 0x0f => {
121 Name => 'AFMode',
122 Writable => 'int8u',
123 Count => 2,
124 PrintConv => { #PH
125 '0 1' => 'Spot Mode On', # (maybe 9-area for some cameras?)
126 '0 16' => 'Spot Mode Off or 3-area (high speed)', # (FZ8 is 3-area)
127 '1 0' => 'Spot Focusing', # (FZ8)
128 '1 1' => '5-area', # (FZ8)
129 '16' => 'Normal?', # (only AFMode for DMC-LC20)
130 '16 0' => '1-area', # (FZ8)
131 '16 16' => '1-area (high speed)', # (FZ8)
132 '32 0' => '3-area (auto)?', # (DMC-L1 guess)
133 '32 1' => '3-area (left)?', # (DMC-L1 guess)
134 '32 2' => '3-area (center)?', # (DMC-L1 guess)
135 '32 3' => '3-area (right)?', # (DMC-L1 guess)
136 },
137 },
138 0x1a => {
139 Name => 'ImageStabilization',
140 Writable => 'int16u',
141 PrintConv => {
142 2 => 'On, Mode 1',
143 3 => 'Off',
144 4 => 'On, Mode 2',
145 },
146 },
147 0x1c => {
148 Name => 'MacroMode',
149 Writable => 'int16u',
150 PrintConv => {
151 1 => 'On',
152 2 => 'Off',
153 0x101 => 'Tele-Macro', #7
154 },
155 },
156 0x1f => {
157 Name => 'ShootingMode',
158 Writable => 'int16u',
159 PrintConv => \%shootingMode,
160 },
161 0x20 => {
162 Name => 'Audio',
163 Writable => 'int16u',
164 PrintConv => { 1 => 'Yes', 2 => 'No' },
165 },
166 0x21 => { #2
167 Name => 'DataDump',
168 Writable => 0,
169 Binary => 1,
170 },
171 # 0x22 - normally 0, but 2 for 'Simple' ShootingMode in LZ6 sample - PH
172 0x23 => {
173 Name => 'WhiteBalanceBias',
174 Format => 'int16s',
175 Writable => 'int16s',
176 ValueConv => '$val / 3',
177 PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
178 ValueConvInv => '$val * 3',
179 PrintConvInv => 'eval $val',
180 },
181 0x24 => {
182 Name => 'FlashBias',
183 Format => 'int16s',
184 Writable => 'int16s',
185 },
186 0x25 => { #PH
187 Name => 'InternalSerialNumber',
188 Writable => 'undef',
189 Count => 16,
190 Notes => q{
191 this number is unique, and contains the date of manufacture, but is not the
192 same as the number printed on the camera body
193 },
194 PrintConv => q{
195 return $val unless $val=~/^([A-Z]\d{2})(\d{2})(\d{2})(\d{2})(\d{4})/;
196 my $yr = $2 + ($2 < 70 ? 2000 : 1900);
197 return "($1) $yr:$3:$4 no. $5";
198 },
199 PrintConvInv => '$_=$val; tr/A-Z0-9//dc; s/(.{3})(19|20)/$1/; $_',
200 },
201 0x26 => { #PH
202 Name => 'PanasonicExifVersion',
203 Writable => 'undef',
204 },
205 # 0x27 - values: 0 (LZ6,FX10K)
206 0x28 => {
207 Name => 'ColorEffect',
208 Writable => 'int16u',
209 # FX30 manual: (ColorMode) natural, vivid, cool, warm, b/w, sepia
210 PrintConv => {
211 1 => 'Off',
212 2 => 'Warm',
213 3 => 'Cool',
214 4 => 'Black & White',
215 5 => 'Sepia',
216 },
217 },
218 0x29 => { #10
219 Name => 'TimeSincePowerOn',
220 Writable => 'int32u',
221 Notes => q{
222 time in 1/100 sec from when the camera was powered on to when the image is
223 written to memory card
224 },
225 ValueConv => '$val / 100',
226 ValueConvInv => '$val * 100',
227 PrintConv => sub { # convert to format "[DD days ]HH:MM:SS.ss"
228 my $val = shift;
229 my $str = '';
230 if ($val >= 24 * 3600) {
231 my $d = int($val / (24 * 3600));
232 $str .= "$d days ";
233 $val -= $d * 24 * 3600;
234 }
235 my $h = int($val / 3600);
236 $val -= $h * 3600;
237 my $m = int($val / 60);
238 $val -= $m * 60;
239 my $s = int($val);
240 my $f = 100 * ($val - int($val));
241 return sprintf("%s%.2d:%.2d:%.2d.%.2d",$str,$h,$m,$s,$f);
242 },
243 PrintConvInv => sub {
244 my $val = shift;
245 my @vals = ($val =~ /\d+(?:\.\d*)?/g);
246 my $sec = 0;
247 $sec += 24 * 3600 * shift(@vals) if @vals > 3;
248 $sec += 3600 * shift(@vals) if @vals > 2;
249 $sec += 60 * shift(@vals) if @vals > 1;
250 $sec += shift(@vals) if @vals;
251 return $sec;
252 },
253 },
254 0x2a => { #4
255 Name => 'BurstMode',
256 Writable => 'int16u',
257 PrintConv => {
258 0 => 'Off',
259 1 => 'Low/High Quality',
260 2 => 'Infinite',
261 },
262 },
263 0x2b => { #4
264 Name => 'SequenceNumber',
265 Writable => 'int32u',
266 },
267 0x2c => {
268 Name => 'Contrast',
269 Flags => 'PrintHex',
270 Writable => 'int16u',
271 PrintConv => {
272 0 => 'Normal',
273 1 => 'Low',
274 2 => 'High',
275 # 3 - observed with LZ6 in "Aerial Photo" mode - PH
276 # 5 - observed with FX10 in "Underwater" mode - PH
277 0x100 => 'Low',
278 0x110 => 'Normal',
279 0x120 => 'High',
280 }
281 },
282 0x2d => {
283 Name => 'NoiseReduction',
284 Writable => 'int16u',
285 PrintConv => {
286 0 => 'Standard',
287 1 => 'Low',
288 2 => 'High',
289 },
290 },
291 0x2e => { #4
292 Name => 'SelfTimer',
293 Writable => 'int16u',
294 PrintConv => {
295 1 => 'Off',
296 2 => '10s',
297 3 => '2s',
298 },
299 },
300 # 0x2f - values: 1 (LZ6,FX10K)
301 0x30 => { #7
302 Name => 'Rotation',
303 Writable => 'int16u',
304 PrintConv => {
305 1 => 'Horizontal (normal)',
306 6 => 'Rotate 90 CW', #PH (ref 7 gives 270 CW)
307 8 => 'Rotate 270 CW', #PH (ref 7 gives 90 CW)
308 },
309 },
310 # 0x31 - values: 1-5 some sort of mode? (changes with FOC-L) (PH/10)
311 0x32 => { #7
312 Name => 'ColorMode',
313 Writable => 'int16u',
314 PrintConv => {
315 0 => 'Normal',
316 1 => 'Natural',
317 # 2 => observed in LZ6 for some shooting modes
318 },
319 },
320 0x33 => { #10
321 Name => 'BabyAge',
322 Writable => 'string',
323 Notes => 'or pet age', #PH
324 PrintConv => '$val eq "9999:99:99 00:00:00" ? "(not set)" : $val',
325 PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
326 },
327 0x34 => { #7/PH
328 Name => 'OpticalZoomMode',
329 Writable => 'int16u',
330 PrintConv => {
331 1 => 'Standard',
332 2 => 'EX Optics',
333 },
334 },
335 0x35 => { #9
336 Name => 'ConversionLens',
337 Writable => 'int16u',
338 PrintConv => { #PH (unconfirmed)
339 1 => 'Off',
340 2 => 'Wide',
341 3 => 'Telephoto',
342 4 => 'Macro',
343 },
344 },
345 0x36 => { #8
346 Name => 'TravelDay',
347 Writable => 'int16u',
348 PrintConv => '$val == 65535 ? "n/a" : $val',
349 PrintConvInv => '$val =~ /(\d+)/ ? $1 : $val',
350 },
351 # 0x37 - values: 0,1,2 (LZ6, 0 for movie preview) and 257 (FX10K)
352 # 0x38 - values: 0,1,2 (LZ6, same as 0x37) and 1,2 (FX10K)
353 0x3a => {
354 Name => 'WorldTimeLocation',
355 Writable => 'int16u',
356 PrintConv => {
357 1 => 'Home',
358 2 => 'Destination',
359 },
360 },
361 # 0x3b - values: 1 (LZ6, FX10K)
362 0x3c => { #PH
363 Name => 'ProgramISO',
364 Writable => 'int16u',
365 PrintConv => '$val == 65535 ? "n/a" : $val',
366 PrintConvInv => '$val eq "n/a" ? 65535 : $val',
367 },
368 # 0x40 Chroma? (ref 7)
369 0x42 => { #7 (DMC-L1)
370 Name => 'FilmMode',
371 Writable => 'int16u',
372 PrintConv => {
373 1 => 'Standard (color)',
374 2 => 'Dynamic (color)',
375 3 => 'Nature (color)',
376 4 => 'Smooth (color)',
377 5 => 'Standard (B&W)',
378 6 => 'Dynamic (B&W)',
379 7 => 'Smooth (B&W)',
380 # 8 => 'My Film 1'? (from owner manual)
381 # 9 => 'My Film 2'?
382 },
383 },
384 0x46 => { #PH/10
385 Name => 'WBAdjustAB',
386 Format => 'int16s',
387 Writable => 'int16u',
388 Notes => 'positive is a shift toward blue',
389 },
390 0x47 => { #PH/10
391 Name => 'WBAdjustGM',
392 Format => 'int16s',
393 Writable => 'int16u',
394 Notes => 'positive is a shift toward green',
395 },
396 0x51 => {
397 Name => 'LensType',
398 Writable => 'string',
399 },
400 0x52 => { #7 (DMC-L1)
401 Name => 'LensSerialNumber',
402 Writable => 'string',
403 },
404 0x53 => { #7 (DMC-L1)
405 Name => 'AccessoryType',
406 Writable => 'string',
407 },
408 0x0e00 => {
409 Name => 'PrintIM',
410 Description => 'Print Image Matching',
411 Writable => 0,
412 SubDirectory => {
413 TagTable => 'Image::ExifTool::PrintIM::Main',
414 },
415 },
416 0x8000 => { #PH
417 Name => 'MakerNoteVersion',
418 Format => 'undef',
419 },
420 0x8001 => { #7/PH/10
421 Name => 'SceneMode',
422 Writable => 'int16u',
423 PrintConv => {
424 0 => 'Off',
425 %shootingMode,
426 },
427 },
428 # 0x8002 - values: 1,2 related to focus? (PH/10)
429 # 0x8003 - values: 1,2 related to focus? (PH/10)
430 0x8004 => { #PH/10
431 Name => 'WBRedLevel',
432 Writable => 'int16u',
433 },
434 0x8005 => { #PH/10
435 Name => 'WBGreenLevel',
436 Writable => 'int16u',
437 },
438 0x8006 => { #PH/10
439 Name => 'WBBlueLevel',
440 Writable => 'int16u',
441 },
442 # 0x8007 - values: 1,2
443 0x8010 => { #PH
444 Name => 'BabyAge',
445 Writable => 'string',
446 Notes => 'or pet age',
447 PrintConv => '$val eq "9999:99:99 00:00:00" ? "(not set)" : $val',
448 PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
449 },
450);
451
452# Type 2 tags (ref PH)
453%Image::ExifTool::Panasonic::Type2 = (
454 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
455 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
456 FIRST_ENTRY => 0,
457 FORMAT => 'int16u',
458 NOTES => q{
459 This type of maker notes is used by models such as the NV-DS65, PV-D2002,
460 PV-DC3000, PV-DV203, PV-DV401, PV-DV702, PV-L2001, PV-SD4090, PV-SD5000 and
461 iPalm.
462 },
463 0 => {
464 Name => 'MakerNoteType',
465 Format => 'string[4]',
466 },
467 # seems to vary inversely with amount of light, so I'll call it 'Gain' - PH
468 # (minimum is 16, maximum is 136. Value is 0 for pictures captured from video)
469 3 => 'Gain',
470);
471
472# Tags found in Panasonic RAW images
473%Image::ExifTool::Panasonic::Raw = (
474 GROUPS => { 0 => 'EXIF', 1 => 'IFD0', 2 => 'Image'},
475 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
476 CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
477 WRITE_GROUP => 'IFD0', # default write group
478 NOTES => 'These tags are found in IFD0 of Panasonic RAW images.',
479 0x01 => {
480 Name => 'PanasonicRawVersion',
481 Writable => 'undef',
482 },
483 0x02 => 'SensorWidth', #5/PH
484 0x03 => 'SensorHeight', #5/PH
485 0x04 => 'SensorTopBorder', #10
486 0x05 => 'SensorLeftBorder', #10
487 0x06 => 'ImageHeight', #5/PH
488 0x07 => 'ImageWidth', #5/PH
489 0x11 => { #10
490 Name => 'RedBalance',
491 Writable => 'int16u',
492 ValueConv => '$val / 256',
493 ValueConvInv => 'int($val * 256 + 0.5)',
494 Notes => 'found in Digilux 2 RAW images',
495 },
496 0x12 => { #10
497 Name => 'BlueBalance',
498 Writable => 'int16u',
499 ValueConv => '$val / 256',
500 ValueConvInv => 'int($val * 256 + 0.5)',
501 },
502 0x17 => { #5
503 Name => 'ISO',
504 Writable => 'int16u',
505 },
506 0x24 => { #6
507 Name => 'WBRedLevel',
508 Writable => 'int16u',
509 },
510 0x25 => { #6
511 Name => 'WBGreenLevel',
512 Writable => 'int16u',
513 },
514 0x26 => { #6
515 Name => 'WBBlueLevel',
516 Writable => 'int16u',
517 },
518 0x10f => {
519 Name => 'Make',
520 Groups => { 2 => 'Camera' },
521 Writable => 'string',
522 DataMember => 'CameraMake',
523 # save this value as an ExifTool member variable
524 RawConv => '$self->{CameraMake} = $val',
525 },
526 0x110 => {
527 Name => 'Model',
528 Description => 'Camera Model Name',
529 Groups => { 2 => 'Camera' },
530 Writable => 'string',
531 DataMember => 'CameraModel',
532 # save this value as an ExifTool member variable
533 RawConv => '$self->{CameraModel} = $val',
534 },
535 0x111 => {
536 Name => 'StripOffsets',
537 Flags => 'IsOffset',
538 OffsetPair => 0x117, # point to associated byte counts
539 ValueConv => 'length($val) > 32 ? \$val : $val',
540 },
541 0x112 => {
542 Name => 'Orientation',
543 Writable => 'int16u',
544 PrintConv => \%Image::ExifTool::Exif::orientation,
545 Priority => 0, # so IFD1 doesn't take precedence
546 },
547 0x116 => {
548 Name => 'RowsPerStrip',
549 Priority => 0,
550 },
551 0x117 => {
552 Name => 'StripByteCounts',
553 OffsetPair => 0x111, # point to associated offset
554 ValueConv => 'length($val) > 32 ? \$val : $val',
555 },
556 0x8769 => {
557 Name => 'ExifOffset',
558 Groups => { 1 => 'ExifIFD' },
559 Flags => 'SubIFD',
560 SubDirectory => {
561 TagTable => 'Image::ExifTool::Exif::Main',
562 DirName => 'ExifIFD',
563 Start => '$val',
564 },
565 },
566 0x8825 => {
567 Name => 'GPSInfo',
568 Groups => { 1 => 'GPS' },
569 Flags => 'SubIFD',
570 SubDirectory => {
571 DirName => 'GPS',
572 TagTable => 'Image::ExifTool::GPS::Main',
573 Start => '$val',
574 },
575 },
576);
577
5781; # end
579
580__END__
581
582=head1 NAME
583
584Image::ExifTool::Panasonic - Panasonic/Leica maker notes tags
585
586=head1 SYNOPSIS
587
588This module is loaded automatically by Image::ExifTool when required.
589
590=head1 DESCRIPTION
591
592This module contains definitions required by Image::ExifTool to interpret
593Panasonic and Leica maker notes in EXIF information.
594
595=head1 AUTHOR
596
597Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
598
599This library is free software; you can redistribute it and/or modify it
600under the same terms as Perl itself.
601
602=head1 REFERENCES
603
604=over 4
605
606=item L<http://www.compton.nu/panasonic.html>
607
608=item L<http://johnst.org/sw/exiftags/>
609
610=item L<http://www.cybercom.net/~dcoffin/dcraw/>
611
612=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm>
613
614=back
615
616=head1 ACKNOWLEDGEMENTS
617
618Thanks to Tels for the information he provided on decoding some tags, and to
619Marcel Coenen and Jens Duttke for their contributions.
620
621=head1 SEE ALSO
622
623L<Image::ExifTool::TagNames/Panasonic Tags>,
624L<Image::ExifTool(3pm)|Image::ExifTool>
625
626=cut
Note: See TracBrowser for help on using the repository browser.