exiftool_vendored 13.06.0 → 13.08.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 +29 -3
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +6 -5
- data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/APE.pm +1 -1
- data/bin/lib/Image/ExifTool/ASF.pm +1 -1
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +4 -3
- data/bin/lib/Image/ExifTool/Canon.pm +19 -1
- data/bin/lib/Image/ExifTool/DJI.pm +1 -1
- data/bin/lib/Image/ExifTool/Exif.pm +2 -2
- data/bin/lib/Image/ExifTool/FITS.pm +2 -2
- data/bin/lib/Image/ExifTool/FLIF.pm +2 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +11 -11
- data/bin/lib/Image/ExifTool/Font.pm +1 -1
- data/bin/lib/Image/ExifTool/HP.pm +1 -1
- data/bin/lib/Image/ExifTool/ID3.pm +3 -3
- data/bin/lib/Image/ExifTool/IPTC.pm +2 -2
- data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +6 -6
- data/bin/lib/Image/ExifTool/M2TS.pm +39 -9
- data/bin/lib/Image/ExifTool/MXF.pm +2 -2
- data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
- data/bin/lib/Image/ExifTool/PDF.pm +15 -15
- data/bin/lib/Image/ExifTool/PLIST.pm +1 -1
- data/bin/lib/Image/ExifTool/PNG.pm +4 -4
- data/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +3 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +63 -3
- data/bin/lib/Image/ExifTool/Protobuf.pm +4 -4
- data/bin/lib/Image/ExifTool/QuickTime.pm +23 -14
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +336 -91
- data/bin/lib/Image/ExifTool/README +4 -1
- data/bin/lib/Image/ExifTool/RIFF.pm +3 -3
- data/bin/lib/Image/ExifTool/RTF.pm +1 -1
- data/bin/lib/Image/ExifTool/Ricoh.pm +3 -3
- data/bin/lib/Image/ExifTool/Sony.pm +2 -2
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +4 -3
- data/bin/lib/Image/ExifTool/TagLookup.pm +6979 -6970
- data/bin/lib/Image/ExifTool/TagNames.pod +26 -5
- data/bin/lib/Image/ExifTool/VCard.pm +2 -2
- data/bin/lib/Image/ExifTool/Validate.pm +3 -3
- data/bin/lib/Image/ExifTool/WriteExif.pl +2 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +4 -4
- data/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
- data/bin/lib/Image/ExifTool/Writer.pl +16 -16
- data/bin/lib/Image/ExifTool/XMP.pm +9 -9
- data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
- data/bin/lib/Image/ExifTool.pm +58 -57
- data/bin/lib/Image/ExifTool.pod +1 -1
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53adc02bd5bb808506a883f10c449fd0172d7d82c099a4c5d5a4dbbcb9971d68
|
4
|
+
data.tar.gz: 76a6795061f0128324568a9907804699dd0635e94bc7042bf5ba1cb3c40c92e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd68829340a5e18d410b4485e0789bef799d78d2fb7d6ff49612fa4a596b918c86b3515c2cd0ef0d90a0a04c72403a7a2113b86d882c93d5a4e0495d01573bbd
|
7
|
+
data.tar.gz: d44cfcbc7dd21d7e74bc26ea46fcdf19f724ccffcb08e7375f21ae58f1544fcc753804348bb61f3dc706b984e5b8bdc43437f296e85a7e8767c1a168be879df9
|
data/bin/Changes
CHANGED
@@ -7,14 +7,40 @@ RSS feed: https://exiftool.org/rss.xml
|
|
7
7
|
Note: The most recent production release is Version 13.00. (Other versions are
|
8
8
|
considered development releases, and are not uploaded to MetaCPAN.)
|
9
9
|
|
10
|
+
Dec. 14, 2024 - Version 13.08
|
11
|
+
|
12
|
+
- Decode ShutterCount for Canon EOS R6 Mark II (thanks Agoston Kapitany)
|
13
|
+
- Decode a few new Photoshop tags
|
14
|
+
- Suppress all duplicate Warning tags and add count to end of message
|
15
|
+
- Changed format of bitmask keys in -list x output
|
16
|
+
- Internal streamlining of LIGOGPSINFO decoding
|
17
|
+
- Fixed issue where some tags were incorrectly shown as writable in -listx
|
18
|
+
output
|
19
|
+
- Fixed incorrect scaling for GPSSpeed in one LIGOGPSINFO variant
|
20
|
+
- Fixed an issue with filename encoding when the -L option is used and the API
|
21
|
+
WindowsLongPath option is active
|
22
|
+
|
23
|
+
Dec. 11, 2024 - Version 13.07
|
24
|
+
|
25
|
+
- Decode a number of LIGOGPSINFO encrypted and enciphered timed GPS types
|
26
|
+
(long overdue, but it took me a couple of years to acquire enough sample
|
27
|
+
videos to have a good cross-section of the different formats)
|
28
|
+
- Fixed another place where FileSequence could be incremented twice when a -if
|
29
|
+
condition was used
|
30
|
+
- Fixed a few places where character 0x7f may not have been escaped in string
|
31
|
+
values
|
32
|
+
- API Changes:
|
33
|
+
- Changed default WindowsLongPath option back to 1 after adding a patch to
|
34
|
+
fix issue with piping from stdin
|
35
|
+
|
10
36
|
Dec. 5, 2024 - Version 13.06
|
11
37
|
|
12
38
|
- Decode timed metadata from MP4 videos of yet another dashcam model
|
13
39
|
- Patched issue where FileSequence could increment twice for each file when a
|
14
40
|
-if condition was used
|
15
41
|
- API Changes:
|
16
|
-
- Revert default
|
17
|
-
problem
|
42
|
+
- Revert default WindowsLongPath option to the pre-13.05 setting
|
43
|
+
until we can solve the pipe problem
|
18
44
|
|
19
45
|
Dec. 4, 2024 - Version 13.05
|
20
46
|
|
@@ -24,7 +50,7 @@ Dec. 4, 2024 - Version 13.05
|
|
24
50
|
- Decode APP10 AROT HDRGainCurve and APP2 URN UniformResourceName
|
25
51
|
- Decode a couple of new GoPro tags
|
26
52
|
- API Changes:
|
27
|
-
- Changed default
|
53
|
+
- Changed default WindowsLongPath option to 1 (please report if this
|
28
54
|
causes any problems)
|
29
55
|
|
30
56
|
Nov. 26, 2024 - Version 13.04
|
data/bin/META.json
CHANGED
data/bin/META.yml
CHANGED
data/bin/README
CHANGED
@@ -109,8 +109,8 @@ your home directory, then you would type the following commands in a
|
|
109
109
|
terminal window to extract and run ExifTool:
|
110
110
|
|
111
111
|
cd ~/Desktop
|
112
|
-
gzip -dc Image-ExifTool-13.
|
113
|
-
cd Image-ExifTool-13.
|
112
|
+
gzip -dc Image-ExifTool-13.08.tar.gz | tar -xf -
|
113
|
+
cd Image-ExifTool-13.08
|
114
114
|
./exiftool t/images/ExifTool.jpg
|
115
115
|
|
116
116
|
Note: These commands extract meta information from one of the test images.
|
data/bin/exiftool
CHANGED
@@ -11,7 +11,7 @@ use strict;
|
|
11
11
|
use warnings;
|
12
12
|
require 5.004;
|
13
13
|
|
14
|
-
my $version = '13.
|
14
|
+
my $version = '13.08';
|
15
15
|
|
16
16
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
17
17
|
my $exePath;
|
@@ -2172,7 +2172,8 @@ sub GetImageInfo($$)
|
|
2172
2172
|
}
|
2173
2173
|
# can't make use of $info if verbose because we must reprocess
|
2174
2174
|
# the file anyway to generate the verbose output
|
2175
|
-
|
2175
|
+
# (also if writing just to avoid double-incrementing FileSequence)
|
2176
|
+
if ($isWriting or $verbose or defined $fastCondition or defined $diff) {
|
2176
2177
|
undef $info;
|
2177
2178
|
--$$et{FILE_SEQUENCE};
|
2178
2179
|
}
|
@@ -3639,7 +3640,7 @@ sub EscapeJSON($;$)
|
|
3639
3640
|
if ($json < 2) { # JSON
|
3640
3641
|
$str =~ tr/\0//d; # remove all nulls
|
3641
3642
|
# escape other control characters with \u
|
3642
|
-
$str =~ s/([\0-\x1f])/sprintf("\\u%.4X",ord $1)/sge;
|
3643
|
+
$str =~ s/([\0-\x1f\x7f])/sprintf("\\u%.4X",ord $1)/sge;
|
3643
3644
|
# JSON strings must be valid UTF8
|
3644
3645
|
Image::ExifTool::XMP::FixUTF8(\$str) unless $altEnc;
|
3645
3646
|
} else { # PHP
|
@@ -3647,7 +3648,7 @@ sub EscapeJSON($;$)
|
|
3647
3648
|
# must escape "$" too for PHP
|
3648
3649
|
$str =~ s/\$/\\\$/sg;
|
3649
3650
|
# escape other control characters with \x
|
3650
|
-
$str =~ s/([\0-\x1f])/sprintf("\\x%.2X",ord $1)/sge;
|
3651
|
+
$str =~ s/([\0-\x1f\x7f])/sprintf("\\x%.2X",ord $1)/sge;
|
3651
3652
|
}
|
3652
3653
|
return '"' . $str . '"'; # return the quoted string
|
3653
3654
|
}
|
@@ -5912,7 +5913,7 @@ with this command:
|
|
5912
5913
|
|
5913
5914
|
produces output like this:
|
5914
5915
|
|
5915
|
-
-- Generated by ExifTool 13.
|
5916
|
+
-- Generated by ExifTool 13.08 --
|
5916
5917
|
File: a.jpg - 2003:10:31 15:44:19
|
5917
5918
|
(f/5.6, 1/60s, ISO 100)
|
5918
5919
|
File: b.jpg - 2006:05:23 11:57:38
|
@@ -231,7 +231,7 @@ sub ProcessAIFF($$)
|
|
231
231
|
$et->Warn('End of processing at large chunk (LargeFileSupport not enabled)');
|
232
232
|
last;
|
233
233
|
} elsif ($et->Options('LargeFileSupport') eq '2') {
|
234
|
-
$et->
|
234
|
+
$et->Warn('Skipping large chunk (LargeFileSupport is 2)');
|
235
235
|
}
|
236
236
|
}
|
237
237
|
if ($tagInfo) {
|
@@ -217,7 +217,7 @@ sub ProcessAPE($$)
|
|
217
217
|
$val = \$buf2;
|
218
218
|
# extract cover art description separately (hackitty hack)
|
219
219
|
if ($tag =~ /^Cover Art/) {
|
220
|
-
$buf2 =~ s/^([\x20-\
|
220
|
+
$buf2 =~ s/^([\x20-\x7e]*)\0//;
|
221
221
|
if ($1) {
|
222
222
|
my $t = "$tag Desc";
|
223
223
|
my $v = $1;
|
@@ -781,7 +781,7 @@ sub ProcessASF($$;$)
|
|
781
781
|
$err = 'Invalid ASF object size';
|
782
782
|
} elsif ($et->Options('LargeFileSupport')) {
|
783
783
|
if ($et->Options('LargeFileSupport') eq '2') {
|
784
|
-
$et->
|
784
|
+
$et->Warn('Skipping large ASF object (LargeFileSupport is 2)');
|
785
785
|
}
|
786
786
|
if ($raf->Seek($size, 1)) {
|
787
787
|
$et->VPrint(0, " Skipped large ASF object ($size bytes)\n");
|
@@ -35,7 +35,7 @@ use Image::ExifTool::Sony;
|
|
35
35
|
use Image::ExifTool::Validate;
|
36
36
|
use Image::ExifTool::MacOS;
|
37
37
|
|
38
|
-
$VERSION = '3.
|
38
|
+
$VERSION = '3.59';
|
39
39
|
@ISA = qw(Exporter);
|
40
40
|
|
41
41
|
sub NumbersFirst($$);
|
@@ -869,7 +869,8 @@ sub new
|
|
869
869
|
my $processBinaryData = ($$table{PROCESS_PROC} and (
|
870
870
|
$$table{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData or
|
871
871
|
$$table{PROCESS_PROC} eq \&Image::ExifTool::Nikon::ProcessNikonEncrypted or
|
872
|
-
$$table{PROCESS_PROC} eq \&Image::ExifTool::Sony::ProcessEnciphered)
|
872
|
+
$$table{PROCESS_PROC} eq \&Image::ExifTool::Sony::ProcessEnciphered) or
|
873
|
+
$$table{VARS} and $$table{VARS}{IS_BINARY});
|
873
874
|
if ($$vars{ID_LABEL} or $processBinaryData) {
|
874
875
|
my $s = $$table{FORMAT} ? Image::ExifTool::FormatSize($$table{FORMAT}) || 1 : 1;
|
875
876
|
$binaryTable = 1;
|
@@ -1248,7 +1249,7 @@ TagID: foreach $tagID (@keys) {
|
|
1248
1249
|
}
|
1249
1250
|
} elsif ($$tagInfo{PrintString} or not /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/) {
|
1250
1251
|
# translate unprintable values
|
1251
|
-
if ($index =~ s/([\x00-\x1f\
|
1252
|
+
if ($index =~ s/([\x00-\x1f\x7f-\xff])/sprintf("\\x%.2x",ord $1)/eg) {
|
1252
1253
|
$index = qq{"$index"};
|
1253
1254
|
} else {
|
1254
1255
|
$index = qq{'${index}'};
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
88
88
|
sub ProcessExifInfo($$$);
|
89
89
|
sub SwapWords($);
|
90
90
|
|
91
|
-
$VERSION = '4.
|
91
|
+
$VERSION = '4.86';
|
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)
|
@@ -1404,6 +1404,11 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
|
|
1404
1404
|
Condition => '$$self{Model} =~ /\bEOS R[56]$/',
|
1405
1405
|
SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoR6' },
|
1406
1406
|
},
|
1407
|
+
{
|
1408
|
+
Name => 'CanonCameraInfoR6m2',
|
1409
|
+
Condition => '$$self{Model} =~ /\bEOS R6m2$/',
|
1410
|
+
SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoR6m2' },
|
1411
|
+
},
|
1407
1412
|
{
|
1408
1413
|
Name => 'CanonCameraInfoG5XII',
|
1409
1414
|
Condition => '$$self{Model} =~ /\bG5 X Mark II$/',
|
@@ -4752,6 +4757,19 @@ my %ciMaxFocal = (
|
|
4752
4757
|
# 0x0bb7 - counts down during focus stack (ref forum16111)
|
4753
4758
|
);
|
4754
4759
|
|
4760
|
+
%Image::ExifTool::Canon::CameraInfoR6m2 = (
|
4761
|
+
%binaryDataAttrs,
|
4762
|
+
FIRST_ENTRY => 0,
|
4763
|
+
PRIORITY => 0,
|
4764
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
|
4765
|
+
NOTES => 'CameraInfo tags for the EOS R6 Mark II.',
|
4766
|
+
0x0d29 => { #AgostonKapitany
|
4767
|
+
Name => 'ShutterCount',
|
4768
|
+
Format => 'int32u',
|
4769
|
+
Notes => 'includes electronic + mechanical shutter',
|
4770
|
+
},
|
4771
|
+
);
|
4772
|
+
|
4755
4773
|
# ref https://exiftool.org/forum/index.php?topic=15356.0
|
4756
4774
|
%Image::ExifTool::Canon::CameraInfoG5XII = (
|
4757
4775
|
%binaryDataAttrs,
|
@@ -295,7 +295,7 @@ sub ProcessDJIInfo($$$)
|
|
295
295
|
while ($$dataPt =~ /\G\[(.*?)\](?=(\[|$))/sg) {
|
296
296
|
my ($tag, $val) = split /:/, $1, 2;
|
297
297
|
next unless defined $tag and defined $val;
|
298
|
-
if ($val =~ /^([\x20-\
|
298
|
+
if ($val =~ /^([\x20-\x7e]+)\0*$/) {
|
299
299
|
$val = $1;
|
300
300
|
} else {
|
301
301
|
my $buff = $val;
|
@@ -6186,7 +6186,7 @@ sub ProcessExif($$$)
|
|
6186
6186
|
if ($$dirInfo{DirName} eq 'MakerNotes' and $$et{FileType} eq 'CR3' and
|
6187
6187
|
$$dirInfo{Parent} and $$dirInfo{Parent} eq 'ExifIFD')
|
6188
6188
|
{
|
6189
|
-
$et->
|
6189
|
+
$et->Warn("MakerNotes shouldn't exist ExifIFD of CR3 image", 1);
|
6190
6190
|
}
|
6191
6191
|
# set flag to calculate image data hash if requested
|
6192
6192
|
$doHash = 1 if $$et{ImageDataHash} and (($$et{FILE_TYPE} eq 'TIFF' and not $base and not $inMakerNotes) or
|
@@ -6656,7 +6656,7 @@ sub ProcessExif($$$)
|
|
6656
6656
|
if ($count > 500 and $formatStr !~ /^(undef|string|binary)$/ and
|
6657
6657
|
(not $tagInfo or $$tagInfo{LongBinary} or $warned) and not $$et{OPTIONS}{IgnoreMinorErrors})
|
6658
6658
|
{
|
6659
|
-
$et->
|
6659
|
+
$et->Warn('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
|
6660
6660
|
next if $$et{TAGS_FROM_FILE}; # don't generate bogus value when copying tags
|
6661
6661
|
$val = "(large array of $count $formatStr values)";
|
6662
6662
|
} else {
|
@@ -61,7 +61,7 @@ sub ProcessFITS($$)
|
|
61
61
|
my $key = substr($buff, 0, 8);
|
62
62
|
$key =~ s/ +$//; # remove trailing space from key
|
63
63
|
if ($key eq 'CONTINUE') {
|
64
|
-
defined $continue or $et->
|
64
|
+
defined $continue or $et->Warn('Unexpected FITS CONTINUE keyword'), next;
|
65
65
|
} else {
|
66
66
|
if (defined $continue) {
|
67
67
|
# the previous value wasn't continued, so store with the trailing '&'
|
@@ -104,7 +104,7 @@ sub ProcessFITS($$)
|
|
104
104
|
# check for possible continuation, removing trailing '&'
|
105
105
|
$val =~ s/\&$// and $continue = $val, next;
|
106
106
|
} elsif (defined $continue) {
|
107
|
-
$et->
|
107
|
+
$et->Warn('Invalid FITS CONTINUE value');
|
108
108
|
next;
|
109
109
|
} else {
|
110
110
|
$val =~ s/ *(\/.*)?$//; # remove trailing spaces and comment
|
@@ -244,7 +244,7 @@ sub WriteFLIF($$)
|
|
244
244
|
}
|
245
245
|
}
|
246
246
|
} else {
|
247
|
-
$et->
|
247
|
+
$et->Warn('Install IO::Compress::RawDeflate to write FLIF metadata');
|
248
248
|
}
|
249
249
|
Write($outfile, $tag, SetVarInt(length $buff), $buff) or return -1;
|
250
250
|
} elsif (not defined $soi) {
|
@@ -301,7 +301,7 @@ sub ProcessFLIF($$)
|
|
301
301
|
$et->Warn("Error inflating FLIF $tag chunk");
|
302
302
|
}
|
303
303
|
} else {
|
304
|
-
$et->
|
304
|
+
$et->Warn('Install IO::Uncompress::RawInflate to decode FLIF metadata');
|
305
305
|
}
|
306
306
|
} else {
|
307
307
|
$raf->Seek($size, 1) or $et->Warn('Seek error'), last;
|
@@ -1449,7 +1449,7 @@ sub ReadFPXValue($$$$$;$$)
|
|
1449
1449
|
$noPad = 1; # values sometimes aren't padded inside vectors!!
|
1450
1450
|
my $size = $oleFormatSize{VT_VECTOR};
|
1451
1451
|
if ($valPos + $size > $dirEnd) {
|
1452
|
-
$et->
|
1452
|
+
$et->Warn('Incorrect FPX VT_VECTOR size');
|
1453
1453
|
last;
|
1454
1454
|
}
|
1455
1455
|
$count = Get32u($dataPt, $valPos);
|
@@ -1457,14 +1457,14 @@ sub ReadFPXValue($$$$$;$$)
|
|
1457
1457
|
$valPos += 4;
|
1458
1458
|
} else {
|
1459
1459
|
# can't yet handle this property flag
|
1460
|
-
$et->
|
1460
|
+
$et->Warn('Unknown FPX property');
|
1461
1461
|
last;
|
1462
1462
|
}
|
1463
1463
|
}
|
1464
1464
|
unless ($format =~ /^VT_/) {
|
1465
1465
|
my $size = Image::ExifTool::FormatSize($format) * $count;
|
1466
1466
|
if ($valPos + $size > $dirEnd) {
|
1467
|
-
$et->
|
1467
|
+
$et->Warn("Incorrect FPX $format size");
|
1468
1468
|
last;
|
1469
1469
|
}
|
1470
1470
|
@vals = ReadValue($dataPt, $valPos, $format, $count, $size);
|
@@ -1476,7 +1476,7 @@ sub ReadFPXValue($$$$$;$$)
|
|
1476
1476
|
my ($item, $val, $len);
|
1477
1477
|
for ($item=0; $item<$count; ++$item) {
|
1478
1478
|
if ($valPos + $size > $dirEnd) {
|
1479
|
-
$et->
|
1479
|
+
$et->Warn("Truncated FPX $format value");
|
1480
1480
|
last;
|
1481
1481
|
}
|
1482
1482
|
# sometimes VT_VECTOR items are padded to even 4-byte boundaries, and sometimes they aren't
|
@@ -1528,7 +1528,7 @@ sub ReadFPXValue($$$$$;$$)
|
|
1528
1528
|
$len = Get32u($dataPt, $valPos);
|
1529
1529
|
$len *= 2 if $format eq 'VT_LPWSTR'; # convert to byte count
|
1530
1530
|
if ($valPos + $len + 4 > $dirEnd) {
|
1531
|
-
$et->
|
1531
|
+
$et->Warn("Truncated $format value");
|
1532
1532
|
last;
|
1533
1533
|
}
|
1534
1534
|
$val = substr($$dataPt, $valPos + 4, $len);
|
@@ -1551,7 +1551,7 @@ sub ReadFPXValue($$$$$;$$)
|
|
1551
1551
|
} elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') {
|
1552
1552
|
my $len = Get32u($dataPt, $valPos); # (use local $len because we always expect padding)
|
1553
1553
|
if ($valPos + $len + 4 > $dirEnd) {
|
1554
|
-
$et->
|
1554
|
+
$et->Warn("Truncated $format value");
|
1555
1555
|
last;
|
1556
1556
|
}
|
1557
1557
|
$val = substr($$dataPt, $valPos + 4, $len);
|
@@ -1627,7 +1627,7 @@ sub ProcessContents($$$)
|
|
1627
1627
|
while ($$dataPt =~ /\x0bTargetRole1(?:.\x80|\xff\xff.\0.\0Vn(\w+))\0\0\x01.{4}(.{24})/sg) {
|
1628
1628
|
my ($index, @coords) = unpack('Vx4V4', $2);
|
1629
1629
|
next if $index == 0xffffffff;
|
1630
|
-
$$et{IeImg_lkup}{$index} and $et->
|
1630
|
+
$$et{IeImg_lkup}{$index} and $et->Warn('Duplicate image index');
|
1631
1631
|
$$et{IeImg_lkup}{$index} = "@coords";
|
1632
1632
|
$$et{IeImg_class}{$index} = $1 if $1;
|
1633
1633
|
}
|
@@ -1661,7 +1661,7 @@ sub ProcessWordDocument($$$)
|
|
1661
1661
|
my $dirLen = length $$dataPt;
|
1662
1662
|
# validate the FIB signature
|
1663
1663
|
unless ($dirLen > 2 and Get16u($dataPt,0) == 0xa5ec) {
|
1664
|
-
$et->
|
1664
|
+
$et->Warn('Invalid FIB signature', 1);
|
1665
1665
|
return 0;
|
1666
1666
|
}
|
1667
1667
|
$et->ProcessBinaryData($dirInfo, $tagTablePtr); # process FIB
|
@@ -2098,7 +2098,7 @@ sub ProcessFPXR($$$)
|
|
2098
2098
|
my $overlap = length($$obj{Stream}) - $offset;
|
2099
2099
|
my $start = $dirStart + 13;
|
2100
2100
|
if ($overlap < 0 or $dirLen - $overlap < 13) {
|
2101
|
-
$et->
|
2101
|
+
$et->Warn("Bad FPXR stream $index offset",1);
|
2102
2102
|
} else {
|
2103
2103
|
# ignore any overlapping data in this segment
|
2104
2104
|
# (this seems to be the convention)
|
@@ -2338,7 +2338,7 @@ sub ProcessFPX($$)
|
|
2338
2338
|
$tag =~ s/\0.*//s; # truncate at null (in case length was wrong)
|
2339
2339
|
|
2340
2340
|
if ($tag eq '0' and not defined $ee) {
|
2341
|
-
$et->
|
2341
|
+
$et->Warn('Use the ExtractEmbedded option to extract embedded information', 3);
|
2342
2342
|
}
|
2343
2343
|
my $sect = Get32u(\$dir, $pos + 0x74); # start sector number
|
2344
2344
|
my $size = Get32u(\$dir, $pos + 0x78); # stream length
|
@@ -2441,7 +2441,7 @@ sub ProcessFPX($$)
|
|
2441
2441
|
my $subTablePtr = GetTagTable($$subdir{TagTable});
|
2442
2442
|
$et->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc});
|
2443
2443
|
} elsif (defined $size and $size > length($buff)) {
|
2444
|
-
$et->
|
2444
|
+
$et->Warn('Truncated object');
|
2445
2445
|
} else {
|
2446
2446
|
$buff = substr($buff, 0, $size) if defined $size and $size < length($buff);
|
2447
2447
|
if ($tag =~ /^IeImg_0*(\d+)$/) {
|
@@ -405,7 +405,7 @@ sub ProcessOTF($$)
|
|
405
405
|
next;
|
406
406
|
}
|
407
407
|
if ($verbose) {
|
408
|
-
$tag =~ s/([\0-\x1f\
|
408
|
+
$tag =~ s/([\0-\x1f\x7f-\xff])/sprintf('\x%.2x',ord $1)/ge;
|
409
409
|
my $str = sprintf("%s%d) Tag '%s' (offset 0x%.4x, %d bytes)\n",
|
410
410
|
$$et{INDENT}, $pos/16, $tag, $offset, $size);
|
411
411
|
$et->VPrint(0, $str);
|
@@ -225,7 +225,7 @@ sub ProcessHP($$$)
|
|
225
225
|
# scan for other tag ID's
|
226
226
|
foreach $tagID (sort(TagTableKeys($tagTablePtr))) {
|
227
227
|
next if $tagID eq 'PreviewImage';
|
228
|
-
next unless $$dataPt =~ /$tagID:\s*([\x20-\
|
228
|
+
next unless $$dataPt =~ /$tagID:\s*([\x20-\x7e]+)/i;
|
229
229
|
$et->HandleTag($tagTablePtr, $tagID, $1);
|
230
230
|
}
|
231
231
|
return 1;
|
@@ -1169,7 +1169,7 @@ sub ProcessID3v2($$$)
|
|
1169
1169
|
}
|
1170
1170
|
$tagInfo = $et->GetTagInfo($otherTable, $id) if $otherTable;
|
1171
1171
|
if ($tagInfo) {
|
1172
|
-
$et->
|
1172
|
+
$et->Warn("Frame '${id}' is not valid for this ID3 version", 1);
|
1173
1173
|
} else {
|
1174
1174
|
next unless $verbose or $et->Options('Unknown');
|
1175
1175
|
$id =~ tr/-A-Za-z0-9_//dc;
|
@@ -1198,7 +1198,7 @@ sub ProcessID3v2($$$)
|
|
1198
1198
|
}
|
1199
1199
|
}
|
1200
1200
|
if ($flags{Encrypt}) {
|
1201
|
-
$et->
|
1201
|
+
$et->Warn('Encrypted frames currently not supported');
|
1202
1202
|
next;
|
1203
1203
|
}
|
1204
1204
|
# extract the value
|
@@ -1232,7 +1232,7 @@ sub ProcessID3v2($$$)
|
|
1232
1232
|
next;
|
1233
1233
|
}
|
1234
1234
|
} else {
|
1235
|
-
$et->
|
1235
|
+
$et->Warn('Install Compress::Zlib to decode compressed frames');
|
1236
1236
|
next;
|
1237
1237
|
}
|
1238
1238
|
}
|
@@ -1025,7 +1025,7 @@ sub TranslateCodedString($$$$)
|
|
1025
1025
|
$$valPtr = $et->Decode($$valPtr, $$xlatPtr);
|
1026
1026
|
} else {
|
1027
1027
|
# don't yet support reading ISO 2022 shifted character sets
|
1028
|
-
$et->
|
1028
|
+
$et->Warn('Some IPTC characters not converted (ISO 2022 shifting not supported)');
|
1029
1029
|
}
|
1030
1030
|
}
|
1031
1031
|
|
@@ -1164,7 +1164,7 @@ sub ProcessIPTC($$$)
|
|
1164
1164
|
}
|
1165
1165
|
my $tableInfo = $tagTablePtr->{$rec};
|
1166
1166
|
unless ($tableInfo) {
|
1167
|
-
$et->
|
1167
|
+
$et->Warn("Unrecognized IPTC record $rec (ignored)");
|
1168
1168
|
$pos += $len;
|
1169
1169
|
next; # ignore this entry
|
1170
1170
|
}
|
@@ -78,7 +78,7 @@ sub ProcessIND($$)
|
|
78
78
|
$err = 'InDesign files larger than 2 GB not supported (LargeFileSupport not set)';
|
79
79
|
goto DONE;
|
80
80
|
} elsif ($et->Options('LargeFileSupport') eq '2') {
|
81
|
-
$et->
|
81
|
+
$et->Warn('Processing large file (LargeFileSupport is 2)');
|
82
82
|
}
|
83
83
|
}
|
84
84
|
if ($outfile) {
|
@@ -866,8 +866,8 @@ sub BrotliWarn($$;$)
|
|
866
866
|
{
|
867
867
|
my ($et, $type, $uncompress) = @_;
|
868
868
|
my ($enc, $mod) = $uncompress ? qw(decoding Uncompress) : qw(encoding Compress);
|
869
|
-
$et->
|
870
|
-
$et->
|
869
|
+
$et->Warn("Error $enc '${type}' brob box");
|
870
|
+
$et->Warn("Try updating to IO::${mod}::Brotli 0.004 or later");
|
871
871
|
}
|
872
872
|
|
873
873
|
#------------------------------------------------------------------------------
|
@@ -933,7 +933,7 @@ sub CreateNewBoxes($$)
|
|
933
933
|
$tag = 'brob';
|
934
934
|
}
|
935
935
|
} else {
|
936
|
-
$et->
|
936
|
+
$et->Warn('Install IO::Compress::Brotli to create Brotli-compressed metadata');
|
937
937
|
}
|
938
938
|
}
|
939
939
|
my $boxhdr = pack('N', length($newdir) + length($pad) + 8) . $tag;
|
@@ -1285,7 +1285,7 @@ sub ProcessJpeg2000Box($$$)
|
|
1285
1285
|
++$$et{CHANGED};
|
1286
1286
|
}
|
1287
1287
|
} else {
|
1288
|
-
$et->
|
1288
|
+
$et->Warn('Install IO::Compress::Brotli to write Brotli-compressed metadata');
|
1289
1289
|
}
|
1290
1290
|
} elsif (not $compress and $boxID eq 'brob') {
|
1291
1291
|
# (in this case, ProcessBrotli has returned uncompressed data,
|
@@ -1410,7 +1410,7 @@ sub ProcessBrotli($$$)
|
|
1410
1410
|
}
|
1411
1411
|
if (eval { require IO::Uncompress::Brotli }) {
|
1412
1412
|
if ($isWriting and not eval { require IO::Compress::Brotli }) {
|
1413
|
-
$et->
|
1413
|
+
$et->Warn('Install IO::Compress::Brotli to write Brotli-compressed metadata');
|
1414
1414
|
return undef;
|
1415
1415
|
}
|
1416
1416
|
my $compress = $et->Options('Compress');
|
@@ -1455,7 +1455,7 @@ sub ProcessBrotli($$$)
|
|
1455
1455
|
return $type . $dat;
|
1456
1456
|
}
|
1457
1457
|
} else {
|
1458
|
-
$et->
|
1458
|
+
$et->Warn('Install IO::Uncompress::Brotli to decode Brotli-compressed metadata');
|
1459
1459
|
return undef if $isWriting;
|
1460
1460
|
}
|
1461
1461
|
return 1;
|
@@ -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.28';
|
36
36
|
|
37
37
|
# program map table "stream_type" lookup (ref 6/1/9)
|
38
38
|
my %streamType = (
|
@@ -305,6 +305,15 @@ sub ParsePID($$$$$)
|
|
305
305
|
# MPEG-1/MPEG-2 Audio
|
306
306
|
require Image::ExifTool::MPEG;
|
307
307
|
Image::ExifTool::MPEG::ParseMPEGAudio($et, $dataPt);
|
308
|
+
} elsif ($type == 6 and $pid == 0x0300) {
|
309
|
+
# LIGOGPSINFO from unknown dashcam (../testpics/gps_video/Wrong Way pass.ts)
|
310
|
+
if ($$dataPt =~ /^LIGOGPSINFO/s) {
|
311
|
+
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
312
|
+
my %dirInfo = ( DataPt => $dataPt, DirName => 'Ligo0x0300' );
|
313
|
+
Image::ExifTool::QuickTime::ProcessLigoGPS($et, \%dirInfo, $tbl, 1);
|
314
|
+
$$et{FoundGoodGPS} = 1;
|
315
|
+
$more = 1;
|
316
|
+
}
|
308
317
|
} elsif ($type == 0x1b) {
|
309
318
|
# H.264 Video
|
310
319
|
require Image::ExifTool::H264;
|
@@ -313,7 +322,7 @@ sub ParsePID($$$$$)
|
|
313
322
|
if ($$et{OPTIONS}{ExtractEmbedded}) {
|
314
323
|
$more = 1;
|
315
324
|
} elsif (not $$et{OPTIONS}{Validate}) {
|
316
|
-
$et->
|
325
|
+
$et->Warn('The ExtractEmbedded option may find more tags in the video data',3);
|
317
326
|
}
|
318
327
|
} elsif ($type == 0x81 or $type == 0x87 or $type == 0x91) {
|
319
328
|
# AC-3 audio
|
@@ -459,11 +468,11 @@ sub ParsePID($$$$$)
|
|
459
468
|
$bad = 1 if $_ < 0x30 or $_ > 0x39;
|
460
469
|
}
|
461
470
|
if ($bad) {
|
462
|
-
$et->
|
471
|
+
$et->Warn('Error decrypting GPS degrees');
|
463
472
|
} else {
|
464
473
|
my $la = pack('C*', @chars[0,1]);
|
465
474
|
my $lo = pack('C*', @chars[2,3,4]);
|
466
|
-
$et->
|
475
|
+
$et->Warn('Decryption of this GPS is highly experimental. More testing samples are required');
|
467
476
|
$et->HandleTag($tagTbl, GPSLatitude => (($la || 0) + (($6-85.95194)/2.43051724137931+42.2568)/60) * ($7 eq 'N' ? 1 : -1));
|
468
477
|
$et->HandleTag($tagTbl, GPSLongitude => (($lo || 0) + (($9-70.14674)/1.460987654320988+9.2028)/60) * ($10 eq 'E' ? 1 : -1));
|
469
478
|
}
|
@@ -476,7 +485,7 @@ sub ParsePID($$$$$)
|
|
476
485
|
my $lon = abs(GetFloat($dataPt, 56)); # (abs just to be safe)
|
477
486
|
my $spd = GetFloat($dataPt, 64);
|
478
487
|
my $trk = GetFloat($dataPt, 68);
|
479
|
-
$et->
|
488
|
+
$et->Warn('GPSLatitude/Longitude encryption is not yet known, so these will be wrong');
|
480
489
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
481
490
|
my @date = unpack('x32V3x28V3', $$dataPt);
|
482
491
|
$date[3] += 2000;
|
@@ -514,9 +523,16 @@ sub ParsePID($$$$$)
|
|
514
523
|
$et->HandleTag($tagTbl, GPSTrack => $a[2] / 100);
|
515
524
|
}
|
516
525
|
# Note: 10 bytes after last GPS record look like a single 3-axis accelerometer reading:
|
517
|
-
# eg. fd ff 00 00 ff ff 00 00 01 00
|
526
|
+
# eg. fd ff 00 00 ff ff 00 00 01 00
|
518
527
|
$$et{FoundGoodGPS} = 1; # so we skip over unrecognized packets
|
519
528
|
$more = 1;
|
529
|
+
} elsif ($$dataPt =~ /^skip.{4}LIGOGPSINFO\0/s) {
|
530
|
+
# (this record contains 2 copies of the same 'skip' atom in my sample --
|
531
|
+
# only extract data from the first one)
|
532
|
+
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
533
|
+
my %dirInfo = ( DataPt => $dataPt, DirStart => 8, DirName => sprintf('Ligo0x%.4x',$pid));
|
534
|
+
Image::ExifTool::QuickTime::ProcessLigoGPS($et, \%dirInfo, $tbl, 1);
|
535
|
+
$$et{FoundGoodGPS} = 1;
|
520
536
|
} elsif ($$et{FoundGoodGPS}) {
|
521
537
|
$more = 1;
|
522
538
|
}
|
@@ -694,7 +710,7 @@ sub ProcessM2TS($$)
|
|
694
710
|
# or if we are just looking for the last timestamp
|
695
711
|
next unless $payload_data_exists and not defined $backScan;
|
696
712
|
|
697
|
-
|
713
|
+
# decode payload data
|
698
714
|
if ($pid == 0 or # program association table
|
699
715
|
defined $pmt{$pid}) # program map table(s)
|
700
716
|
{
|
@@ -787,7 +803,7 @@ sub ProcessM2TS($$)
|
|
787
803
|
last if $j + $descriptor_length > $program_info_length;
|
788
804
|
my $desc = substr($buf2, $pos+$j, $descriptor_length);
|
789
805
|
$j += $descriptor_length;
|
790
|
-
$desc =~ s/([\x00-\x1f\
|
806
|
+
$desc =~ s/([\x00-\x1f\x7f-\xff])/sprintf("\\x%.2x",ord $1)/eg;
|
791
807
|
printf $out " Program Descriptor: Type=0x%.2x \"$desc\"\n", $descriptor_tag;
|
792
808
|
}}
|
793
809
|
$pos += $program_info_length; # skip descriptors (for now)
|
@@ -822,7 +838,7 @@ sub ProcessM2TS($$)
|
|
822
838
|
$j += $descriptor_length;
|
823
839
|
if ($verbose > 1) {
|
824
840
|
my $dstr = $desc;
|
825
|
-
$dstr =~ s/([\x00-\x1f\
|
841
|
+
$dstr =~ s/([\x00-\x1f\x7f-\xff])/sprintf("\\x%.2x",ord $1)/eg;
|
826
842
|
printf $out " ES Descriptor: Type=0x%.2x \"$dstr\"\n", $descriptor_tag;
|
827
843
|
}
|
828
844
|
# parse type-specific descriptor information (once)
|
@@ -954,6 +970,20 @@ sub ProcessM2TS($$)
|
|
954
970
|
ParsePID($et, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
|
955
971
|
delete $data{$pid};
|
956
972
|
}
|
973
|
+
|
974
|
+
# look for LIGOGPSINFO trailer
|
975
|
+
if ($et->Options('ExtractEmbedded') and
|
976
|
+
$raf->Seek(-8, 2) and $raf->Read($buff, 8) == 8 and
|
977
|
+
$buff =~ /^&&&&/)
|
978
|
+
{
|
979
|
+
my $len = unpack('x4N', $buff);
|
980
|
+
if ($len < $raf->Tell() and $raf->Seek(-$len, 2) and $raf->Read($buff,$len) == $len) {
|
981
|
+
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
982
|
+
my %dirInfo = ( DataPt => \$buff, DirStart => 8, DirName => 'LigoTrailer' );
|
983
|
+
Image::ExifTool::QuickTime::ProcessLigoGPS($et, \%dirInfo, $tbl);
|
984
|
+
}
|
985
|
+
}
|
986
|
+
|
957
987
|
return 1;
|
958
988
|
}
|
959
989
|
|