exiftool-vendored.exe 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/exiftool.exe +0 -0
- package/bin/exiftool_files/exiftool.pl +14 -4
- package/bin/exiftool_files/lib/Image/ExifTool/BMP.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/DJI.pm +256 -20
- package/bin/exiftool_files/lib/Image/ExifTool/DSF.pm +138 -0
- package/bin/exiftool_files/lib/Image/ExifTool/EXE.pm +3 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Font.pm +386 -118
- package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +10 -7
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +21 -2
- package/bin/exiftool_files/lib/Image/ExifTool/GoPro.pm +6 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Google.pm +16 -6
- package/bin/exiftool_files/lib/Image/ExifTool/ID3.pm +11 -10
- package/bin/exiftool_files/lib/Image/ExifTool/LNK.pm +63 -2
- package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +32 -23
- package/bin/exiftool_files/lib/Image/ExifTool/MIEUnits.pod +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/OOXML.pm +3 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +3 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +7 -2
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +44 -35
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +19 -14
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +35 -1
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +1383 -1217
- package/bin/exiftool_files/lib/Image/ExifTool/WavPack.pm +144 -0
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +12 -7
- package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +11 -5
- package/bin/exiftool_files/lib/Image/ExifTool.pm +46 -26
- package/bin/exiftool_files/lib/Image/ExifTool.pod +64 -56
- package/bin/exiftool_files/windows_exiftool.txt +67 -64
- package/package.json +4 -4
package/bin/exiftool.exe
CHANGED
|
Binary file
|
|
@@ -11,7 +11,7 @@ use strict;
|
|
|
11
11
|
use warnings;
|
|
12
12
|
require 5.004;
|
|
13
13
|
|
|
14
|
-
my $version = '13.
|
|
14
|
+
my $version = '13.40';
|
|
15
15
|
|
|
16
16
|
$^W = 1; # enable global warnings
|
|
17
17
|
|
|
@@ -1936,7 +1936,7 @@ if (@fileOrder) {
|
|
|
1936
1936
|
# set file count for progress message
|
|
1937
1937
|
$progressMax = scalar @files if defined $progress;
|
|
1938
1938
|
|
|
1939
|
-
# store duplicate database information under absolute path
|
|
1939
|
+
# store duplicate database information under absolute path and with standardized case
|
|
1940
1940
|
my @dbKeys = keys %database;
|
|
1941
1941
|
if (@dbKeys) {
|
|
1942
1942
|
if (eval { require Cwd }) {
|
|
@@ -1945,6 +1945,7 @@ if (@dbKeys) {
|
|
|
1945
1945
|
foreach (@dbKeys) {
|
|
1946
1946
|
my $db = $database{$_};
|
|
1947
1947
|
tr/\\/\// and $database{$_} = $db; # allow for backslashes in SourceFile
|
|
1948
|
+
$database{lc} = $db unless $database{lc}; # duplicate entry with lower case
|
|
1948
1949
|
# (punt on using ConvertFileName here, so $absPath may be a mix of encodings)
|
|
1949
1950
|
my $absPath = AbsPath($_);
|
|
1950
1951
|
if (defined $absPath) {
|
|
@@ -1952,6 +1953,7 @@ if (@dbKeys) {
|
|
|
1952
1953
|
if ($verbose and $verbose > 1) {
|
|
1953
1954
|
print $vout "Imported entry for '${_}' (full path: '${absPath}')\n";
|
|
1954
1955
|
}
|
|
1956
|
+
$database{lc $absPath} = $db unless $database{lc $absPath};
|
|
1955
1957
|
} elsif ($verbose and $verbose > 1) {
|
|
1956
1958
|
print $vout "Imported entry for '${_}' (no full path)\n";
|
|
1957
1959
|
}
|
|
@@ -3260,10 +3262,18 @@ sub SetImageInfo($$$)
|
|
|
3260
3262
|
my $csvInfo = $database{$f};
|
|
3261
3263
|
unless ($csvInfo) {
|
|
3262
3264
|
next if $f eq '*';
|
|
3263
|
-
# check absolute path
|
|
3265
|
+
# check absolute path and case-insensitive name
|
|
3264
3266
|
# (punt on using ConvertFileName here, so $absPath may be a mix of encodings)
|
|
3265
3267
|
my $absPath = AbsPath($f);
|
|
3266
|
-
|
|
3268
|
+
if (defined $absPath and $database{$absPath}) {
|
|
3269
|
+
$csvInfo = $database{$absPath};
|
|
3270
|
+
} elsif ($database{lc $f}) {
|
|
3271
|
+
$csvInfo = $database{lc $f};
|
|
3272
|
+
} elsif (defined $absPath and $database{lc $absPath}) {
|
|
3273
|
+
$csvInfo = $database{lc $absPath};
|
|
3274
|
+
} else {
|
|
3275
|
+
next;
|
|
3276
|
+
}
|
|
3267
3277
|
}
|
|
3268
3278
|
$found = 1;
|
|
3269
3279
|
if ($verbose) {
|
|
@@ -248,7 +248,7 @@ my %fixed2_30 = (
|
|
|
248
248
|
);
|
|
249
249
|
|
|
250
250
|
#------------------------------------------------------------------------------
|
|
251
|
-
# Extract
|
|
251
|
+
# Extract metadata from a BMP image
|
|
252
252
|
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
|
253
253
|
# Returns: 1 on success, 0 if this wasn't a valid BMP file
|
|
254
254
|
sub ProcessBMP($$)
|
|
@@ -74,7 +74,8 @@ my %tweakOrder = (
|
|
|
74
74
|
DJI => 'Casio',
|
|
75
75
|
FLIR => 'DJI',
|
|
76
76
|
FujiFilm => 'FLIR',
|
|
77
|
-
|
|
77
|
+
Google => 'GE',
|
|
78
|
+
GoPro => 'Google',
|
|
78
79
|
Kodak => 'JVC',
|
|
79
80
|
Leaf => 'Kodak',
|
|
80
81
|
Lytro => 'Leaf',
|
|
@@ -109,7 +110,6 @@ my %tweakOrder = (
|
|
|
109
110
|
'FujiFilm::RAFData' => 'FujiFilm::RAF',
|
|
110
111
|
'QuickTime::AudioKeys' => 'QuickTime::Keys',
|
|
111
112
|
'QuickTime::VideoKeys' => 'QuickTime::AudioKeys',
|
|
112
|
-
'Google::HDRPText' => 'Google::HDRPlusMakerNote',
|
|
113
113
|
);
|
|
114
114
|
|
|
115
115
|
# list of all recognized Format strings
|
|
@@ -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) {
|