exiftool_vendored 12.68.0 → 12.72.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +98 -15
- data/bin/MANIFEST +5 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +10 -10
- data/bin/exiftool +32 -25
- data/bin/lib/Image/ExifTool/AAC.pm +175 -0
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +2 -1
- data/bin/lib/Image/ExifTool/CBOR.pm +18 -2
- data/bin/lib/Image/ExifTool/Canon.pm +87 -20
- data/bin/lib/Image/ExifTool/DJI.pm +3 -2
- data/bin/lib/Image/ExifTool/DNG.pm +25 -2
- data/bin/lib/Image/ExifTool/EXE.pm +54 -6
- data/bin/lib/Image/ExifTool/Exif.pm +204 -22
- data/bin/lib/Image/ExifTool/FujiFilm.pm +145 -20
- data/bin/lib/Image/ExifTool/GIF.pm +5 -1
- data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
- data/bin/lib/Image/ExifTool/ID3.pm +76 -10
- data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +1 -1
- data/bin/lib/Image/ExifTool/JSON.pm +4 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +30 -15
- data/bin/lib/Image/ExifTool/M2TS.pm +21 -16
- data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +213 -105
- data/bin/lib/Image/ExifTool/Olympus.pm +7 -1
- data/bin/lib/Image/ExifTool/PNG.pm +8 -13
- data/bin/lib/Image/ExifTool/Panasonic.pm +15 -2
- data/bin/lib/Image/ExifTool/Pentax.pm +15 -6
- data/bin/lib/Image/ExifTool/PhotoMechanic.pm +2 -2
- data/bin/lib/Image/ExifTool/QuickTime.pm +60 -14
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +59 -11
- data/bin/lib/Image/ExifTool/README +14 -5
- data/bin/lib/Image/ExifTool/RIFF.pm +60 -10
- data/bin/lib/Image/ExifTool/Ricoh.pm +109 -1
- data/bin/lib/Image/ExifTool/Samsung.pm +3 -2
- data/bin/lib/Image/ExifTool/Sony.pm +177 -37
- data/bin/lib/Image/ExifTool/TagLookup.pm +6971 -6714
- data/bin/lib/Image/ExifTool/TagNames.pod +957 -372
- data/bin/lib/Image/ExifTool/Text.pm +4 -5
- data/bin/lib/Image/ExifTool/Validate.pm +23 -20
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +2 -2
- data/bin/lib/Image/ExifTool/WriteExif.pl +33 -8
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +1 -0
- data/bin/lib/Image/ExifTool/WriteRIFF.pl +31 -6
- data/bin/lib/Image/ExifTool/Writer.pl +121 -28
- data/bin/lib/Image/ExifTool/XMP.pm +67 -2
- data/bin/lib/Image/ExifTool/XMP2.pl +35 -0
- data/bin/lib/Image/ExifTool.pm +94 -43
- data/bin/lib/Image/ExifTool.pod +28 -17
- data/bin/perl-Image-ExifTool.spec +9 -9
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
@@ -18,12 +18,13 @@ use strict;
|
|
18
18
|
use vars qw($VERSION);
|
19
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
20
20
|
|
21
|
-
$VERSION = '1.
|
21
|
+
$VERSION = '1.60';
|
22
22
|
|
23
23
|
sub ProcessID3v2($$$);
|
24
24
|
sub ProcessPrivate($$$);
|
25
25
|
sub ProcessSynText($$$);
|
26
26
|
sub ProcessID3Dir($$$);
|
27
|
+
sub ProcessGEOB($$$);
|
27
28
|
sub ConvertID3v1Text($$);
|
28
29
|
sub ConvertTimeStamp($);
|
29
30
|
|
@@ -419,7 +420,7 @@ my %genre = (
|
|
419
420
|
|
420
421
|
# Tags for ID2v2.2
|
421
422
|
%Image::ExifTool::ID3::v2_2 = (
|
422
|
-
PROCESS_PROC => \&
|
423
|
+
PROCESS_PROC => \&ProcessID3v2,
|
423
424
|
GROUPS => { 1 => 'ID3v2_2', 2 => 'Audio' },
|
424
425
|
NOTES => q{
|
425
426
|
ExifTool extracts mainly text-based tags from ID3v2 information. The tags
|
@@ -511,6 +512,9 @@ my %genre = (
|
|
511
512
|
TSC => 'ComposerSortOrder',
|
512
513
|
ITU => { Name => 'iTunesU', Description => 'iTunes U', Binary => 1, Unknown => 1 },
|
513
514
|
PCS => { Name => 'Podcast', Binary => 1, Unknown => 1 },
|
515
|
+
GP1 => 'Grouping', #github142 (NC)
|
516
|
+
MVN => 'MovementName', #github142 (NC)
|
517
|
+
MVI => 'MovementNumber', #github142 (NC)
|
514
518
|
);
|
515
519
|
|
516
520
|
# tags common to ID3v2.3 and ID3v2.4
|
@@ -534,7 +538,10 @@ my %id3v2_common = (
|
|
534
538
|
# COMR => 'Commercial',
|
535
539
|
# ENCR => 'EncryptionMethod',
|
536
540
|
# ETCO => 'EventTimingCodes',
|
537
|
-
|
541
|
+
GEOB => {
|
542
|
+
Name => 'GeneralEncapsulatedObject',
|
543
|
+
SubDirectory => { TagTable => 'Image::ExifTool::ID3::GEOB' },
|
544
|
+
},
|
538
545
|
# GRID => 'GroupIdentification',
|
539
546
|
# LINK => 'LinkedInformation',
|
540
547
|
MCDI => { Name => 'MusicCDIdentifier', Binary => 1 },
|
@@ -640,9 +647,25 @@ my %id3v2_common = (
|
|
640
647
|
MVIN => 'MovementNumber', # (NC)
|
641
648
|
);
|
642
649
|
|
650
|
+
%Image::ExifTool::ID3::GEOB = (
|
651
|
+
GROUPS => { 1 => 'ID3v2_3', 2 => 'Other' },
|
652
|
+
PROCESS_PROC => \&ProcessGEOB,
|
653
|
+
'application/x-c2pa-manifest-store' => {
|
654
|
+
Name => 'JUMBF',
|
655
|
+
SubDirectory => {
|
656
|
+
TagTable => 'Image::ExifTool::Jpeg2000::Main',
|
657
|
+
ByteOrder => 'BigEndian',
|
658
|
+
},
|
659
|
+
},
|
660
|
+
'GEOB-Mime' => { },
|
661
|
+
'GEOB-File' => { },
|
662
|
+
'GEOB-Desc' => { },
|
663
|
+
'GEOB-Data' => { },
|
664
|
+
);
|
665
|
+
|
643
666
|
# Tags for ID3v2.3 (http://www.id3.org/id3v2.3.0)
|
644
667
|
%Image::ExifTool::ID3::v2_3 = (
|
645
|
-
PROCESS_PROC => \&
|
668
|
+
PROCESS_PROC => \&ProcessID3v2,
|
646
669
|
GROUPS => { 1 => 'ID3v2_3', 2 => 'Audio' },
|
647
670
|
NOTES => q{
|
648
671
|
ID3 version 2.3 tags. Includes some non-standard tags written by other
|
@@ -662,7 +685,7 @@ my %id3v2_common = (
|
|
662
685
|
|
663
686
|
# Tags for ID3v2.4 (http://www.id3.org/id3v2.4.0-frames)
|
664
687
|
%Image::ExifTool::ID3::v2_4 = (
|
665
|
-
PROCESS_PROC => \&
|
688
|
+
PROCESS_PROC => \&ProcessID3v2,
|
666
689
|
GROUPS => { 1 => 'ID3v2_4', 2 => 'Audio' },
|
667
690
|
NOTES => q{
|
668
691
|
ID3 version 2.4 tags. Includes some non-standard tags written by other
|
@@ -802,8 +825,8 @@ my %id3v2_common = (
|
|
802
825
|
|
803
826
|
# lookup to check for existence of tags in other ID3 versions
|
804
827
|
my %otherTable = (
|
805
|
-
\%Image::ExifTool::ID3::v2_4 =>
|
806
|
-
\%Image::ExifTool::ID3::v2_3 =>
|
828
|
+
\%Image::ExifTool::ID3::v2_4 => 'Image::ExifTool::ID3::v2_3',
|
829
|
+
\%Image::ExifTool::ID3::v2_3 => 'Image::ExifTool::ID3::v2_4',
|
807
830
|
);
|
808
831
|
|
809
832
|
# ID3 Composite tags
|
@@ -1075,6 +1098,7 @@ sub ProcessID3v2($$$)
|
|
1075
1098
|
my $vers = $$dirInfo{Version};
|
1076
1099
|
my $verbose = $et->Options('Verbose');
|
1077
1100
|
my $len; # frame data length
|
1101
|
+
my $otherTable;
|
1078
1102
|
|
1079
1103
|
$et->VerboseDir($tagTablePtr->{GROUPS}->{1}, 0, $size);
|
1080
1104
|
$et->VerboseDump($dataPt, Len => $size, Start => $offset);
|
@@ -1101,7 +1125,11 @@ sub ProcessID3v2($$$)
|
|
1101
1125
|
my $oldLen = $len;
|
1102
1126
|
$len = UnSyncSafe($len);
|
1103
1127
|
if (not defined $len or $offset + $len + 10 > $size) {
|
1104
|
-
$
|
1128
|
+
if ($offset + $len == $size) {
|
1129
|
+
$et->Warn('Missing ID3 terminating frame', 1);
|
1130
|
+
} else {
|
1131
|
+
$et->Warn('Invalid ID3 frame size');
|
1132
|
+
}
|
1105
1133
|
last;
|
1106
1134
|
}
|
1107
1135
|
# check next ID to see if it makes sense
|
@@ -1117,7 +1145,9 @@ sub ProcessID3v2($$$)
|
|
1117
1145
|
last if $offset + $len > $size;
|
1118
1146
|
my $tagInfo = $et->GetTagInfo($tagTablePtr, $id);
|
1119
1147
|
unless ($tagInfo) {
|
1120
|
-
|
1148
|
+
if (not $otherTable and $otherTable{$tagTablePtr}) {
|
1149
|
+
$otherTable = GetTagTable($otherTable{$tagTablePtr});
|
1150
|
+
}
|
1121
1151
|
$tagInfo = $et->GetTagInfo($otherTable, $id) if $otherTable;
|
1122
1152
|
if ($tagInfo) {
|
1123
1153
|
$et->WarnOnce("Frame '${id}' is not valid for this ID3 version", 1);
|
@@ -1218,7 +1248,7 @@ sub ProcessID3v2($$$)
|
|
1218
1248
|
my @vals = DecodeString($et, $val);
|
1219
1249
|
foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
|
1220
1250
|
($val = "($vals[0]) $vals[1]") =~ s/^\(\) //;
|
1221
|
-
} elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS)$/) {
|
1251
|
+
} elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS|GP1|MVI|MVN)$/) {
|
1222
1252
|
$val = DecodeString($et, $val);
|
1223
1253
|
} elsif ($id =~ /^(WXX|WXXX)$/) {
|
1224
1254
|
# one encoded string and one Latin string separated by a null
|
@@ -1582,6 +1612,42 @@ sub ProcessID3Dir($$$)
|
|
1582
1612
|
return ProcessID3($et, $dirInfo);
|
1583
1613
|
}
|
1584
1614
|
|
1615
|
+
#------------------------------------------------------------------------------
|
1616
|
+
# Process ID3 General Encapsulated Object
|
1617
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
1618
|
+
# Returns: 1 on success
|
1619
|
+
sub ProcessGEOB($$$)
|
1620
|
+
{
|
1621
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
1622
|
+
$et->VerboseDir('GEOB', undef, length ${$$dirInfo{DataPt}});
|
1623
|
+
my $dataPt = $$dirInfo{DataPt};
|
1624
|
+
my $len = length $$dataPt;
|
1625
|
+
$len >= 4 or $et->Warn("Short GEOB frame"), return 0;
|
1626
|
+
my ($hdr, $attr);
|
1627
|
+
my $enc = unpack('C', $$dataPt);
|
1628
|
+
if ($enc == 1 or $enc == 2) {
|
1629
|
+
$hdr = ".(.*?)\0((?:..)*?)\0\0((?:..)*?)\0\0";
|
1630
|
+
} else {
|
1631
|
+
$hdr = ".(.*?)\0(.*?)\0(.*?)\0";
|
1632
|
+
}
|
1633
|
+
# remove header (encoding, mime, filename, description)
|
1634
|
+
$$dataPt =~ s/^$hdr//s or $et->Warn("Invalid GEOB frame"), return 0;
|
1635
|
+
my ($mime, $file, $desc) = ($1, DecodeString($et, $2, $enc), DecodeString($et, $3, $enc));
|
1636
|
+
$et->HandleTag($tagTablePtr, 'GEOB-Mime', $mime) if length $mime;
|
1637
|
+
$et->HandleTag($tagTablePtr, 'GEOB-File', $file) if length $file;
|
1638
|
+
$et->HandleTag($tagTablePtr, 'GEOB-Desc', $desc) if length $desc;
|
1639
|
+
if ($$tagTablePtr{$mime}) {
|
1640
|
+
$et->HandleTag($tagTablePtr, $mime, undef,
|
1641
|
+
DataPt => $dataPt,
|
1642
|
+
Start => 0,
|
1643
|
+
Size => length($$dataPt),
|
1644
|
+
);
|
1645
|
+
} else {
|
1646
|
+
$et->HandleTag($tagTablePtr, 'GEOB-Data', $dataPt);
|
1647
|
+
}
|
1648
|
+
return 1;
|
1649
|
+
}
|
1650
|
+
|
1585
1651
|
#------------------------------------------------------------------------------
|
1586
1652
|
# Extract ID3 information from an MP3 audio file
|
1587
1653
|
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
@@ -122,7 +122,7 @@ sub ProcessIND($$)
|
|
122
122
|
# memory troubles (with its apparent 1 GB limit) if the XMP is larger
|
123
123
|
# than about 400 MB, so guard against this
|
124
124
|
if ($len > 300 * 1024 * 1024) {
|
125
|
-
my $msg = sprintf('Insanely large XMP (%.0f
|
125
|
+
my $msg = sprintf('Insanely large XMP (%.0f MiB)', $len / (1024 * 1024));
|
126
126
|
if ($outfile) {
|
127
127
|
$et->Error($msg, 2) and $err = 1, last;
|
128
128
|
} elsif ($et->Options('IgnoreMinorErrors')) {
|
@@ -251,7 +251,7 @@ sub ProcessJPEG_HDR($$$);
|
|
251
251
|
Name => 'JUMBF',
|
252
252
|
Condition => '$$valPt =~ /^JP/',
|
253
253
|
SubDirectory => { TagTable => 'Image::ExifTool::Jpeg2000::Main' },
|
254
|
-
# Note: The
|
254
|
+
# Note: The suggested options for reading C2PA CAI JUMBF metadata are "-G3 -b -j -u"
|
255
255
|
}],
|
256
256
|
APP12 => [{
|
257
257
|
Name => 'PictureInfo',
|
@@ -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.06';
|
18
18
|
|
19
19
|
sub ProcessJSON($$);
|
20
20
|
sub ProcessTag($$$$%);
|
@@ -60,6 +60,9 @@ sub FoundTag($$$$%)
|
|
60
60
|
# avoid conflict with special table entries
|
61
61
|
$tag .= '!' if $Image::ExifTool::specialTags{$tag};
|
62
62
|
|
63
|
+
# use underline instead of colon if necessary in tag name
|
64
|
+
$tag =~ s/([A-Z]):([A-Z]{2})/${1}_$2/g;
|
65
|
+
|
63
66
|
AddTagToTable($tagTablePtr, $tag, {
|
64
67
|
Name => Image::ExifTool::MakeTagName($tag),
|
65
68
|
%flags,
|
@@ -89,12 +89,14 @@ my %uuid = (
|
|
89
89
|
# JPEG2000 codestream markers (ref ISO/IEC FCD15444-1/2)
|
90
90
|
my %j2cMarker = (
|
91
91
|
0x4f => 'SOC', # start of codestream
|
92
|
+
# 0x50 - seen in JPH codestream
|
92
93
|
0x51 => 'SIZ', # image and tile size
|
93
94
|
0x52 => 'COD', # coding style default
|
94
95
|
0x53 => 'COC', # coding style component
|
95
96
|
0x55 => 'TLM', # tile-part lengths
|
96
97
|
0x57 => 'PLM', # packet length, main header
|
97
98
|
0x58 => 'PLT', # packet length, tile-part header
|
99
|
+
# 0x59 - seen in JPH codestream
|
98
100
|
0x5c => 'QCD', # quantization default
|
99
101
|
0x5d => 'QCC', # quantization component
|
100
102
|
0x5e => 'RGN', # region of interest
|
@@ -128,12 +130,21 @@ my %j2cMarker = (
|
|
128
130
|
WRITE_PROC => \&ProcessJpeg2000Box,
|
129
131
|
PREFERRED => 1, # always add these tags when writing
|
130
132
|
NOTES => q{
|
131
|
-
The tags below are found in JPEG 2000 images and the JUMBF metadata
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
133
|
+
The tags below are found in JPEG 2000 images and the C2PA CAI JUMBF metadata
|
134
|
+
in various file types (see below). Note that ExifTool currently writes only
|
135
|
+
EXIF, IPTC and XMP tags in Jpeg2000 images, and EXIF and XMP in JXL images.
|
136
|
+
ExifTool will read/write Brotli-compressed EXIF and XMP in JXL images, but
|
137
|
+
the API L<Compress|../ExifTool.html#Compress> option must be set to create new EXIF and XMP in compressed
|
138
|
+
format.
|
139
|
+
|
140
|
+
C2PA (Coalition for Content Provenance and Authenticity) CAI (Content
|
141
|
+
Authenticity Initiative) JUMBF (JPEG Universal Metadata Box Format) metdata
|
142
|
+
is currently extracted from JPEG, PNG, TIFF-based (eg. TIFF, DNG),
|
143
|
+
QuickTime-based (eg. MP4, MOV, HEIF, AVIF), RIFF-based (eg. WAV, AVI, WebP),
|
144
|
+
GIF files and ID3v2 metadata. The suggested ExifTool command-line arguments
|
145
|
+
for reading C2PA metadata are C<-jumbf:all -G3 -b -j -u -struct>. This
|
146
|
+
metadata may be deleted from writable JPEG, PNG, WebP, TIFF-based, and
|
147
|
+
QuickTime-based files by deleting the JUMBF group with C<-jumbf:all=>.
|
137
148
|
},
|
138
149
|
#
|
139
150
|
# NOTE: ONLY TAGS WITH "Format" DEFINED ARE EXTRACTED!
|
@@ -345,13 +356,6 @@ my %j2cMarker = (
|
|
345
356
|
Start => '$valuePtr + 16',
|
346
357
|
},
|
347
358
|
},
|
348
|
-
{
|
349
|
-
Name => 'UUID-Signature', # (seen in JUMB data of JPEG images)
|
350
|
-
# (may be able to remove this when JUMBF specification is finalized)
|
351
|
-
Condition => '$$valPt=~/^casg\x00\x11\x00\x10\x80\x00\x00\xaa\x00\x38\x9b\x71/',
|
352
|
-
Format => 'undef',
|
353
|
-
ValueConv => 'substr($val,16)',
|
354
|
-
},
|
355
359
|
{
|
356
360
|
Name => 'UUID-C2PAClaimSignature', # (seen in incorrectly-formatted JUMB data of JPEG images)
|
357
361
|
# (may be able to remove this when JUMBF specification is finalized)
|
@@ -361,6 +365,13 @@ my %j2cMarker = (
|
|
361
365
|
Start => '$valuePtr + 16',
|
362
366
|
},
|
363
367
|
},
|
368
|
+
{
|
369
|
+
Name => 'UUID-Signature', # (seen in JUMB data of JPEG images)
|
370
|
+
# (may be able to remove this when JUMBF specification is finalized)
|
371
|
+
Condition => '$$valPt=~/^casg\x00\x11\x00\x10\x80\x00\x00\xaa\x00\x38\x9b\x71/',
|
372
|
+
Format => 'undef',
|
373
|
+
ValueConv => 'substr($val,16)',
|
374
|
+
},
|
364
375
|
{
|
365
376
|
Name => 'UUID-Unknown',
|
366
377
|
},
|
@@ -549,6 +560,7 @@ my %j2cMarker = (
|
|
549
560
|
'jpm ' => 'JPEG 2000 Compound Image (.JPM)', # image/jpm
|
550
561
|
'jpx ' => 'JPEG 2000 with extensions (.JPX)', # image/jpx
|
551
562
|
'jxl ' => 'JPEG XL Image (.JXL)', # image/jxl
|
563
|
+
'jph ' => 'High-throughput JPEG 2000 (.JPH)', # image/jph
|
552
564
|
},
|
553
565
|
},
|
554
566
|
1 => {
|
@@ -993,10 +1005,12 @@ sub ProcessJpeg2000Box($$$)
|
|
993
1005
|
my $dirLen = $$dirInfo{DirLen} || 0;
|
994
1006
|
my $dirStart = $$dirInfo{DirStart} || 0;
|
995
1007
|
my $base = $$dirInfo{Base} || 0;
|
996
|
-
my $raf = $$dirInfo{RAF};
|
997
1008
|
my $outfile = $$dirInfo{OutFile};
|
998
1009
|
my $dirEnd = $dirStart + $dirLen;
|
999
|
-
my ($err, $outBuff, $verbose, $doColour, $hash);
|
1010
|
+
my ($err, $outBuff, $verbose, $doColour, $hash, $raf);
|
1011
|
+
|
1012
|
+
# read from RAF unless reading from buffer
|
1013
|
+
$raf = $$dirInfo{RAF} unless $dataPt;
|
1000
1014
|
|
1001
1015
|
if ($outfile) {
|
1002
1016
|
unless ($raf) {
|
@@ -1516,6 +1530,7 @@ sub ProcessJP2($$)
|
|
1516
1530
|
$fileType = 'JPX' if $1 eq 'jpx ';
|
1517
1531
|
$fileType = 'JPM' if $1 eq 'jpm ';
|
1518
1532
|
$fileType = 'JXL' if $1 eq 'jxl ';
|
1533
|
+
$fileType = 'JPH' if $1 eq 'jph ';
|
1519
1534
|
}
|
1520
1535
|
$raf->Seek(-length($buff), 1) if defined $buff;
|
1521
1536
|
$et->SetFileType($fileType);
|
@@ -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.24';
|
36
36
|
|
37
37
|
# program map table "stream_type" lookup (ref 6/1/9)
|
38
38
|
my %streamType = (
|
@@ -354,29 +354,32 @@ sub ParsePID($$$$$)
|
|
354
354
|
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
355
355
|
Image::ExifTool::QuickTime::ProcessFreeGPS($et, { DataPt => \$dat }, $tbl);
|
356
356
|
$more = 1;
|
357
|
-
} elsif ($$dataPt =~ /^A([NS])([EW])\0/s) {
|
358
|
-
# INNOVV TS video (same format
|
357
|
+
} elsif ($$dataPt =~ /^(V00|A([NS])([EW]))\0/s) {
|
358
|
+
# INNOVV TS video (same format as INNOVV MP4)
|
359
359
|
SetByteOrder('II');
|
360
360
|
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
361
|
-
while ($$dataPt =~ /(A[NS][EW]\0.{28})/g) {
|
361
|
+
while ($$dataPt =~ /((V00|A[NS][EW])\0.{28})/g) {
|
362
362
|
my $dat = $1;
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
363
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
364
|
+
if ($2 ne 'V00') {
|
365
|
+
my $lat = abs(GetFloat(\$dat, 4)); # (abs just to be safe)
|
366
|
+
my $lon = abs(GetFloat(\$dat, 8)); # (abs just to be safe)
|
367
|
+
my $spd = GetFloat(\$dat, 12) * $knotsToKph;
|
368
|
+
my $trk = GetFloat(\$dat, 16);
|
369
|
+
Image::ExifTool::QuickTime::ConvertLatLon($lat, $lon);
|
370
|
+
$et->HandleTag($tagTbl, GPSLatitude => abs($lat) * (substr($dat,1,1) eq 'S' ? -1 : 1));
|
371
|
+
$et->HandleTag($tagTbl, GPSLongitude => abs($lon) * (substr($dat,2,1) eq 'W' ? -1 : 1));
|
372
|
+
$et->HandleTag($tagTbl, GPSSpeed => $spd);
|
373
|
+
$et->HandleTag($tagTbl, GPSSpeedRef => 'K');
|
374
|
+
$et->HandleTag($tagTbl, GPSTrack => $trk);
|
375
|
+
$et->HandleTag($tagTbl, GPSTrackRef => 'T');
|
376
|
+
}
|
367
377
|
my @acc = unpack('x20V3', $dat);
|
368
378
|
map { $_ = $_ - 4294967296 if $_ >= 0x80000000 } @acc;
|
369
|
-
Image::ExifTool::QuickTime::ConvertLatLon($lat, $lon);
|
370
|
-
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
371
|
-
$et->HandleTag($tagTbl, GPSLatitude => abs($lat) * (substr($dat,1,1) eq 'S' ? -1 : 1));
|
372
|
-
$et->HandleTag($tagTbl, GPSLongitude => abs($lon) * (substr($dat,2,1) eq 'W' ? -1 : 1));
|
373
|
-
$et->HandleTag($tagTbl, GPSSpeed => $spd);
|
374
|
-
$et->HandleTag($tagTbl, GPSSpeedRef => 'K');
|
375
|
-
$et->HandleTag($tagTbl, GPSTrack => $trk);
|
376
|
-
$et->HandleTag($tagTbl, GPSTrackRef => 'T');
|
377
379
|
$et->HandleTag($tagTbl, Accelerometer => "@acc");
|
378
380
|
}
|
379
381
|
SetByteOrder('MM');
|
382
|
+
$$et{HasINNOV} = 1; # (necessary to skip over empty/unknown INNOV records)
|
380
383
|
$more = 1;
|
381
384
|
} elsif ($$dataPt =~ /^\$(GPSINFO|GSNRINFO),/) {
|
382
385
|
# $GPSINFO,0x0004,2021.08.09 13:27:36,2341.54561,12031.70135,8.0,51,153,0,0,\x0d
|
@@ -478,6 +481,8 @@ sub ParsePID($$$$$)
|
|
478
481
|
$et->HandleTag($tagTbl, GPSTrackRef => 'T');
|
479
482
|
SetByteOrder('MM');
|
480
483
|
$more = 1;
|
484
|
+
} elsif ($$et{HasINNOV}) {
|
485
|
+
$more = 1;
|
481
486
|
}
|
482
487
|
delete $$et{DOC_NUM};
|
483
488
|
}
|
@@ -21,7 +21,7 @@ sub ProcessKodakPatch($$$);
|
|
21
21
|
sub WriteUnknownOrPreview($$$);
|
22
22
|
sub FixLeicaBase($$;$);
|
23
23
|
|
24
|
-
$VERSION = '2.
|
24
|
+
$VERSION = '2.15';
|
25
25
|
|
26
26
|
my $debug; # set to 1 to enable debugging code
|
27
27
|
|
@@ -694,7 +694,7 @@ my $debug; # set to 1 to enable debugging code
|
|
694
694
|
Name => 'MakerNoteLeica8', # used by the Q (Type 116)
|
695
695
|
# (Q (Typ 116) starts with "LEICA\0\x08\0", Make is "LEICA CAMERA AG")
|
696
696
|
# (SL (Typ 601) and CL start with "LEICA\0\x09\0", Make is "LEICA CAMERA AG")
|
697
|
-
Condition => '$$valPt =~ /^LEICA\0[\x08\x09]\0/',
|
697
|
+
Condition => '$$valPt =~ /^LEICA\0[\x08\x09\x0a]\0/',
|
698
698
|
SubDirectory => {
|
699
699
|
TagTable => 'Image::ExifTool::Panasonic::Leica5',
|
700
700
|
Start => '$valuePtr + 8',
|