exiftool_vendored 13.38.0 → 13.41.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.
- checksums.yaml +4 -4
- data/bin/Changes +42 -0
- data/bin/MANIFEST +3 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +49 -47
- data/bin/config_files/local_time.config +55 -0
- data/bin/exiftool +136 -90
- data/bin/lib/Image/ExifTool/Canon.pm +15 -12
- data/bin/lib/Image/ExifTool/DJI.pm +256 -20
- data/bin/lib/Image/ExifTool/Exif.pm +11 -6
- data/bin/lib/Image/ExifTool/Font.pm +388 -121
- data/bin/lib/Image/ExifTool/Geolocation.pm +10 -7
- data/bin/lib/Image/ExifTool/Geotag.pm +18 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -1
- data/bin/lib/Image/ExifTool/LNK.pm +77 -3
- data/bin/lib/Image/ExifTool/OOXML.pm +3 -2
- data/bin/lib/Image/ExifTool/Olympus.pm +5 -2
- data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
- data/bin/lib/Image/ExifTool/QuickTime.pm +22 -4
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +42 -35
- data/bin/lib/Image/ExifTool/Red.pm +19 -9
- data/bin/lib/Image/ExifTool/Sony.pm +14 -9
- data/bin/lib/Image/ExifTool/TagLookup.pm +31 -0
- data/bin/lib/Image/ExifTool/TagNames.pod +164 -24
- data/bin/lib/Image/ExifTool/XMP2.pl +11 -5
- data/bin/lib/Image/ExifTool.pm +25 -8
- data/bin/lib/Image/ExifTool.pod +52 -45
- data/bin/perl-Image-ExifTool.spec +47 -46
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -1
|
@@ -35,7 +35,7 @@ use vars qw($VERSION);
|
|
|
35
35
|
use Image::ExifTool qw(:Public);
|
|
36
36
|
use Image::ExifTool::GPS;
|
|
37
37
|
|
|
38
|
-
$VERSION = '1.
|
|
38
|
+
$VERSION = '1.83';
|
|
39
39
|
|
|
40
40
|
sub JITTER() { return 2 } # maximum time jitter
|
|
41
41
|
|
|
@@ -1345,6 +1345,23 @@ Category: foreach $category (qw{pos track alt orient atemp err dop}) {
|
|
|
1345
1345
|
if (defined $dop) {
|
|
1346
1346
|
$et->SetNewValue(GPSMeasureMode => $mm, %opts);
|
|
1347
1347
|
$et->SetNewValue(GPSDOP => $dop, %opts);
|
|
1348
|
+
# also set GPSHPositioningError if specified
|
|
1349
|
+
my $hposErr = $$et{OPTIONS}{GeoHPosErr};
|
|
1350
|
+
if ($hposErr) {
|
|
1351
|
+
$hposErr =~ s/gpsdop/GPSDOP/i;
|
|
1352
|
+
my $GPSDOP = $dop;
|
|
1353
|
+
local $SIG{'__WARN__'} = \&Image::ExifTool::SetWarning;
|
|
1354
|
+
undef $Image::ExifTool::evalWarning;
|
|
1355
|
+
#### eval GeoHPosErr ($GPSDOP)
|
|
1356
|
+
$hposErr = eval $hposErr;
|
|
1357
|
+
my $err = Image::ExifTool::GetWarning() || $@;
|
|
1358
|
+
if ($err) {
|
|
1359
|
+
$err = Image::ExifTool::CleanWarning($err);
|
|
1360
|
+
$et->Warn("Error calculating GPSHPositioningError: $err", 1);
|
|
1361
|
+
} else {
|
|
1362
|
+
$et->SetNewValue(GPSHPositioningError => $hposErr, %opts);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1348
1365
|
}
|
|
1349
1366
|
}
|
|
1350
1367
|
unless ($xmp) {
|
|
@@ -26,7 +26,7 @@ use strict;
|
|
|
26
26
|
use vars qw($VERSION);
|
|
27
27
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
28
28
|
|
|
29
|
-
$VERSION = '1.
|
|
29
|
+
$VERSION = '1.42';
|
|
30
30
|
|
|
31
31
|
sub ProcessICC($$);
|
|
32
32
|
sub ProcessICC_Profile($$$);
|
|
@@ -330,6 +330,7 @@ my %manuSig = ( #6
|
|
|
330
330
|
'WTG2' => 'Ware To Go',
|
|
331
331
|
'WYSE' => 'WYSE Technology',
|
|
332
332
|
'XERX' => 'Xerox Corporation',
|
|
333
|
+
'XM ' => 'Xiaomi',
|
|
333
334
|
'XRIT' => 'X-Rite',
|
|
334
335
|
'yxym' => 'YxyMaster GmbH',
|
|
335
336
|
'Z123' => "Lavanya's test Company",
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# Description: Read meta information from MS Shell Link files
|
|
5
5
|
#
|
|
6
6
|
# Revisions: 2009/09/19 - P. Harvey Created
|
|
7
|
+
# 2025/10/20 - PH Added .URL file support
|
|
7
8
|
#
|
|
8
9
|
# References: 1) http://msdn.microsoft.com/en-us/library/dd871305(PROT.10).aspx
|
|
9
10
|
# 2) http://www.i2s-lab.com/Papers/The_Windows_Shortcut_File_Format.pdf
|
|
@@ -17,7 +18,7 @@ use vars qw($VERSION);
|
|
|
17
18
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
18
19
|
use Image::ExifTool::Microsoft;
|
|
19
20
|
|
|
20
|
-
$VERSION = '1.
|
|
21
|
+
$VERSION = '1.13';
|
|
21
22
|
|
|
22
23
|
sub ProcessItemID($$$);
|
|
23
24
|
sub ProcessLinkInfo($$$);
|
|
@@ -190,7 +191,7 @@ sub ProcessLinkInfo($$$);
|
|
|
190
191
|
},
|
|
191
192
|
0xa0000001 => {
|
|
192
193
|
Name => 'EnvVarData',
|
|
193
|
-
SubDirectory => { TagTable => 'Image::ExifTool::LNK::
|
|
194
|
+
SubDirectory => { TagTable => 'Image::ExifTool::LNK::EnvVarData' },
|
|
194
195
|
},
|
|
195
196
|
0xa0000002 => {
|
|
196
197
|
Name => 'ConsoleData',
|
|
@@ -447,6 +448,52 @@ sub ProcessLinkInfo($$$);
|
|
|
447
448
|
},
|
|
448
449
|
);
|
|
449
450
|
|
|
451
|
+
%Image::ExifTool::LNK::EnvVarData = (
|
|
452
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
453
|
+
GROUPS => { 2 => 'Other' },
|
|
454
|
+
8 => {
|
|
455
|
+
Name => 'EnvironmentTarget',
|
|
456
|
+
Format => 'string[260]',
|
|
457
|
+
},
|
|
458
|
+
268 => {
|
|
459
|
+
Name => 'EnvironmentTargetUnicode',
|
|
460
|
+
Format => 'unicode[260]',
|
|
461
|
+
},
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
%Image::ExifTool::LNK::INI = (
|
|
465
|
+
GROUPS => { 2 => 'Document' },
|
|
466
|
+
VARS => { ID_FMT => 'none' },
|
|
467
|
+
NOTES => 'Tags found in INI-format Windows .URL files.',
|
|
468
|
+
URL => { },
|
|
469
|
+
IconFile => { },
|
|
470
|
+
IconIndex => { },
|
|
471
|
+
WorkingDirectory => { },
|
|
472
|
+
HotKey => { },
|
|
473
|
+
ShowCommand => { PrintConv => { 1 => 'Normal', 2 => 'Minimized', 3 => 'Maximized' } },
|
|
474
|
+
Modified => {
|
|
475
|
+
Groups => { 2 => 'Time' },
|
|
476
|
+
Format => 'int64u',
|
|
477
|
+
Groups => { 2 => 'Time' },
|
|
478
|
+
# convert time from 100-ns intervals since Jan 1, 1601 (NC)
|
|
479
|
+
RawConv => q{
|
|
480
|
+
my $dat = pack('H*', $val);
|
|
481
|
+
return undef if length $dat < 8;
|
|
482
|
+
my ($lo, $hi) = unpack('V2', $dat);
|
|
483
|
+
return undef unless $lo or $hi;
|
|
484
|
+
return $hi * 4294967296 + $lo;
|
|
485
|
+
},
|
|
486
|
+
ValueConv => '$val=$val/1e7-11644473600; ConvertUnixTime($val,1)',
|
|
487
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
|
488
|
+
},
|
|
489
|
+
Author => { Groups => { 2 => 'Author' } },
|
|
490
|
+
WhatsNew => { },
|
|
491
|
+
Comment => { },
|
|
492
|
+
Desc => { },
|
|
493
|
+
Roamed => { Notes => '1 if synced across multiple devices' },
|
|
494
|
+
IDList => { },
|
|
495
|
+
);
|
|
496
|
+
|
|
450
497
|
#------------------------------------------------------------------------------
|
|
451
498
|
# Extract null-terminated ASCII or Unicode string from buffer
|
|
452
499
|
# Inputs: 0) buffer ref, 1) start position, 2) flag for unicode string
|
|
@@ -588,6 +635,27 @@ sub ProcessLinkInfo($$$)
|
|
|
588
635
|
return 1;
|
|
589
636
|
}
|
|
590
637
|
|
|
638
|
+
#------------------------------------------------------------------------------
|
|
639
|
+
# Extract information from a INI-format file
|
|
640
|
+
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
|
641
|
+
# Returns: 1 on success, 0 if this wasn't a valid INI file
|
|
642
|
+
sub ProcessINI($$)
|
|
643
|
+
{
|
|
644
|
+
my ($et, $dirInfo) = @_;
|
|
645
|
+
my $raf = $$dirInfo{RAF};
|
|
646
|
+
my $buff;
|
|
647
|
+
local $/ = "\x0d\x0a";
|
|
648
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::LNK::INI');
|
|
649
|
+
while ($raf->ReadLine($buff)) {
|
|
650
|
+
if ($buff =~ /^\[(.*?)\]/) {
|
|
651
|
+
$et->VPrint(0, "$1 section:\n");
|
|
652
|
+
} elsif ($buff =~ /^\s*(\w+)=(.*)\x0d\x0a$/) {
|
|
653
|
+
$et->HandleTag($tagTablePtr, $1, $2, MakeTagInfo => 1);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return 1;
|
|
657
|
+
}
|
|
658
|
+
|
|
591
659
|
#------------------------------------------------------------------------------
|
|
592
660
|
# Extract information from a MS Shell Link (Windows shortcut) file
|
|
593
661
|
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
|
@@ -600,7 +668,13 @@ sub ProcessLNK($$)
|
|
|
600
668
|
|
|
601
669
|
# read LNK file header
|
|
602
670
|
$raf->Read($buff, 0x4c) == 0x4c or return 0;
|
|
603
|
-
$buff =~ /^.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46/s
|
|
671
|
+
unless ($buff =~ /^.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46/s) {
|
|
672
|
+
# check for INI-format LNK file (eg. .URL file)
|
|
673
|
+
return undef unless $buff =~ /^\[[InternetShortcut\][\x0d\x0a]/;
|
|
674
|
+
$raf->Seek(0,0) or return 0;
|
|
675
|
+
$et->SetFileType('URL', 'application/x-mswinurl');
|
|
676
|
+
return ProcessINI($et, $dirInfo);
|
|
677
|
+
};
|
|
604
678
|
$len = unpack('V', $buff);
|
|
605
679
|
$len >= 0x4c or return 0;
|
|
606
680
|
if ($len > 0x4c) {
|
|
@@ -14,7 +14,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
14
14
|
use Image::ExifTool::XMP;
|
|
15
15
|
use Image::ExifTool::ZIP;
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.10';
|
|
18
18
|
|
|
19
19
|
# test for recognized OOXML document extensions
|
|
20
20
|
my %isOOXML = (
|
|
@@ -27,6 +27,7 @@ my %isOOXML = (
|
|
|
27
27
|
XLAM => 1,
|
|
28
28
|
XLSX => 1, XLSM => 1, XLSB => 1,
|
|
29
29
|
XLTX => 1, XLTM => 1,
|
|
30
|
+
VSDX => 1,
|
|
30
31
|
);
|
|
31
32
|
|
|
32
33
|
# generate reverse lookup for file type based on MIME
|
|
@@ -57,7 +58,7 @@ my @vectorVals;
|
|
|
57
58
|
VARS => { ID_FMT => 'none' },
|
|
58
59
|
NOTES => q{
|
|
59
60
|
The Office Open XML (OOXML) format was introduced with Microsoft Office 2007
|
|
60
|
-
and is used by file types such as DOCX, PPTX and
|
|
61
|
+
and is used by file types such as DOCX, PPTX, XLSX and VSDX. These are
|
|
61
62
|
essentially ZIP archives containing XML files. The table below lists some
|
|
62
63
|
tags which have been observed in OOXML documents, but ExifTool will extract
|
|
63
64
|
any tags found from XML files of the OOXML document properties ("docProps")
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
# 25) Karsten Gieselmann private communication (OM series)
|
|
32
32
|
# IB) Iliah Borg private communication (LibRaw)
|
|
33
33
|
# NJ) Niels Kristian Bech Jensen private communication
|
|
34
|
+
# KG) Karsten Gieselmann private communication
|
|
34
35
|
#------------------------------------------------------------------------------
|
|
35
36
|
|
|
36
37
|
package Image::ExifTool::Olympus;
|
|
@@ -41,7 +42,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
41
42
|
use Image::ExifTool::Exif;
|
|
42
43
|
use Image::ExifTool::APP12;
|
|
43
44
|
|
|
44
|
-
$VERSION = '2.
|
|
45
|
+
$VERSION = '2.93';
|
|
45
46
|
|
|
46
47
|
sub PrintLensInfo($$$);
|
|
47
48
|
|
|
@@ -200,7 +201,9 @@ my %olympusLensTypes = (
|
|
|
200
201
|
# '65535 07 40' - Seen for LUMIX S 16-35/F4 on Panasonic DC-S1H (ref PH)
|
|
201
202
|
# Other makes
|
|
202
203
|
'24 01 10' => 'Venus Optics Laowa 50mm F2.8 2x Macro', #DonKomarechka
|
|
203
|
-
'
|
|
204
|
+
'247 03 10' => 'LAOWA C&D-Dreamer MFT 7.5mm F2.0', #forum3833
|
|
205
|
+
'247 10 10' => 'LAOWA C&D-Dreamer MFT 6.0mm F2.0', #KG
|
|
206
|
+
'65522 02 10' => 'Xiaoyi 42.5mm F1.8', #github363
|
|
204
207
|
);
|
|
205
208
|
|
|
206
209
|
# lookup for Olympus camera types (ref PH)
|
|
@@ -59,7 +59,7 @@ use Image::ExifTool::Exif;
|
|
|
59
59
|
use Image::ExifTool::GPS;
|
|
60
60
|
use Image::ExifTool::HP;
|
|
61
61
|
|
|
62
|
-
$VERSION = '3.
|
|
62
|
+
$VERSION = '3.59';
|
|
63
63
|
|
|
64
64
|
sub CryptShutterCount($$);
|
|
65
65
|
sub PrintFilter($$$);
|
|
@@ -1947,7 +1947,8 @@ my %binaryDataAttrs = (
|
|
|
1947
1947
|
'0 28' => 'Quick Macro', # (Q)
|
|
1948
1948
|
'0 29' => 'Forest', # (Q)
|
|
1949
1949
|
'0 30' => 'Backlight Silhouette', # (Q)
|
|
1950
|
-
'0
|
|
1950
|
+
'0 31' => 'Max. Aperture Priority', #KG (Ricoh GR III)
|
|
1951
|
+
'0 32' => 'DOF', #PH (GR III) #KG ???? GR III 'DOF Priority (Deep)' is mapped to '0 2' ???
|
|
1951
1952
|
# AUTO PICT modes (auto-selected)
|
|
1952
1953
|
'1 4' => 'Auto PICT (Standard)', #13
|
|
1953
1954
|
'1 5' => 'Auto PICT (Portrait)', #7 (K100D)
|
|
@@ -1962,7 +1963,11 @@ my %binaryDataAttrs = (
|
|
|
1962
1963
|
'2 22' => 'Shallow DOF (HyP)', #PH (K-5)
|
|
1963
1964
|
'3 0' => 'Green Mode', #16
|
|
1964
1965
|
'4 0' => 'Shutter Speed Priority',
|
|
1966
|
+
'4 2' => 'Shutter Speed Priority 2', #KG Coding error? 'DOF Priority' in Tv makes no sense
|
|
1967
|
+
'4 31' => 'Shutter Speed Priority 31',#KG Coding error? 'Max Aperture' in Tv makes no sense
|
|
1965
1968
|
'5 0' => 'Aperture Priority',
|
|
1969
|
+
'5 2' => 'Aperture Priority 2', #KG Coding error? 'DOF Priority' in Av makes no sense
|
|
1970
|
+
'5 31' => 'Aperture Priority 31', #KG Coding error? 'DOF Priority' in Av makes no sense
|
|
1966
1971
|
'6 0' => 'Program Tv Shift',
|
|
1967
1972
|
'7 0' => 'Program Av Shift', #19
|
|
1968
1973
|
'8 0' => 'Manual',
|
|
@@ -49,7 +49,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
49
49
|
use Image::ExifTool::Exif;
|
|
50
50
|
use Image::ExifTool::GPS;
|
|
51
51
|
|
|
52
|
-
$VERSION = '3.
|
|
52
|
+
$VERSION = '3.23';
|
|
53
53
|
|
|
54
54
|
sub ProcessMOV($$;$);
|
|
55
55
|
sub ProcessKeys($$$);
|
|
@@ -578,11 +578,29 @@ my %userDefined = (
|
|
|
578
578
|
return substr($val, 8, $len-8);
|
|
579
579
|
},
|
|
580
580
|
Binary => 1,
|
|
581
|
+
},{
|
|
582
|
+
Name => 'HighlightMarkers',
|
|
583
|
+
# (DJI Action 4, forum17700)
|
|
584
|
+
Notes => 'written by some DJI models',
|
|
585
|
+
Condition => '$$valPt =~ /^data.{4}hglg.{5}/s',
|
|
586
|
+
RawConv => q{
|
|
587
|
+
my $len = unpack 'x4N', $val;
|
|
588
|
+
return undef if $len < 13 or $len + 4 > length($val);
|
|
589
|
+
my $n = int(($len - 13) / 5);
|
|
590
|
+
my @a = map $_/1000, unpack "x17(xV)$n", $val;
|
|
591
|
+
return \@a;
|
|
592
|
+
},
|
|
581
593
|
},{
|
|
582
594
|
Unknown => 1,
|
|
583
595
|
Binary => 1,
|
|
584
596
|
},
|
|
585
|
-
#
|
|
597
|
+
# DJI videos also have block of offset/size of various atoms, eg)
|
|
598
|
+
# Atom name ???? Offset Size
|
|
599
|
+
# 0000: 63 6f 76 72 00 00 00 00 00 ed 6f da 00 0a 46 e0 [covr......o...F.]
|
|
600
|
+
# 0010: 73 6e 61 6c 00 00 00 00 00 f7 b6 d2 00 0a 46 e0 [snal..........F.]
|
|
601
|
+
# 0020: 68 67 6c 67 00 00 00 00 01 02 0a a2 00 00 00 21 [hglg...........!]
|
|
602
|
+
# 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
|
|
603
|
+
# (also Samsung WB750 uncompressed thumbnail data starting with "SDIC\0")
|
|
586
604
|
],
|
|
587
605
|
# fre1 - 4 bytes: "june" (Kodak PixPro SP360)
|
|
588
606
|
frea => {
|
|
@@ -10515,9 +10533,9 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
|
10515
10533
|
$et->Warn($warnStr);
|
|
10516
10534
|
}
|
|
10517
10535
|
}
|
|
10518
|
-
# tweak file type based on track content ("iso*" and "dash" ftyp only)
|
|
10536
|
+
# tweak file type based on track content ("iso*" and "dash" ftyp only ["mp42" added in 13.39])
|
|
10519
10537
|
if ($topLevel and $$et{FileType} and $$et{FileType} eq 'MP4' and
|
|
10520
|
-
$$et{save_ftyp} and $$et{HasHandler} and $$et{save_ftyp} =~ /^(iso|dash)/ and
|
|
10538
|
+
$$et{save_ftyp} and $$et{HasHandler} and $$et{save_ftyp} =~ /^(iso|dash|mp42)/ and
|
|
10521
10539
|
$$et{HasHandler}{soun} and not $$et{HasHandler}{vide})
|
|
10522
10540
|
{
|
|
10523
10541
|
$et->OverrideFileType('M4A', 'audio/mp4');
|
|
@@ -111,7 +111,7 @@ my %insvLimit = (
|
|
|
111
111
|
The tags below are extracted from timed metadata in QuickTime and other
|
|
112
112
|
formats of video files when the ExtractEmbedded option is used. Although
|
|
113
113
|
most of these tags are combined into the single table below, ExifTool
|
|
114
|
-
currently reads
|
|
114
|
+
currently reads 116 different types of timed GPS metadata from video files.
|
|
115
115
|
},
|
|
116
116
|
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
|
|
117
117
|
GPSLongitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")' },
|
|
@@ -1006,6 +1006,28 @@ sub HandleTextTags($$$)
|
|
|
1006
1006
|
undef %$tags; # clear the hash
|
|
1007
1007
|
}
|
|
1008
1008
|
|
|
1009
|
+
#------------------------------------------------------------------------------
|
|
1010
|
+
# Handle new time in NMEA stream and store queued tags if necessary
|
|
1011
|
+
# Inputs: 0) ExifTool ref, 1) time string, 2) tag table ref, 3) tags hash
|
|
1012
|
+
sub HandleNewTime($$$$)
|
|
1013
|
+
{
|
|
1014
|
+
my ($et, $time, $tagTbl, $tags) = @_;
|
|
1015
|
+
if ($$et{LastTime}) {
|
|
1016
|
+
if ($$et{LastTime} eq $time) {
|
|
1017
|
+
# combine with the previous NMEA sentence
|
|
1018
|
+
$$et{DOC_NUM} = $$et{LastDoc};
|
|
1019
|
+
} elsif (%$tags) {
|
|
1020
|
+
# handle existing tags and start a new document
|
|
1021
|
+
# (see https://exiftool.org/forum/index.php?msg=75422)
|
|
1022
|
+
HandleTextTags($et, $tagTbl, $tags);
|
|
1023
|
+
# increment document number and update document count if necessary
|
|
1024
|
+
$$et{DOC_COUNT} < ++$$et{DOC_NUM} and $$et{DOC_COUNT} = $$et{DOC_NUM};
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
$$et{LastTime} = $time;
|
|
1028
|
+
$$et{LastDoc} = $$et{DOC_NUM};
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1009
1031
|
#------------------------------------------------------------------------------
|
|
1010
1032
|
# Process subtitle 'text'
|
|
1011
1033
|
# Inputs: 0) ExifTool ref, 1) data ref or dirInfo ref, 2) tag table ref
|
|
@@ -1032,41 +1054,18 @@ sub Process_text($$$;$)
|
|
|
1032
1054
|
next;
|
|
1033
1055
|
}
|
|
1034
1056
|
my $time = "$1:$2:$3";
|
|
1035
|
-
|
|
1036
|
-
if ($$et{LastTime} eq $time) {
|
|
1037
|
-
# combine with the previous NMEA sentence
|
|
1038
|
-
$$et{DOC_NUM} = $$et{LastDoc};
|
|
1039
|
-
} elsif (%tags) {
|
|
1040
|
-
# handle existing tags and start a new document
|
|
1041
|
-
# (see https://exiftool.org/forum/index.php?msg=75422)
|
|
1042
|
-
HandleTextTags($et, $tagTbl, \%tags);
|
|
1043
|
-
undef %tags;
|
|
1044
|
-
# increment document number and update document count if necessary
|
|
1045
|
-
$$et{DOC_COUNT} < ++$$et{DOC_NUM} and $$et{DOC_COUNT} = $$et{DOC_NUM};
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
$$et{LastTime} = $time;
|
|
1049
|
-
$$et{LastDoc} = $$et{DOC_NUM};
|
|
1057
|
+
HandleNewTime($et, $time, $tagTbl, \%tags);
|
|
1050
1058
|
my $year = $14 + ($14 >= 70 ? 1900 : 2000);
|
|
1051
|
-
my $
|
|
1052
|
-
|
|
1059
|
+
my $date = sprintf('%.4d:%.2d:%.2d', $year, $13, $12);
|
|
1060
|
+
$$et{LastDate} = $date;
|
|
1061
|
+
$tags{GPSDateTime} = "$date ${time}Z";
|
|
1053
1062
|
$tags{GPSLatitude} = (($4 || 0) + $5/60) * ($6 eq 'N' ? 1 : -1);
|
|
1054
1063
|
$tags{GPSLongitude} = (($7 || 0) + $8/60) * ($9 eq 'E' ? 1 : -1);
|
|
1055
1064
|
$tags{GPSSpeed} = $10 * $knotsToKph if length $10;
|
|
1056
1065
|
$tags{GPSTrack} = $11 if length $11;
|
|
1057
1066
|
} elsif ($tag =~ /^[A-Z]{2}GGA$/ and $dat =~ /^,(\d{2})(\d{2})(\d+(?:\.\d*)?),(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),[1-6]?,(\d+)?,(\.\d+|\d+\.?\d*)?,(-?\d+\.?\d*)?,M?/s) {
|
|
1058
1067
|
my $time = "$1:$2:$3";
|
|
1059
|
-
|
|
1060
|
-
if ($$et{LastTime} eq $time) {
|
|
1061
|
-
$$et{DOC_NUM} = $$et{LastDoc};
|
|
1062
|
-
} elsif (%tags) {
|
|
1063
|
-
HandleTextTags($et, $tagTbl, \%tags);
|
|
1064
|
-
undef %tags;
|
|
1065
|
-
$$et{DOC_COUNT} < ++$$et{DOC_NUM} and $$et{DOC_COUNT} = $$et{DOC_NUM};
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
$$et{LastTime} = $time;
|
|
1069
|
-
$$et{LastDoc} = $$et{DOC_NUM};
|
|
1068
|
+
HandleNewTime($et, $time, $tagTbl, \%tags);
|
|
1070
1069
|
$tags{GPSTimeStamp} = $time;
|
|
1071
1070
|
$tags{GPSLatitude} = (($4 || 0) + $5/60) * ($6 eq 'N' ? 1 : -1);
|
|
1072
1071
|
$tags{GPSLongitude} = (($7 || 0) + $8/60) * ($9 eq 'E' ? 1 : -1);
|
|
@@ -1114,6 +1113,11 @@ sub Process_text($$$;$)
|
|
|
1114
1113
|
}
|
|
1115
1114
|
}
|
|
1116
1115
|
}
|
|
1116
|
+
if ($tags{GPSTimeStamp} and not $tags{GPSDateTime} and $$et{LastDate}) {
|
|
1117
|
+
# hack to fill in missing date for NextBase 662GW
|
|
1118
|
+
# (note: this doesn't necessarily handle day rollover properly)
|
|
1119
|
+
$tags{GPSDateTime} = "$$et{LastDate} $tags{GPSTimeStamp}Z";
|
|
1120
|
+
}
|
|
1117
1121
|
HandleTextTags($et, $tagTbl, \%tags);
|
|
1118
1122
|
return;
|
|
1119
1123
|
}
|
|
@@ -3490,14 +3494,17 @@ sub ProcessGarminGPS($$$)
|
|
|
3490
3494
|
while ($pos + 20 <= $dataLen) {
|
|
3491
3495
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
|
3492
3496
|
my $time = Image::ExifTool::ConvertUnixTime(Get32u($dataPt, $pos) - $epoch) . 'Z';
|
|
3493
|
-
my $lat = Get32s($dataPt, $pos + 12)
|
|
3494
|
-
my $lon = Get32s($dataPt, $pos + 16)
|
|
3497
|
+
my $lat = Get32s($dataPt, $pos + 12);
|
|
3498
|
+
my $lon = Get32s($dataPt, $pos + 16);
|
|
3495
3499
|
my $spd = Get16u($dataPt, $pos + 4); # (in mph)
|
|
3496
3500
|
$et->HandleTag($tagTbl, 'GPSDateTime', $time);
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
+
# skip bad GPS fixes
|
|
3502
|
+
if ($lat != -2147483648 or $lon != -2147483648) {
|
|
3503
|
+
$et->HandleTag($tagTbl, 'GPSLatitude', $lat * $scl);
|
|
3504
|
+
$et->HandleTag($tagTbl, 'GPSLongitude', $lon * $scl);
|
|
3505
|
+
$et->HandleTag($tagTbl, 'GPSSpeed', $spd);
|
|
3506
|
+
$et->HandleTag($tagTbl, 'GPSSpeedRef', 'M');
|
|
3507
|
+
}
|
|
3501
3508
|
$pos += 20;
|
|
3502
3509
|
}
|
|
3503
3510
|
delete $$et{DOC_NUM};
|
|
@@ -14,7 +14,7 @@ use strict;
|
|
|
14
14
|
use vars qw($VERSION);
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.02';
|
|
18
18
|
|
|
19
19
|
sub ProcessR3D($$);
|
|
20
20
|
|
|
@@ -45,7 +45,8 @@ my $errTrunc = 'Truncated R3D file';
|
|
|
45
45
|
RED2 => { Name => 'Red2Header', SubDirectory => { TagTable => 'Image::ExifTool::Red::RED2' } },
|
|
46
46
|
|
|
47
47
|
# (upper 4 bits of tag ID are the format code)
|
|
48
|
-
# ---- format
|
|
48
|
+
# ---- format 0 (int8u) ----
|
|
49
|
+
# ---- format 1 (string) ----
|
|
49
50
|
0x1000 => 'StartEdgeCode', #1
|
|
50
51
|
0x1001 => { Name => 'StartTimecode', Groups => { 2 => 'Time' } }, #1
|
|
51
52
|
0x1002 => { #1
|
|
@@ -104,6 +105,7 @@ my $errTrunc = 'Truncated R3D file';
|
|
|
104
105
|
# 0x1041 - seen 'NA'
|
|
105
106
|
0x1042 => 'Revision', # ? (seen "TODO, rev EPIC-1.0" and "MYSTERIUM X, rev EPIC-1.0")
|
|
106
107
|
# 0x1051 - seen 'C', 'L'
|
|
108
|
+
# 0x1052 - seen 'E9'
|
|
107
109
|
0x1056 => 'OriginalFileName',
|
|
108
110
|
0x106e => 'LensMake',
|
|
109
111
|
0x106f => 'LensNumber', # (last 2 hex digits are LensType)
|
|
@@ -120,7 +122,8 @@ my $errTrunc = 'Truncated R3D file';
|
|
|
120
122
|
0x1096 => 'Filter', # optical low-pass filter
|
|
121
123
|
0x10a0 => 'Brain',
|
|
122
124
|
0x10a1 => 'Sensor',
|
|
123
|
-
|
|
125
|
+
0x10be => 'Quality',
|
|
126
|
+
# ---- format 2 (float) ----
|
|
124
127
|
0x200d => 'ColorTemperature',
|
|
125
128
|
# 0x200e - (sometimes this is frame rate)
|
|
126
129
|
# 0x2015 - seen '1 1 1' (RGBGain or RGBGamma?)
|
|
@@ -130,7 +133,8 @@ my $errTrunc = 'Truncated R3D file';
|
|
|
130
133
|
Groups => { 2 => 'Video' },
|
|
131
134
|
PrintConv => 'int($val * 1000 + 0.5) / 1000',
|
|
132
135
|
},
|
|
133
|
-
# ---- format
|
|
136
|
+
# ---- format 3 (int8u?) ----
|
|
137
|
+
# ---- format 4 (int16u) ----
|
|
134
138
|
0x4037 => { Name => 'CropArea' }, # (NC)
|
|
135
139
|
0x403b => 'ISO',
|
|
136
140
|
# 0x404e - related to CropArea (or "0 0 0 0")
|
|
@@ -138,8 +142,12 @@ my $errTrunc = 'Truncated R3D file';
|
|
|
138
142
|
0x406b => 'FocalLength',
|
|
139
143
|
# 0x4084 - related to ISO?
|
|
140
144
|
# 0x4087 - related to ISO?
|
|
141
|
-
# ---- format
|
|
145
|
+
# ---- format 5 (int8s?) ----
|
|
146
|
+
# ---- format 6 (int32s) ----
|
|
142
147
|
0x606c => { Name => 'FocusDistance', ValueConv => '$val/1000', PrintConv => '"$val m"' },
|
|
148
|
+
# ---- format 7 (undef? structure?) ----
|
|
149
|
+
# ---- format 8 (int32u?) ----
|
|
150
|
+
# ---- format 9 (undef?) ----
|
|
143
151
|
);
|
|
144
152
|
|
|
145
153
|
# RED1 file header (ref PH)
|
|
@@ -240,9 +248,11 @@ sub ProcessR3D($$)
|
|
|
240
248
|
$pos = 0x22; # directory starts at offset 0x22
|
|
241
249
|
} else {
|
|
242
250
|
# calculate position of Red directory start
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
$pos
|
|
251
|
+
$pos = 0x44;
|
|
252
|
+
length($buff) < $pos and return $et->Warn($errTrunc);
|
|
253
|
+
$pos += Get8u(\$buff, 0x40) * 0x18; # skip "rdi" records
|
|
254
|
+
$pos += Get8u(\$buff, 0x41) * 0x14; # skip "rda" records
|
|
255
|
+
$pos += Get8u(\$buff, 0x42) * 0x10; # skip "rdx" records
|
|
246
256
|
}
|
|
247
257
|
if ($pos + 8 > length $buff) {
|
|
248
258
|
$dirLen = 0; # find directory the hard way
|
|
@@ -253,7 +263,7 @@ sub ProcessR3D($$)
|
|
|
253
263
|
# do sanity check on the directory size (in case our assumptions were wrong)
|
|
254
264
|
if ($dirLen < 300 or $dirLen >= 2048 or $pos + $dirLen > length $buff) {
|
|
255
265
|
# tag 0x1000 with length 0x000f should be near the directory start
|
|
256
|
-
$buff =~ /\0\x0f\x10\0/g or return $et->Warn("Can't find Red directory");
|
|
266
|
+
$buff =~ /\0\x0f\x10[\0\x06]/g or return $et->Warn("Can't find Red directory. Please submit sample for testing");
|
|
257
267
|
$pos = pos($buff) - 4;
|
|
258
268
|
$dirEnd = length $buff;
|
|
259
269
|
undef $dirLen;
|
|
@@ -34,7 +34,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
34
34
|
use Image::ExifTool::Exif;
|
|
35
35
|
use Image::ExifTool::Minolta;
|
|
36
36
|
|
|
37
|
-
$VERSION = '3.
|
|
37
|
+
$VERSION = '3.79';
|
|
38
38
|
|
|
39
39
|
sub ProcessSRF($$$);
|
|
40
40
|
sub ProcessSR2($$$);
|
|
@@ -180,6 +180,9 @@ sub PrintInvLensSpec($;$$);
|
|
|
180
180
|
32889 => 'Sony FE 28-70mm F2 GM',
|
|
181
181
|
32890 => 'Sony FE 400-800mm F6.3-8 G OSS', #JR
|
|
182
182
|
32891 => 'Sony FE 50-150mm F2 GM', #github335
|
|
183
|
+
32893 => 'Sony FE 100mm F2.8 Macro GM OSS', #JR
|
|
184
|
+
33093 => 'Sony FE 100mm F2.8 Macro GM OSS + 1.4X Teleconverter', #JR (NC)
|
|
185
|
+
33094 => 'Sony FE 100mm F2.8 Macro GM OSS + 2X Teleconverter', #JR
|
|
183
186
|
|
|
184
187
|
# (comment this out so LensID will report the LensModel, which is more useful)
|
|
185
188
|
# 32952 => 'Metabones Canon EF Speed Booster Ultra', #JR (corresponds to 184, but 'Advanced' mode, LensMount reported as E-mount)
|
|
@@ -1135,7 +1138,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
1135
1138
|
SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010h' },
|
|
1136
1139
|
},{
|
|
1137
1140
|
Name => 'Tag2010i', # ?
|
|
1138
|
-
Condition => '$$self{Model} =~ /^(ILCE-(6100A?|6400A?|6600|7C|7M3|7RM3A?|7RM4A?|9|9M2)|DSC-(RX10M4|RX100M6|RX100M5A|
|
|
1141
|
+
Condition => '$$self{Model} =~ /^(ILCE-(6100A?|6400A?|6600|7C|7M3|7RM3A?|7RM4A?|9|9M2)|DSC-(RX10M4|RX100M6|RX100M5A|RX100M7A?|HX95|HX99|RX0M2)|ZV-(1[AF]?|1M2|E10))\b/',
|
|
1139
1142
|
SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010i' },
|
|
1140
1143
|
},{
|
|
1141
1144
|
Name => 'Tag_0x2010',
|
|
@@ -2209,8 +2212,10 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
2209
2212
|
400 => 'ILCE-1M2', #PH
|
|
2210
2213
|
401 => 'DSC-RX1RM3', #JR
|
|
2211
2214
|
402 => 'ILCE-6400A', #github347
|
|
2215
|
+
403 => 'ILCE-6100A', #JR
|
|
2212
2216
|
404 => 'DSC-RX100M7A', #github347
|
|
2213
2217
|
406 => 'ILME-FX2', #JR
|
|
2218
|
+
408 => 'ZV-1A', #JR
|
|
2214
2219
|
},
|
|
2215
2220
|
},
|
|
2216
2221
|
0xb020 => { #2
|
|
@@ -8525,7 +8530,7 @@ my %isoSetting2010 = (
|
|
|
8525
8530
|
},
|
|
8526
8531
|
0x002a => [{
|
|
8527
8532
|
Name => 'Quality2',
|
|
8528
|
-
Condition => '$$self{Model} !~ /^(DSC-RX1RM3|ILCE-(1|1M2|6700|7CM2|7CR|7M4|7RM5|7SM3|9M3)|ILME-(FX2|
|
|
8533
|
+
Condition => '$$self{Model} !~ /^(DSC-RX1RM3|ILCE-(1|1M2|6700|7CM2|7CR|7M4|7RM5|7SM3|9M3)|ILME-(FX2|FX3A?|FX30)|ZV-(E1|E10M2))\b/',
|
|
8529
8534
|
PrintConv => {
|
|
8530
8535
|
0 => 'JPEG',
|
|
8531
8536
|
1 => 'RAW',
|
|
@@ -8544,13 +8549,13 @@ my %isoSetting2010 = (
|
|
|
8544
8549
|
}],
|
|
8545
8550
|
# 0x0047 => { # often incorrect, requires 16x for some models
|
|
8546
8551
|
# Name => 'SonyImageHeight',
|
|
8547
|
-
# Condition => '$$self{Model} !~ /^(ILCE-(1|6700|7CM2|7CR|7M4|7RM5|7SM3|9M3)|ILME-(
|
|
8552
|
+
# Condition => '$$self{Model} !~ /^(ILCE-(1|6700|7CM2|7CR|7M4|7RM5|7SM3|9M3)|ILME-(FX3A?|FX30)|ZV-E1)\b/',
|
|
8548
8553
|
# Format => 'int16u',
|
|
8549
8554
|
# PrintConv => '$val > 0 ? 8*$val : "n.a."',
|
|
8550
8555
|
# },
|
|
8551
8556
|
0x0053 => {
|
|
8552
8557
|
Name => 'ModelReleaseYear',
|
|
8553
|
-
Condition => '$$self{Model} !~ /^(DSC-RX1RM3|ILCE-(1|6700|7CM2|7CR|7M4|7RM5|7SM3|9M3)|ILME-(FX2|
|
|
8558
|
+
Condition => '$$self{Model} !~ /^(DSC-RX1RM3|ILCE-(1|6700|7CM2|7CR|7M4|7RM5|7SM3|9M3)|ILME-(FX2|FX3A?|FX30)|ZV-(E1|E10M2))\b/',
|
|
8554
8559
|
Format => 'int8u',
|
|
8555
8560
|
PrintConv => 'sprintf("20%.2d", $val)',
|
|
8556
8561
|
},
|
|
@@ -8572,7 +8577,7 @@ my %isoSetting2010 = (
|
|
|
8572
8577
|
},
|
|
8573
8578
|
0x013f => {
|
|
8574
8579
|
Name => 'ShutterType',
|
|
8575
|
-
Condition => '$$self{Model} =~ /^(DSC-
|
|
8580
|
+
Condition => '$$self{Model} =~ /^(DSC-RX100M7A?|ZV-(1A?|1F|1M2))\b/',
|
|
8576
8581
|
PrintConv => {
|
|
8577
8582
|
7 => 'Electronic',
|
|
8578
8583
|
23 => 'Mechanical',
|
|
@@ -10087,7 +10092,7 @@ my %isoSetting2010 = (
|
|
|
10087
10092
|
},
|
|
10088
10093
|
0x088f => {
|
|
10089
10094
|
Name => 'VignettingCorrParams',
|
|
10090
|
-
Condition => '$$self{Model} =~ /^(ILCE-(1|7SM3)|ILME-
|
|
10095
|
+
Condition => '$$self{Model} =~ /^(ILCE-(1|7SM3)|ILME-FX3A?)\b/',
|
|
10091
10096
|
Format => 'int16s[16]',
|
|
10092
10097
|
},
|
|
10093
10098
|
0x0891 => {
|
|
@@ -10102,7 +10107,7 @@ my %isoSetting2010 = (
|
|
|
10102
10107
|
},
|
|
10103
10108
|
0x08b5 => {
|
|
10104
10109
|
Name => 'APS-CSizeCapture',
|
|
10105
|
-
Condition => '$$self{Model} =~ /^(ILCE-(1|7SM3)|ILME-
|
|
10110
|
+
Condition => '$$self{Model} =~ /^(ILCE-(1|7SM3)|ILME-FX3A?)\b/',
|
|
10106
10111
|
PrintConv => {
|
|
10107
10112
|
0 => 'Off',
|
|
10108
10113
|
1 => 'On',
|
|
@@ -10126,7 +10131,7 @@ my %isoSetting2010 = (
|
|
|
10126
10131
|
},
|
|
10127
10132
|
0x0914 => {
|
|
10128
10133
|
Name => 'ChromaticAberrationCorrParams',
|
|
10129
|
-
Condition => '$$self{Model} =~ /^(ILCE-(1|7SM3)|ILME-
|
|
10134
|
+
Condition => '$$self{Model} =~ /^(ILCE-(1|7SM3)|ILME-FX3A?)\b/',
|
|
10130
10135
|
Format => 'int16s[32]',
|
|
10131
10136
|
},
|
|
10132
10137
|
0x0916 => {
|