exiftool-vendored.pl 12.62.0 → 12.67.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 +96 -1
- package/bin/MANIFEST +4 -0
- package/bin/META.json +5 -3
- package/bin/META.yml +5 -3
- package/bin/Makefile.PL +7 -1
- package/bin/README +50 -46
- package/bin/config_files/guano.config +161 -0
- package/bin/exiftool +116 -79
- package/bin/lib/Image/ExifTool/7Z.pm +793 -0
- package/bin/lib/Image/ExifTool/Apple.pm +19 -8
- package/bin/lib/Image/ExifTool/BigTIFF.pm +8 -1
- package/bin/lib/Image/ExifTool/Canon.pm +33 -12
- package/bin/lib/Image/ExifTool/CanonRaw.pm +4 -4
- package/bin/lib/Image/ExifTool/CanonVRD.pm +4 -1
- package/bin/lib/Image/ExifTool/Exif.pm +31 -14
- package/bin/lib/Image/ExifTool/FlashPix.pm +8 -2
- package/bin/lib/Image/ExifTool/FujiFilm.pm +6 -3
- package/bin/lib/Image/ExifTool/GPS.pm +5 -2
- package/bin/lib/Image/ExifTool/Geotag.pm +5 -2
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +226 -28
- package/bin/lib/Image/ExifTool/Lang/fr.pm +1467 -202
- package/bin/lib/Image/ExifTool/MPF.pm +2 -1
- package/bin/lib/Image/ExifTool/Matroska.pm +16 -1
- package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
- package/bin/lib/Image/ExifTool/Nikon.pm +948 -31
- package/bin/lib/Image/ExifTool/NikonCustom.pm +874 -63
- package/bin/lib/Image/ExifTool/PDF.pm +23 -5
- package/bin/lib/Image/ExifTool/PLIST.pm +8 -1
- package/bin/lib/Image/ExifTool/PLUS.pm +19 -4
- package/bin/lib/Image/ExifTool/PNG.pm +6 -6
- package/bin/lib/Image/ExifTool/Pentax.pm +3 -1
- package/bin/lib/Image/ExifTool/PhaseOne.pm +5 -5
- package/bin/lib/Image/ExifTool/QuickTime.pm +91 -30
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +20 -19
- package/bin/lib/Image/ExifTool/README +2 -2
- package/bin/lib/Image/ExifTool/RIFF.pm +11 -9
- package/bin/lib/Image/ExifTool/Samsung.pm +227 -227
- package/bin/lib/Image/ExifTool/Shortcuts.pm +2 -1
- package/bin/lib/Image/ExifTool/SigmaRaw.pm +4 -4
- package/bin/lib/Image/ExifTool/Sony.pm +229 -30
- package/bin/lib/Image/ExifTool/TagLookup.pm +4758 -4633
- package/bin/lib/Image/ExifTool/TagNames.pod +715 -23
- package/bin/lib/Image/ExifTool/Validate.pm +17 -1
- package/bin/lib/Image/ExifTool/WriteExif.pl +9 -7
- package/bin/lib/Image/ExifTool/WriteQuickTime.pl +21 -9
- package/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
- package/bin/lib/Image/ExifTool/Writer.pl +36 -12
- package/bin/lib/Image/ExifTool/XMP.pm +14 -2
- package/bin/lib/Image/ExifTool/XMP2.pl +33 -1
- package/bin/lib/Image/ExifTool/XMPStruct.pl +96 -28
- package/bin/lib/Image/ExifTool/ZIP.pm +5 -5
- package/bin/lib/Image/ExifTool.pm +184 -132
- package/bin/lib/Image/ExifTool.pod +124 -58
- package/bin/perl-Image-ExifTool.spec +44 -44
- package/bin/pp_build_exe.args +7 -4
- package/package.json +3 -3
|
@@ -21,7 +21,7 @@ use vars qw($VERSION $AUTOLOAD $lastFetched);
|
|
|
21
21
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
22
22
|
require Exporter;
|
|
23
23
|
|
|
24
|
-
$VERSION = '1.
|
|
24
|
+
$VERSION = '1.57';
|
|
25
25
|
|
|
26
26
|
sub FetchObject($$$$);
|
|
27
27
|
sub ExtractObject($$;$$);
|
|
@@ -109,7 +109,18 @@ my %supportedFilter = (
|
|
|
109
109
|
Title => { },
|
|
110
110
|
Author => { Groups => { 2 => 'Author' } },
|
|
111
111
|
Subject => { },
|
|
112
|
-
Keywords => {
|
|
112
|
+
Keywords => {
|
|
113
|
+
List => 'string', # this is a string list
|
|
114
|
+
Notes => q{
|
|
115
|
+
stored as a string but treated as a comma- or semicolon-separated list of
|
|
116
|
+
items when reading if the string contains commas or semicolons, whichever is
|
|
117
|
+
more numerous, otherwise it is treated a space-separated list of items.
|
|
118
|
+
Written as a comma-separated list. The list behaviour may be defeated by
|
|
119
|
+
setting the API NoPDFList option. Note that the corresponding
|
|
120
|
+
XMP-pdf:Keywords tag is not treated as a list, so the NoPDFList option
|
|
121
|
+
should be used when copying between these two.
|
|
122
|
+
},
|
|
123
|
+
},
|
|
113
124
|
Creator => { },
|
|
114
125
|
Producer => { },
|
|
115
126
|
CreationDate => {
|
|
@@ -1754,6 +1765,7 @@ sub ExpandArray($)
|
|
|
1754
1765
|
# 4) nesting depth, 5) dictionary capture type
|
|
1755
1766
|
sub ProcessDict($$$$;$$)
|
|
1756
1767
|
{
|
|
1768
|
+
local $_;
|
|
1757
1769
|
my ($et, $tagTablePtr, $dict, $xref, $nesting, $type) = @_;
|
|
1758
1770
|
my $verbose = $et->Options('Verbose');
|
|
1759
1771
|
my $unknown = $$tagTablePtr{EXTRACT_UNKNOWN};
|
|
@@ -2017,10 +2029,16 @@ sub ProcessDict($$$$;$$)
|
|
|
2017
2029
|
}
|
|
2018
2030
|
if ($$tagInfo{List} and not $$et{OPTIONS}{NoPDFList}) {
|
|
2019
2031
|
# separate tokens in comma or whitespace delimited lists
|
|
2020
|
-
my
|
|
2021
|
-
|
|
2022
|
-
|
|
2032
|
+
my $comma = $val =~ tr/,/,/;
|
|
2033
|
+
my $semi = $val =~ tr/;/;/;
|
|
2034
|
+
my $split;
|
|
2035
|
+
if ($comma or $semi) {
|
|
2036
|
+
$split = $comma > $semi ? ',+\\s*' : ';+\\s*';
|
|
2037
|
+
} else {
|
|
2038
|
+
$split = ' ';
|
|
2023
2039
|
}
|
|
2040
|
+
my @values = split $split, $val;
|
|
2041
|
+
$et->FoundTag($tagInfo, $_) foreach @values;
|
|
2024
2042
|
} else {
|
|
2025
2043
|
# a simple tag value
|
|
2026
2044
|
$et->FoundTag($tagInfo, $val);
|
|
@@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
21
21
|
use Image::ExifTool::XMP;
|
|
22
22
|
use Image::ExifTool::GPS;
|
|
23
23
|
|
|
24
|
-
$VERSION = '1.
|
|
24
|
+
$VERSION = '1.11';
|
|
25
25
|
|
|
26
26
|
sub ExtractObject($$;$);
|
|
27
27
|
sub Get24u($$);
|
|
@@ -288,6 +288,12 @@ sub ExtractObject($$;$)
|
|
|
288
288
|
my $obj = ExtractObject($et, $plistInfo, $tag);
|
|
289
289
|
next if not defined $obj;
|
|
290
290
|
unless ($tagTablePtr) {
|
|
291
|
+
# make sure this is a valid structure field name
|
|
292
|
+
if (not defined $key or $key !~ /^[-_a-zA-Z0-9]+$/) {
|
|
293
|
+
$key = "Tag$i"; # (generate fake tag name if it had illegal characters)
|
|
294
|
+
} elsif ($key !~ /^[_a-zA-Z]/) {
|
|
295
|
+
$key = "_$key"; # (must begin with alpha or underline)
|
|
296
|
+
}
|
|
291
297
|
$$val{$key} = $obj if defined $obj;
|
|
292
298
|
next;
|
|
293
299
|
}
|
|
@@ -298,6 +304,7 @@ sub ExtractObject($$;$)
|
|
|
298
304
|
my $name = $tag;
|
|
299
305
|
$name =~ s/([^A-Za-z])([a-z])/$1\u$2/g; # capitalize words
|
|
300
306
|
$name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
|
|
307
|
+
$name = "Tag$name" if length($name) < 2 or $name =~ /^[-0-9]/;
|
|
301
308
|
$tagInfo = { Name => ucfirst($name), List => 1 };
|
|
302
309
|
if ($$plistInfo{DateFormat}) {
|
|
303
310
|
$$tagInfo{Groups}{2} = 'Time';
|
|
@@ -14,7 +14,7 @@ use strict;
|
|
|
14
14
|
use vars qw($VERSION);
|
|
15
15
|
use Image::ExifTool::XMP;
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.02';
|
|
18
18
|
|
|
19
19
|
sub ValidateMediaSummary($);
|
|
20
20
|
|
|
@@ -2311,12 +2311,13 @@ my %mediaMatrix = (
|
|
|
2311
2311
|
GROUPS => { 0 => 'XMP', 1 => 'XMP-plus', 2 => 'Author' },
|
|
2312
2312
|
NAMESPACE => 'plus',
|
|
2313
2313
|
NOTES => q{
|
|
2314
|
-
PLUS (Picture Licensing Universal System) License Data Format
|
|
2314
|
+
PLUS (Picture Licensing Universal System) License Data Format 2.0.1 XMP
|
|
2315
2315
|
tags. Note that all controlled-vocabulary tags in this table (ie. tags with
|
|
2316
2316
|
a fixed set of values) have raw values which begin with
|
|
2317
2317
|
"http://ns.useplus.org/ldf/vocab/", but to reduce clutter this prefix has
|
|
2318
|
-
been removed from the values shown below
|
|
2319
|
-
the
|
|
2318
|
+
been removed from the values shown below, and from the values read and
|
|
2319
|
+
written with the -n option. See L<http://ns.useplus.org/> for the complete
|
|
2320
|
+
specification.
|
|
2320
2321
|
},
|
|
2321
2322
|
Version => { Name => 'PLUSVersion' },
|
|
2322
2323
|
Licensee => {
|
|
@@ -2529,6 +2530,20 @@ my %mediaMatrix = (
|
|
|
2529
2530
|
Custom8 => { List => 'Bag', Writable => 'lang-alt' },
|
|
2530
2531
|
Custom9 => { List => 'Bag', Writable => 'lang-alt' },
|
|
2531
2532
|
Custom10 => { List => 'Bag', Writable => 'lang-alt' },
|
|
2533
|
+
DataMining => {
|
|
2534
|
+
%plusVocab,
|
|
2535
|
+
PrintConv => {
|
|
2536
|
+
'DMI-UNSPECIFIED' => 'Unspecified - no prohibition defined',
|
|
2537
|
+
'DMI-ALLOWED' => 'Allowed',
|
|
2538
|
+
'DMI-PROHIBITED-AIMLTRAINING' => 'Prohibited for AI/ML training',
|
|
2539
|
+
'DMI-PROHIBITED-GENAIMLTRAINING' => 'Prohibited for Generative AI/ML training',
|
|
2540
|
+
'DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING' => 'Prohibited except for search engine indexing',
|
|
2541
|
+
'DMI-PROHIBITED' => 'Prohibited',
|
|
2542
|
+
'DMI-PROHIBITED-SEECONSTRAINT' => 'Prohibited, see plus:OtherConstraints',
|
|
2543
|
+
'DMI-PROHIBITED-SEEEMBEDDEDRIGHTSEXPR' => 'Prohibited, see iptcExt:EmbdEncRightsExpr',
|
|
2544
|
+
'DMI-PROHIBITED-SEELINKEDRIGHTSEXPR' => 'Prohibited, see iptcExt:LinkedEncRightsExpr',
|
|
2545
|
+
},
|
|
2546
|
+
},
|
|
2532
2547
|
);
|
|
2533
2548
|
|
|
2534
2549
|
#------------------------------------------------------------------------------
|
|
@@ -36,7 +36,7 @@ use strict;
|
|
|
36
36
|
use vars qw($VERSION $AUTOLOAD %stdCase);
|
|
37
37
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
38
38
|
|
|
39
|
-
$VERSION = '1.
|
|
39
|
+
$VERSION = '1.64';
|
|
40
40
|
|
|
41
41
|
sub ProcessPNG_tEXt($$$);
|
|
42
42
|
sub ProcessPNG_iTXt($$$);
|
|
@@ -1374,7 +1374,7 @@ sub ProcessPNG($$)
|
|
|
1374
1374
|
my $datCount = 0;
|
|
1375
1375
|
my $datBytes = 0;
|
|
1376
1376
|
my $fastScan = $et->Options('FastScan');
|
|
1377
|
-
my $
|
|
1377
|
+
my $hash = $$et{ImageDataHash};
|
|
1378
1378
|
my ($n, $sig, $err, $hbuf, $dbuf, $cbuf);
|
|
1379
1379
|
my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset);
|
|
1380
1380
|
|
|
@@ -1454,7 +1454,7 @@ sub ProcessPNG($$)
|
|
|
1454
1454
|
if ($datCount and $chunk ne $datChunk) {
|
|
1455
1455
|
my $s = $datCount > 1 ? 's' : '';
|
|
1456
1456
|
print $out "$fileType $datChunk ($datCount chunk$s, total $datBytes bytes)\n";
|
|
1457
|
-
print $out "$$et{INDENT}(
|
|
1457
|
+
print $out "$$et{INDENT}(ImageDataHash: $datBytes bytes of $datChunk data)\n" if $hash;
|
|
1458
1458
|
$datCount = $datBytes = 0;
|
|
1459
1459
|
}
|
|
1460
1460
|
}
|
|
@@ -1541,8 +1541,8 @@ sub ProcessPNG($$)
|
|
|
1541
1541
|
}
|
|
1542
1542
|
# skip over data chunks if possible/necessary
|
|
1543
1543
|
} elsif (not $validate or $len > $chunkSizeLimit) {
|
|
1544
|
-
if ($
|
|
1545
|
-
$et->
|
|
1544
|
+
if ($hash) {
|
|
1545
|
+
$et->ImageDataHash($raf, $len);
|
|
1546
1546
|
$raf->Read($cbuf, 4) == 4 or $et->Warn('Truncated data'), last;
|
|
1547
1547
|
} else {
|
|
1548
1548
|
$raf->Seek($len + 4, 1) or $et->Warn('Seek error'), last;
|
|
@@ -1565,7 +1565,7 @@ sub ProcessPNG($$)
|
|
|
1565
1565
|
$et->Warn("Corrupted $fileType image") unless $wasEnd;
|
|
1566
1566
|
last;
|
|
1567
1567
|
}
|
|
1568
|
-
$
|
|
1568
|
+
$hash->add($dbuf) if $hash and $datChunk; # add to hash if necessary
|
|
1569
1569
|
if ($verbose or $validate or ($outfile and not $fastScan)) {
|
|
1570
1570
|
# check CRC when in verbose mode (since we don't care about speed)
|
|
1571
1571
|
my $crc = CalculateCRC(\$hbuf, undef, 4);
|
|
@@ -58,7 +58,7 @@ use Image::ExifTool::Exif;
|
|
|
58
58
|
use Image::ExifTool::GPS;
|
|
59
59
|
use Image::ExifTool::HP;
|
|
60
60
|
|
|
61
|
-
$VERSION = '3.
|
|
61
|
+
$VERSION = '3.43';
|
|
62
62
|
|
|
63
63
|
sub CryptShutterCount($$);
|
|
64
64
|
sub PrintFilter($$$);
|
|
@@ -175,6 +175,7 @@ sub DecodeAFPoints($$$$;$);
|
|
|
175
175
|
'4 2' => 'smc PENTAX-FA 80-320mm F4.5-5.6',
|
|
176
176
|
'4 3' => 'smc PENTAX-FA 43mm F1.9 Limited',
|
|
177
177
|
'4 6' => 'smc PENTAX-FA 35-80mm F4-5.6',
|
|
178
|
+
'4 7' => 'Irix 45mm F1.4', #27
|
|
178
179
|
'4 8' => 'Irix 150mm F2.8 Macro', #exiv2 issue 1084
|
|
179
180
|
'4 9' => 'Irix 11mm F4 Firefly', #27
|
|
180
181
|
'4 10' => 'Irix 15mm F2.4', #27
|
|
@@ -265,6 +266,7 @@ sub DecodeAFPoints($$$$;$);
|
|
|
265
266
|
'6 14' => 'smc PENTAX-FA* Macro 200mm F4 ED[IF]',
|
|
266
267
|
'7 0' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #13
|
|
267
268
|
'7 58' => 'smc PENTAX-D FA Macro 100mm F2.8 WR', #PH - this bit of information cost me $600 ;)
|
|
269
|
+
# '7 58' also 'HD PENTAX-D FA MACRO 100mm F2.8 ED AW' (ref 27)
|
|
268
270
|
'7 75' => 'Tamron SP AF 70-200mm F2.8 Di LD [IF] Macro (A001)', #(Anton Bondar)
|
|
269
271
|
'7 201' => 'smc Pentax-DA L 50-200mm F4-5.6 ED WR', #(Bruce Rusk)
|
|
270
272
|
'7 202' => 'smc PENTAX-DA L 18-55mm F3.5-5.6 AL WR', #29
|
|
@@ -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.09';
|
|
19
19
|
|
|
20
20
|
sub WritePhaseOne($$$);
|
|
21
21
|
sub ProcessPhaseOne($$$);
|
|
@@ -585,7 +585,7 @@ sub ProcessPhaseOne($$$)
|
|
|
585
585
|
my $dirLen = $$dirInfo{DirLen} || $$dirInfo{DataLen} - $dirStart;
|
|
586
586
|
my $binary = $et->Options('Binary');
|
|
587
587
|
my $verbose = $et->Options('Verbose');
|
|
588
|
-
my $
|
|
588
|
+
my $hash = $$et{ImageDataHash};
|
|
589
589
|
my $htmlDump = $$et{HTML_DUMP};
|
|
590
590
|
|
|
591
591
|
return 0 if $dirLen < 12;
|
|
@@ -678,16 +678,16 @@ sub ProcessPhaseOne($$$)
|
|
|
678
678
|
}
|
|
679
679
|
}
|
|
680
680
|
}
|
|
681
|
-
if ($
|
|
681
|
+
if ($hash and $tagInfo and $$tagInfo{IsImageData}) {
|
|
682
682
|
my ($pos, $len) = ($valuePtr, $size);
|
|
683
683
|
while ($len) {
|
|
684
684
|
my $n = $len > 65536 ? 65536 : $len;
|
|
685
685
|
my $tmp = substr($$dataPt, $pos, $n);
|
|
686
|
-
$
|
|
686
|
+
$hash->add($tmp);
|
|
687
687
|
$len -= $n;
|
|
688
688
|
$pos += $n;
|
|
689
689
|
}
|
|
690
|
-
$et->VPrint(0, "$$et{INDENT}(
|
|
690
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataHash: $size bytes of PhaseOne:$$tagInfo{Name})\n");
|
|
691
691
|
}
|
|
692
692
|
my %parms = (
|
|
693
693
|
DirName => $ifdType,
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
# 25) https://cconcolato.github.io/mp4ra/atoms.html
|
|
38
38
|
# 26) https://github.com/SamsungVR/android_upload_sdk/blob/master/SDKLib/src/main/java/com/samsung/msca/samsungvr/sdk/UserVideo.java
|
|
39
39
|
# 27) https://exiftool.org/forum/index.php?topic=11517.0
|
|
40
|
+
# 28) https://docs.mp3tag.de/mapping/
|
|
40
41
|
#------------------------------------------------------------------------------
|
|
41
42
|
|
|
42
43
|
package Image::ExifTool::QuickTime;
|
|
@@ -47,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
47
48
|
use Image::ExifTool::Exif;
|
|
48
49
|
use Image::ExifTool::GPS;
|
|
49
50
|
|
|
50
|
-
$VERSION = '2.
|
|
51
|
+
$VERSION = '2.87';
|
|
51
52
|
|
|
52
53
|
sub ProcessMOV($$;$);
|
|
53
54
|
sub ProcessKeys($$$);
|
|
@@ -224,6 +225,9 @@ my %ftypLookup = (
|
|
|
224
225
|
'crx ' => 'Canon Raw (.CRX)', #PH (CR3 or CRM; use Canon CompressorVersion to decide)
|
|
225
226
|
);
|
|
226
227
|
|
|
228
|
+
# use extension to determine file type
|
|
229
|
+
my %useExt = ( GLV => 'MP4' );
|
|
230
|
+
|
|
227
231
|
# information for int32u date/time tags (time zero is Jan 1, 1904)
|
|
228
232
|
my %timeInfo = (
|
|
229
233
|
Notes => 'converted from UTC to local time if the QuickTimeUTC option is set',
|
|
@@ -447,8 +451,8 @@ my %dupDirOK = ( ipco => 1, '----' => 1 );
|
|
|
447
451
|
my %eeStd = ( stco => 'stbl', co64 => 'stbl', stsz => 'stbl', stz2 => 'stbl',
|
|
448
452
|
stsc => 'stbl', stts => 'stbl' );
|
|
449
453
|
|
|
450
|
-
# atoms required for generating
|
|
451
|
-
my %
|
|
454
|
+
# atoms required for generating ImageDataHash
|
|
455
|
+
my %hashBox = ( vide => { %eeStd }, soun => { %eeStd } );
|
|
452
456
|
|
|
453
457
|
# boxes and their containers for the various handler types that we want to save
|
|
454
458
|
# when the ExtractEmbedded is enabled (currently only the 'gps ' container name is
|
|
@@ -1006,7 +1010,8 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
1006
1010
|
0 => 'Monoscopic',
|
|
1007
1011
|
1 => 'Stereoscopic Top-Bottom',
|
|
1008
1012
|
2 => 'Stereoscopic Left-Right',
|
|
1009
|
-
3 => 'Stereoscopic Stereo-Custom',
|
|
1013
|
+
3 => 'Stereoscopic Stereo-Custom',
|
|
1014
|
+
4 => 'Stereoscopic Right-Left',
|
|
1010
1015
|
},
|
|
1011
1016
|
},
|
|
1012
1017
|
sv3d => {
|
|
@@ -2070,8 +2075,8 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
2070
2075
|
ValueConv => 'substr($val, 4)',
|
|
2071
2076
|
ValueConvInv => '"\0\0\0\x01$val"',
|
|
2072
2077
|
},
|
|
2073
|
-
# hmtp - "\0\0\0\x01"
|
|
2074
|
-
# vrin - "\0\0\0\x01" followed by 8 bytes of zero
|
|
2078
|
+
# hmtp - 412 bytes: "\0\0\0\x01" then maybe "\0\0\0\x64" and the rest zeros
|
|
2079
|
+
# vrin - 12 bytes: "\0\0\0\x01" followed by 8 bytes of zero
|
|
2075
2080
|
# ---- GoPro ---- (ref PH)
|
|
2076
2081
|
GoPr => 'GoProType', # (Hero3+)
|
|
2077
2082
|
FIRM => { Name => 'FirmwareVersion', Avoid => 1 }, # (Hero4)
|
|
@@ -2867,6 +2872,25 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
2867
2872
|
Name => 'AV1Configuration',
|
|
2868
2873
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::AV1Config' },
|
|
2869
2874
|
},
|
|
2875
|
+
clli => {
|
|
2876
|
+
Name => 'ContentLightLevel',
|
|
2877
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ContentLightLevel' },
|
|
2878
|
+
},
|
|
2879
|
+
# ref https://nokiatech.github.io/heif/technical.html
|
|
2880
|
+
# cclv - Content Color Volume
|
|
2881
|
+
# mdcv - Mastering Display Color Volume
|
|
2882
|
+
# rrtp - Required reference types
|
|
2883
|
+
# crtt - Creation time information
|
|
2884
|
+
# mdft - Modification time information
|
|
2885
|
+
# udes - User description
|
|
2886
|
+
# altt - Accessibility text
|
|
2887
|
+
# aebr - Auto exposure information
|
|
2888
|
+
# wbbr - White balance information
|
|
2889
|
+
# fobr - Focus information
|
|
2890
|
+
# afbr - Flash exposure information
|
|
2891
|
+
# dobr - Depth of field information
|
|
2892
|
+
# pano - Panorama information
|
|
2893
|
+
# iscl - Image Scaling
|
|
2870
2894
|
);
|
|
2871
2895
|
|
|
2872
2896
|
# ref https://aomediacodec.github.io/av1-spec/av1-spec.pdf
|
|
@@ -2901,8 +2925,8 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
2901
2925
|
1 => 'BT.709',
|
|
2902
2926
|
2 => 'Unspecified',
|
|
2903
2927
|
3 => 'For future use (3)',
|
|
2904
|
-
4 => 'BT.470 System M (historical)',
|
|
2905
|
-
5 => 'BT.470 System B, G (historical)',
|
|
2928
|
+
4 => 'BT.470 System M (historical)', # Gamma 2.2? (ref forum14960)
|
|
2929
|
+
5 => 'BT.470 System B, G (historical)', # Gamma 2.8? (ref forum14960)
|
|
2906
2930
|
6 => 'BT.601',
|
|
2907
2931
|
7 => 'SMPTE 240 M',
|
|
2908
2932
|
8 => 'Linear',
|
|
@@ -3128,6 +3152,16 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
3128
3152
|
},
|
|
3129
3153
|
);
|
|
3130
3154
|
|
|
3155
|
+
# ref https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/MPEG4Writer.cpp
|
|
3156
|
+
%Image::ExifTool::QuickTime::ContentLightLevel = (
|
|
3157
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
3158
|
+
GROUPS => { 2 => 'Video' },
|
|
3159
|
+
FIRST_ENTRY => 0,
|
|
3160
|
+
FORMAT => 'int16u',
|
|
3161
|
+
0 => 'MaxContentLightLevel',
|
|
3162
|
+
1 => 'MaxPicAverageLightLevel',
|
|
3163
|
+
);
|
|
3164
|
+
|
|
3131
3165
|
%Image::ExifTool::QuickTime::ItemRef = (
|
|
3132
3166
|
PROCESS_PROC => \&ProcessMOV,
|
|
3133
3167
|
WRITE_PROC => \&WriteQuickTime,
|
|
@@ -3363,8 +3397,9 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
3363
3397
|
},
|
|
3364
3398
|
albm => { Name => 'Album', Avoid => 1 }, #(ffmpeg source)
|
|
3365
3399
|
apID => 'AppleStoreAccount',
|
|
3366
|
-
atID => {
|
|
3367
|
-
|
|
3400
|
+
atID => {
|
|
3401
|
+
# (ref 10 called this AlbumTitleID or TVSeries)
|
|
3402
|
+
Name => 'ArtistID', #28 (or Track ID ref https://gist.github.com/maf654321/2b44c7b15d798f0c52ee)
|
|
3368
3403
|
Format => 'int32u',
|
|
3369
3404
|
Writable => 'int32s', #27
|
|
3370
3405
|
},
|
|
@@ -3375,6 +3410,7 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
3375
3410
|
Format => 'int32u',
|
|
3376
3411
|
Writable => 'int32s', #27
|
|
3377
3412
|
},
|
|
3413
|
+
cmID => 'ComposerID', #28 (need sample to get format)
|
|
3378
3414
|
cprt => { Name => 'Copyright', Groups => { 2 => 'Author' } },
|
|
3379
3415
|
dscp => { Name => 'Description', Avoid => 1 },
|
|
3380
3416
|
desc => { Name => 'Description', Avoid => 1 }, #7
|
|
@@ -6067,10 +6103,10 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
6067
6103
|
PrintConv => { 0 => 'No', 1 => 'Yes' },
|
|
6068
6104
|
},
|
|
6069
6105
|
perf => 'Performer',
|
|
6070
|
-
plID => {
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6106
|
+
plID => {
|
|
6107
|
+
# (ref 10 called this PlayListID or TVSeason)
|
|
6108
|
+
Name => 'AlbumID', #28
|
|
6109
|
+
Format => 'int64u',
|
|
6074
6110
|
Writable => 'int32s', #27
|
|
6075
6111
|
},
|
|
6076
6112
|
purd => 'PurchaseDate', #7
|
|
@@ -6532,6 +6568,7 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
6532
6568
|
'rating.user' => 'UserRating', # (Canon ELPH 510 HS)
|
|
6533
6569
|
'collection.user' => 'UserCollection', #22
|
|
6534
6570
|
'Encoded_With' => 'EncodedWith',
|
|
6571
|
+
'content.identifier' => 'ContentIdentifier', #forum14874
|
|
6535
6572
|
#
|
|
6536
6573
|
# the following tags aren't in the com.apple.quicktime namespace:
|
|
6537
6574
|
#
|
|
@@ -7187,7 +7224,7 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
7187
7224
|
#
|
|
7188
7225
|
# AudioFormat Offset Child atoms
|
|
7189
7226
|
# ----------- ------ ----------------
|
|
7190
|
-
# mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?,also GoPro Max)
|
|
7227
|
+
# mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?,also GoPro Max and Garmin VIRB 360)
|
|
7191
7228
|
# in24 52 wave, chan
|
|
7192
7229
|
# "ms\0\x11" 52 wave
|
|
7193
7230
|
# sowt 52 chan
|
|
@@ -7220,11 +7257,14 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
7220
7257
|
chan => {
|
|
7221
7258
|
Name => 'AudioChannelLayout',
|
|
7222
7259
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ChannelLayout' },
|
|
7223
|
-
}
|
|
7260
|
+
},
|
|
7261
|
+
SA3D => { # written by Garmin VIRB360
|
|
7262
|
+
Name => 'SpatialAudio',
|
|
7263
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SpatialAudio' },
|
|
7264
|
+
},
|
|
7224
7265
|
# alac - 28 bytes
|
|
7225
7266
|
# adrm - AAX DRM atom? 148 bytes
|
|
7226
7267
|
# aabd - AAX unknown 17kB (contains 'aavd' strings)
|
|
7227
|
-
# SA3D - written by Garmin VIRB360
|
|
7228
7268
|
);
|
|
7229
7269
|
|
|
7230
7270
|
# AMR decode config box (ref 3)
|
|
@@ -7572,6 +7612,20 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
7572
7612
|
# (arbitrarily decode only first 8 channels)
|
|
7573
7613
|
);
|
|
7574
7614
|
|
|
7615
|
+
# spatial audio (ref https://github.com/google/spatial-media/blob/master/docs/spatial-audio-rfc.md)
|
|
7616
|
+
%Image::ExifTool::QuickTime::SpatialAudio = (
|
|
7617
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
7618
|
+
GROUPS => { 2 => 'Audio' },
|
|
7619
|
+
NOTES => 'Spatial Audio tags.',
|
|
7620
|
+
0 => 'SpatialAudioVersion',
|
|
7621
|
+
1 => { Name => 'AmbisonicType', PrintConv => { 0 => 'Periphonic' } },
|
|
7622
|
+
2 => { Name => 'AmbisonicOrder', Format => 'int32u' },
|
|
7623
|
+
6 => { Name => 'AmbisonicChannelOrdering', PrintConv => { 0 => 'ACN' } },
|
|
7624
|
+
7 => { Name => 'AmbisonicNormalization', PrintConv => { 0 => 'SN3D' } },
|
|
7625
|
+
8 => { Name => 'AmbisonicChannels', Format => 'int32u' },
|
|
7626
|
+
12 => { Name => 'AmbisonicChannelMap', Format => 'int32u[$val{8}]' },
|
|
7627
|
+
);
|
|
7628
|
+
|
|
7575
7629
|
# scheme type atom
|
|
7576
7630
|
# ref http://xhelmboyx.tripod.com/formats/mp4-layout.txt
|
|
7577
7631
|
%Image::ExifTool::QuickTime::SchemeType = (
|
|
@@ -8787,15 +8841,15 @@ sub HandleItemInfo($)
|
|
|
8787
8841
|
$et->VPrint(0, "$$et{INDENT} [snip $snip bytes]\n") if $snip;
|
|
8788
8842
|
}
|
|
8789
8843
|
}
|
|
8790
|
-
# do
|
|
8791
|
-
if ($isImageData{$type} and $$et{
|
|
8792
|
-
my $
|
|
8844
|
+
# do hash of AVIF "av01" and HEIC image data
|
|
8845
|
+
if ($isImageData{$type} and $$et{ImageDataHash}) {
|
|
8846
|
+
my $hash = $$et{ImageDataHash};
|
|
8793
8847
|
my $tot = 0;
|
|
8794
8848
|
foreach $extent (@{$$item{Extents}}) {
|
|
8795
8849
|
$raf->Seek($$extent[1] + $base, 0) or $et->Warn("Seek error in $type image data"), last;
|
|
8796
|
-
$tot += $et->
|
|
8850
|
+
$tot += $et->ImageDataHash($raf, $$extent[2], "$type image", 1);
|
|
8797
8851
|
}
|
|
8798
|
-
$et->VPrint(0, "$$et{INDENT}(
|
|
8852
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataHash: $tot bytes of $type data)\n") if $tot;
|
|
8799
8853
|
}
|
|
8800
8854
|
next unless $name;
|
|
8801
8855
|
# assemble the data for this item
|
|
@@ -9285,6 +9339,9 @@ sub ProcessMOV($$;$)
|
|
|
9285
9339
|
}
|
|
9286
9340
|
}
|
|
9287
9341
|
$fileType or $fileType = 'MP4'; # default to MP4
|
|
9342
|
+
# set file type from extension if appropriate
|
|
9343
|
+
my $ext = $$et{FILE_EXT};
|
|
9344
|
+
$fileType = $ext if $ext and $useExt{$ext} and $fileType eq $useExt{$ext};
|
|
9288
9345
|
$et->SetFileType($fileType, $mimeLookup{$fileType} || 'video/mp4');
|
|
9289
9346
|
# temporarily set ExtractEmbedded option for CRX files
|
|
9290
9347
|
$saveOptions{ExtractEmbedded} = $et->Options(ExtractEmbedded => 1) if $fileType eq 'CRX';
|
|
@@ -9299,8 +9356,8 @@ sub ProcessMOV($$;$)
|
|
|
9299
9356
|
$$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode
|
|
9300
9357
|
|
|
9301
9358
|
my $ee = $$et{OPTIONS}{ExtractEmbedded};
|
|
9302
|
-
my $
|
|
9303
|
-
if ($ee or $
|
|
9359
|
+
my $hash = $$et{ImageDataHash};
|
|
9360
|
+
if ($ee or $hash) {
|
|
9304
9361
|
$unkOpt = $$et{OPTIONS}{Unknown};
|
|
9305
9362
|
require 'Image/ExifTool/QuickTimeStream.pl';
|
|
9306
9363
|
}
|
|
@@ -9382,7 +9439,7 @@ sub ProcessMOV($$;$)
|
|
|
9382
9439
|
# set flag to store additional information for ExtractEmbedded option
|
|
9383
9440
|
my $handlerType = $$et{HandlerType};
|
|
9384
9441
|
if ($eeBox{$handlerType} and $eeBox{$handlerType}{$tag}) {
|
|
9385
|
-
if ($ee or $
|
|
9442
|
+
if ($ee or $hash) {
|
|
9386
9443
|
# (there is another 'gps ' box with a track log that doesn't contain offsets)
|
|
9387
9444
|
if ($tag ne 'gps ' or $eeBox{$handlerType}{$tag} eq $dirID) {
|
|
9388
9445
|
$eeTag = 1;
|
|
@@ -9394,7 +9451,7 @@ sub ProcessMOV($$;$)
|
|
|
9394
9451
|
} elsif ($ee and $ee > 1 and $eeBox2{$handlerType} and $eeBox2{$handlerType}{$tag}) {
|
|
9395
9452
|
$eeTag = 1;
|
|
9396
9453
|
$$et{OPTIONS}{Unknown} = 1;
|
|
9397
|
-
} elsif ($
|
|
9454
|
+
} elsif ($hash and $hashBox{$handlerType} and $hashBox{$handlerType}{$tag}) {
|
|
9398
9455
|
$eeTag = 1;
|
|
9399
9456
|
$$et{OPTIONS}{Unknown} = 1;
|
|
9400
9457
|
}
|
|
@@ -9466,13 +9523,17 @@ sub ProcessMOV($$;$)
|
|
|
9466
9523
|
my $items = $$et{ItemInfo};
|
|
9467
9524
|
my ($id, $prop, $docNum, $lowest);
|
|
9468
9525
|
my $primary = $$et{PrimaryItem} || 0;
|
|
9469
|
-
ItemID: foreach $id (keys %$items) {
|
|
9526
|
+
ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
9470
9527
|
next unless $$items{$id}{Association};
|
|
9471
9528
|
my $item = $$items{$id};
|
|
9472
9529
|
foreach $prop (@{$$item{Association}}) {
|
|
9473
9530
|
next unless $prop == $index;
|
|
9474
9531
|
if ($id == $primary or (not $dontInherit{$tag} and
|
|
9475
|
-
(
|
|
9532
|
+
(($$item{RefersTo} and $$item{RefersTo}{$primary}) or
|
|
9533
|
+
# hack: assume Item 1 is from the main image (eg. hvc1 data)
|
|
9534
|
+
# to hack the case where the primary item (ie. main image)
|
|
9535
|
+
# doesn't directly reference this property
|
|
9536
|
+
(not $$item{RefersTo} and $id == 1))))
|
|
9476
9537
|
{
|
|
9477
9538
|
# this is associated with the primary item or an item describing
|
|
9478
9539
|
# the primary item, so consider this part of the main document
|
|
@@ -9483,7 +9544,7 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9483
9544
|
# this property is already associated with an item that has
|
|
9484
9545
|
# an ExifTool document number, so use the lowest associated DocNum
|
|
9485
9546
|
$docNum = $$item{DocNum} if not defined $docNum or $docNum > $$item{DocNum};
|
|
9486
|
-
}
|
|
9547
|
+
} else {
|
|
9487
9548
|
# keep track of the lowest associated item ID
|
|
9488
9549
|
$lowest = $id;
|
|
9489
9550
|
}
|
|
@@ -9629,7 +9690,7 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9629
9690
|
}
|
|
9630
9691
|
if ($tag eq 'stbl') {
|
|
9631
9692
|
# process sample data when exiting SampleTable box if extracting embedded
|
|
9632
|
-
ProcessSamples($et) if $ee or $
|
|
9693
|
+
ProcessSamples($et) if $ee or $hash;
|
|
9633
9694
|
} elsif ($tag eq 'minf') {
|
|
9634
9695
|
$$et{HandlerType} = ''; # reset handler type at end of media info box
|
|
9635
9696
|
}
|
|
@@ -1128,14 +1128,14 @@ sub Process_text($$$;$)
|
|
|
1128
1128
|
# Inputs: 0) ExifTool ref
|
|
1129
1129
|
# Notes: Also accesses ExifTool RAF*, SET_GROUP1, HandlerType, MetaFormat,
|
|
1130
1130
|
# ee*, and avcC elements (* = must exist)
|
|
1131
|
-
# - may be called either due to ExtractEmbedded option, or
|
|
1132
|
-
# -
|
|
1131
|
+
# - may be called either due to ExtractEmbedded option, or ImageDataHash requested
|
|
1132
|
+
# - hash includes only video and audio data
|
|
1133
1133
|
sub ProcessSamples($)
|
|
1134
1134
|
{
|
|
1135
1135
|
my $et = shift;
|
|
1136
1136
|
my ($raf, $ee) = @$et{qw(RAF ee)};
|
|
1137
|
-
my ($i, $buff, $pos, $hdrLen, $hdrFmt, @time, @dur, $oldIndent, $
|
|
1138
|
-
my ($mdatOffset, $mdatSize); # (for range-checking samples when
|
|
1137
|
+
my ($i, $buff, $pos, $hdrLen, $hdrFmt, @time, @dur, $oldIndent, $hash);
|
|
1138
|
+
my ($mdatOffset, $mdatSize); # (for range-checking samples when hash is done)
|
|
1139
1139
|
|
|
1140
1140
|
return unless $ee;
|
|
1141
1141
|
delete $$et{ee}; # use only once
|
|
@@ -1144,22 +1144,22 @@ sub ProcessSamples($)
|
|
|
1144
1144
|
my $type = $$et{HandlerType} || '';
|
|
1145
1145
|
if ($type eq 'vide') {
|
|
1146
1146
|
# only process specific types of video streams
|
|
1147
|
-
$
|
|
1147
|
+
$hash = $$et{ImageDataHash};
|
|
1148
1148
|
# only process specific video types if ExtractEmbedded was used
|
|
1149
|
-
# (otherwise we are only here to calculate the audio/video
|
|
1149
|
+
# (otherwise we are only here to calculate the audio/video hash)
|
|
1150
1150
|
if ($eeOpt) {
|
|
1151
1151
|
if ($$ee{avcC}) { $type = 'avcC' }
|
|
1152
1152
|
elsif ($$ee{JPEG}) { $type = 'JPEG' }
|
|
1153
|
-
else { return unless $
|
|
1153
|
+
else { return unless $hash }
|
|
1154
1154
|
}
|
|
1155
1155
|
} elsif ($type eq 'soun') {
|
|
1156
|
-
$
|
|
1157
|
-
return unless $
|
|
1156
|
+
$hash = $$et{ImageDataHash};
|
|
1157
|
+
return unless $hash;
|
|
1158
1158
|
} else {
|
|
1159
|
-
return unless $eeOpt; # (don't do
|
|
1159
|
+
return unless $eeOpt; # (don't do hash on other types)
|
|
1160
1160
|
}
|
|
1161
1161
|
|
|
1162
|
-
my $
|
|
1162
|
+
my $hashSize = 0;
|
|
1163
1163
|
my ($start, $size) = @$ee{qw(start size)};
|
|
1164
1164
|
#
|
|
1165
1165
|
# determine sample start offsets from chunk offsets (stco) and sample-to-chunk table (stsc),
|
|
@@ -1213,7 +1213,7 @@ Sample: for ($i=0; ; ) {
|
|
|
1213
1213
|
++$iChunk;
|
|
1214
1214
|
}
|
|
1215
1215
|
@$start == @$size or $et->WarnOnce('Incorrect sample start/size count'), return;
|
|
1216
|
-
# process as chunks if we are only interested in calculating
|
|
1216
|
+
# process as chunks if we are only interested in calculating hash
|
|
1217
1217
|
if ($type eq 'soun' or $type eq 'vide') {
|
|
1218
1218
|
$start = $stco;
|
|
1219
1219
|
$size = \@chunkSize;
|
|
@@ -1232,7 +1232,7 @@ Sample: for ($i=0; ; ) {
|
|
|
1232
1232
|
$oldIndent = $$et{INDENT};
|
|
1233
1233
|
$$et{INDENT} = '';
|
|
1234
1234
|
}
|
|
1235
|
-
if ($
|
|
1235
|
+
if ($hash) {
|
|
1236
1236
|
$mdatSize = $$et{MediaDataSize};
|
|
1237
1237
|
$mdatOffset = $$et{MediaDataOffset} if defined $mdatSize;
|
|
1238
1238
|
}
|
|
@@ -1249,7 +1249,7 @@ Sample: for ($i=0; ; ) {
|
|
|
1249
1249
|
delete $$et{FoundGPSLatitude};
|
|
1250
1250
|
delete $$et{FoundGPSDateTime};
|
|
1251
1251
|
|
|
1252
|
-
# range check the sample data for
|
|
1252
|
+
# range check the sample data for hash if necessary
|
|
1253
1253
|
my $size = $$size[$i];
|
|
1254
1254
|
if (defined $mdatOffset) {
|
|
1255
1255
|
if ($$start[$i] < $mdatOffset) {
|
|
@@ -1268,9 +1268,9 @@ Sample: for ($i=0; ; ) {
|
|
|
1268
1268
|
next unless $n;
|
|
1269
1269
|
$size = $n;
|
|
1270
1270
|
}
|
|
1271
|
-
if ($
|
|
1272
|
-
$
|
|
1273
|
-
$
|
|
1271
|
+
if ($hash) {
|
|
1272
|
+
$hash->add($buff);
|
|
1273
|
+
$hashSize += length $buff;
|
|
1274
1274
|
}
|
|
1275
1275
|
if ($type eq 'avcC') {
|
|
1276
1276
|
next if length($buff) <= $hdrLen;
|
|
@@ -1378,7 +1378,7 @@ Sample: for ($i=0; ; ) {
|
|
|
1378
1378
|
DataPos => $$start[$i],
|
|
1379
1379
|
SampleTime => $time[$i],
|
|
1380
1380
|
SampleDuration => $dur[$i],
|
|
1381
|
-
}, $tagTbl)
|
|
1381
|
+
}, $tagTbl);
|
|
1382
1382
|
}
|
|
1383
1383
|
|
|
1384
1384
|
} elsif ($$tagTbl{$type}) {
|
|
@@ -1399,7 +1399,7 @@ Sample: for ($i=0; ; ) {
|
|
|
1399
1399
|
}
|
|
1400
1400
|
if ($verbose) {
|
|
1401
1401
|
my $str = $type eq 'soun' ? 'Audio' : 'Video';
|
|
1402
|
-
$et->VPrint(0, "$$et{INDENT}(
|
|
1402
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataHash: $hashSize bytes of $str data)\n") if $hashSize;
|
|
1403
1403
|
$$et{INDENT} = $oldIndent;
|
|
1404
1404
|
$et->VPrint(0, "--------------------------\n");
|
|
1405
1405
|
}
|
|
@@ -2904,6 +2904,7 @@ sub ProcessInsta360($;$)
|
|
|
2904
2904
|
# when the language is french? ie. "Ouest"?)
|
|
2905
2905
|
$a[7] eq 'O'))
|
|
2906
2906
|
{
|
|
2907
|
+
next if $a[3] eq 'V'; # void fixes don't have N/S E/W
|
|
2907
2908
|
$et->Warn('Unrecognized INSV GPS format');
|
|
2908
2909
|
last;
|
|
2909
2910
|
}
|