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 | # 12) Joerg - http://www.cpanforum.com/threads/11602 (LX3 firmware 2.0)
|
---|
18 | # 13) Michael Byczkowski private communication (Leica M9)
|
---|
19 | # 14) Carl Bretteville private communication (M9)
|
---|
20 | # 15) Zdenek Mihula private communication (TZ8)
|
---|
21 | # JD) Jens Duttke private communication (TZ3,FZ30,FZ50)
|
---|
22 | #------------------------------------------------------------------------------
|
---|
23 |
|
---|
24 | package Image::ExifTool::Panasonic;
|
---|
25 |
|
---|
26 | use strict;
|
---|
27 | use vars qw($VERSION);
|
---|
28 | use Image::ExifTool qw(:DataAccess :Utils);
|
---|
29 | use Image::ExifTool::Exif;
|
---|
30 |
|
---|
31 | $VERSION = '1.59';
|
---|
32 |
|
---|
33 | sub ProcessPanasonicType2($$$);
|
---|
34 | sub WhiteBalanceConv($;$$);
|
---|
35 |
|
---|
36 | # Leica lens types (ref 10)
|
---|
37 | my %leicaLensType = (
|
---|
38 | OTHER => sub {
|
---|
39 | my ($val, $inv, $conv) = @_;
|
---|
40 | return undef if $inv or not $val =~ s/ .*//;
|
---|
41 | return $$conv{$val};
|
---|
42 | },
|
---|
43 | Notes => q{
|
---|
44 | Entries with 2 numbers give the lower 2 bits of the LensType value which are
|
---|
45 | used to identify certain manually coded lenses on the M9, or the focal
|
---|
46 | length of some multi-focal lenses.
|
---|
47 | },
|
---|
48 | # All M9 codes (two numbers: first the LensID then the lower 2 bits)
|
---|
49 | # are ref PH with samples from ref 13. From ref 10, the lower 2 bits of
|
---|
50 | # the LensType value give the frame selector position for most lenses,
|
---|
51 | # although for the 28-35-50mm (at least) it gives the focal length selection.
|
---|
52 | # The M9 also gives the focal length selection but for other lenses the
|
---|
53 | # lower 3 bits don't change with frame selector position except for the lens
|
---|
54 | # shows as uncoded for certain lenses and some incorrect positions of the
|
---|
55 | # frame selector. The bits are zero for uncoded lenses when manually coding
|
---|
56 | # from the menu on the M9. - PH
|
---|
57 | '0 0' => 'Uncoded lens',
|
---|
58 | #
|
---|
59 | # NOTE: MUST ADD ENTRY TO %frameSelectorBits below when a new lens is added!!!!
|
---|
60 | #
|
---|
61 | # model number(s):
|
---|
62 | 1 => 'Elmarit-M 21mm f/2.8', # 11134
|
---|
63 | 3 => 'Elmarit-M 28mm f/2.8 (III)', # 11804
|
---|
64 | 4 => 'Tele-Elmarit-M 90mm f/2.8 (II)', # 11800
|
---|
65 | 5 => 'Summilux-M 50mm f/1.4 (II)', # 11868/11856/11114
|
---|
66 | 6 => 'Summicron-M 35mm f/2 (IV)', # 11310/11311
|
---|
67 | '6 0' => 'Summilux-M 35mm f/1.4', # 11869/11870/11860
|
---|
68 | 7 => 'Summicron-M 90mm f/2 (II)', # 11136/11137
|
---|
69 | 9 => 'Elmarit-M 135mm f/2.8 (I/II)', # 11829
|
---|
70 | '9 0' => 'Apo-Telyt-M 135mm f/3.4', # 11889
|
---|
71 | 16 => 'Tri-Elmar-M 16-18-21mm f/4 ASPH.',# 11626
|
---|
72 | '16 1' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 16mm)',
|
---|
73 | '16 2' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 18mm)',
|
---|
74 | '16 3' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 21mm)',
|
---|
75 | 23 => 'Summicron-M 50mm f/2 (III)', # 11817, version (I) in camera menu
|
---|
76 | 24 => 'Elmarit-M 21mm f/2.8 ASPH.', # 11135/11897
|
---|
77 | 25 => 'Elmarit-M 24mm f/2.8 ASPH.', # 11878/11898
|
---|
78 | 26 => 'Summicron-M 28mm f/2 ASPH.', # 11604
|
---|
79 | 27 => 'Elmarit-M 28mm f/2.8 (IV)', # 11809
|
---|
80 | 28 => 'Elmarit-M 28mm f/2.8 ASPH.', # 11606
|
---|
81 | 29 => 'Summilux-M 35mm f/1.4 ASPH.', # 11874/11883
|
---|
82 | '29 0' => 'Summilux-M 35mm f/1.4 ASPHERICAL', # 11873 (different from "ASPH." model!)
|
---|
83 | 30 => 'Summicron-M 35mm f/2 ASPH.', # 11879/11882
|
---|
84 | 31 => 'Noctilux-M 50mm f/1', # 11821/11822
|
---|
85 | '31 0' => 'Noctilux-M 50mm f/1.2', # 11820
|
---|
86 | 32 => 'Summilux-M 50mm f/1.4 ASPH.', # 11891/11892
|
---|
87 | 33 => 'Summicron-M 50mm f/2 (IV, V)', # 11819/11825/11826/11816, version (II,III) in camera menu
|
---|
88 | 34 => 'Elmar-M 50mm f/2.8', # 11831/11823/11825
|
---|
89 | 35 => 'Summilux-M 75mm f/1.4', # 11814/11815/11810
|
---|
90 | 36 => 'Apo-Summicron-M 75mm f/2 ASPH.', # 11637
|
---|
91 | 37 => 'Apo-Summicron-M 90mm f/2 ASPH.', # 11884/11885
|
---|
92 | 38 => 'Elmarit-M 90mm f/2.8', # 11807/11808, version (II) in camera menu
|
---|
93 | 39 => 'Macro-Elmar-M 90mm f/4', # 11633/11634
|
---|
94 | '39 0' => 'Tele-Elmar-M 135mm f/4 (II)',# 11861
|
---|
95 | 40 => 'Macro-Adapter M', # 14409
|
---|
96 | 42 => 'Tri-Elmar-M 28-35-50mm f/4 ASPH.',# 11625
|
---|
97 | '42 1' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 28mm)',
|
---|
98 | '42 2' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 35mm)',
|
---|
99 | '42 3' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 50mm)',
|
---|
100 | 43 => 'Summarit-M 35mm f/2.5', # ? (ref PH)
|
---|
101 | 44 => 'Summarit-M 50mm f/2.5', # ? (ref PH)
|
---|
102 | 45 => 'Summarit-M 75mm f/2.5', # ? (ref PH)
|
---|
103 | 46 => 'Summarit-M 90mm f/2.5', # ?
|
---|
104 | 47 => 'Summilux-M 21mm f/1.4 ASPH.', # ? (ref 11)
|
---|
105 | 48 => 'Summilux-M 24mm f/1.4 ASPH.', # ? (ref 11)
|
---|
106 | 49 => 'Noctilux-M 50mm f/0.95 ASPH.', # ? (ref 11)
|
---|
107 | 50 => 'Elmar-M 24mm f/3.8 ASPH.', # ? (ref 11)
|
---|
108 | 52 => 'Super-Elmar-M 18mm f/3.8 ASPH.', # ? (ref PH/11)
|
---|
109 | );
|
---|
110 |
|
---|
111 | # M9 frame selector bits for each lens
|
---|
112 | # 1 = towards lens = 28/90mm or 21mm or Adapter (or Elmarit-M 135mm f/2.8)
|
---|
113 | # 2 = away from lens = 24/35mm (or 35/135mm on the M9)
|
---|
114 | # 3 = middle position = 50/75mm or 18mm
|
---|
115 | my %frameSelectorBits = (
|
---|
116 | 1 => 1,
|
---|
117 | 3 => 1,
|
---|
118 | 4 => 1,
|
---|
119 | 5 => 3,
|
---|
120 | 6 => 2,
|
---|
121 | 7 => 1,
|
---|
122 | 9 => 1, # (because lens has special magnifier for the rangefinder)
|
---|
123 | 16 => 1, # or 2 or 3
|
---|
124 | 23 => 3,
|
---|
125 | 24 => 1,
|
---|
126 | 25 => 2,
|
---|
127 | 26 => 1,
|
---|
128 | 27 => 1,
|
---|
129 | 28 => 1,
|
---|
130 | 29 => 2,
|
---|
131 | 30 => 2,
|
---|
132 | 31 => 3,
|
---|
133 | 32 => 3,
|
---|
134 | 33 => 3,
|
---|
135 | 34 => 3,
|
---|
136 | 35 => 3,
|
---|
137 | 36 => 3,
|
---|
138 | 37 => 1,
|
---|
139 | 38 => 1,
|
---|
140 | 39 => 1,
|
---|
141 | 40 => 1,
|
---|
142 | 42 => 1, # or 2 or 3
|
---|
143 | 43 => 2, # (NC)
|
---|
144 | 44 => 3, # (NC)
|
---|
145 | 45 => 3,
|
---|
146 | 46 => 1, # (NC)
|
---|
147 | 47 => 1, # (NC)
|
---|
148 | 48 => 2, # (NC)
|
---|
149 | 49 => 3, # (NC)
|
---|
150 | 50 => 2, # (NC)
|
---|
151 | 52 => 3,
|
---|
152 | );
|
---|
153 |
|
---|
154 | # conversions for ShootingMode and SceneMode
|
---|
155 | my %shootingMode = (
|
---|
156 | 1 => 'Normal',
|
---|
157 | 2 => 'Portrait',
|
---|
158 | 3 => 'Scenery',
|
---|
159 | 4 => 'Sports',
|
---|
160 | 5 => 'Night Portrait',
|
---|
161 | 6 => 'Program',
|
---|
162 | 7 => 'Aperture Priority',
|
---|
163 | 8 => 'Shutter Priority',
|
---|
164 | 9 => 'Macro',
|
---|
165 | 10 => 'Spot', #7
|
---|
166 | 11 => 'Manual',
|
---|
167 | 12 => 'Movie Preview', #PH (LZ6)
|
---|
168 | 13 => 'Panning',
|
---|
169 | 14 => 'Simple', #PH (LZ6)
|
---|
170 | 15 => 'Color Effects', #7
|
---|
171 | 16 => 'Self Portrait', #PH (TZ5)
|
---|
172 | 17 => 'Economy', #7
|
---|
173 | 18 => 'Fireworks',
|
---|
174 | 19 => 'Party',
|
---|
175 | 20 => 'Snow',
|
---|
176 | 21 => 'Night Scenery',
|
---|
177 | 22 => 'Food', #7
|
---|
178 | 23 => 'Baby', #JD
|
---|
179 | 24 => 'Soft Skin', #PH (LZ6)
|
---|
180 | 25 => 'Candlelight', #PH (LZ6)
|
---|
181 | 26 => 'Starry Night', #PH (LZ6)
|
---|
182 | 27 => 'High Sensitivity', #7 (LZ6)
|
---|
183 | 28 => 'Panorama Assist', #7
|
---|
184 | 29 => 'Underwater', #7
|
---|
185 | 30 => 'Beach', #PH (LZ6)
|
---|
186 | 31 => 'Aerial Photo', #PH (LZ6)
|
---|
187 | 32 => 'Sunset', #PH (LZ6)
|
---|
188 | 33 => 'Pet', #JD
|
---|
189 | 34 => 'Intelligent ISO', #PH (LZ6)
|
---|
190 | 35 => 'Clipboard', #7
|
---|
191 | 36 => 'High Speed Continuous Shooting', #7
|
---|
192 | 37 => 'Intelligent Auto', #7
|
---|
193 | 39 => 'Multi-aspect', #PH (TZ5)
|
---|
194 | 41 => 'Transform', #PH (FS7)
|
---|
195 | 42 => 'Flash Burst', #PH (FZ28)
|
---|
196 | 43 => 'Pin Hole', #PH (FZ28)
|
---|
197 | 44 => 'Film Grain', #PH (FZ28)
|
---|
198 | 45 => 'My Color', #PH (GF1)
|
---|
199 | 46 => 'Photo Frame', #PH (FS7)
|
---|
200 | 51 => 'HDR', #12
|
---|
201 | );
|
---|
202 |
|
---|
203 | %Image::ExifTool::Panasonic::Main = (
|
---|
204 | WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
|
---|
205 | CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
|
---|
206 | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
|
---|
207 | WRITABLE => 1,
|
---|
208 | 0x01 => {
|
---|
209 | Name => 'ImageQuality',
|
---|
210 | Writable => 'int16u',
|
---|
211 | PrintConv => {
|
---|
212 | 2 => 'High',
|
---|
213 | 3 => 'Normal',
|
---|
214 | 6 => 'Very High', #3 (Leica)
|
---|
215 | 7 => 'Raw', #3 (Leica)
|
---|
216 | 9 => 'Motion Picture', #PH (LZ6)
|
---|
217 | },
|
---|
218 | },
|
---|
219 | 0x02 => {
|
---|
220 | Name => 'FirmwareVersion',
|
---|
221 | Writable => 'undef',
|
---|
222 | Notes => q{
|
---|
223 | for some camera models such as the FZ30 this may be an internal production
|
---|
224 | reference number and not the actual firmware version
|
---|
225 | }, # (ref http://www.stevesforums.com/forums/view_topic.php?id=87764&forum_id=23&)
|
---|
226 | # (can be either binary or ascii -- add decimal points if binary)
|
---|
227 | ValueConv => '$val=~/[\0-\x2f]/ ? join(" ",unpack("C*",$val)) : $val',
|
---|
228 | ValueConvInv => q{
|
---|
229 | $val =~ /(\d+ ){3}\d+/ and $val = pack('C*',split(' ', $val));
|
---|
230 | length($val) == 4 or warn "Version must be 4 numbers\n";
|
---|
231 | return $val;
|
---|
232 | },
|
---|
233 | PrintConv => '$val=~tr/ /./; $val',
|
---|
234 | PrintConvInv => '$val=~tr/./ /; $val',
|
---|
235 | },
|
---|
236 | 0x03 => {
|
---|
237 | Name => 'WhiteBalance',
|
---|
238 | Writable => 'int16u',
|
---|
239 | PrintConv => {
|
---|
240 | 1 => 'Auto',
|
---|
241 | 2 => 'Daylight',
|
---|
242 | 3 => 'Cloudy',
|
---|
243 | 4 => 'Incandescent', #PH
|
---|
244 | 5 => 'Manual',
|
---|
245 | 8 => 'Flash',
|
---|
246 | 10 => 'Black & White', #3 (Leica)
|
---|
247 | 11 => 'Manual', #PH (FZ8)
|
---|
248 | 12 => 'Shade', #PH (FS7)
|
---|
249 | },
|
---|
250 | },
|
---|
251 | 0x07 => {
|
---|
252 | Name => 'FocusMode',
|
---|
253 | Writable => 'int16u',
|
---|
254 | PrintConv => {
|
---|
255 | 1 => 'Auto',
|
---|
256 | 2 => 'Manual',
|
---|
257 | 4 => 'Auto, Focus button', #4
|
---|
258 | 5 => 'Auto, Continuous', #4
|
---|
259 | # have seens 6 for GF1 - PH
|
---|
260 | },
|
---|
261 | },
|
---|
262 | 0x0f => [
|
---|
263 | {
|
---|
264 | Name => 'AFAreaMode',
|
---|
265 | Condition => '$$self{Model} =~ /DMC-FZ10\b/', #JD
|
---|
266 | Writable => 'int8u',
|
---|
267 | Count => 2,
|
---|
268 | Notes => 'DMC-FZ10',
|
---|
269 | PrintConv => {
|
---|
270 | '0 1' => 'Spot Mode On',
|
---|
271 | '0 16' => 'Spot Mode Off',
|
---|
272 | },
|
---|
273 | },{
|
---|
274 | Name => 'AFAreaMode',
|
---|
275 | Writable => 'int8u',
|
---|
276 | Count => 2,
|
---|
277 | Notes => 'other models',
|
---|
278 | PrintConv => { #PH
|
---|
279 | '0 1' => '9-area', # (FS7)
|
---|
280 | '0 16' => '3-area (high speed)', # (FZ8)
|
---|
281 | '1 0' => 'Spot Focusing', # (FZ8)
|
---|
282 | '1 1' => '5-area', # (FZ8)
|
---|
283 | '16' => 'Normal?', # (only mode for DMC-LC20)
|
---|
284 | '16 0' => '1-area', # (FZ8)
|
---|
285 | '16 16' => '1-area (high speed)', # (FZ8)
|
---|
286 | '32 0' => 'Auto or Face Detect', # (Face Detect for FS7, Auto is DMC-L1 guess)
|
---|
287 | '32 1' => '3-area (left)?', # (DMC-L1 guess)
|
---|
288 | '32 2' => '3-area (center)?', # (DMC-L1 guess)
|
---|
289 | '32 3' => '3-area (right)?', # (DMC-L1 guess)
|
---|
290 | '64 0' => 'Face Detect',
|
---|
291 | },
|
---|
292 | },
|
---|
293 | ],
|
---|
294 | 0x1a => {
|
---|
295 | Name => 'ImageStabilization',
|
---|
296 | Writable => 'int16u',
|
---|
297 | PrintConv => {
|
---|
298 | 2 => 'On, Mode 1',
|
---|
299 | 3 => 'Off',
|
---|
300 | 4 => 'On, Mode 2',
|
---|
301 | # GF1 also has a mode 3
|
---|
302 | },
|
---|
303 | },
|
---|
304 | 0x1c => {
|
---|
305 | Name => 'MacroMode',
|
---|
306 | Writable => 'int16u',
|
---|
307 | PrintConv => {
|
---|
308 | 1 => 'On',
|
---|
309 | 2 => 'Off',
|
---|
310 | 0x101 => 'Tele-Macro', #7
|
---|
311 | 0x201 => 'Macro Zoom', #PH (FS7)
|
---|
312 | },
|
---|
313 | },
|
---|
314 | 0x1f => {
|
---|
315 | Name => 'ShootingMode',
|
---|
316 | Writable => 'int16u',
|
---|
317 | PrintConvColumns => 2,
|
---|
318 | PrintConv => \%shootingMode,
|
---|
319 | },
|
---|
320 | 0x20 => {
|
---|
321 | Name => 'Audio',
|
---|
322 | Writable => 'int16u',
|
---|
323 | PrintConv => { 1 => 'Yes', 2 => 'No' },
|
---|
324 | },
|
---|
325 | 0x21 => { #2
|
---|
326 | Name => 'DataDump',
|
---|
327 | Writable => 0,
|
---|
328 | Binary => 1,
|
---|
329 | },
|
---|
330 | # 0x22 - normally 0, but 2 for 'Simple' ShootingMode in LZ6 sample - PH
|
---|
331 | 0x23 => {
|
---|
332 | Name => 'WhiteBalanceBias',
|
---|
333 | Format => 'int16s',
|
---|
334 | Writable => 'int16s',
|
---|
335 | ValueConv => '$val / 3',
|
---|
336 | ValueConvInv => '$val * 3',
|
---|
337 | PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
|
---|
338 | PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
|
---|
339 | },
|
---|
340 | 0x24 => {
|
---|
341 | Name => 'FlashBias',
|
---|
342 | Format => 'int16s',
|
---|
343 | Writable => 'int16s',
|
---|
344 | },
|
---|
345 | 0x25 => { #PH
|
---|
346 | Name => 'InternalSerialNumber',
|
---|
347 | Writable => 'undef',
|
---|
348 | Count => 16,
|
---|
349 | Notes => q{
|
---|
350 | this number is unique, and contains the date of manufacture, but is not the
|
---|
351 | same as the number printed on the camera body
|
---|
352 | },
|
---|
353 | PrintConv => q{
|
---|
354 | return $val unless $val=~/^([A-Z]\d{2})(\d{2})(\d{2})(\d{2})(\d{4})/;
|
---|
355 | my $yr = $2 + ($2 < 70 ? 2000 : 1900);
|
---|
356 | return "($1) $yr:$3:$4 no. $5";
|
---|
357 | },
|
---|
358 | PrintConvInv => '$_=$val; tr/A-Z0-9//dc; s/(.{3})(19|20)/$1/; $_',
|
---|
359 | },
|
---|
360 | 0x26 => { #PH
|
---|
361 | Name => 'PanasonicExifVersion',
|
---|
362 | Writable => 'undef',
|
---|
363 | },
|
---|
364 | # 0x27 - values: 0 (LZ6,FX10K)
|
---|
365 | 0x28 => {
|
---|
366 | Name => 'ColorEffect',
|
---|
367 | Writable => 'int16u',
|
---|
368 | # FX30 manual: (ColorMode) natural, vivid, cool, warm, b/w, sepia
|
---|
369 | PrintConv => {
|
---|
370 | 1 => 'Off',
|
---|
371 | 2 => 'Warm',
|
---|
372 | 3 => 'Cool',
|
---|
373 | 4 => 'Black & White',
|
---|
374 | 5 => 'Sepia',
|
---|
375 | 6 => 'Happy', #PH (FX70) (yes, really. you wouldn't want sad colors now would you?)
|
---|
376 | },
|
---|
377 | },
|
---|
378 | 0x29 => { #JD
|
---|
379 | Name => 'TimeSincePowerOn',
|
---|
380 | Writable => 'int32u',
|
---|
381 | Notes => q{
|
---|
382 | time in 1/100 s from when the camera was powered on to when the image is
|
---|
383 | written to memory card
|
---|
384 | },
|
---|
385 | ValueConv => '$val / 100',
|
---|
386 | ValueConvInv => '$val * 100',
|
---|
387 | PrintConv => sub { # convert to format "[DD days ]HH:MM:SS.ss"
|
---|
388 | my $val = shift;
|
---|
389 | my $str = '';
|
---|
390 | if ($val >= 24 * 3600) {
|
---|
391 | my $d = int($val / (24 * 3600));
|
---|
392 | $str .= "$d days ";
|
---|
393 | $val -= $d * 24 * 3600;
|
---|
394 | }
|
---|
395 | my $h = int($val / 3600);
|
---|
396 | $val -= $h * 3600;
|
---|
397 | my $m = int($val / 60);
|
---|
398 | $val -= $m * 60;
|
---|
399 | my $s = int($val);
|
---|
400 | my $f = 100 * ($val - int($val));
|
---|
401 | return sprintf("%s%.2d:%.2d:%.2d.%.2d",$str,$h,$m,$s,$f);
|
---|
402 | },
|
---|
403 | PrintConvInv => sub {
|
---|
404 | my $val = shift;
|
---|
405 | my @vals = ($val =~ /\d+(?:\.\d*)?/g);
|
---|
406 | my $sec = 0;
|
---|
407 | $sec += 24 * 3600 * shift(@vals) if @vals > 3;
|
---|
408 | $sec += 3600 * shift(@vals) if @vals > 2;
|
---|
409 | $sec += 60 * shift(@vals) if @vals > 1;
|
---|
410 | $sec += shift(@vals) if @vals;
|
---|
411 | return $sec;
|
---|
412 | },
|
---|
413 | },
|
---|
414 | 0x2a => { #4
|
---|
415 | Name => 'BurstMode',
|
---|
416 | Writable => 'int16u',
|
---|
417 | Notes => 'decoding may be different for some models',
|
---|
418 | PrintConv => {
|
---|
419 | 0 => 'Off',
|
---|
420 | 1 => 'On', #PH (TZ5) [was "Low/High Quality" from ref 4]
|
---|
421 | 2 => 'Infinite',
|
---|
422 | 4 => 'Unlimited', #PH (TZ5)
|
---|
423 | },
|
---|
424 | },
|
---|
425 | 0x2b => { #4
|
---|
426 | Name => 'SequenceNumber',
|
---|
427 | Writable => 'int32u',
|
---|
428 | },
|
---|
429 | 0x2c => [
|
---|
430 | {
|
---|
431 | Name => 'ContrastMode',
|
---|
432 | Condition => '$$self{Model} !~ /^DMC-(FX10|G1|L1|L10|LC80|GF1|TZ10|ZS7)$/',
|
---|
433 | Flags => 'PrintHex',
|
---|
434 | Writable => 'int16u',
|
---|
435 | Notes => q{
|
---|
436 | this decoding seems to work for some models such as the LC1, LX2, FZ7, FZ8,
|
---|
437 | FZ18 and FZ50, but may not be correct for other models such as the FX10, G1, L1,
|
---|
438 | L10 and LC80
|
---|
439 | },
|
---|
440 | PrintConv => {
|
---|
441 | 0 => 'Normal',
|
---|
442 | 1 => 'Low',
|
---|
443 | 2 => 'High',
|
---|
444 | # 3 - observed with LZ6 and TZ5 in Fireworks mode - PH
|
---|
445 | # 5 - observed with FX01, FX40 and FP8 (EXIF contrast "Normal") - PH
|
---|
446 | 6 => 'Medium Low', #PH (FZ18)
|
---|
447 | 7 => 'Medium High', #PH (FZ18)
|
---|
448 | # DMC-LC1 values:
|
---|
449 | 0x100 => 'Low',
|
---|
450 | 0x110 => 'Normal',
|
---|
451 | 0x120 => 'High',
|
---|
452 | }
|
---|
453 | },{
|
---|
454 | Name => 'ContrastMode',
|
---|
455 | Condition => '$$self{Model} eq "DMC-GF1"',
|
---|
456 | Notes => 'these values are used by the GF1',
|
---|
457 | Writable => 'int16u',
|
---|
458 | PrintConv => {
|
---|
459 | 0 => '-2',
|
---|
460 | 1 => '-1',
|
---|
461 | 2 => 'Normal',
|
---|
462 | 3 => '+1',
|
---|
463 | 4 => '+2',
|
---|
464 | # Note: Other Contrast tags will be "Normal" in any of these modes:
|
---|
465 | 7 => 'Nature (Color Film)',
|
---|
466 | 12 => 'Smooth (Color Film) or Pure (My Color)',
|
---|
467 | 17 => 'Dynamic (B&W Film)',
|
---|
468 | 22 => 'Smooth (B&W Film)',
|
---|
469 | 27 => 'Dynamic (Color Film)',
|
---|
470 | 32 => 'Vibrant (Color Film) or Expressive (My Color)',
|
---|
471 | 33 => 'Elegant (My Color)',
|
---|
472 | 37 => 'Nostalgic (Color Film)',
|
---|
473 | 41 => 'Dynamic Art (My Color)',
|
---|
474 | 42 => 'Retro (My Color)',
|
---|
475 | },
|
---|
476 | },{
|
---|
477 | Name => 'ContrastMode',
|
---|
478 | Condition => '$$self{Model} =~ /^DMC-(TZ10|ZS7)$/',
|
---|
479 | Notes => 'these values are used by the TZ10 and ZS7',
|
---|
480 | Writable => 'int16u',
|
---|
481 | PrintConv => {
|
---|
482 | 0 => 'Normal',
|
---|
483 | 1 => '-2',
|
---|
484 | 2 => '+2',
|
---|
485 | 5 => '-1',
|
---|
486 | 6 => '+1',
|
---|
487 | },
|
---|
488 | },{
|
---|
489 | Name => 'ContrastMode',
|
---|
490 | Writable => 'int16u',
|
---|
491 | },
|
---|
492 | ],
|
---|
493 | 0x2d => {
|
---|
494 | Name => 'NoiseReduction',
|
---|
495 | Writable => 'int16u',
|
---|
496 | PrintConv => {
|
---|
497 | 0 => 'Standard',
|
---|
498 | 1 => 'Low (-1)',
|
---|
499 | 2 => 'High (+1)',
|
---|
500 | 3 => 'Lowest (-2)', #JD
|
---|
501 | 4 => 'Highest (+2)', #JD
|
---|
502 | },
|
---|
503 | },
|
---|
504 | 0x2e => { #4
|
---|
505 | Name => 'SelfTimer',
|
---|
506 | Writable => 'int16u',
|
---|
507 | PrintConv => {
|
---|
508 | 1 => 'Off',
|
---|
509 | 2 => '10 s',
|
---|
510 | 3 => '2 s',
|
---|
511 | },
|
---|
512 | },
|
---|
513 | # 0x2f - values: 1 (LZ6,FX10K)
|
---|
514 | 0x30 => { #7
|
---|
515 | Name => 'Rotation',
|
---|
516 | Writable => 'int16u',
|
---|
517 | PrintConv => {
|
---|
518 | 1 => 'Horizontal (normal)',
|
---|
519 | 3 => 'Rotate 180', #PH
|
---|
520 | 6 => 'Rotate 90 CW', #PH (ref 7 gives 270 CW)
|
---|
521 | 8 => 'Rotate 270 CW', #PH (ref 7 gives 90 CW)
|
---|
522 | },
|
---|
523 | },
|
---|
524 | 0x31 => { #PH (FS7)
|
---|
525 | Name => 'AFAssistLamp',
|
---|
526 | Writable => 'int16u',
|
---|
527 | PrintConv => {
|
---|
528 | 1 => 'Fired',
|
---|
529 | 2 => 'Enabled but Not Used',
|
---|
530 | 3 => 'Disabled but Required',
|
---|
531 | 4 => 'Disabled and Not Required',
|
---|
532 | # have seen a value of 5 - PH
|
---|
533 | # values possibly related to FOC-L? - JD
|
---|
534 | },
|
---|
535 | },
|
---|
536 | 0x32 => { #7
|
---|
537 | Name => 'ColorMode',
|
---|
538 | Writable => 'int16u',
|
---|
539 | PrintConv => {
|
---|
540 | 0 => 'Normal',
|
---|
541 | 1 => 'Natural',
|
---|
542 | 2 => 'Vivid',
|
---|
543 | # have seen 3 for GF2 - PH
|
---|
544 | },
|
---|
545 | },
|
---|
546 | 0x33 => { #JD
|
---|
547 | Name => 'BabyAge',
|
---|
548 | Writable => 'string',
|
---|
549 | Notes => 'or pet age', #PH
|
---|
550 | PrintConv => '$val eq "9999:99:99 00:00:00" ? "(not set)" : $val',
|
---|
551 | PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
|
---|
552 | },
|
---|
553 | 0x34 => { #7/PH
|
---|
554 | Name => 'OpticalZoomMode',
|
---|
555 | Writable => 'int16u',
|
---|
556 | PrintConv => {
|
---|
557 | 1 => 'Standard',
|
---|
558 | 2 => 'Extended',
|
---|
559 | },
|
---|
560 | },
|
---|
561 | 0x35 => { #9
|
---|
562 | Name => 'ConversionLens',
|
---|
563 | Writable => 'int16u',
|
---|
564 | PrintConv => { #PH (unconfirmed)
|
---|
565 | 1 => 'Off',
|
---|
566 | 2 => 'Wide',
|
---|
567 | 3 => 'Telephoto',
|
---|
568 | 4 => 'Macro',
|
---|
569 | },
|
---|
570 | },
|
---|
571 | 0x36 => { #8
|
---|
572 | Name => 'TravelDay',
|
---|
573 | Writable => 'int16u',
|
---|
574 | PrintConv => '$val == 65535 ? "n/a" : $val',
|
---|
575 | PrintConvInv => '$val =~ /(\d+)/ ? $1 : $val',
|
---|
576 | },
|
---|
577 | # 0x37 - values: 0,1,2 (LZ6, 0 for movie preview); 257 (FX10K); 0,256 (TZ5, 0 for movie preview)
|
---|
578 | # 0x38 - values: 0,1,2 (LZ6, same as 0x37); 1,2 (FX10K); 0,256 (TZ5, 0 for movie preview)
|
---|
579 | 0x39 => { #7 (L1/L10)
|
---|
580 | Name => 'Contrast',
|
---|
581 | Format => 'int16s',
|
---|
582 | Writable => 'int16u',
|
---|
583 | %Image::ExifTool::Exif::printParameter,
|
---|
584 | },
|
---|
585 | 0x3a => {
|
---|
586 | Name => 'WorldTimeLocation',
|
---|
587 | Writable => 'int16u',
|
---|
588 | PrintConv => {
|
---|
589 | 1 => 'Home',
|
---|
590 | 2 => 'Destination',
|
---|
591 | },
|
---|
592 | },
|
---|
593 | 0x3b => { #PH (TZ5/FS7)
|
---|
594 | # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
|
---|
595 | Name => 'TextStamp',
|
---|
596 | Writable => 'int16u',
|
---|
597 | PrintConv => { 1 => 'Off', 2 => 'On' },
|
---|
598 | },
|
---|
599 | 0x3c => { #PH
|
---|
600 | Name => 'ProgramISO', # (maybe should rename this ISOSetting?)
|
---|
601 | Writable => 'int16u',
|
---|
602 | PrintConv => {
|
---|
603 | OTHER => sub { return shift },
|
---|
604 | 65534 => 'Intelligent ISO', #PH (FS7)
|
---|
605 | 65535 => 'n/a',
|
---|
606 | },
|
---|
607 | },
|
---|
608 | 0x3d => { #PH
|
---|
609 | Name => 'AdvancedSceneMode',
|
---|
610 | Writable => 'int16u',
|
---|
611 | # values for the FZ28 (SceneMode/AdvancedSceneMode, "*"=add mode name) - PH:
|
---|
612 | # Portrait: 2/1=Normal*, 24/1=Soft Skin, 2/2=Outdoor*, 2/3=Indoor*, 2/4=Creative*
|
---|
613 | # Scenery: 3/1=Normal*, 3/2=Nature, 3/3=Architecture, 3/4=Creative*
|
---|
614 | # Sports: 4/1=Normal*, 4/2=Outdoor*, 4/3=Indoor*, 4/4=Creative*
|
---|
615 | # Night Scenery: 5/1=Night Portrait, 21/1=*, 21/2=Illuminations, 21/4=Creative*
|
---|
616 | # Macro (Close-up): 9/2=Flower, 22/1=Food, 9/3=Objects, 9/4=Creative*
|
---|
617 | # - have seen value of 5 for TZ5 (Macro) and FS20 (Scenery and Intelligent Auto)
|
---|
618 | # --> I'm guessing this is "Auto" - PH
|
---|
619 | # - values for HDR mode (ref 12): 1=Standard, 2=Art, 3=B&W
|
---|
620 | PrintConv => {
|
---|
621 | 1 => 'Normal',
|
---|
622 | 2 => 'Outdoor/Illuminations/Flower/HDR Art',
|
---|
623 | 3 => 'Indoor/Architecture/Objects/HDR B&W',
|
---|
624 | 4 => 'Creative',
|
---|
625 | 5 => 'Auto',
|
---|
626 | 7 => 'Expressive', #(GF1)
|
---|
627 | 8 => 'Retro', #(GF1)
|
---|
628 | 9 => 'Pure', #(GF1)
|
---|
629 | 10 => 'Elegant', #(GF1)
|
---|
630 | 12 => 'Monochrome', #(GF1)
|
---|
631 | 13 => 'Dynamic Art', #(GF1)
|
---|
632 | 14 => 'Silhouette', #(GF1)
|
---|
633 | },
|
---|
634 | },
|
---|
635 | 0x3e => { #PH (TZ5/FS7)
|
---|
636 | # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
|
---|
637 | Name => 'TextStamp',
|
---|
638 | Writable => 'int16u',
|
---|
639 | PrintConv => { 1 => 'Off', 2 => 'On' },
|
---|
640 | },
|
---|
641 | 0x3f => { #PH (TZ7)
|
---|
642 | Name => 'FacesDetected',
|
---|
643 | Writable => 'int16u',
|
---|
644 | },
|
---|
645 | 0x40 => { #7 (L1/L10)
|
---|
646 | Name => 'Saturation',
|
---|
647 | Format => 'int16s',
|
---|
648 | Writable => 'int16u',
|
---|
649 | %Image::ExifTool::Exif::printParameter,
|
---|
650 | },
|
---|
651 | 0x41 => { #7 (L1/L10)
|
---|
652 | Name => 'Sharpness',
|
---|
653 | Format => 'int16s',
|
---|
654 | Writable => 'int16u',
|
---|
655 | %Image::ExifTool::Exif::printParameter,
|
---|
656 | },
|
---|
657 | 0x42 => { #7 (DMC-L1)
|
---|
658 | Name => 'FilmMode',
|
---|
659 | Writable => 'int16u',
|
---|
660 | PrintConv => {
|
---|
661 | 0 => 'n/a', #PH (ie. FZ100 "Photo Frame" ShootingMode)
|
---|
662 | 1 => 'Standard (color)',
|
---|
663 | 2 => 'Dynamic (color)',
|
---|
664 | 3 => 'Nature (color)',
|
---|
665 | 4 => 'Smooth (color)',
|
---|
666 | 5 => 'Standard (B&W)',
|
---|
667 | 6 => 'Dynamic (B&W)',
|
---|
668 | 7 => 'Smooth (B&W)',
|
---|
669 | # 8 => 'My Film 1'? (from owner manual)
|
---|
670 | # 9 => 'My Film 2'?
|
---|
671 | 10 => 'Nostalgic', # GH1
|
---|
672 | 11 => 'Vibrant', # GH1
|
---|
673 | # 12 => 'Multi Film'? (in the GH1 specs)
|
---|
674 | },
|
---|
675 | },
|
---|
676 | # 0x43 - int16u: 2,3
|
---|
677 | # 0x44 - int16u: 0,2500
|
---|
678 | # 0x45 - int16u: 0
|
---|
679 | 0x46 => { #PH/JD
|
---|
680 | Name => 'WBAdjustAB',
|
---|
681 | Format => 'int16s',
|
---|
682 | Writable => 'int16u',
|
---|
683 | Notes => 'positive is a shift toward blue',
|
---|
684 | },
|
---|
685 | 0x47 => { #PH/JD
|
---|
686 | Name => 'WBAdjustGM',
|
---|
687 | Format => 'int16s',
|
---|
688 | Writable => 'int16u',
|
---|
689 | Notes => 'positive is a shift toward green',
|
---|
690 | },
|
---|
691 | # 0x48 - int16u: 0
|
---|
692 | # 0x49 - int16u: 2
|
---|
693 | # 0x4a - int16u: 0
|
---|
694 | 0x4b => { #PH
|
---|
695 | Name => 'PanasonicImageWidth',
|
---|
696 | Writable => 'int32u',
|
---|
697 | },
|
---|
698 | 0x4c => { #PH
|
---|
699 | Name => 'PanasonicImageHeight',
|
---|
700 | Writable => 'int32u',
|
---|
701 | },
|
---|
702 | 0x4d => { #PH (FS7)
|
---|
703 | Name => 'AFPointPosition',
|
---|
704 | Writable => 'rational64u',
|
---|
705 | Count => 2,
|
---|
706 | Notes => 'X Y coordinates of primary AF area center, in the range 0.0 to 1.0',
|
---|
707 | PrintConv => q{
|
---|
708 | return 'none' if $val eq '16777216 16777216';
|
---|
709 | my @a = split ' ', $val;
|
---|
710 | sprintf("%.2g %.2g",@a);
|
---|
711 | },
|
---|
712 | PrintConvInv => '$val eq "none" ? "16777216 16777216" : $val',
|
---|
713 | },
|
---|
714 | 0x4e => { #PH
|
---|
715 | Name => 'FaceDetInfo',
|
---|
716 | PrintConv => 'length $val',
|
---|
717 | SubDirectory => {
|
---|
718 | TagTable => 'Image::ExifTool::Panasonic::FaceDetInfo',
|
---|
719 | },
|
---|
720 | },
|
---|
721 | # 0x4f,0x50 - int16u: 0
|
---|
722 | 0x51 => {
|
---|
723 | Name => 'LensType',
|
---|
724 | Writable => 'string',
|
---|
725 | },
|
---|
726 | 0x52 => { #7 (DMC-L1)
|
---|
727 | Name => 'LensSerialNumber',
|
---|
728 | Writable => 'string',
|
---|
729 | },
|
---|
730 | 0x53 => { #7 (DMC-L1)
|
---|
731 | Name => 'AccessoryType',
|
---|
732 | Writable => 'string',
|
---|
733 | },
|
---|
734 | # 0x54 - string[14]: "0000000"
|
---|
735 | # 0x55 - int16u: 1
|
---|
736 | # 0x57 - int16u: 0
|
---|
737 | 0x59 => { #PH (FS7)
|
---|
738 | Name => 'Transform',
|
---|
739 | Writable => 'undef',
|
---|
740 | Notes => 'decoded as two 16-bit signed integers',
|
---|
741 | Format => 'int16s',
|
---|
742 | Count => 2,
|
---|
743 | PrintConv => {
|
---|
744 | '-3 2' => 'Slim High',
|
---|
745 | '-1 1' => 'Slim Low',
|
---|
746 | '0 0' => 'Off',
|
---|
747 | '1 1' => 'Stretch Low',
|
---|
748 | '3 2' => 'Stretch High',
|
---|
749 | },
|
---|
750 | },
|
---|
751 | # 0x5a - int16u: 0,2
|
---|
752 | # 0x5b - int16u: 0
|
---|
753 | # 0x5c - int16u: 0,2
|
---|
754 | 0x5d => { #PH (GF1, FZ35)
|
---|
755 | Name => 'IntelligentExposure',
|
---|
756 | Notes => 'not valid for some models', # (doesn't change in ZS7 and GH1 images)
|
---|
757 | Writable => 'int16u',
|
---|
758 | PrintConv => {
|
---|
759 | 0 => 'Off',
|
---|
760 | 1 => 'Low',
|
---|
761 | 2 => 'Standard',
|
---|
762 | 3 => 'High',
|
---|
763 | },
|
---|
764 | },
|
---|
765 | # 0x5e,0x5f,0x60 - undef[4]
|
---|
766 | 0x61 => { #PH
|
---|
767 | Name => 'FaceRecInfo',
|
---|
768 | SubDirectory => {
|
---|
769 | TagTable => 'Image::ExifTool::Panasonic::FaceRecInfo',
|
---|
770 | },
|
---|
771 | },
|
---|
772 | 0x62 => { #PH (FS7)
|
---|
773 | Name => 'FlashWarning',
|
---|
774 | Writable => 'int16u',
|
---|
775 | PrintConv => { 0 => 'No', 1 => 'Yes (flash required but disabled)' },
|
---|
776 | },
|
---|
777 | 0x63 => { #PH
|
---|
778 | # not sure exactly what this means, but in my samples this is
|
---|
779 | # FacesRecognized bytes of 0x01, padded with 0x00 to a length of 4 - PH
|
---|
780 | Name => 'RecognizedFaceFlags',
|
---|
781 | Format => 'int8u',
|
---|
782 | Count => 4,
|
---|
783 | Writable => 'undef',
|
---|
784 | Unknown => 1,
|
---|
785 | },
|
---|
786 | 0x65 => { #15
|
---|
787 | Name => 'Title',
|
---|
788 | Format => 'string',
|
---|
789 | Writable => 'undef', # (Count 64)
|
---|
790 | },
|
---|
791 | 0x66 => { #15
|
---|
792 | Name => 'BabyName',
|
---|
793 | Notes => 'or pet name',
|
---|
794 | Format => 'string',
|
---|
795 | Writable => 'undef', # (Count 64)
|
---|
796 | },
|
---|
797 | 0x67 => { #15
|
---|
798 | Name => 'Location',
|
---|
799 | Groups => { 2 => 'Location' },
|
---|
800 | Format => 'string',
|
---|
801 | Writable => 'undef', # (Count 64)
|
---|
802 | },
|
---|
803 | # 0x68 - int8u: 1
|
---|
804 | 0x69 => { #PH (ZS7)
|
---|
805 | Name => 'Country', # (Country/Region)
|
---|
806 | Groups => { 2 => 'Location' },
|
---|
807 | Format => 'string',
|
---|
808 | Writable => 'undef', # (Count 72)
|
---|
809 | },
|
---|
810 | # 0x6a - int8u: 1
|
---|
811 | 0x6b => { #PH (ZS7)
|
---|
812 | Name => 'State', # (State/Province/Count -- what is Count?)
|
---|
813 | Groups => { 2 => 'Location' },
|
---|
814 | Format => 'string',
|
---|
815 | Writable => 'undef', # (Count 72)
|
---|
816 | },
|
---|
817 | # 0x6c - int8u: 1
|
---|
818 | 0x6d => { #PH (ZS7)
|
---|
819 | Name => 'City', # (City/Town)
|
---|
820 | Groups => { 2 => 'Location' },
|
---|
821 | Format => 'string',
|
---|
822 | Writable => 'undef', # (Count 72)
|
---|
823 | },
|
---|
824 | # 0x6e - int8u: 1
|
---|
825 | 0x6f => { #PH (ZS7)
|
---|
826 | Name => 'Landmark', # (Landmark)
|
---|
827 | Groups => { 2 => 'Location' },
|
---|
828 | Format => 'string',
|
---|
829 | Writable => 'undef', # (Count 128)
|
---|
830 | },
|
---|
831 | 0x70 => { #PH (ZS7)
|
---|
832 | Name => 'IntelligentResolution',
|
---|
833 | Writable => 'int8u',
|
---|
834 | PrintConv => {
|
---|
835 | 0 => 'Off',
|
---|
836 | # Note: I think these values make sense for the GH2, but meanings
|
---|
837 | # may be different for other models
|
---|
838 | 1 => 'Low',
|
---|
839 | 2 => 'Standard',
|
---|
840 | 3 => 'High',
|
---|
841 | 4 => 'Extended',
|
---|
842 | },
|
---|
843 | },
|
---|
844 | # 0x71 - undef[128] (maybe text stamp text?)
|
---|
845 | # 0x72,0x73,0x74,0x75,0x76,0x77,0x78: 0
|
---|
846 | 0x79 => { #PH (GH2)
|
---|
847 | Name => 'IntelligentD-Range',
|
---|
848 | Writable => 'int16u',
|
---|
849 | PrintConv => {
|
---|
850 | 0 => 'Off',
|
---|
851 | 1 => 'Low',
|
---|
852 | 2 => 'Standard',
|
---|
853 | 3 => 'High',
|
---|
854 | },
|
---|
855 | },
|
---|
856 | # 0x7a,0x7b: 0
|
---|
857 | 0x0e00 => {
|
---|
858 | Name => 'PrintIM',
|
---|
859 | Description => 'Print Image Matching',
|
---|
860 | Writable => 0,
|
---|
861 | SubDirectory => {
|
---|
862 | TagTable => 'Image::ExifTool::PrintIM::Main',
|
---|
863 | },
|
---|
864 | },
|
---|
865 | 0x8000 => { #PH
|
---|
866 | Name => 'MakerNoteVersion',
|
---|
867 | Format => 'undef',
|
---|
868 | },
|
---|
869 | 0x8001 => { #7/PH/JD
|
---|
870 | Name => 'SceneMode',
|
---|
871 | Writable => 'int16u',
|
---|
872 | PrintConvColumns => 2,
|
---|
873 | PrintConv => {
|
---|
874 | 0 => 'Off',
|
---|
875 | %shootingMode,
|
---|
876 | },
|
---|
877 | },
|
---|
878 | # 0x8002 - values: 1,2 related to focus? (PH/JD)
|
---|
879 | # 1 for HDR modes, 2 for Portrait (ref 12)
|
---|
880 | # 0x8003 - values: 1,2 related to focus? (PH/JD)
|
---|
881 | 0x8004 => { #PH/JD
|
---|
882 | Name => 'WBRedLevel',
|
---|
883 | Writable => 'int16u',
|
---|
884 | },
|
---|
885 | 0x8005 => { #PH/JD
|
---|
886 | Name => 'WBGreenLevel',
|
---|
887 | Writable => 'int16u',
|
---|
888 | },
|
---|
889 | 0x8006 => { #PH/JD
|
---|
890 | Name => 'WBBlueLevel',
|
---|
891 | Writable => 'int16u',
|
---|
892 | },
|
---|
893 | 0x8007 => { #PH
|
---|
894 | Name => 'FlashFired',
|
---|
895 | Writable => 'int16u',
|
---|
896 | PrintConv => { 1 => 'No', 2 => 'Yes' },
|
---|
897 | },
|
---|
898 | 0x8008 => { #PH (TZ5/FS7)
|
---|
899 | # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
|
---|
900 | Name => 'TextStamp',
|
---|
901 | Writable => 'int16u',
|
---|
902 | PrintConv => { 1 => 'Off', 2 => 'On' },
|
---|
903 | },
|
---|
904 | 0x8009 => { #PH (TZ5/FS7)
|
---|
905 | # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
|
---|
906 | Name => 'TextStamp',
|
---|
907 | Writable => 'int16u',
|
---|
908 | PrintConv => { 1 => 'Off', 2 => 'On' },
|
---|
909 | },
|
---|
910 | 0x8010 => { #PH
|
---|
911 | Name => 'BabyAge',
|
---|
912 | Writable => 'string',
|
---|
913 | Notes => 'or pet age',
|
---|
914 | PrintConv => '$val eq "9999:99:99 00:00:00" ? "(not set)" : $val',
|
---|
915 | PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
|
---|
916 | },
|
---|
917 | 0x8012 => { #PH (FS7)
|
---|
918 | Name => 'Transform',
|
---|
919 | Writable => 'undef',
|
---|
920 | Notes => 'decoded as two 16-bit signed integers',
|
---|
921 | Format => 'int16s',
|
---|
922 | Count => 2,
|
---|
923 | PrintConv => {
|
---|
924 | '-3 2' => 'Slim High',
|
---|
925 | '-1 1' => 'Slim Low',
|
---|
926 | '0 0' => 'Off',
|
---|
927 | '1 1' => 'Stretch Low',
|
---|
928 | '3 2' => 'Stretch High',
|
---|
929 | },
|
---|
930 | },
|
---|
931 | );
|
---|
932 |
|
---|
933 | # Leica type2 maker notes (ref 10)
|
---|
934 | %Image::ExifTool::Panasonic::Leica2 = (
|
---|
935 | WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
|
---|
936 | CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
|
---|
937 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
938 | WRITABLE => 1,
|
---|
939 | NOTES => 'These tags are used by the Leica M8.',
|
---|
940 | 0x300 => {
|
---|
941 | Name => 'Quality',
|
---|
942 | Writable => 'int16u',
|
---|
943 | PrintConv => {
|
---|
944 | 1 => 'Fine',
|
---|
945 | 2 => 'Basic',
|
---|
946 | },
|
---|
947 | },
|
---|
948 | 0x302 => {
|
---|
949 | Name => 'UserProfile',
|
---|
950 | Writable => 'int32u',
|
---|
951 | PrintConv => {
|
---|
952 | 1 => 'User Profile 1',
|
---|
953 | 2 => 'User Profile 2',
|
---|
954 | 3 => 'User Profile 3',
|
---|
955 | 4 => 'User Profile 0 (Dynamic)',
|
---|
956 | },
|
---|
957 | },
|
---|
958 | 0x303 => {
|
---|
959 | Name => 'SerialNumber',
|
---|
960 | Writable => 'int32u',
|
---|
961 | PrintConv => 'sprintf("%.7d", $val)',
|
---|
962 | PrintConvInv => '$val',
|
---|
963 | },
|
---|
964 | 0x304 => {
|
---|
965 | Name => 'WhiteBalance',
|
---|
966 | Writable => 'int16u',
|
---|
967 | Notes => 'values above 0x8000 are converted to Kelvin color temperatures',
|
---|
968 | PrintConv => {
|
---|
969 | 0 => 'Auto or Manual',
|
---|
970 | 1 => 'Daylight',
|
---|
971 | 2 => 'Fluorescent',
|
---|
972 | 3 => 'Tungsten',
|
---|
973 | 4 => 'Flash',
|
---|
974 | 10 => 'Cloudy',
|
---|
975 | 11 => 'Shade',
|
---|
976 | OTHER => \&WhiteBalanceConv,
|
---|
977 | },
|
---|
978 | },
|
---|
979 | 0x310 => {
|
---|
980 | Name => 'LensInfo',
|
---|
981 | SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::LensInfo' },
|
---|
982 | },
|
---|
983 | 0x311 => {
|
---|
984 | Name => 'ExternalSensorBrightnessValue',
|
---|
985 | Format => 'rational64s', # (incorrectly unsigned in JPEG images)
|
---|
986 | Writable => 'rational64s',
|
---|
987 | Notes => '"blue dot" measurement',
|
---|
988 | PrintConv => 'sprintf("%.2f", $val)',
|
---|
989 | PrintConvInv => '$val',
|
---|
990 | },
|
---|
991 | 0x312 => {
|
---|
992 | Name => 'MeasuredLV',
|
---|
993 | Format => 'rational64s', # (incorrectly unsigned in JPEG images)
|
---|
994 | Writable => 'rational64s',
|
---|
995 | Notes => 'imaging sensor or TTL exposure meter measurement',
|
---|
996 | PrintConv => 'sprintf("%.2f", $val)',
|
---|
997 | PrintConvInv => '$val',
|
---|
998 | },
|
---|
999 | 0x313 => {
|
---|
1000 | Name => 'ApproximateFNumber',
|
---|
1001 | Writable => 'rational64u',
|
---|
1002 | PrintConv => 'sprintf("%.1f", $val)',
|
---|
1003 | PrintConvInv => '$val',
|
---|
1004 | },
|
---|
1005 | 0x320 => {
|
---|
1006 | Name => 'CameraTemperature',
|
---|
1007 | Writable => 'int32s',
|
---|
1008 | PrintConv => '"$val C"',
|
---|
1009 | PrintConvInv => '$val=~s/ ?C//; $val',
|
---|
1010 | },
|
---|
1011 | 0x321 => { Name => 'ColorTemperature', Writable => 'int32u' },
|
---|
1012 | 0x322 => { Name => 'WBRedLevel', Writable => 'rational64u' },
|
---|
1013 | 0x323 => { Name => 'WBGreenLevel', Writable => 'rational64u' },
|
---|
1014 | 0x324 => { Name => 'WBBlueLevel', Writable => 'rational64u' },
|
---|
1015 | 0x325 => {
|
---|
1016 | Name => 'UV-IRFilterCorrection',
|
---|
1017 | Description => 'UV/IR Filter Correction',
|
---|
1018 | Writable => 'int32u',
|
---|
1019 | PrintConv => {
|
---|
1020 | 0 => 'Not Active',
|
---|
1021 | 1 => 'Active',
|
---|
1022 | },
|
---|
1023 | },
|
---|
1024 | 0x330 => { Name => 'CCDVersion', Writable => 'int32u' },
|
---|
1025 | 0x331 => { Name => 'CCDBoardVersion', Writable => 'int32u' },
|
---|
1026 | 0x332 => { Name => 'ControllerBoardVersion', Writable => 'int32u' },
|
---|
1027 | 0x333 => { Name => 'M16CVersion', Writable => 'int32u' },
|
---|
1028 | 0x340 => { Name => 'ImageIDNumber', Writable => 'int32u' },
|
---|
1029 | );
|
---|
1030 |
|
---|
1031 | # Leica type3 maker notes (ref PH)
|
---|
1032 | %Image::ExifTool::Panasonic::Leica3 = (
|
---|
1033 | WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
|
---|
1034 | CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
|
---|
1035 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
1036 | WRITABLE => 1,
|
---|
1037 | NOTES => 'These tags are used by the Leica R8 and R9 digital backs.',
|
---|
1038 | 0x0d => {
|
---|
1039 | Name => 'WB_RGBLevels',
|
---|
1040 | Writable => 'int16u',
|
---|
1041 | Count => 3,
|
---|
1042 | },
|
---|
1043 | );
|
---|
1044 |
|
---|
1045 | # Leica type4 maker notes (ref PH) (M9)
|
---|
1046 | %Image::ExifTool::Panasonic::Leica4 = (
|
---|
1047 | WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
|
---|
1048 | CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
|
---|
1049 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
1050 | WRITABLE => 1,
|
---|
1051 | NOTES => 'This information is written by the M9.',
|
---|
1052 | 0x3000 => {
|
---|
1053 | Name => 'Subdir3000',
|
---|
1054 | SubDirectory => {
|
---|
1055 | TagTable => 'Image::ExifTool::Panasonic::Subdir',
|
---|
1056 | ByteOrder => 'Unknown',
|
---|
1057 | },
|
---|
1058 | },
|
---|
1059 | 0x3100 => {
|
---|
1060 | Name => 'Subdir3100',
|
---|
1061 | SubDirectory => {
|
---|
1062 | TagTable => 'Image::ExifTool::Panasonic::Subdir',
|
---|
1063 | ByteOrder => 'Unknown',
|
---|
1064 | },
|
---|
1065 | },
|
---|
1066 | 0x3400 => {
|
---|
1067 | Name => 'Subdir3400',
|
---|
1068 | SubDirectory => {
|
---|
1069 | TagTable => 'Image::ExifTool::Panasonic::Subdir',
|
---|
1070 | ByteOrder => 'Unknown',
|
---|
1071 | },
|
---|
1072 | },
|
---|
1073 | 0x3900 => {
|
---|
1074 | Name => 'Subdir3900',
|
---|
1075 | SubDirectory => {
|
---|
1076 | TagTable => 'Image::ExifTool::Panasonic::Subdir',
|
---|
1077 | ByteOrder => 'Unknown',
|
---|
1078 | },
|
---|
1079 | },
|
---|
1080 | );
|
---|
1081 |
|
---|
1082 | # Leica M9 SubDirectory tags (ref PH)
|
---|
1083 | %Image::ExifTool::Panasonic::Subdir = (
|
---|
1084 | WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
|
---|
1085 | CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
|
---|
1086 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
1087 | TAG_PREFIX => 'Leica_Subdir',
|
---|
1088 | WRITABLE => 1,
|
---|
1089 | # 0x3001 - normally 0 but value of 2 when manual coding is used
|
---|
1090 | # with a coded lens (but only tested with Elmar-M 50mm f/2.8) - PH
|
---|
1091 | 0x300a => {
|
---|
1092 | Name => 'Contrast',
|
---|
1093 | Writable => 'int32u',
|
---|
1094 | PrintConv => {
|
---|
1095 | 0 => 'Low',
|
---|
1096 | 1 => 'Medium Low',
|
---|
1097 | 2 => 'Normal',
|
---|
1098 | 3 => 'Medium High',
|
---|
1099 | 4 => 'High',
|
---|
1100 | },
|
---|
1101 | },
|
---|
1102 | 0x300b => {
|
---|
1103 | Name => 'Sharpening',
|
---|
1104 | Writable => 'int32u',
|
---|
1105 | PrintConv => {
|
---|
1106 | 0 => 'Off',
|
---|
1107 | 1 => 'Low',
|
---|
1108 | 2 => 'Normal',
|
---|
1109 | 3 => 'Medium High',
|
---|
1110 | 4 => 'High',
|
---|
1111 | },
|
---|
1112 | },
|
---|
1113 | 0x300d => {
|
---|
1114 | Name => 'Saturation',
|
---|
1115 | Writable => 'int32u',
|
---|
1116 | PrintConv => {
|
---|
1117 | 0 => 'Low',
|
---|
1118 | 1 => 'Medium Low',
|
---|
1119 | 2 => 'Normal',
|
---|
1120 | 3 => 'Medium High',
|
---|
1121 | 4 => 'High',
|
---|
1122 | 5 => 'Black & White',
|
---|
1123 | 6 => 'Vintage B&W',
|
---|
1124 | },
|
---|
1125 | },
|
---|
1126 | # 0x3032 - some sort of RGB coefficients? (zeros unless Kelvin WB, but same for all Color Temps)
|
---|
1127 | 0x3033 => {
|
---|
1128 | Name => 'WhiteBalance',
|
---|
1129 | Writable => 'int32u',
|
---|
1130 | PrintConv => { #13
|
---|
1131 | 0 => 'Auto',
|
---|
1132 | 1 => 'Tungsten',
|
---|
1133 | 2 => 'Fluorescent',
|
---|
1134 | 3 => 'Daylight Fluorescent',
|
---|
1135 | 4 => 'Daylight',
|
---|
1136 | 5 => 'Flash',
|
---|
1137 | 6 => 'Cloudy',
|
---|
1138 | 7 => 'Shade',
|
---|
1139 | 8 => 'Manual',
|
---|
1140 | 9 => 'Kelvin',
|
---|
1141 | },
|
---|
1142 | },
|
---|
1143 | 0x3034 => {
|
---|
1144 | Name => 'JPEGQuality',
|
---|
1145 | Writable => 'int32u',
|
---|
1146 | PrintConv => {
|
---|
1147 | 94 => 'Basic',
|
---|
1148 | 97 => 'Fine',
|
---|
1149 | },
|
---|
1150 | },
|
---|
1151 | # 0x3035 (int32u): -1 unless Manual WB (2 in my Manual sample)
|
---|
1152 | 0x3036 => {
|
---|
1153 | Name => 'WB_RGBLevels',
|
---|
1154 | Writable => 'rational64u',
|
---|
1155 | Count => 3,
|
---|
1156 | },
|
---|
1157 | 0x3038 => {
|
---|
1158 | Name => 'UserProfile', # (CameraProfile according to ref 14)
|
---|
1159 | Writable => 'string',
|
---|
1160 | },
|
---|
1161 | 0x303a => {
|
---|
1162 | Name => 'JPEGSize',
|
---|
1163 | Writable => 'int32u',
|
---|
1164 | PrintConv => {
|
---|
1165 | 0 => '5216x3472',
|
---|
1166 | 1 => '3840x2592',
|
---|
1167 | 2 => '2592x1728',
|
---|
1168 | 3 => '1728x1152',
|
---|
1169 | 4 => '1280x864',
|
---|
1170 | },
|
---|
1171 | },
|
---|
1172 | 0x3103 => { #13 (valid for FW 1.116 and later)
|
---|
1173 | Name => 'SerialNumber',
|
---|
1174 | Writable => 'string',
|
---|
1175 | },
|
---|
1176 | # 0x3104 body-dependent string ("00012905000000") (not serial number)
|
---|
1177 | # 0x3105 body-dependent string ("00012905000000")
|
---|
1178 | # 0x3107 - body-dependent string ("4H205800116800") (not serial number)
|
---|
1179 | 0x3109 => {
|
---|
1180 | Name => 'FirmwareVersion',
|
---|
1181 | Writable => 'string',
|
---|
1182 | },
|
---|
1183 | 0x312a => { #14 (NC)
|
---|
1184 | Name => 'BaseISO',
|
---|
1185 | Writable => 'int32u',
|
---|
1186 | },
|
---|
1187 | 0x312b => {
|
---|
1188 | Name => 'SensorWidth',
|
---|
1189 | Writable => 'int32u',
|
---|
1190 | },
|
---|
1191 | 0x312c => {
|
---|
1192 | Name => 'SensorHeight',
|
---|
1193 | Writable => 'int32u',
|
---|
1194 | },
|
---|
1195 | 0x312d => { #14 (NC)
|
---|
1196 | Name => 'SensorBitDepth',
|
---|
1197 | Writable => 'int32u',
|
---|
1198 | },
|
---|
1199 | 0x3402 => { #PH/13
|
---|
1200 | Name => 'CameraTemperature',
|
---|
1201 | Writable => 'int32s',
|
---|
1202 | PrintConv => '"$val C"',
|
---|
1203 | PrintConvInv => '$val=~s/ ?C//; $val',
|
---|
1204 | },
|
---|
1205 | 0x3405 => {
|
---|
1206 | Name => 'LensType',
|
---|
1207 | Writable => 'int32u',
|
---|
1208 | SeparateTable => 1,
|
---|
1209 | ValueConv => '($val >> 2) . " " . ($val & 0x3)',
|
---|
1210 | ValueConvInv => \&LensTypeConvInv,
|
---|
1211 | PrintConv => \%leicaLensType,
|
---|
1212 | },
|
---|
1213 | 0x3406 => { #PH/13
|
---|
1214 | Name => 'ApproximateFNumber',
|
---|
1215 | Writable => 'rational64u',
|
---|
1216 | PrintConv => 'sprintf("%.1f", $val)',
|
---|
1217 | PrintConvInv => '$val',
|
---|
1218 | },
|
---|
1219 | 0x3407 => { #14
|
---|
1220 | Name => 'MeasuredLV',
|
---|
1221 | Writable => 'int32s',
|
---|
1222 | Notes => 'imaging sensor or TTL exposure meter measurement',
|
---|
1223 | ValueConv => '$val / 1e5', #PH (NC)
|
---|
1224 | ValueConvInv => '$val * 1e5', #PH (NC)
|
---|
1225 | PrintConv => 'sprintf("%.2f", $val)',
|
---|
1226 | PrintConvInv => '$val',
|
---|
1227 | },
|
---|
1228 | 0x3408 => { #14
|
---|
1229 | Name => 'ExternalSensorBrightnessValue',
|
---|
1230 | Writable => 'int32s',
|
---|
1231 | Notes => '"blue dot" measurement',
|
---|
1232 | ValueConv => '$val / 1e5', #PH (NC)
|
---|
1233 | ValueConvInv => '$val * 1e5', #PH (NC)
|
---|
1234 | PrintConv => 'sprintf("%.2f", $val)',
|
---|
1235 | PrintConvInv => '$val',
|
---|
1236 | },
|
---|
1237 | 0x3901 => {
|
---|
1238 | Name => 'Data1',
|
---|
1239 | SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::Data1' },
|
---|
1240 | },
|
---|
1241 | 0x3902 => {
|
---|
1242 | Name => 'Data2',
|
---|
1243 | SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::Data2' },
|
---|
1244 | },
|
---|
1245 | # 0x3903 - larger binary data block
|
---|
1246 | );
|
---|
1247 |
|
---|
1248 | %Image::ExifTool::Panasonic::Data1 = (
|
---|
1249 | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
---|
1250 | WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
|
---|
1251 | CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
|
---|
1252 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
1253 | WRITABLE => 1,
|
---|
1254 | TAG_PREFIX => 'Leica_Data1',
|
---|
1255 | FIRST_ENTRY => 0,
|
---|
1256 | 0x0016 => {
|
---|
1257 | Name => 'LensType',
|
---|
1258 | Writable => 'int32u',
|
---|
1259 | Priority => 0,
|
---|
1260 | SeparateTable => 1,
|
---|
1261 | ValueConv => '($val >> 2) . " " . ($val & 0x3)',
|
---|
1262 | ValueConvInv => \&LensTypeConvInv,
|
---|
1263 | PrintConv => \%leicaLensType,
|
---|
1264 | },
|
---|
1265 | );
|
---|
1266 |
|
---|
1267 | %Image::ExifTool::Panasonic::Data2 = (
|
---|
1268 | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
---|
1269 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
1270 | TAG_PREFIX => 'Leica_Data2',
|
---|
1271 | FIRST_ENTRY => 0,
|
---|
1272 | );
|
---|
1273 |
|
---|
1274 | # Leica type5 maker notes (ref PH) (X1)
|
---|
1275 | %Image::ExifTool::Panasonic::Leica5 = (
|
---|
1276 | WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
|
---|
1277 | CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
|
---|
1278 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
1279 | WRITABLE => 1,
|
---|
1280 | NOTES => 'This information is written by the X1.',
|
---|
1281 | # 0x0406 - saturation or sharpness
|
---|
1282 | 0x0407 => { Name => 'OriginalFileName', Writable => 'string' },
|
---|
1283 | 0x0408 => { Name => 'OriginalDirectory',Writable => 'string' },
|
---|
1284 | # 0x040b - related to white balance
|
---|
1285 | 0x040d => {
|
---|
1286 | Name => 'ExposureMode',
|
---|
1287 | Format => 'int8u',
|
---|
1288 | Count => 4,
|
---|
1289 | PrintConv => {
|
---|
1290 | '0 0 0 0' => 'Program AE',
|
---|
1291 | '1 0 0 0' => 'Aperture-priority AE',
|
---|
1292 | '2 0 0 0' => 'Shutter speed priority AE', #(guess)
|
---|
1293 | '3 0 0 0' => 'Manual',
|
---|
1294 | },
|
---|
1295 | },
|
---|
1296 | # 0x0411 - saturation or sharpness
|
---|
1297 | 0x0412 => { Name => 'FilmMode', Writable => 'string' },
|
---|
1298 | 0x0413 => { Name => 'WB_RGBLevels', Writable => 'rational64u', Count => 3 },
|
---|
1299 | );
|
---|
1300 |
|
---|
1301 | # Leica type6 maker notes (ref PH) (S2)
|
---|
1302 | %Image::ExifTool::Panasonic::Leica6 = (
|
---|
1303 | WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
|
---|
1304 | CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
|
---|
1305 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
1306 | NOTES => 'This information is written by the S2 (as a trailer in JPEG images).',
|
---|
1307 | 0x300 => {
|
---|
1308 | Name => 'PreviewImage',
|
---|
1309 | Writable => 'undef',
|
---|
1310 | Notes => 'S2',
|
---|
1311 | DataTag => 'PreviewImage',
|
---|
1312 | RawConv => q{
|
---|
1313 | return \$val if $val =~ /^Binary/;
|
---|
1314 | return \$val if $val =~ /^\xff\xd8\xff/;
|
---|
1315 | $$self{PreviewError} = 1 unless $val eq 'none';
|
---|
1316 | return undef;
|
---|
1317 | },
|
---|
1318 | ValueConvInv => '$val || "none"',
|
---|
1319 | WriteCheck => 'return $val=~/^(none|\xff\xd8\xff)/s ? undef : "Not a valid image"',
|
---|
1320 | ChangeBase => '$dirStart + $dataPos - 8',
|
---|
1321 | },
|
---|
1322 | 0x301 => {
|
---|
1323 | Name => 'UnknownBlock',
|
---|
1324 | Notes => 'unknown 320kB block, not copied to JPEG images',
|
---|
1325 | Flags => [ 'Unknown', 'Binary', 'Drop' ],
|
---|
1326 | },
|
---|
1327 | # 0x302 - same value as 4 unknown bytes at the end of JPEG or after the DNG TIFF header
|
---|
1328 | 0x303 => {
|
---|
1329 | Name => 'LensType',
|
---|
1330 | Writable => 'string',
|
---|
1331 | },
|
---|
1332 | # 0x340 - same as 0x302
|
---|
1333 | );
|
---|
1334 |
|
---|
1335 | # Type 2 tags (ref PH)
|
---|
1336 | %Image::ExifTool::Panasonic::Type2 = (
|
---|
1337 | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
---|
1338 | GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
---|
1339 | FIRST_ENTRY => 0,
|
---|
1340 | FORMAT => 'int16u',
|
---|
1341 | NOTES => q{
|
---|
1342 | This type of maker notes is used by models such as the NV-DS65, PV-D2002,
|
---|
1343 | PV-DC3000, PV-DV203, PV-DV401, PV-DV702, PV-L2001, PV-SD4090, PV-SD5000 and
|
---|
1344 | iPalm.
|
---|
1345 | },
|
---|
1346 | 0 => {
|
---|
1347 | Name => 'MakerNoteType',
|
---|
1348 | Format => 'string[4]',
|
---|
1349 | },
|
---|
1350 | # seems to vary inversely with amount of light, so I'll call it 'Gain' - PH
|
---|
1351 | # (minimum is 16, maximum is 136. Value is 0 for pictures captured from video)
|
---|
1352 | 3 => 'Gain',
|
---|
1353 | );
|
---|
1354 |
|
---|
1355 | # lens information (ref 10)
|
---|
1356 | %Image::ExifTool::Panasonic::LensInfo = (
|
---|
1357 | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
---|
1358 | WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
|
---|
1359 | CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
|
---|
1360 | GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
|
---|
1361 | WRITABLE => 1,
|
---|
1362 | FORMAT => 'int32u',
|
---|
1363 | FIRST_ENTRY => 0,
|
---|
1364 | 0 => {
|
---|
1365 | Name => 'LensType',
|
---|
1366 | Mask => 0xfffffffc,
|
---|
1367 | PrintHex => 0,
|
---|
1368 | SeparateTable => 1,
|
---|
1369 | ValueConv => '$val >> 2',
|
---|
1370 | ValueConvInv => '$val << 2',
|
---|
1371 | PrintConv => \%leicaLensType,
|
---|
1372 | },
|
---|
1373 | 0.1 => { # lower 2 bits give frame selector position
|
---|
1374 | Name => 'FrameSelector',
|
---|
1375 | Mask => 0x03,
|
---|
1376 | PrintConv => {
|
---|
1377 | 1 => '28/90mm frame lines engaged',
|
---|
1378 | 2 => '24/35mm frame lines engaged',
|
---|
1379 | 3 => '50/75mm frame lines engaged',
|
---|
1380 | },
|
---|
1381 | },
|
---|
1382 | );
|
---|
1383 |
|
---|
1384 | # Face detection position information (ref PH)
|
---|
1385 | %Image::ExifTool::Panasonic::FaceDetInfo = (
|
---|
1386 | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
---|
1387 | WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
|
---|
1388 | CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
|
---|
1389 | GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
---|
1390 | WRITABLE => 1,
|
---|
1391 | FORMAT => 'int16u',
|
---|
1392 | FIRST_ENTRY => 0,
|
---|
1393 | DATAMEMBER => [ 0 ],
|
---|
1394 | NOTES => 'Face detection position information.',
|
---|
1395 | 0 => {
|
---|
1396 | Name => 'NumFacePositions',
|
---|
1397 | Format => 'int16u',
|
---|
1398 | DataMember => 'NumFacePositions',
|
---|
1399 | RawConv => '$$self{NumFacePositions} = $val',
|
---|
1400 | Notes => q{
|
---|
1401 | number of detected face positions stored in this record. May be less than
|
---|
1402 | FacesDetected
|
---|
1403 | },
|
---|
1404 | },
|
---|
1405 | 1 => {
|
---|
1406 | Name => 'Face1Position',
|
---|
1407 | Format => 'int16u[4]',
|
---|
1408 | RawConv => '$$self{NumFacePositions} < 1 ? undef : $val',
|
---|
1409 | Notes => q{
|
---|
1410 | 4 numbers: X/Y coordinates of the face center and width/height of face.
|
---|
1411 | Coordinates are relative to an image twice the size of the thumbnail, or 320
|
---|
1412 | pixels wide
|
---|
1413 | },
|
---|
1414 | },
|
---|
1415 | 5 => {
|
---|
1416 | Name => 'Face2Position',
|
---|
1417 | Format => 'int16u[4]',
|
---|
1418 | RawConv => '$$self{NumFacePositions} < 2 ? undef : $val',
|
---|
1419 | },
|
---|
1420 | 9 => {
|
---|
1421 | Name => 'Face3Position',
|
---|
1422 | Format => 'int16u[4]',
|
---|
1423 | RawConv => '$$self{NumFacePositions} < 3 ? undef : $val',
|
---|
1424 | },
|
---|
1425 | 13 => {
|
---|
1426 | Name => 'Face4Position',
|
---|
1427 | Format => 'int16u[4]',
|
---|
1428 | RawConv => '$$self{NumFacePositions} < 4 ? undef : $val',
|
---|
1429 | },
|
---|
1430 | 17 => {
|
---|
1431 | Name => 'Face5Position',
|
---|
1432 | Format => 'int16u[4]',
|
---|
1433 | RawConv => '$$self{NumFacePositions} < 5 ? undef : $val',
|
---|
1434 | },
|
---|
1435 | );
|
---|
1436 |
|
---|
1437 | # Face recognition information from DMC-TZ7 (ref PH)
|
---|
1438 | %Image::ExifTool::Panasonic::FaceRecInfo = (
|
---|
1439 | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
---|
1440 | WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
|
---|
1441 | CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
|
---|
1442 | GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
---|
1443 | WRITABLE => 1,
|
---|
1444 | FIRST_ENTRY => 0,
|
---|
1445 | DATAMEMBER => [ 0 ],
|
---|
1446 | NOTES => q{
|
---|
1447 | Tags written by cameras with facial recognition. These cameras not only
|
---|
1448 | detect faces in an image, but also recognize specific people based a
|
---|
1449 | user-supplied set of known faces.
|
---|
1450 | },
|
---|
1451 | 0 => {
|
---|
1452 | Name => 'FacesRecognized',
|
---|
1453 | Format => 'int16u',
|
---|
1454 | DataMember => 'FacesRecognized',
|
---|
1455 | RawConv => '$$self{FacesRecognized} = $val',
|
---|
1456 | },
|
---|
1457 | 4 => {
|
---|
1458 | Name => 'RecognizedFace1Name',
|
---|
1459 | Format => 'string[20]',
|
---|
1460 | RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
|
---|
1461 | },
|
---|
1462 | 24 => {
|
---|
1463 | Name => 'RecognizedFace1Position',
|
---|
1464 | Format => 'int16u[4]',
|
---|
1465 | RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
|
---|
1466 | Notes => 'coordinates in same format as face detection tags above',
|
---|
1467 | },
|
---|
1468 | 32 => {
|
---|
1469 | Name => 'RecognizedFace1Age',
|
---|
1470 | Format => 'string[20]',
|
---|
1471 | RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
|
---|
1472 | },
|
---|
1473 | 52 => {
|
---|
1474 | Name => 'RecognizedFace2Name',
|
---|
1475 | Format => 'string[20]',
|
---|
1476 | RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
|
---|
1477 | },
|
---|
1478 | 72 => {
|
---|
1479 | Name => 'RecognizedFace2Position',
|
---|
1480 | Format => 'int16u[4]',
|
---|
1481 | RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
|
---|
1482 | },
|
---|
1483 | 80 => {
|
---|
1484 | Name => 'RecognizedFace2Age',
|
---|
1485 | Format => 'string[20]',
|
---|
1486 | RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
|
---|
1487 | },
|
---|
1488 | 100 => {
|
---|
1489 | Name => 'RecognizedFace3Name',
|
---|
1490 | Format => 'string[20]',
|
---|
1491 | RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
|
---|
1492 | },
|
---|
1493 | 120 => {
|
---|
1494 | Name => 'RecognizedFace3Position',
|
---|
1495 | Format => 'int16u[4]',
|
---|
1496 | RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
|
---|
1497 | },
|
---|
1498 | 128 => {
|
---|
1499 | Name => 'RecognizedFace3Age',
|
---|
1500 | Format => 'string[20]',
|
---|
1501 | RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
|
---|
1502 | },
|
---|
1503 | );
|
---|
1504 |
|
---|
1505 | #------------------------------------------------------------------------------
|
---|
1506 | # Inverse conversion for Leica M9 lens codes
|
---|
1507 | # Inputs: 0) value
|
---|
1508 | # Returns: Converted value, or undef on error
|
---|
1509 | sub LensTypeConvInv($)
|
---|
1510 | {
|
---|
1511 | my $val = shift;
|
---|
1512 | if ($val =~ /^(\d+) (\d+)$/) {
|
---|
1513 | return ($1 << 2) + ($2 & 0x03);
|
---|
1514 | } elsif ($val =~ /^\d+$/) {
|
---|
1515 | my $bits = $frameSelectorBits{$val};
|
---|
1516 | return undef unless defined $bits;
|
---|
1517 | return ($val << 2) | $bits;
|
---|
1518 | } else {
|
---|
1519 | return undef;
|
---|
1520 | }
|
---|
1521 | }
|
---|
1522 |
|
---|
1523 | #------------------------------------------------------------------------------
|
---|
1524 | # Convert Leica Kelvin white balance
|
---|
1525 | # Inputs: 0) value, 1) flag to perform inverse conversion
|
---|
1526 | # Returns: Converted value, or undef on error
|
---|
1527 | sub WhiteBalanceConv($;$$)
|
---|
1528 | {
|
---|
1529 | my ($val, $inv) = @_;
|
---|
1530 | if ($inv) {
|
---|
1531 | return $1 + 0x8000 if $val =~ /(\d+)/;
|
---|
1532 | } else {
|
---|
1533 | return ($val - 0x8000) . ' Kelvin' if $val > 0x8000;
|
---|
1534 | }
|
---|
1535 | return undef;
|
---|
1536 | }
|
---|
1537 |
|
---|
1538 | #------------------------------------------------------------------------------
|
---|
1539 | # Process MakerNote trailer written by Leica S2
|
---|
1540 | # Inputs: 0) ExifTool object ref, 1) new absolute position of Leica trailer when writing
|
---|
1541 | # Returns: On success: 1 when reading, directory data when writing; othewise undef
|
---|
1542 | # Notes:
|
---|
1543 | # - may be called twice for a file if the first call doesn't succeed
|
---|
1544 | # - must leave RAF position unchanged
|
---|
1545 | # - uses information from LeicaTrailer member:
|
---|
1546 | # TagInfo = tag info ref for MakerNote SubDirectory
|
---|
1547 | # Offset/Size = value offset/size from MakerNote IFD
|
---|
1548 | # TrailStart/TrailLen = actual JPEG trailer position/size (2nd call only)
|
---|
1549 | # - deletes LeicaTrailer member and sets LeicaTrailerPos when successful
|
---|
1550 | sub ProcessLeicaTrailer($;$)
|
---|
1551 | {
|
---|
1552 | my ($exifTool, $newPos) = @_;
|
---|
1553 | my $trail = $$exifTool{LeicaTrailer};
|
---|
1554 | my $raf = $$exifTool{RAF};
|
---|
1555 | my $trailPos = $$trail{TrailPos};
|
---|
1556 | my $pos = $trailPos || $$trail{Offset};
|
---|
1557 | my $len = $$trail{TrailLen} || $$trail{Size};
|
---|
1558 | my ($buff, $result, %tagPtr);
|
---|
1559 |
|
---|
1560 | delete $$exifTool{LeicaTrailer} if $trailPos; # done after this
|
---|
1561 | unless ($len > 0) {
|
---|
1562 | $exifTool->Warn('Missing Leica MakerNote trailer', 1) if $trailPos;
|
---|
1563 | undef $$exifTool{LeicaTrailer};
|
---|
1564 | return undef;
|
---|
1565 | }
|
---|
1566 | my $oldPos = $raf->Tell();
|
---|
1567 | my $ok = ($raf->Seek($pos, 0) and $raf->Read($buff, $len) == $len);
|
---|
1568 | $raf->Seek($oldPos, 0);
|
---|
1569 | unless ($ok) {
|
---|
1570 | $exifTool->Warn('Error reading Leica MakerNote trailer', 1) if $trailPos;
|
---|
1571 | return undef;
|
---|
1572 | }
|
---|
1573 | # look for Leica MakerNote header (should be at start of
|
---|
1574 | # trailer, but allow up to 256 bytes of garbage just in case)
|
---|
1575 | if ($buff !~ /^(.{0,256})LEICA\0..../sg) {
|
---|
1576 | my $what = $trailPos ? 'trailer' : 'offset';
|
---|
1577 | $exifTool->Warn("Invalid Leica MakerNote $what", 1);
|
---|
1578 | return undef;
|
---|
1579 | }
|
---|
1580 | my $junk = $1;
|
---|
1581 | my $start = pos($buff) - 10;
|
---|
1582 | if ($start and not $trailPos) {
|
---|
1583 | $exifTool->Warn('Invalid Leica MakerNote offset', 1);
|
---|
1584 | return undef;
|
---|
1585 | }
|
---|
1586 | #
|
---|
1587 | # all checks passed -- go ahead and process the trailer now
|
---|
1588 | #
|
---|
1589 | my $hdrLen = 8;
|
---|
1590 | my $dirStart = $start + $hdrLen;
|
---|
1591 | my $tagInfo = $$trail{TagInfo};
|
---|
1592 | if ($$exifTool{HTML_DUMP}) {
|
---|
1593 | my $name = $$tagInfo{Name};
|
---|
1594 | $exifTool->HDump($pos+$start, $len-$start, "$name value", 'Leica MakerNote trailer', 4);
|
---|
1595 | $exifTool->HDump($pos+$start, $hdrLen, "MakerNotes header", $name);
|
---|
1596 | } elsif ($exifTool->Options('Verbose')) {
|
---|
1597 | my $where = sprintf('at offset 0x%x', $pos);
|
---|
1598 | $exifTool->VPrint(0, "Leica MakerNote trailer ($len bytes $where):\n");
|
---|
1599 | }
|
---|
1600 | # delete LeicaTrailer member so we don't try to process it again
|
---|
1601 | delete $$exifTool{LeicaTrailer};
|
---|
1602 | $$exifTool{LeicaTrailerPos} = $pos + $start; # return actual start position of Leica trailer
|
---|
1603 |
|
---|
1604 | my $oldOrder = GetByteOrder();
|
---|
1605 | my $num = Get16u(\$buff, $dirStart); # get entry count
|
---|
1606 | ToggleByteOrder() if ($num>>8) > ($num&0xff); # set byte order
|
---|
1607 |
|
---|
1608 | # use specialized algorithm to automatically fix offsets
|
---|
1609 | my $valStart = $dirStart + 2 + 12 * $num + 4;
|
---|
1610 | my $fix = 0;
|
---|
1611 | if ($valStart < $len) {
|
---|
1612 | my $valBlock = Image::ExifTool::MakerNotes::GetValueBlocks(\$buff, $dirStart, \%tagPtr);
|
---|
1613 | # find the minimum offset (excluding the PreviewImage tag 0x300)
|
---|
1614 | my $minPtr;
|
---|
1615 | foreach (keys %tagPtr) {
|
---|
1616 | my $ptr = $tagPtr{$_};
|
---|
1617 | next if $_ == 0x300 or not $ptr;
|
---|
1618 | $minPtr = $ptr if not defined $minPtr or $minPtr > $ptr;
|
---|
1619 | }
|
---|
1620 | if ($minPtr) {
|
---|
1621 | my $diff = $minPtr - ($valStart + $pos);
|
---|
1622 | # scan value data for the first non-zero byte
|
---|
1623 | pos($buff) = $valStart;
|
---|
1624 | if ($buff =~ /[^\0]/g) {
|
---|
1625 | my $n = pos($buff) - 1 - $valStart; # number of zero bytes
|
---|
1626 | # S2 writes 282 bytes of zeros, exiftool writes none
|
---|
1627 | my $expect = $n >= 282 ? 282 : 0;
|
---|
1628 | my $fixBase = $exifTool->Options('FixBase');
|
---|
1629 | if ($diff != $expect or defined $fixBase) {
|
---|
1630 | $fix = $expect - $diff;
|
---|
1631 | if (defined $fixBase) {
|
---|
1632 | $fix = $fixBase if $fixBase ne '';
|
---|
1633 | $exifTool->Warn("Adjusted MakerNotes base by $fix",1);
|
---|
1634 | } else {
|
---|
1635 | $exifTool->Warn("Possibly incorrect maker notes offsets (fixed by $fix)",1);
|
---|
1636 | }
|
---|
1637 | }
|
---|
1638 | }
|
---|
1639 | }
|
---|
1640 | }
|
---|
1641 | # generate dirInfo for Leica MakerNote directory
|
---|
1642 | my %dirInfo = (
|
---|
1643 | Name => $$tagInfo{Name},
|
---|
1644 | Base => $fix,
|
---|
1645 | DataPt => \$buff,
|
---|
1646 | DataPos => $pos - $fix,
|
---|
1647 | DataLen => $len,
|
---|
1648 | DirStart => $dirStart,
|
---|
1649 | DirLen => $len - $dirStart,
|
---|
1650 | DirName => 'MakerNotes',
|
---|
1651 | Parent => 'ExifIFD',
|
---|
1652 | TagInfo => $tagInfo,
|
---|
1653 | );
|
---|
1654 | my $tagTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
|
---|
1655 | if ($newPos) { # are we writing?
|
---|
1656 | # set position of new MakerNote IFD (+ 8 for Leica MakerNote header)
|
---|
1657 | $dirInfo{NewDataPos} = $newPos + $start + 8;
|
---|
1658 | $result = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
|
---|
1659 | # write preview image last if necessary and fix up the preview offsets
|
---|
1660 | my $previewInfo = $$exifTool{PREVIEW_INFO};
|
---|
1661 | delete $$exifTool{PREVIEW_INFO};
|
---|
1662 | if ($result) {
|
---|
1663 | if ($previewInfo) {
|
---|
1664 | my $fixup = $previewInfo->{Fixup};
|
---|
1665 | # set preview offset (relative to start of makernotes, + 8 for makernote header)
|
---|
1666 | $fixup->SetMarkerPointers(\$result, 'PreviewImage', length($result) + 8);
|
---|
1667 | $result .= $$previewInfo{Data};
|
---|
1668 | }
|
---|
1669 | return $junk . substr($buff, $start, $hdrLen) . $result;
|
---|
1670 | }
|
---|
1671 | } else {
|
---|
1672 | # extract information
|
---|
1673 | $result = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
---|
1674 | # also extract as a block if necessary
|
---|
1675 | if ($exifTool->Options('MakerNotes') or
|
---|
1676 | $exifTool->{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})})
|
---|
1677 | {
|
---|
1678 | # makernote header must be included in RebuildMakerNotes call
|
---|
1679 | $dirInfo{DirStart} -= 8;
|
---|
1680 | $dirInfo{DirLen} += 8;
|
---|
1681 | $exifTool->{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
|
---|
1682 | # rebuild maker notes (creates $exifTool->{MAKER_NOTE_FIXUP})
|
---|
1683 | my $val = Image::ExifTool::Exif::RebuildMakerNotes($exifTool, $tagTablePtr, \%dirInfo);
|
---|
1684 | unless (defined $val) {
|
---|
1685 | $exifTool->Warn('Error rebuilding maker notes (may be corrupt)');
|
---|
1686 | $val = $buff,
|
---|
1687 | }
|
---|
1688 | my $key = $exifTool->FoundTag($tagInfo, $val);
|
---|
1689 | $exifTool->SetGroup($key, 'ExifIFD');
|
---|
1690 | }
|
---|
1691 | }
|
---|
1692 | SetByteOrder($oldOrder);
|
---|
1693 | return $result;
|
---|
1694 | }
|
---|
1695 |
|
---|
1696 | 1; # end
|
---|
1697 |
|
---|
1698 | __END__
|
---|
1699 |
|
---|
1700 | =head1 NAME
|
---|
1701 |
|
---|
1702 | Image::ExifTool::Panasonic - Panasonic/Leica maker notes tags
|
---|
1703 |
|
---|
1704 | =head1 SYNOPSIS
|
---|
1705 |
|
---|
1706 | This module is loaded automatically by Image::ExifTool when required.
|
---|
1707 |
|
---|
1708 | =head1 DESCRIPTION
|
---|
1709 |
|
---|
1710 | This module contains definitions required by Image::ExifTool to interpret
|
---|
1711 | Panasonic and Leica maker notes in EXIF information.
|
---|
1712 |
|
---|
1713 | =head1 AUTHOR
|
---|
1714 |
|
---|
1715 | Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
|
---|
1716 |
|
---|
1717 | This library is free software; you can redistribute it and/or modify it
|
---|
1718 | under the same terms as Perl itself.
|
---|
1719 |
|
---|
1720 | =head1 REFERENCES
|
---|
1721 |
|
---|
1722 | =over 4
|
---|
1723 |
|
---|
1724 | =item L<http://www.compton.nu/panasonic.html>
|
---|
1725 |
|
---|
1726 | =item L<http://johnst.org/sw/exiftags/>
|
---|
1727 |
|
---|
1728 | =item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm>
|
---|
1729 |
|
---|
1730 | =item L<http://bretteville.com/pdfs/M8Metadata_v2.pdf>
|
---|
1731 |
|
---|
1732 | =item L<http://www.digital-leica.com/lens_codes/index.html>
|
---|
1733 |
|
---|
1734 | =item (...plus lots of testing with store demos and my wife's DMC-FS7!)
|
---|
1735 |
|
---|
1736 | =back
|
---|
1737 |
|
---|
1738 | =head1 ACKNOWLEDGEMENTS
|
---|
1739 |
|
---|
1740 | Thanks to Tels for the information he provided on decoding some tags, and to
|
---|
1741 | Marcel Coenen, Jens Duttke and Michael Byczkowski for their contributions.
|
---|
1742 |
|
---|
1743 | =head1 SEE ALSO
|
---|
1744 |
|
---|
1745 | L<Image::ExifTool::TagNames/Panasonic Tags>,
|
---|
1746 | L<Image::ExifTool(3pm)|Image::ExifTool>
|
---|
1747 |
|
---|
1748 | =cut
|
---|