exiftool-vendored.pl 13.37.0 → 13.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/Changes +41 -3
- package/bin/MANIFEST +7 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +49 -47
- package/bin/config_files/local_time.config +55 -0
- package/bin/exiftool +83 -70
- package/bin/lib/Image/ExifTool/BMP.pm +1 -1
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +2 -2
- package/bin/lib/Image/ExifTool/DJI.pm +256 -20
- package/bin/lib/Image/ExifTool/DSF.pm +138 -0
- package/bin/lib/Image/ExifTool/EXE.pm +3 -1
- package/bin/lib/Image/ExifTool/Font.pm +386 -118
- package/bin/lib/Image/ExifTool/Geolocation.pm +10 -7
- package/bin/lib/Image/ExifTool/Geotag.pm +21 -2
- package/bin/lib/Image/ExifTool/GoPro.pm +6 -3
- package/bin/lib/Image/ExifTool/Google.pm +16 -6
- package/bin/lib/Image/ExifTool/ID3.pm +11 -10
- package/bin/lib/Image/ExifTool/LNK.pm +63 -2
- package/bin/lib/Image/ExifTool/M2TS.pm +32 -23
- package/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
- package/bin/lib/Image/ExifTool/OOXML.pm +3 -2
- package/bin/lib/Image/ExifTool/Olympus.pm +3 -1
- package/bin/lib/Image/ExifTool/Pentax.pm +7 -2
- package/bin/lib/Image/ExifTool/QuickTime.pm +3 -3
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +44 -35
- package/bin/lib/Image/ExifTool/Sony.pm +19 -14
- package/bin/lib/Image/ExifTool/TagLookup.pm +35 -1
- package/bin/lib/Image/ExifTool/TagNames.pod +1383 -1217
- package/bin/lib/Image/ExifTool/WavPack.pm +144 -0
- package/bin/lib/Image/ExifTool/XMP.pm +12 -7
- package/bin/lib/Image/ExifTool/XMP2.pl +11 -5
- package/bin/lib/Image/ExifTool.pm +46 -26
- package/bin/lib/Image/ExifTool.pod +64 -56
- package/bin/perl-Image-ExifTool.spec +47 -46
- package/package.json +4 -4
|
@@ -18,22 +18,29 @@ use Image::ExifTool::XMP;
|
|
|
18
18
|
use Image::ExifTool::GPS;
|
|
19
19
|
use Image::ExifTool::Protobuf;
|
|
20
20
|
|
|
21
|
-
$VERSION = '1.
|
|
21
|
+
$VERSION = '1.16';
|
|
22
22
|
|
|
23
23
|
sub ProcessDJIInfo($$$);
|
|
24
24
|
sub ProcessSettings($$$);
|
|
25
25
|
|
|
26
26
|
%knownProtocol = (
|
|
27
|
-
'dvtm_ac203.proto' => 1,
|
|
28
|
-
'dvtm_ac204.proto' => 1,
|
|
29
|
-
'dvtm_AVATA2.proto' => 1,
|
|
30
|
-
'dvtm_wm265e.proto' => 1,
|
|
31
|
-
'dvtm_pm320.proto' => 1,
|
|
32
|
-
'dvtm_Mini4_Pro.proto' => 1, #
|
|
33
|
-
'
|
|
34
|
-
'
|
|
27
|
+
'dvtm_ac203.proto' => 1, # Osmo Action 4
|
|
28
|
+
'dvtm_ac204.proto' => 1, # Osmo Action 5
|
|
29
|
+
'dvtm_AVATA2.proto' => 1, # Avata 2
|
|
30
|
+
'dvtm_wm265e.proto' => 1, # Mavic 3
|
|
31
|
+
'dvtm_pm320.proto' => 1, # Matrice 30
|
|
32
|
+
'dvtm_Mini4_Pro.proto' => 1, # Mini 4
|
|
33
|
+
'dvtm_dji_neo.proto' => 1, # Neo
|
|
34
|
+
'dvtm_Air3.proto' => 1, # Air 3
|
|
35
|
+
'dvtm_Air3s.proto' => 1, # Air 3s
|
|
36
|
+
'dvtm_PP-101.proto' => 1, # Osmo Pocket 3
|
|
37
|
+
'dvtm_oq101.proto' => 1, # Osmo 360
|
|
38
|
+
'dvtm_wa345e.proto' => 1, # Matrice 4E
|
|
39
|
+
'dvtm_wm261.proto' => 1, # Mavic Pro 3
|
|
40
|
+
# dvtm_wm169.proto seems to be DJI O3 but the structure is unknown
|
|
35
41
|
);
|
|
36
42
|
|
|
43
|
+
|
|
37
44
|
my %convFloat2 = (
|
|
38
45
|
PrintConv => 'sprintf("%+.2f", $val)',
|
|
39
46
|
PrintConvInv => '$val',
|
|
@@ -89,7 +96,7 @@ my %convFloat2 = (
|
|
|
89
96
|
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
90
97
|
GROUPS => { 0 => 'APP4', 2 => 'Image' },
|
|
91
98
|
NOTES => 'Thermal parameters extracted from APP4 of DJI RJPEG files from the ZH20T.',
|
|
92
|
-
# 0x00 - 0xaa551206 - temperature header magic number
|
|
99
|
+
# 0x00 - 0xaa551206 - temperature header magic number
|
|
93
100
|
0x24 => { Name => 'K1', Format => 'float' },
|
|
94
101
|
0x28 => { Name => 'K2', Format => 'float' },
|
|
95
102
|
0x2c => { Name => 'K3', Format => 'float' },
|
|
@@ -106,7 +113,7 @@ my %convFloat2 = (
|
|
|
106
113
|
0x54 => { Name => 'KJ', Format => 'int16u' },
|
|
107
114
|
0x56 => { Name => 'DB', Format => 'int16u' },
|
|
108
115
|
0x58 => { Name => 'KK', Format => 'int16u' },
|
|
109
|
-
# 0x500 - 0x55aa1206 - device header magic number
|
|
116
|
+
# 0x500 - 0x55aa1206 - device header magic number
|
|
110
117
|
# (nothing yet decoded from device header)
|
|
111
118
|
);
|
|
112
119
|
|
|
@@ -128,7 +135,7 @@ my %convFloat2 = (
|
|
|
128
135
|
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
129
136
|
GROUPS => { 0 => 'APP4', 2 => 'Image' },
|
|
130
137
|
NOTES => 'Thermal parameters extracted from APP4 of some DJI RJPEG files.',
|
|
131
|
-
# 0x00 - 0xaa553800 - params3 magic number
|
|
138
|
+
# 0x00 - 0xaa553800 - params3 magic number
|
|
132
139
|
0x04 => { Name => 'RelativeHumidity', Format => 'int16u' },
|
|
133
140
|
0x06 => { Name => 'ObjectDistance', Format => 'int16u', ValueConv => '$val / 10' },
|
|
134
141
|
0x08 => { Name => 'Emissivity', Format => 'int16u', ValueConv => '$val / 100' },
|
|
@@ -237,7 +244,10 @@ my %convFloat2 = (
|
|
|
237
244
|
which use the following protocols: dvtm_AVATA2.proto (Avata 2),
|
|
238
245
|
dvtm_ac203.proto (Osmo Action 4), dvtm_ac204.proto (Osmo Action 5),
|
|
239
246
|
dvtm_wm265e.proto (Mavic 3), dvtm_pm320.proto (Matrice 30),
|
|
240
|
-
dvtm_Mini4_Pro.proto (Mini 4 Pro)
|
|
247
|
+
dvtm_Mini4_Pro.proto (Mini 4 Pro), dvtm_dji_neo.proto (DJI Neo),
|
|
248
|
+
dvtm_Air3.proto (Air 3), dvtm_Air3s.proto (Air 3s), dvtm_PP-101.proto (Osmo
|
|
249
|
+
Pocket 3), dvtm_oq101.proto (Osmo 360), dvtm_wa345e.proto (Matrice 4E) and
|
|
250
|
+
dvtm_wm261.proto (Mavic Pro 3).
|
|
241
251
|
|
|
242
252
|
Note that with the protobuf format, numerical tags missing from the output
|
|
243
253
|
for a given protocol should be considered to have the default value of 0.
|
|
@@ -258,7 +268,7 @@ my %convFloat2 = (
|
|
|
258
268
|
# dvtm_ac203_1-1-6 - some version number
|
|
259
269
|
'dvtm_ac203_1-1-10' => 'Model',
|
|
260
270
|
'dvtm_ac203_2-3' => {
|
|
261
|
-
Name => 'FrameInfo',
|
|
271
|
+
Name => 'FrameInfo',
|
|
262
272
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
263
273
|
},
|
|
264
274
|
'dvtm_ac203_3-2-2-1' => { Name => 'ISO', Format => 'float' },
|
|
@@ -298,7 +308,7 @@ my %convFloat2 = (
|
|
|
298
308
|
# dvtm_ac204_1-1-6 - some version number
|
|
299
309
|
'dvtm_ac204_1-1-10' => 'Model',
|
|
300
310
|
'dvtm_ac204_2-3' => {
|
|
301
|
-
Name => 'FrameInfo',
|
|
311
|
+
Name => 'FrameInfo',
|
|
302
312
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
303
313
|
},
|
|
304
314
|
'dvtm_ac204_3-2-4-1' => { # (NC)
|
|
@@ -339,7 +349,7 @@ my %convFloat2 = (
|
|
|
339
349
|
# dvtm_AVATA2_2-2-1-4 - model code?
|
|
340
350
|
'dvtm_AVATA2_2-2-3-1' => 'SerialNumber2', # (NC)
|
|
341
351
|
'dvtm_AVATA2_2-3' => {
|
|
342
|
-
Name => 'FrameInfo',
|
|
352
|
+
Name => 'FrameInfo',
|
|
343
353
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
344
354
|
},
|
|
345
355
|
# dvtm_AVATA2_3-1-1 - frame number (starting at 1)
|
|
@@ -381,7 +391,7 @@ my %convFloat2 = (
|
|
|
381
391
|
'dvtm_wm265e_1-1-5' => { Name => 'SerialNumber', Notes => 'Mavic 3' }, # (confirmed)
|
|
382
392
|
'dvtm_wm265e_1-1-10' => 'Model',
|
|
383
393
|
'dvtm_wm265e_2-2' => {
|
|
384
|
-
Name => 'FrameInfo',
|
|
394
|
+
Name => 'FrameInfo',
|
|
385
395
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
386
396
|
},
|
|
387
397
|
# dvtm_wm265e_3-2-1-4 - model code?
|
|
@@ -413,7 +423,7 @@ my %convFloat2 = (
|
|
|
413
423
|
'dvtm_pm320_1-1-5' => { Name => 'SerialNumber', Notes => 'Matrice 30' },
|
|
414
424
|
'dvtm_pm320_1-1-10' => 'Model',
|
|
415
425
|
'dvtm_pm320_2-2' => {
|
|
416
|
-
Name => 'FrameInfo',
|
|
426
|
+
Name => 'FrameInfo',
|
|
417
427
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
418
428
|
},
|
|
419
429
|
'dvtm_pm320_3-2-2-1' => { Name => 'ISO', Format => 'float' },
|
|
@@ -448,7 +458,7 @@ my %convFloat2 = (
|
|
|
448
458
|
'dvtm_Mini4_Pro_1-1-5' => { Name => 'SerialNumber', Notes => 'Mini 4 Pro' },
|
|
449
459
|
'dvtm_Mini4_Pro_1-1-10' => 'Model',
|
|
450
460
|
'dvtm_Mini4_Pro_2-3' => {
|
|
451
|
-
Name => 'FrameInfo',
|
|
461
|
+
Name => 'FrameInfo',
|
|
452
462
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
453
463
|
},
|
|
454
464
|
'dvtm_Mini4_Pro_3-2-7-1' => { Name => 'ISO', Format => 'float' },
|
|
@@ -490,7 +500,7 @@ my %convFloat2 = (
|
|
|
490
500
|
# dvtm_dji_neo_2-2-2-2 - some version number?
|
|
491
501
|
'dvtm_dji_neo_2-2-3-1' => 'SerialNumber2', # (NC)
|
|
492
502
|
'dvtm_dji_neo_2-3' => {
|
|
493
|
-
Name => 'FrameInfo',
|
|
503
|
+
Name => 'FrameInfo',
|
|
494
504
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
495
505
|
},
|
|
496
506
|
# dvtm_dji_neo_3-1-1 - frame number (starting at 1)
|
|
@@ -525,6 +535,232 @@ my %convFloat2 = (
|
|
|
525
535
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
|
|
526
536
|
},
|
|
527
537
|
'dvtm_dji_neo_3-4-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' }, # (NC)
|
|
538
|
+
#
|
|
539
|
+
# Air 3
|
|
540
|
+
#
|
|
541
|
+
'dvtm_Air3_1-1-5' => { Name => 'SerialNumber', Notes => 'Air 3' },
|
|
542
|
+
'dvtm_Air3_2-3' => {
|
|
543
|
+
Name => 'FrameInfo',
|
|
544
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
545
|
+
},
|
|
546
|
+
'dvtm_Air3_3-1-2' => {
|
|
547
|
+
Name => 'TimeStamp',
|
|
548
|
+
Groups => { 2 => 'Time' },
|
|
549
|
+
Format => 'unsigned',
|
|
550
|
+
ValueConv => '$val / 1e6',
|
|
551
|
+
},
|
|
552
|
+
'dvtm_Air3_3-2-7-1' => { Name => 'ISO', Format => 'float' },
|
|
553
|
+
'dvtm_Air3_3-2-10-1' => {
|
|
554
|
+
Name => 'ShutterSpeed',
|
|
555
|
+
Format => 'rational',
|
|
556
|
+
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
|
557
|
+
},
|
|
558
|
+
'dvtm_Air3_3-2-32-1' => { Name => 'ColorTemperature', Format => 'unsigned' },
|
|
559
|
+
'dvtm_Air3_3-2-11-1' => {
|
|
560
|
+
Name => 'FNumber',
|
|
561
|
+
Format => 'rational',
|
|
562
|
+
PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
|
|
563
|
+
},
|
|
564
|
+
'dvtm_Air3_3-3-3' => {
|
|
565
|
+
Name => 'DroneInfo',
|
|
566
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
|
|
567
|
+
},
|
|
568
|
+
'dvtm_Air3_3-3-4-1' => {
|
|
569
|
+
Name => 'GPSInfo',
|
|
570
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
|
|
571
|
+
},
|
|
572
|
+
'dvtm_Air3_3-3-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
|
|
573
|
+
'dvtm_Air3_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
|
|
574
|
+
'dvtm_Air3_3-4-3' => {
|
|
575
|
+
Name => 'GimbalInfo',
|
|
576
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
|
|
577
|
+
},
|
|
578
|
+
#
|
|
579
|
+
# Air 3s (same structure as Air 3)
|
|
580
|
+
#
|
|
581
|
+
'dvtm_Air3s_1-1-5' => { Name => 'SerialNumber', Notes => 'Air 3s' },
|
|
582
|
+
'dvtm_Air3s_2-3' => {
|
|
583
|
+
Name => 'FrameInfo',
|
|
584
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
585
|
+
},
|
|
586
|
+
'dvtm_Air3s_3-1-2' => {
|
|
587
|
+
Name => 'TimeStamp',
|
|
588
|
+
Groups => { 2 => 'Time' },
|
|
589
|
+
Format => 'unsigned',
|
|
590
|
+
ValueConv => '$val / 1e6',
|
|
591
|
+
},
|
|
592
|
+
'dvtm_Air3s_3-2-7-1' => { Name => 'ISO', Format => 'float' },
|
|
593
|
+
'dvtm_Air3s_3-2-10-1' => {
|
|
594
|
+
Name => 'ShutterSpeed',
|
|
595
|
+
Format => 'rational',
|
|
596
|
+
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
|
597
|
+
},
|
|
598
|
+
'dvtm_Air3s_3-2-32-1' => { Name => 'ColorTemperature', Format => 'unsigned' },
|
|
599
|
+
'dvtm_Air3s_3-2-11-1' => {
|
|
600
|
+
Name => 'FNumber',
|
|
601
|
+
Format => 'rational',
|
|
602
|
+
PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
|
|
603
|
+
},
|
|
604
|
+
'dvtm_Air3s_3-3-3' => {
|
|
605
|
+
Name => 'DroneInfo',
|
|
606
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
|
|
607
|
+
},
|
|
608
|
+
'dvtm_Air3s_3-3-4-1' => {
|
|
609
|
+
Name => 'GPSInfo',
|
|
610
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
|
|
611
|
+
},
|
|
612
|
+
'dvtm_Air3s_3-3-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
|
|
613
|
+
'dvtm_Air3s_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
|
|
614
|
+
'dvtm_Air3s_3-4-3' => {
|
|
615
|
+
Name => 'GimbalInfo',
|
|
616
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
|
|
617
|
+
},
|
|
618
|
+
#
|
|
619
|
+
# Osmo 360 (similar to Action 4/5)
|
|
620
|
+
#
|
|
621
|
+
'dvtm_oq101_1-1-5' => { Name => 'SerialNumber', Notes => 'Osmo 360' },
|
|
622
|
+
'dvtm_oq101_1-1-10' => 'Model',
|
|
623
|
+
'dvtm_oq101_3-1-2' => {
|
|
624
|
+
Name => 'TimeStamp',
|
|
625
|
+
Groups => { 2 => 'Time' },
|
|
626
|
+
Format => 'unsigned',
|
|
627
|
+
ValueConv => '$val / 1e6',
|
|
628
|
+
},
|
|
629
|
+
'dvtm_oq101_3-2-3-1' => { Name => 'ISO', Format => 'float' },
|
|
630
|
+
'dvtm_oq101_3-2-4-1' => {
|
|
631
|
+
Name => 'ShutterSpeed',
|
|
632
|
+
Format => 'rational',
|
|
633
|
+
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
|
634
|
+
},
|
|
635
|
+
'dvtm_oq101_3-2-6-1' => { Name => 'ColorTemperature', Format => 'unsigned' },
|
|
636
|
+
'dvtm_oq101_1-14-1' => {
|
|
637
|
+
Name => 'FNumber',
|
|
638
|
+
Format => 'rational',
|
|
639
|
+
PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
|
|
640
|
+
},
|
|
641
|
+
'dvtm_oq101_3-4-2-1' => {
|
|
642
|
+
Name => 'GPSInfo',
|
|
643
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
|
|
644
|
+
},
|
|
645
|
+
'dvtm_oq101_3-4-2-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
|
|
646
|
+
'dvtm_oq101_3-4-2-6-1' => {
|
|
647
|
+
Name => 'GPSDateTime',
|
|
648
|
+
Format => 'string',
|
|
649
|
+
Groups => { 2 => 'Time' },
|
|
650
|
+
RawConv => '$$self{GPSDateTime} = $val',
|
|
651
|
+
ValueConv => '$val =~ tr/-/:/; $val',
|
|
652
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
|
653
|
+
},
|
|
654
|
+
'dvtm_oq101_3-2-10-2' => { Name => 'AccelerometerX', Format => 'float' },
|
|
655
|
+
'dvtm_oq101_3-2-10-3' => { Name => 'AccelerometerY', Format => 'float' },
|
|
656
|
+
'dvtm_oq101_3-2-10-4' => { Name => 'AccelerometerZ', Format => 'float' },
|
|
657
|
+
#
|
|
658
|
+
# Osmo Pocket 3
|
|
659
|
+
#
|
|
660
|
+
'dvtm_PP-101_1-1-5' => { Name => 'SerialNumber', Notes => 'Osmo Pocket 3' },
|
|
661
|
+
'dvtm_PP-101_1-1-10' => 'Model',
|
|
662
|
+
'dvtm_PP-101_2-3' => {
|
|
663
|
+
Name => 'FrameInfo',
|
|
664
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
665
|
+
},
|
|
666
|
+
'dvtm_PP-101_3-1-2' => {
|
|
667
|
+
Name => 'TimeStamp',
|
|
668
|
+
Groups => { 2 => 'Time' },
|
|
669
|
+
Format => 'unsigned',
|
|
670
|
+
ValueConv => '$val / 1e6',
|
|
671
|
+
},
|
|
672
|
+
'dvtm_PP-101_3-2-9-1' => { Name => 'ISO', Format => 'float' },
|
|
673
|
+
'dvtm_PP-101_3-2-10-1' => {
|
|
674
|
+
Name => 'ShutterSpeed',
|
|
675
|
+
Format => 'rational',
|
|
676
|
+
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
|
677
|
+
},
|
|
678
|
+
'dvtm_PP-101_3-2-24-1' => { Name => 'ColorTemperature', Format => 'unsigned' },
|
|
679
|
+
#
|
|
680
|
+
# Matrice 4E
|
|
681
|
+
#
|
|
682
|
+
'dvtm_wa345e_1-1-5' => { Name => 'SerialNumber', Notes => 'Matrice 4E' },
|
|
683
|
+
'dvtm_wa345e_1-1-10' => 'Model',
|
|
684
|
+
'dvtm_wa345e_2-2' => {
|
|
685
|
+
Name => 'FrameInfo',
|
|
686
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
687
|
+
},
|
|
688
|
+
'dvtm_wa345e_3-1-2' => {
|
|
689
|
+
Name => 'TimeStamp',
|
|
690
|
+
Groups => { 2 => 'Time' },
|
|
691
|
+
Format => 'unsigned',
|
|
692
|
+
ValueConv => '$val / 1e6',
|
|
693
|
+
},
|
|
694
|
+
'dvtm_wa345e_3-3-3' => {
|
|
695
|
+
Name => 'DroneInfo',
|
|
696
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
|
|
697
|
+
},
|
|
698
|
+
'dvtm_wa345e_3-3-4-1' => {
|
|
699
|
+
Name => 'GPSInfo',
|
|
700
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
|
|
701
|
+
},
|
|
702
|
+
'dvtm_wa345e_3-3-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
|
|
703
|
+
'dvtm_wa345e_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
|
|
704
|
+
'dvtm_wa345e_3-4-3' => {
|
|
705
|
+
Name => 'GimbalInfo',
|
|
706
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
|
|
707
|
+
},
|
|
708
|
+
'dvtm_wa345e_3-3-4-6-1' => {
|
|
709
|
+
Name => 'GPSDateTime',
|
|
710
|
+
Format => 'string',
|
|
711
|
+
Groups => { 2 => 'Time' },
|
|
712
|
+
RawConv => '$$self{GPSDateTime} = $val',
|
|
713
|
+
ValueConv => '$val =~ tr/-/:/; $val',
|
|
714
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
|
715
|
+
},
|
|
716
|
+
#
|
|
717
|
+
# Mavic Pro 3
|
|
718
|
+
#
|
|
719
|
+
'dvtm_wm261_1-1-5' => { Name => 'SerialNumber', Notes => 'Mavic Pro 3' },
|
|
720
|
+
'dvtm_wm261_1-1-10' => 'Model',
|
|
721
|
+
'dvtm_wm261_2-3' => {
|
|
722
|
+
Name => 'FrameInfo',
|
|
723
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
|
|
724
|
+
},
|
|
725
|
+
'dvtm_wm261_3-1-2' => {
|
|
726
|
+
Name => 'TimeStamp',
|
|
727
|
+
Groups => { 2 => 'Time' },
|
|
728
|
+
Format => 'unsigned',
|
|
729
|
+
ValueConv => '$val / 1e6',
|
|
730
|
+
},
|
|
731
|
+
'dvtm_wm261_3-2-9-1' => { Name => 'ISO', Format => 'float' },
|
|
732
|
+
'dvtm_wm261_3-2-10-1' => {
|
|
733
|
+
Name => 'ShutterSpeed',
|
|
734
|
+
Format => 'rational',
|
|
735
|
+
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
|
736
|
+
},
|
|
737
|
+
'dvtm_wm261_3-2-11-1'=> {
|
|
738
|
+
Name => 'FNumber',
|
|
739
|
+
Format => 'rational',
|
|
740
|
+
PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
|
|
741
|
+
},
|
|
742
|
+
'dvtm_wm261_3-3-3' => {
|
|
743
|
+
Name => 'DroneInfo',
|
|
744
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
|
|
745
|
+
},
|
|
746
|
+
'dvtm_wm261_3-3-4-1' => {
|
|
747
|
+
Name => 'GPSInfo',
|
|
748
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
|
|
749
|
+
},
|
|
750
|
+
'dvtm_wm261_3-3-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
|
|
751
|
+
'dvtm_wm261_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
|
|
752
|
+
'dvtm_wm261_3-4-3' => {
|
|
753
|
+
Name => 'GimbalInfo',
|
|
754
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
|
|
755
|
+
},
|
|
756
|
+
'dvtm_wm261_3-3-4-6-1' => {
|
|
757
|
+
Name => 'GPSDateTime',
|
|
758
|
+
Format => 'string',
|
|
759
|
+
Groups => { 2 => 'Time' },
|
|
760
|
+
RawConv => '$$self{GPSDateTime} = $val',
|
|
761
|
+
ValueConv => '$val =~ tr/-/:/; $val',
|
|
762
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
|
763
|
+
},
|
|
528
764
|
);
|
|
529
765
|
|
|
530
766
|
%Image::ExifTool::DJI::DroneInfo = (
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#------------------------------------------------------------------------------
|
|
2
|
+
# File: DSF.pm
|
|
3
|
+
#
|
|
4
|
+
# Description: Read DSF meta information
|
|
5
|
+
#
|
|
6
|
+
# Revisions: 2025-09-24 - P. Harvey Created
|
|
7
|
+
#
|
|
8
|
+
# References: 1) https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
|
|
9
|
+
#------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
package Image::ExifTool::DSF;
|
|
12
|
+
|
|
13
|
+
use strict;
|
|
14
|
+
use vars qw($VERSION);
|
|
15
|
+
use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
|
+
|
|
17
|
+
$VERSION = '1.00';
|
|
18
|
+
|
|
19
|
+
# DSF header format
|
|
20
|
+
%Image::ExifTool::DSF::Main = (
|
|
21
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
22
|
+
GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Audio' },
|
|
23
|
+
FORMAT => 'int32u',
|
|
24
|
+
NOTES => q{
|
|
25
|
+
Tags read from the 'fmt ' header of a DSF (DSD Stream File) audio files. As
|
|
26
|
+
well, ID3 metadata may also exist in these files. See
|
|
27
|
+
L<https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf>
|
|
28
|
+
for the specification.
|
|
29
|
+
},
|
|
30
|
+
3 => 'FormatVersion',
|
|
31
|
+
4 => { Name => 'FormatID', PrintConv => { 0 => 'DSD Raw' }},
|
|
32
|
+
5 => {
|
|
33
|
+
Name => 'ChannelType',
|
|
34
|
+
PrintConv => {
|
|
35
|
+
1 => 'Mono',
|
|
36
|
+
2 => 'Stereo (Left, Right)',
|
|
37
|
+
3 => '3 Channels (Left, Right, Center)',
|
|
38
|
+
4 => 'Quad (Left, Right, Back L, Back R)',
|
|
39
|
+
5 => '4 Channels (Left, Right, Center, Bass)',
|
|
40
|
+
6 => '5 Channels (Left, Right, Center, Back L, Back R)',
|
|
41
|
+
7 => '5.1 Channels (Left, Right, Center, Bass, Back L, Back R)',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
6 => 'ChannelCount',
|
|
45
|
+
7 => 'SampleRate',
|
|
46
|
+
8 => 'BitsPerSample',
|
|
47
|
+
9 => { Name => 'SampleCount', Format => 'int64u' },
|
|
48
|
+
11 => 'BlockSize',
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
#------------------------------------------------------------------------------
|
|
52
|
+
# Extract metadata from a DSF file
|
|
53
|
+
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
|
54
|
+
# Returns: 1 on success, 0 if this wasn't a valid DSF file
|
|
55
|
+
sub ProcessDSF($$)
|
|
56
|
+
{
|
|
57
|
+
my ($et, $dirInfo) = @_;
|
|
58
|
+
my $raf = $$dirInfo{RAF};
|
|
59
|
+
my ($buff, $buf2, $tagTablePtr);
|
|
60
|
+
|
|
61
|
+
# verify this is a valid DSF file
|
|
62
|
+
return 0 unless $raf->Read($buff, 40) == 40;
|
|
63
|
+
return 0 unless $buff =~ /^DSD \x1c\0{7}.{16}fmt /s;
|
|
64
|
+
$et->SetFileType(); # set the FileType tag
|
|
65
|
+
my $tagTbl = GetTagTable('Image::ExifTool::DSF::Main');
|
|
66
|
+
SetByteOrder('II');
|
|
67
|
+
my $fmtLen = Get64u(\$buff,32);
|
|
68
|
+
unless ($fmtLen > 12 and $fmtLen < 1000 and
|
|
69
|
+
$raf->Read($buf2, $fmtLen - 12) == $fmtLen - 12)
|
|
70
|
+
{
|
|
71
|
+
$et->Warn('Error reading DSF fmt chunk');
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
my $fileSize = Get64u(\$buff, 12);
|
|
75
|
+
my $metaPos = Get64u(\$buff, 20);
|
|
76
|
+
$buff = substr($buff, 28) . $buf2;
|
|
77
|
+
#
|
|
78
|
+
# process the DSF 'fmt ' chunk
|
|
79
|
+
#
|
|
80
|
+
my %dirInfo = (
|
|
81
|
+
DataPt => \$buff,
|
|
82
|
+
DirStart => 0,
|
|
83
|
+
DirLen => length($buff),
|
|
84
|
+
);
|
|
85
|
+
$et->ProcessBinaryData(\%dirInfo, $tagTbl);
|
|
86
|
+
#
|
|
87
|
+
# process ID3v2 if it exists
|
|
88
|
+
#
|
|
89
|
+
my $metaLen = $fileSize - $metaPos;
|
|
90
|
+
if ($metaPos and $metaLen > 0 and $metaLen < 20000000 and
|
|
91
|
+
$raf->Seek($metaPos, 0) and $raf->Read($buff, $metaLen) == $metaLen)
|
|
92
|
+
{
|
|
93
|
+
$dirInfo{DataPos} = $metaPos;
|
|
94
|
+
$dirInfo{DirLen} = $metaLen;
|
|
95
|
+
my $id3Tbl = GetTagTable('Image::ExifTool::ID3::Main');
|
|
96
|
+
$et->ProcessDirectory(\%dirInfo, $id3Tbl);
|
|
97
|
+
}
|
|
98
|
+
return 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
1; # end
|
|
102
|
+
|
|
103
|
+
__END__
|
|
104
|
+
|
|
105
|
+
=head1 NAME
|
|
106
|
+
|
|
107
|
+
Image::ExifTool::DSF - Read DSF meta information
|
|
108
|
+
|
|
109
|
+
=head1 SYNOPSIS
|
|
110
|
+
|
|
111
|
+
This module is used by Image::ExifTool
|
|
112
|
+
|
|
113
|
+
=head1 DESCRIPTION
|
|
114
|
+
|
|
115
|
+
This module contains definitions required by Image::ExifTool to read DSF
|
|
116
|
+
(DSD Stream File) audio files.
|
|
117
|
+
|
|
118
|
+
=head1 AUTHOR
|
|
119
|
+
|
|
120
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
121
|
+
|
|
122
|
+
This library is free software; you can redistribute it and/or modify it
|
|
123
|
+
under the same terms as Perl itself.
|
|
124
|
+
|
|
125
|
+
=head1 REFERENCES
|
|
126
|
+
|
|
127
|
+
=over 4
|
|
128
|
+
|
|
129
|
+
=item L<https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf>
|
|
130
|
+
|
|
131
|
+
=back
|
|
132
|
+
|
|
133
|
+
=head1 SEE ALSO
|
|
134
|
+
|
|
135
|
+
L<Image::ExifTool::TagNames/DSF Tags>,
|
|
136
|
+
L<Image::ExifTool(3pm)|Image::ExifTool>
|
|
137
|
+
|
|
138
|
+
=cut
|
|
@@ -22,7 +22,7 @@ use strict;
|
|
|
22
22
|
use vars qw($VERSION);
|
|
23
23
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
24
24
|
|
|
25
|
-
$VERSION = '1.
|
|
25
|
+
$VERSION = '1.25';
|
|
26
26
|
|
|
27
27
|
sub ProcessPEResources($$);
|
|
28
28
|
sub ProcessPEVersion($$);
|
|
@@ -962,6 +962,7 @@ sub ProcessPEVersion($$)
|
|
|
962
962
|
$pos = ($pos + 3) & 0xfffffffc; # align on a 4-byte boundary
|
|
963
963
|
last if $pos + 6 > $end;
|
|
964
964
|
$len = Get16u($dataPt, $pos);
|
|
965
|
+
return 0 if $pos + $len > $end;
|
|
965
966
|
$valLen = Get16u($dataPt, $pos + 2);
|
|
966
967
|
$type = Get16u($dataPt, $pos + 4);
|
|
967
968
|
return 0 unless $len or $valLen; # prevent possible infinite loop
|
|
@@ -989,6 +990,7 @@ sub ProcessPEVersion($$)
|
|
|
989
990
|
$valLen = Get16u($dataPt, $pt + 2);
|
|
990
991
|
# $type = Get16u($dataPt, $pt + 4);
|
|
991
992
|
my $entryEnd = $pt + $len;
|
|
993
|
+
return 0 if $entryEnd > $end;
|
|
992
994
|
# get tag ID (converted to UTF8)
|
|
993
995
|
($string, $pt) = ReadUnicodeStr($dataPt, $pt + 6, $entryEnd);
|
|
994
996
|
unless ($index) {
|