exiftool-vendored.pl 12.97.0 → 13.0.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 +48 -2
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +2 -2
- package/bin/arg_files/exif2xmp.args +4 -0
- package/bin/arg_files/xmp2exif.args +4 -0
- package/bin/config_files/example.config +2 -1
- package/bin/exiftool +255 -54
- package/bin/lib/File/RandomAccess.pm +5 -2
- package/bin/lib/Image/ExifTool/APP12.pm +3 -2
- package/bin/lib/Image/ExifTool/Canon.pm +2 -1
- package/bin/lib/Image/ExifTool/Exif.pm +1 -1
- package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/lib/Image/ExifTool/Geotag.pm +4 -3
- package/bin/lib/Image/ExifTool/Import.pm +7 -3
- package/bin/lib/Image/ExifTool/InDesign.pm +4 -3
- package/bin/lib/Image/ExifTool/JSON.pm +3 -4
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -1
- package/bin/lib/Image/ExifTool/Lytro.pm +2 -2
- package/bin/lib/Image/ExifTool/M2TS.pm +10 -2
- package/bin/lib/Image/ExifTool/PhaseOne.pm +2 -1
- package/bin/lib/Image/ExifTool/QuickTime.pm +17 -6
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +88 -9
- package/bin/lib/Image/ExifTool/Sony.pm +6 -1
- package/bin/lib/Image/ExifTool/TagLookup.pm +14 -9
- package/bin/lib/Image/ExifTool/TagNames.pod +40 -23
- package/bin/lib/Image/ExifTool/WritePDF.pl +47 -21
- package/bin/lib/Image/ExifTool/WriteXMP.pl +16 -4
- package/bin/lib/Image/ExifTool/Writer.pl +16 -6
- package/bin/lib/Image/ExifTool/XMP.pm +19 -4
- package/bin/lib/Image/ExifTool/XMPStruct.pl +15 -7
- package/bin/lib/Image/ExifTool.pm +37 -12
- package/bin/lib/Image/ExifTool.pod +31 -8
- package/bin/perl-Image-ExifTool.spec +1 -1
- package/bin/pp_build_exe.args +4 -4
- package/bin/windows_exiftool.txt +32 -10
- package/package.json +3 -3
|
@@ -41,7 +41,7 @@ require 5.002;
|
|
|
41
41
|
require Exporter;
|
|
42
42
|
|
|
43
43
|
use vars qw($VERSION @ISA @EXPORT_OK);
|
|
44
|
-
$VERSION = '1.
|
|
44
|
+
$VERSION = '1.13';
|
|
45
45
|
@ISA = qw(Exporter);
|
|
46
46
|
|
|
47
47
|
sub Read($$$);
|
|
@@ -158,7 +158,10 @@ sub Seek($$;$)
|
|
|
158
158
|
$self->Slurp(); # read whole file into buffer
|
|
159
159
|
$newPos = $num + $self->{LEN}; # relative to end of file
|
|
160
160
|
}
|
|
161
|
-
if ($newPos >= 0
|
|
161
|
+
if ($newPos >= 0 and
|
|
162
|
+
# can't go backwards in unbuffered non-seekable file
|
|
163
|
+
(not $self->{NoBuffer} or $newPos >= $self->{POS}))
|
|
164
|
+
{
|
|
162
165
|
$self->{POS} = $newPos;
|
|
163
166
|
$rtnVal = 1;
|
|
164
167
|
}
|
|
@@ -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.14';
|
|
18
18
|
|
|
19
19
|
sub ProcessAPP12($$$);
|
|
20
20
|
sub ProcessDucky($$$);
|
|
@@ -72,7 +72,7 @@ sub WriteDucky($$$);
|
|
|
72
72
|
StrobeTime => { },
|
|
73
73
|
Resolution => { },
|
|
74
74
|
Protect => { },
|
|
75
|
-
|
|
75
|
+
ContTake => { },
|
|
76
76
|
ImageSize => { PrintConv => '$val=~tr/-/x/;$val' },
|
|
77
77
|
ColorMode => { },
|
|
78
78
|
Zoom => { },
|
|
@@ -278,6 +278,7 @@ sub ProcessAPP12($$$)
|
|
|
278
278
|
$tagInfo = { Name => ucfirst $tag };
|
|
279
279
|
# put in Camera group if information in "Camera" section
|
|
280
280
|
$$tagInfo{Groups} = { 2 => 'Camera' } if $section =~ /camera/i;
|
|
281
|
+
$et->VPrint(0, $$et{INDENT}, "[adding APP12:$$tagInfo{Name}]\n");
|
|
281
282
|
AddTagToTable($tagTablePtr, $tag, $tagInfo);
|
|
282
283
|
}
|
|
283
284
|
$et->FoundTag($tagInfo, $val);
|
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
|
88
88
|
sub ProcessExifInfo($$$);
|
|
89
89
|
sub SwapWords($);
|
|
90
90
|
|
|
91
|
-
$VERSION = '4.
|
|
91
|
+
$VERSION = '4.82';
|
|
92
92
|
|
|
93
93
|
# Note: Removed 'USM' from 'L' lenses since it is redundant - PH
|
|
94
94
|
# (or is it? Ref 32 shows 5 non-USM L-type lenses)
|
|
@@ -6999,6 +6999,7 @@ my %ciMaxFocal = (
|
|
|
6999
6999
|
314 => 'Canon RF 24-105mm F2.8 L IS USM Z', #42
|
|
7000
7000
|
315 => 'Canon RF-S 10-18mm F4.5-6.3 IS STM', #42
|
|
7001
7001
|
316 => 'Canon RF 35mm F1.4 L VCM', #42
|
|
7002
|
+
317 => 'Canon RF-S 3.9mm F3.5 STM DUAL FISHEYE', #42
|
|
7002
7003
|
318 => 'Canon RF 28-70mm F2.8 IS STM', #42
|
|
7003
7004
|
# Note: add new RF lenses to %canonLensTypes with ID 61182
|
|
7004
7005
|
},
|
|
@@ -2931,7 +2931,7 @@ my %opcodeInfo = (
|
|
|
2931
2931
|
0xa433 => { Name => 'LensMake', Writable => 'string' }, #24
|
|
2932
2932
|
0xa434 => { Name => 'LensModel', Writable => 'string' }, #24
|
|
2933
2933
|
0xa435 => { Name => 'LensSerialNumber', Writable => 'string' }, #24
|
|
2934
|
-
0xa436 => { Name => '
|
|
2934
|
+
0xa436 => { Name => 'ImageTitle', Writable => 'string' }, #33
|
|
2935
2935
|
0xa437 => { Name => 'Photographer', Writable => 'string' }, #33
|
|
2936
2936
|
0xa438 => { Name => 'ImageEditor', Writable => 'string' }, #33
|
|
2937
2937
|
0xa439 => { Name => 'CameraFirmware', Writable => 'string' }, #33
|
|
Binary file
|
|
@@ -31,7 +31,7 @@ use vars qw($VERSION);
|
|
|
31
31
|
use Image::ExifTool qw(:Public);
|
|
32
32
|
use Image::ExifTool::GPS;
|
|
33
33
|
|
|
34
|
-
$VERSION = '1.
|
|
34
|
+
$VERSION = '1.79';
|
|
35
35
|
|
|
36
36
|
sub JITTER() { return 2 } # maximum time jitter
|
|
37
37
|
|
|
@@ -1127,8 +1127,9 @@ sub SetGeoValues($$;$)
|
|
|
1127
1127
|
$iExt = $i1;
|
|
1128
1128
|
}
|
|
1129
1129
|
if (abs($time - $tn) > $geoMaxExtSecs) {
|
|
1130
|
-
$err or $err = 'Time is too far from nearest GPS fix'
|
|
1131
|
-
$et->VPrint(2, ' Nearest fix: ', PrintFixTime($tn),
|
|
1130
|
+
$err or $err = 'Time is too far from nearest GPS fix';
|
|
1131
|
+
$et->VPrint(2, ' Nearest fix: ', PrintFixTime($tn), ' (',
|
|
1132
|
+
int(abs $time-$tn), " sec away)\n") if $verbose > 2;
|
|
1132
1133
|
$fix = { } if $$geotag{DateTimeOnly};
|
|
1133
1134
|
} else {
|
|
1134
1135
|
$fix = $$points{$tn};
|
|
@@ -12,7 +12,7 @@ require Exporter;
|
|
|
12
12
|
|
|
13
13
|
use vars qw($VERSION @ISA @EXPORT_OK);
|
|
14
14
|
|
|
15
|
-
$VERSION = '1.
|
|
15
|
+
$VERSION = '1.13';
|
|
16
16
|
@ISA = qw(Exporter);
|
|
17
17
|
@EXPORT_OK = qw(ReadCSV ReadJSON);
|
|
18
18
|
|
|
@@ -87,6 +87,7 @@ sub ReadCSV($$;$$)
|
|
|
87
87
|
$fileInfo{$tags[$i]} =
|
|
88
88
|
(defined $missingValue and $vals[$i] eq $missingValue) ? undef : $vals[$i];
|
|
89
89
|
}
|
|
90
|
+
$fileInfo{_ordered_keys_} = \@tags;
|
|
90
91
|
# figure out the file name to use
|
|
91
92
|
if ($fileInfo{SourceFile}) {
|
|
92
93
|
$$database{$fileInfo{SourceFile}} = \%fileInfo;
|
|
@@ -173,7 +174,7 @@ Tok: for (;;) {
|
|
|
173
174
|
}
|
|
174
175
|
# see what type of object this is
|
|
175
176
|
if ($tok eq '{') { # object (hash)
|
|
176
|
-
$rtnVal = { } unless defined $rtnVal;
|
|
177
|
+
$rtnVal = { _ordered_keys_ => [ ] } unless defined $rtnVal;
|
|
177
178
|
for (;;) {
|
|
178
179
|
# read "KEY":"VALUE" pairs
|
|
179
180
|
unless (defined $key) {
|
|
@@ -189,6 +190,7 @@ Tok: for (;;) {
|
|
|
189
190
|
$pos = pos $$buffPt;
|
|
190
191
|
return undef unless defined $val;
|
|
191
192
|
$$rtnVal{$key} = $val;
|
|
193
|
+
push @{$$rtnVal{_ordered_keys_}}, $key;
|
|
192
194
|
undef $key;
|
|
193
195
|
}
|
|
194
196
|
# scan to delimiting ',' or bounding '}'
|
|
@@ -345,7 +347,9 @@ option for a list of valid character sets.
|
|
|
345
347
|
These functions return an error string, or undef on success and populate the
|
|
346
348
|
database hash with entries from the CSV or JSON file. Entries are keyed
|
|
347
349
|
based on the SourceFile column of the CSV or JSON information, and are
|
|
348
|
-
stored as hash lookups of tag name/value for each SourceFile.
|
|
350
|
+
stored as hash lookups of tag name/value for each SourceFile. The order
|
|
351
|
+
of the keys (CSV column order or order in a JSON object) is stored as an
|
|
352
|
+
ARRAY reference in a special "_ordered_keys_" element of this hash.
|
|
349
353
|
|
|
350
354
|
=back
|
|
351
355
|
|
|
@@ -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.09';
|
|
18
18
|
|
|
19
19
|
# map for writing metadata to InDesign files (currently only write XMP)
|
|
20
20
|
my %indMap = (
|
|
@@ -104,9 +104,10 @@ sub ProcessIND($$)
|
|
|
104
104
|
# this must be null padding or we have a possible error
|
|
105
105
|
last if $hdr =~ /^\0+$/;
|
|
106
106
|
# (could be up to 4095 bytes of non-null garbage plus 4095 null bytes from ExifTool)
|
|
107
|
-
$raf->Read($buff,
|
|
107
|
+
$raf->Read($buff, 8192) and $hdr .= $buff;
|
|
108
|
+
my $n = length $hdr;
|
|
108
109
|
$hdr =~ s/\0+$//; # remove trailing nulls
|
|
109
|
-
if (length($hdr) > 4095) {
|
|
110
|
+
if ($n > 8190 or length($hdr) > 4095) {
|
|
110
111
|
$err = 'Corrupt file or unsupported InDesign version';
|
|
111
112
|
last;
|
|
112
113
|
}
|
|
@@ -14,7 +14,7 @@ use vars qw($VERSION);
|
|
|
14
14
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
15
15
|
use Image::ExifTool::Import;
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.09';
|
|
18
18
|
|
|
19
19
|
sub ProcessJSON($$);
|
|
20
20
|
sub ProcessTag($$$$%);
|
|
@@ -92,8 +92,7 @@ sub ProcessTag($$$$%)
|
|
|
92
92
|
return unless $et->Options('Struct') > 1;
|
|
93
93
|
}
|
|
94
94
|
# support hashes with ordered keys
|
|
95
|
-
|
|
96
|
-
foreach (@keys) {
|
|
95
|
+
foreach (Image::ExifTool::OrderedKeys($val)) {
|
|
97
96
|
my $tg = $tag . ((/^\d/ and $tag =~ /\d$/) ? '_' : '') . ucfirst;
|
|
98
97
|
$tg =~ s/([^a-zA-Z])([a-z])/$1\U$2/g;
|
|
99
98
|
ProcessTag($et, $tagTablePtr, $tg, $$val{$_}, %flags, Flat => 1);
|
|
@@ -155,7 +154,7 @@ sub ProcessJSON($$)
|
|
|
155
154
|
|
|
156
155
|
# extract tags from JSON database
|
|
157
156
|
foreach $key (sort keys %database) {
|
|
158
|
-
foreach $tag (
|
|
157
|
+
foreach $tag (Image::ExifTool::OrderedKeys($database{$key})) {
|
|
159
158
|
my $val = $database{$key}{$tag};
|
|
160
159
|
# (ignore SourceFile if generated automatically by ReadJSON)
|
|
161
160
|
next if $tag eq 'SourceFile' and defined $val and $val eq '*';
|
|
@@ -16,7 +16,7 @@ use strict;
|
|
|
16
16
|
use vars qw($VERSION);
|
|
17
17
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
18
18
|
|
|
19
|
-
$VERSION = '1.
|
|
19
|
+
$VERSION = '1.41';
|
|
20
20
|
|
|
21
21
|
sub ProcessJpeg2000Box($$$);
|
|
22
22
|
sub ProcessJUMD($$$);
|
|
@@ -574,6 +574,7 @@ my %j2cMarker = (
|
|
|
574
574
|
2 => {
|
|
575
575
|
Name => 'CompatibleBrands',
|
|
576
576
|
Format => 'undef[$size-8]',
|
|
577
|
+
List => 1, # (for documentation only)
|
|
577
578
|
# ignore any entry with a null, and return others as a list
|
|
578
579
|
ValueConv => 'my @a=($val=~/.{4}/sg); @a=grep(!/\0/,@a); \@a',
|
|
579
580
|
},
|
|
@@ -15,7 +15,7 @@ use vars qw($VERSION);
|
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
16
|
use Image::ExifTool::Import;
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.04';
|
|
19
19
|
|
|
20
20
|
sub ExtractTags($$$);
|
|
21
21
|
|
|
@@ -106,7 +106,7 @@ sub ExtractTags($$$)
|
|
|
106
106
|
my ($et, $meta, $parent) = @_;
|
|
107
107
|
ref $meta eq 'HASH' or $et->Warn('Invalid LFP metadata'), return;
|
|
108
108
|
my ($key, $val, $name, $tagTablePtr);
|
|
109
|
-
foreach $key (
|
|
109
|
+
foreach $key (Image::ExifTool::OrderedKeys($meta)) {
|
|
110
110
|
my $tag = $parent . ucfirst($key);
|
|
111
111
|
foreach $val (ref $$meta{$key} eq 'ARRAY' ? @{$$meta{$key}} : $$meta{$key}) {
|
|
112
112
|
ref $val eq 'HASH' and ExtractTags($et, $val, $tag), next;
|
|
@@ -32,7 +32,7 @@ use strict;
|
|
|
32
32
|
use vars qw($VERSION);
|
|
33
33
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
34
34
|
|
|
35
|
-
$VERSION = '1.
|
|
35
|
+
$VERSION = '1.26';
|
|
36
36
|
|
|
37
37
|
# program map table "stream_type" lookup (ref 6/1/9)
|
|
38
38
|
my %streamType = (
|
|
@@ -82,7 +82,7 @@ my %streamType = (
|
|
|
82
82
|
0x86 => 'DTS-HD Audio',
|
|
83
83
|
0x87 => 'E-AC-3 Audio',
|
|
84
84
|
0x8a => 'DTS Audio',
|
|
85
|
-
0x90 => '
|
|
85
|
+
0x90 => 'Presentation Graphic Stream (subtitle)', #https://en.wikipedia.org/wiki/Program-specific_information
|
|
86
86
|
0x91 => 'A52b/AC-3 Audio',
|
|
87
87
|
0x92 => 'DVD_SPU vls Subtitle',
|
|
88
88
|
0x94 => 'SDDS Audio',
|
|
@@ -328,6 +328,14 @@ sub ParsePID($$$$$)
|
|
|
328
328
|
$more = 1; # read past unknown 0x15 packets if ExtractEmbedded > 2
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
|
+
# still have a lot of questions about how to decode this...
|
|
332
|
+
# (see https://exiftool.org/forum/index.php?topic=16486 and ../testpics/gps_video/forum16486.ts)
|
|
333
|
+
# } elsif ($type == 6) {
|
|
334
|
+
# my @a = unpack('x17x2NNx2nx2nx2nx2Cx2a4x2a5x2Nx2Nx2nx2Nx2Nx2Nx2nx2nx2Nx2nx2n', $$dataPt . " ");
|
|
335
|
+
# my $hi = shift @a;
|
|
336
|
+
# $a[0] = Image::ExifTool::ConvertUnixTime(($a[0] + $hi * 4294967296) * 1e-6, undef, 6);
|
|
337
|
+
# print "@a\n";
|
|
338
|
+
# $more = 1;
|
|
331
339
|
} elsif ($type < 0) {
|
|
332
340
|
if ($$dataPt =~ /^(.{164})?(.{24})A[NS][EW]/s) {
|
|
333
341
|
# (Blueskysea B4K, Novatek NT96670)
|
|
@@ -15,7 +15,7 @@ use vars qw($VERSION);
|
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
16
|
use Image::ExifTool::Exif;
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.11';
|
|
19
19
|
|
|
20
20
|
sub WritePhaseOne($$$);
|
|
21
21
|
sub ProcessPhaseOne($$$);
|
|
@@ -71,6 +71,7 @@ my @formatName = ( undef, 'string', 'int16s', undef, 'int32s' );
|
|
|
71
71
|
# >2 = compressed
|
|
72
72
|
# 5 = non-linear
|
|
73
73
|
PrintConv => { #PH
|
|
74
|
+
0 => 'Uncompressed', #https://github.com/darktable-org/darktable/issues/7308
|
|
74
75
|
1 => 'RAW 1', #? (encrypted)
|
|
75
76
|
2 => 'RAW 2', #? (encrypted)
|
|
76
77
|
3 => 'IIQ L', # (now "L14", ref IB)
|
|
@@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
48
48
|
use Image::ExifTool::Exif;
|
|
49
49
|
use Image::ExifTool::GPS;
|
|
50
50
|
|
|
51
|
-
$VERSION = '3.
|
|
51
|
+
$VERSION = '3.04';
|
|
52
52
|
|
|
53
53
|
sub ProcessMOV($$;$);
|
|
54
54
|
sub ProcessKeys($$$);
|
|
@@ -901,6 +901,7 @@ my %userDefined = (
|
|
|
901
901
|
Writable => 1,
|
|
902
902
|
},
|
|
903
903
|
# '35AX'? - seen "AT" (Yada RoadCam Pro 4K dashcam)
|
|
904
|
+
cust => 'CustomInfo', # 70mai A810
|
|
904
905
|
);
|
|
905
906
|
|
|
906
907
|
# stuff seen in 'skip' atom (70mai Pro Plus+ MP4 videos)
|
|
@@ -935,6 +936,7 @@ my %userDefined = (
|
|
|
935
936
|
2 => {
|
|
936
937
|
Name => 'CompatibleBrands',
|
|
937
938
|
Format => 'undef[$size-8]',
|
|
939
|
+
List => 1, # (for documentation only)
|
|
938
940
|
# ignore any entry with a null, and return others as a list
|
|
939
941
|
ValueConv => 'my @a=($val=~/.{4}/sg); @a=grep(!/\0/,@a); \@a',
|
|
940
942
|
},
|
|
@@ -2551,7 +2553,7 @@ my %userDefined = (
|
|
|
2551
2553
|
TTID => { Name => 'TomTomID', ValueConv => 'unpack("x4H*",$val)' },
|
|
2552
2554
|
TTVI => { Name => 'TomTomVI', Format => 'int32u', Unknown => 1 }, # seen: "0 1 61 508 508"
|
|
2553
2555
|
# TTVD seen: "normal 720p 60fps 60fps 16/9 wide 1x"
|
|
2554
|
-
TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\x7f]+/g); "@a"' },
|
|
2556
|
+
TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\x7f]+/g); "@a"', List => 1 },
|
|
2555
2557
|
);
|
|
2556
2558
|
|
|
2557
2559
|
# User-specific media data atoms (ref 11)
|
|
@@ -3350,6 +3352,7 @@ my %userDefined = (
|
|
|
3350
3352
|
PrintConv => '"Track $val"',
|
|
3351
3353
|
},
|
|
3352
3354
|
# cdep (Structural Dependency QT tag?)
|
|
3355
|
+
# fall - ? int32u, seen: 2
|
|
3353
3356
|
);
|
|
3354
3357
|
|
|
3355
3358
|
# track aperture mode dimensions atoms
|
|
@@ -6743,6 +6746,13 @@ my %userDefined = (
|
|
|
6743
6746
|
Avoid => 1,
|
|
6744
6747
|
%iso8601Date,
|
|
6745
6748
|
},
|
|
6749
|
+
# (mdta)com.apple.quicktime.scene-illuminance
|
|
6750
|
+
'scene-illuminance' => {
|
|
6751
|
+
Name => 'SceneIlluminance',
|
|
6752
|
+
Notes => 'milli-lux',
|
|
6753
|
+
ValueConv => 'unpack("N", $val)',
|
|
6754
|
+
Writable => 0, # (don't make this writable because it is found in timed metadata)
|
|
6755
|
+
},
|
|
6746
6756
|
#
|
|
6747
6757
|
# seen in Apple ProRes RAW file
|
|
6748
6758
|
#
|
|
@@ -7392,6 +7402,7 @@ my %userDefined = (
|
|
|
7392
7402
|
# alac - 28 bytes
|
|
7393
7403
|
# adrm - AAX DRM atom? 148 bytes
|
|
7394
7404
|
# aabd - AAX unknown 17kB (contains 'aavd' strings)
|
|
7405
|
+
# dapa - ? 203 bytes
|
|
7395
7406
|
);
|
|
7396
7407
|
|
|
7397
7408
|
# AMR decode config box (ref 3)
|
|
@@ -9151,7 +9162,7 @@ sub HandleItemInfo($)
|
|
|
9151
9162
|
$et->ProcessDirectory(\%dirInfo, $subTable, $proc);
|
|
9152
9163
|
delete $$et{DOC_NUM};
|
|
9153
9164
|
}
|
|
9154
|
-
$raf->Seek($curPos, 0); # seek back to original position
|
|
9165
|
+
$raf->Seek($curPos, 0) or $et->Warn('Seek error'), last; # seek back to original position
|
|
9155
9166
|
pop @{$$et{PATH}};
|
|
9156
9167
|
}
|
|
9157
9168
|
# process the item properties now that we should know their associations and document numbers
|
|
@@ -9577,7 +9588,7 @@ sub ProcessMOV($$;$)
|
|
|
9577
9588
|
if ($tag eq 'ftyp' and $size >= 12) {
|
|
9578
9589
|
# read ftyp atom to see what type of file this is
|
|
9579
9590
|
if ($raf->Read($buff, $size-8) == $size-8) {
|
|
9580
|
-
$raf->Seek(-($size-8), 1);
|
|
9591
|
+
$raf->Seek(-($size-8), 1) or $et->Warn('Seek error'), return 0;
|
|
9581
9592
|
my $type = substr($buff, 0, 4);
|
|
9582
9593
|
$$et{save_ftyp} = $type;
|
|
9583
9594
|
# see if we know the extension for this file type
|
|
@@ -9629,7 +9640,7 @@ sub ProcessMOV($$;$)
|
|
|
9629
9640
|
# a zero size isn't legal for contained atoms, but Canon uses it to
|
|
9630
9641
|
# terminate the CNTH atom (eg. CanonEOS100D.mov), so tolerate it here
|
|
9631
9642
|
my $pos = $raf->Tell() - 4;
|
|
9632
|
-
$raf->Seek(0,2);
|
|
9643
|
+
$raf->Seek(0,2) or $et->Warn('Seek error'), return 0;
|
|
9633
9644
|
my $str = $$dirInfo{DirName} . ' with ' . ($raf->Tell() - $pos) . ' bytes';
|
|
9634
9645
|
$et->VPrint(0,"$$et{INDENT}\[Terminator found in $str remaining]");
|
|
9635
9646
|
} else {
|
|
@@ -9638,7 +9649,7 @@ sub ProcessMOV($$;$)
|
|
|
9638
9649
|
if ($$tagTablePtr{"$tag-size"}) {
|
|
9639
9650
|
my $pos = $raf->Tell();
|
|
9640
9651
|
unless ($fast) {
|
|
9641
|
-
$raf->Seek(0, 2);
|
|
9652
|
+
$raf->Seek(0, 2) or $et->Warn('Seek error'), return 0;
|
|
9642
9653
|
$et->HandleTag($tagTablePtr, "$tag-size", $raf->Tell() - $pos);
|
|
9643
9654
|
}
|
|
9644
9655
|
$et->HandleTag($tagTablePtr, "$tag-offset", $pos) if $$tagTablePtr{"$tag-offset"};
|
|
@@ -109,7 +109,7 @@ my %insvLimit = (
|
|
|
109
109
|
The tags below are extracted from timed metadata in QuickTime and other
|
|
110
110
|
formats of video files when the ExtractEmbedded option is used. Although
|
|
111
111
|
most of these tags are combined into the single table below, ExifTool
|
|
112
|
-
currently reads
|
|
112
|
+
currently reads 78 different formats of timed GPS metadata from video files.
|
|
113
113
|
},
|
|
114
114
|
VARS => { NO_ID => 1 },
|
|
115
115
|
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
|
|
@@ -591,8 +591,8 @@ my %insvLimit = (
|
|
|
591
591
|
GROUPS => { 2 => 'Location' },
|
|
592
592
|
FIRST_ENTRY => 0,
|
|
593
593
|
NOTES => q{
|
|
594
|
-
Tags extracted from the tx3g sbtl timed metadata of Yuneec drones,
|
|
595
|
-
subtitle text in some other videos.
|
|
594
|
+
Tags extracted from the tx3g sbtl timed metadata of Yuneec and Autel drones,
|
|
595
|
+
and subtitle text in some other videos.
|
|
596
596
|
},
|
|
597
597
|
Lat => {
|
|
598
598
|
Name => 'GPSLatitude',
|
|
@@ -619,6 +619,32 @@ my %insvLimit = (
|
|
|
619
619
|
PrintConv => '$self->ConvertDateTime($val)',
|
|
620
620
|
},
|
|
621
621
|
Text => { Groups => { 2 => 'Other' } },
|
|
622
|
+
# the following tags are extracted from Autel Evo II drone videos
|
|
623
|
+
GPSDateTime => {
|
|
624
|
+
Groups => { 2 => 'Time' },
|
|
625
|
+
Description => 'GPS Date/Time',
|
|
626
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
|
627
|
+
},
|
|
628
|
+
HomeLat => {
|
|
629
|
+
Name => 'GPSHomeLatitude',
|
|
630
|
+
RawConv => '$$self{FoundGPSLatitude} = 1; $val',
|
|
631
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
|
|
632
|
+
},
|
|
633
|
+
HomeLon => {
|
|
634
|
+
Name => 'GPSHomeLongitude',
|
|
635
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
|
|
636
|
+
},
|
|
637
|
+
ISO => { },
|
|
638
|
+
SHUTTER => {
|
|
639
|
+
Name => 'ExposureTime',
|
|
640
|
+
ValueConv => '1 / $val',
|
|
641
|
+
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
|
642
|
+
},
|
|
643
|
+
'F-NUM' => {
|
|
644
|
+
Name => 'FNumber',
|
|
645
|
+
PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
|
|
646
|
+
},
|
|
647
|
+
EV => 'ExposureCompensation',
|
|
622
648
|
);
|
|
623
649
|
|
|
624
650
|
%Image::ExifTool::QuickTime::INSV_MakerNotes = (
|
|
@@ -2163,9 +2189,26 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
|
2163
2189
|
push(@xtra, $1 => $2), next;
|
|
2164
2190
|
}
|
|
2165
2191
|
|
|
2192
|
+
} elsif ($$dataPt =~ m/^.{30}A.{20}VV/) {
|
|
2193
|
+
|
|
2194
|
+
$debug and $et->FoundTag(GPSType => 17);
|
|
2195
|
+
# 70mai A810 dashcam (note: no timestamps in the samples I have)
|
|
2196
|
+
# 0000: 00 00 40 00 66 72 65 65 47 50 53 20 ed 01 00 00 [..@.freeGPS ....]
|
|
2197
|
+
# 0010: 03 00 ed 01 00 00 00 0f 00 00 70 08 00 00 41 66 [..........p...Af]
|
|
2198
|
+
# 0020: 13 7d 1e 3c 11 dc 03 5d 01 00 00 01 00 00 00 23 [.}.<...].......#]
|
|
2199
|
+
# 0030: 00 00 00 56 56 00 00 00 00 00 00 00 00 00 00 00 [...VV...........]
|
|
2200
|
+
# 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
|
|
2201
|
+
SetByteOrder('II');
|
|
2202
|
+
SetGPSDateTime($et, $tagTbl, $$dirInfo{SampleTime});
|
|
2203
|
+
$lat = Get32s($dataPt, 31) / 1e5;
|
|
2204
|
+
$lon = Get32s($dataPt, 35) / 1e5;
|
|
2205
|
+
$spd = Get32s($dataPt, 43); # (seems to be km/h but not confirmed)
|
|
2206
|
+
# offset 475 - int16u=N string[N] - some sort of settings?:
|
|
2207
|
+
# eg. "\x15\x00{pA:V,rA:V,sF:0,tF:2}"
|
|
2208
|
+
|
|
2166
2209
|
} else {
|
|
2167
2210
|
|
|
2168
|
-
$debug and $et->FoundTag(GPSType =>
|
|
2211
|
+
$debug and $et->FoundTag(GPSType => 18);
|
|
2169
2212
|
# (look for binary GPS as stored by Nextbase 512G, ref PH)
|
|
2170
2213
|
# 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 01 00 00 [....freeGPS x...]
|
|
2171
2214
|
# 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............]
|
|
@@ -2344,7 +2387,7 @@ sub ParseTag($$$)
|
|
|
2344
2387
|
}
|
|
2345
2388
|
|
|
2346
2389
|
#------------------------------------------------------------------------------
|
|
2347
|
-
# Process Yuneec 'tx3g' sbtl metadata (ref PH)
|
|
2390
|
+
# Process Yuneec 'tx3g' and Autel sbtl metadata (ref PH)
|
|
2348
2391
|
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
|
2349
2392
|
# Returns: 1 on success
|
|
2350
2393
|
sub Process_tx3g($$$)
|
|
@@ -2352,13 +2395,49 @@ sub Process_tx3g($$$)
|
|
|
2352
2395
|
my ($et, $dirInfo, $tagTablePtr) = @_;
|
|
2353
2396
|
my $dataPt = $$dirInfo{DataPt};
|
|
2354
2397
|
return 0 if length $$dataPt < 2;
|
|
2355
|
-
pos($$dataPt) = 2; # skip 2-byte length word
|
|
2356
2398
|
$et->VerboseDir('tx3g', undef, length($$dataPt)-2);
|
|
2357
|
-
$
|
|
2358
|
-
|
|
2399
|
+
my $text = substr($$dataPt, 2); # remove 2-byte length word
|
|
2400
|
+
$et->HandleTag($tagTablePtr, 'Text', $text);
|
|
2401
|
+
if ($text =~ /^HOME\(/) {
|
|
2402
|
+
# --- sample text from Autel Evo II drone ---
|
|
2403
|
+
# HOME(W: 109.318642, N: 40.769371) 2023-09-12 10:28:07
|
|
2404
|
+
# GPS(W: 109.339287, N: 40.768574, 2371.76m)
|
|
2405
|
+
# HDR ISO:100 SHUTTER:1000 EV:-0.7 F-NUM:1.8
|
|
2406
|
+
# F.PRY (1.0\xc2\xb0, -3.7\xc2\xb0, -59.0\xc2\xb0), G.PRY (-51.1\xc2\xb0, 0.0\xc2\xb0, -58.9\xc2\xb0)
|
|
2407
|
+
my $line;
|
|
2408
|
+
foreach $line (split /\x0a/, $text) {
|
|
2409
|
+
if ($line =~ /^HOME\(([EW]):\s*(\d+\.\d+),\s*([NS]):\s*(\d+\.\d+)\)\s*(.*)/) {
|
|
2410
|
+
my ($lon, $lat, $time) = ($2, $4, $5);
|
|
2411
|
+
$lon = -$lon if $1 eq 'W';
|
|
2412
|
+
$lat = -$lat if $3 eq 'S';
|
|
2413
|
+
$time =~ tr/-/:/; # (likely local time zone, but not confirmed)
|
|
2414
|
+
$et->HandleTag($tagTablePtr, GPSDateTime => $time);
|
|
2415
|
+
$et->HandleTag($tagTablePtr, HomeLat => $lat);
|
|
2416
|
+
$et->HandleTag($tagTablePtr, HomeLon => $lon);
|
|
2417
|
+
} elsif ($line =~ /^GPS\(([EW]):\s*(\d+\.\d+),\s*([NS]):\s*(\d+\.\d+),\s*(.*)m/) {
|
|
2418
|
+
my ($lon, $lat, $alt) = ($2, $4, $5);
|
|
2419
|
+
$lon = -$lon if $1 eq 'W';
|
|
2420
|
+
$lat = -$lat if $3 eq 'S';
|
|
2421
|
+
$et->HandleTag($tagTablePtr, Lat => $lat);
|
|
2422
|
+
$et->HandleTag($tagTablePtr, Lon => $lon);
|
|
2423
|
+
$et->HandleTag($tagTablePtr, Alt => $alt);
|
|
2424
|
+
} elsif ($line =~ /^F\.PRY\s*\((-?[\d.]+)\xc2\xb0,\s*(-?[\d.]+)\xc2\xb0,\s*(-?[\d.]+)\xc2\xb0/) {
|
|
2425
|
+
$et->HandleTag($tagTablePtr, Yaw => $1);
|
|
2426
|
+
$et->HandleTag($tagTablePtr, Pitch => $2);
|
|
2427
|
+
$et->HandleTag($tagTablePtr, Roll => $3);
|
|
2428
|
+
if ($line =~ /G\.PRY\s*\((-?[\d.]+)\xc2\xb0,\s*(-?[\d.]+)\xc2\xb0,\s*(-?[\d.]+)\xc2\xb0/) {
|
|
2429
|
+
$et->HandleTag($tagTablePtr, GimYaw => $1);
|
|
2430
|
+
$et->HandleTag($tagTablePtr, GimPitch => $2);
|
|
2431
|
+
$et->HandleTag($tagTablePtr, GimRoll => $3);
|
|
2432
|
+
}
|
|
2433
|
+
} else {
|
|
2434
|
+
$et->HandleTag($tagTablePtr, $1, $2) while $line =~ /([-\w]+):([^:]*[^:\s])(\s|$)/sg;
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
} elsif ($text =~ /^\w{3} (\d{4})-(\d{2})-(\d{2}) (\d{2}:\d{2}:\d{2}) ?([-+])(\d{2}):?(\d{2})$/s) {
|
|
2359
2438
|
$et->HandleTag($tagTablePtr, 'DateTime', "$1:$2:$3 $4$5$6:$7");
|
|
2360
2439
|
} else {
|
|
2361
|
-
$et->HandleTag($tagTablePtr, $1, $2) while
|
|
2440
|
+
$et->HandleTag($tagTablePtr, $1, $2) while $text =~ /(\w+):([^:]*[^:\s])(\s|$)/sg;
|
|
2362
2441
|
}
|
|
2363
2442
|
return 1;
|
|
2364
2443
|
}
|
|
@@ -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.70';
|
|
38
38
|
|
|
39
39
|
sub ProcessSRF($$$);
|
|
40
40
|
sub ProcessSR2($$$);
|
|
@@ -170,6 +170,7 @@ sub PrintInvLensSpec($;$$);
|
|
|
170
170
|
32885 => 'Sony FE 16-35mm F2.8 GM II', #JR
|
|
171
171
|
32886 => 'Sony FE 300mm F2.8 GM OSS', #JR
|
|
172
172
|
32887 => 'Sony E PZ 16-50mm F3.5-5.6 OSS II', #JR
|
|
173
|
+
32888 => 'Sony FE 85mm F1.4 GM II', #JR
|
|
173
174
|
|
|
174
175
|
# (comment this out so LensID will report the LensModel, which is more useful)
|
|
175
176
|
# 32952 => 'Metabones Canon EF Speed Booster Ultra', #JR (corresponds to 184, but 'Advanced' mode, LensMount reported as E-mount)
|
|
@@ -241,6 +242,8 @@ sub PrintInvLensSpec($;$$);
|
|
|
241
242
|
49474.9 => 'Viltrox 75mm F1.2 E', #JR
|
|
242
243
|
'49474.10' => 'Viltrox 20mm F2.8 FE', #JR
|
|
243
244
|
49475 => 'Tamron 50-300mm F4.5-6.3 Di III VC VXD', #JR (Model A069)
|
|
245
|
+
49476 => 'Tamron 28-300mm F4-7.1 Di III VC VXD', #JR (Model A074)
|
|
246
|
+
49477 => 'Tamron 90mm F2.8 Di III Macro VXD', #JR (Model F072)
|
|
244
247
|
|
|
245
248
|
49712 => 'Tokina FiRIN 20mm F2 FE AF', # (firmware Ver.01)
|
|
246
249
|
49713 => 'Tokina FiRIN 100mm F2.8 FE MACRO', # (firmware Ver.01)
|
|
@@ -299,6 +302,7 @@ sub PrintInvLensSpec($;$$);
|
|
|
299
302
|
50547 => 'Sigma 10-18mm F2.8 DC DN | C', #JR (023)
|
|
300
303
|
50548 => 'Sigma 15mm F1.4 DG DN DIAGONAL FISHEYE | A', #JR (024)
|
|
301
304
|
50549 => 'Sigma 50mm F1.2 DG DN | A', #JR (024)
|
|
305
|
+
50550 => 'Sigma 28-105mm F2.8 DG DN | A', #JR (024)
|
|
302
306
|
50551 => 'Sigma 28-45mm F1.8 DG DN | A', #JR (024)
|
|
303
307
|
|
|
304
308
|
50992 => 'Voigtlander SUPER WIDE-HELIAR 15mm F4.5 III', #JR
|
|
@@ -315,6 +319,7 @@ sub PrintInvLensSpec($;$$);
|
|
|
315
319
|
51003 => 'Voigtlander NOKTON 35mm F1.2 Aspherical SE', #JR
|
|
316
320
|
51006 => 'Voigtlander APO-LANTHAR 35mm F2 Aspherical', #JR
|
|
317
321
|
51007 => 'Voigtlander NOKTON 50mm F1 Aspherical', #JR
|
|
322
|
+
51008 => 'Voigtlander NOKTON 75mm F1.5 Aspherical', #JR
|
|
318
323
|
|
|
319
324
|
# lenses listed in the Sigma MC-11 list, but not yet seen:
|
|
320
325
|
# 504xx => 'Sigma 18-200mm F3.5-6.3 DC MACRO OS HSM | C + MC-11', # (014)
|