exiftool_vendored 12.41.0 → 12.50.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 +209 -6
- data/bin/MANIFEST +12 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +45 -44
- data/bin/config_files/acdsee.config +2 -1
- data/bin/config_files/frameCount.config +56 -0
- data/bin/config_files/tiff_version.config +1 -1
- data/bin/exiftool +115 -96
- data/bin/fmt_files/gpx.fmt +3 -0
- data/bin/fmt_files/gpx_wpt.fmt +3 -0
- data/bin/lib/Image/ExifTool/Apple.pm +16 -3
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -12
- data/bin/lib/Image/ExifTool/Canon.pm +71 -33
- data/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
- data/bin/lib/Image/ExifTool/CanonVRD.pm +7 -8
- data/bin/lib/Image/ExifTool/DJI.pm +60 -1
- data/bin/lib/Image/ExifTool/DNG.pm +8 -2
- data/bin/lib/Image/ExifTool/DarwinCore.pm +13 -1
- data/bin/lib/Image/ExifTool/EXE.pm +9 -1
- data/bin/lib/Image/ExifTool/Exif.pm +26 -12
- data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
- data/bin/lib/Image/ExifTool/FLIR.pm +4 -3
- data/bin/lib/Image/ExifTool/FlashPix.pm +26 -3
- data/bin/lib/Image/ExifTool/FujiFilm.pm +51 -4
- data/bin/lib/Image/ExifTool/GPS.pm +21 -1
- data/bin/lib/Image/ExifTool/Geotag.pm +25 -5
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +12 -9
- data/bin/lib/Image/ExifTool/ICO.pm +143 -0
- data/bin/lib/Image/ExifTool/ID3.pm +11 -11
- data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
- data/bin/lib/Image/ExifTool/LNK.pm +5 -2
- data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
- data/bin/lib/Image/ExifTool/MIE.pm +9 -3
- data/bin/lib/Image/ExifTool/MISB.pm +494 -0
- data/bin/lib/Image/ExifTool/MakerNotes.pm +8 -1
- data/bin/lib/Image/ExifTool/Matroska.pm +24 -16
- data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +293 -122
- data/bin/lib/Image/ExifTool/NikonCustom.pm +4 -1
- data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
- data/bin/lib/Image/ExifTool/Olympus.pm +22 -2
- data/bin/lib/Image/ExifTool/PDF.pm +2 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +30 -4
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
- data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
- data/bin/lib/Image/ExifTool/Pentax.pm +8 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +35 -8
- data/bin/lib/Image/ExifTool/QuickTime.pm +163 -13
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +119 -13
- data/bin/lib/Image/ExifTool/README +13 -3
- data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
- data/bin/lib/Image/ExifTool/Samsung.pm +234 -3
- data/bin/lib/Image/ExifTool/Shortcuts.pm +2 -1
- data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
- data/bin/lib/Image/ExifTool/Sony.pm +71 -43
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +3 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +4752 -4516
- data/bin/lib/Image/ExifTool/TagNames.pod +1885 -1434
- data/bin/lib/Image/ExifTool/Text.pm +3 -4
- data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
- data/bin/lib/Image/ExifTool/Validate.pm +3 -3
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
- data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
- data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
- data/bin/lib/Image/ExifTool/Writer.pl +14 -6
- data/bin/lib/Image/ExifTool/XMP.pm +78 -59
- data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
- data/bin/lib/Image/ExifTool.pm +120 -33
- data/bin/lib/Image/ExifTool.pod +83 -69
- data/bin/perl-Image-ExifTool.spec +43 -43
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +9 -4
@@ -13,6 +13,7 @@
|
|
13
13
|
# 6) http://trac.handbrake.fr/browser/trunk/libhb/stream.c
|
14
14
|
# 7) http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=04560141
|
15
15
|
# 8) http://www.w6rz.net/xport.zip
|
16
|
+
# 9) https://en.wikipedia.org/wiki/Program-specific_information
|
16
17
|
#
|
17
18
|
# Notes: Variable names containing underlines are the same as in ref 1.
|
18
19
|
#
|
@@ -31,9 +32,9 @@ use strict;
|
|
31
32
|
use vars qw($VERSION);
|
32
33
|
use Image::ExifTool qw(:DataAccess :Utils);
|
33
34
|
|
34
|
-
$VERSION = '1.
|
35
|
+
$VERSION = '1.23';
|
35
36
|
|
36
|
-
# program map table "stream_type" lookup (ref 6/1)
|
37
|
+
# program map table "stream_type" lookup (ref 6/1/9)
|
37
38
|
my %streamType = (
|
38
39
|
0x00 => 'Reserved',
|
39
40
|
0x01 => 'MPEG-1 Video',
|
@@ -56,9 +57,22 @@ my %streamType = (
|
|
56
57
|
0x12 => 'MPEG-4 generic',
|
57
58
|
0x13 => 'ISO 14496-1 SL-packetized',
|
58
59
|
0x14 => 'ISO 13818-6 Synchronized Download Protocol',
|
59
|
-
|
60
|
+
0x15 => 'Packetized metadata',
|
61
|
+
0x16 => 'Sectioned metadata',
|
62
|
+
0x17 => 'ISO/IEC 13818-6 DSM CC Data Carousel metadata',
|
63
|
+
0x18 => 'ISO/IEC 13818-6 DSM CC Object Carousel metadata',
|
64
|
+
0x19 => 'ISO/IEC 13818-6 Synchronized Download Protocol metadata',
|
65
|
+
0x1a => 'ISO/IEC 13818-11 IPMP',
|
60
66
|
0x1b => 'H.264 (AVC) Video',
|
67
|
+
0x1c => 'ISO/IEC 14496-3 (MPEG-4 raw audio)',
|
68
|
+
0x1d => 'ISO/IEC 14496-17 (MPEG-4 text)',
|
69
|
+
0x1e => 'ISO/IEC 23002-3 (MPEG-4 auxiliary video)',
|
70
|
+
0x1f => 'ISO/IEC 14496-10 SVC (MPEG-4 AVC sub-bitstream)',
|
71
|
+
0x20 => 'ISO/IEC 14496-10 MVC (MPEG-4 AVC sub-bitstream)',
|
72
|
+
0x21 => 'ITU-T Rec. T.800 and ISO/IEC 15444 (JPEG 2000 video)',
|
61
73
|
0x24 => 'H.265 (HEVC) Video', #PH
|
74
|
+
0x42 => 'Chinese Video Standard',
|
75
|
+
0x7f => 'ISO/IEC 13818-11 IPMP (DRM)',
|
62
76
|
0x80 => 'DigiCipher II Video',
|
63
77
|
0x81 => 'A52/AC-3 Audio',
|
64
78
|
0x82 => 'HDMV DTS Audio',
|
@@ -145,6 +159,7 @@ my $knotsToKph = 1.852; # knots --> km/h
|
|
145
159
|
# the following tags are for documentation purposes only
|
146
160
|
_AC3 => { SubDirectory => { TagTable => 'Image::ExifTool::M2TS::AC3' } },
|
147
161
|
_H264 => { SubDirectory => { TagTable => 'Image::ExifTool::H264::Main' } },
|
162
|
+
_MISB => { SubDirectory => { TagTable => 'Image::ExifTool::MISB::Main' } },
|
148
163
|
);
|
149
164
|
|
150
165
|
# information extracted from AC-3 audio streams
|
@@ -278,7 +293,7 @@ sub ParsePID($$$$$)
|
|
278
293
|
my $verbose = $et->Options('Verbose');
|
279
294
|
if ($verbose > 1) {
|
280
295
|
my $out = $et->Options('TextOut');
|
281
|
-
printf $out "Parsing stream 0x%.4x (%s)\n", $pid, $pidName;
|
296
|
+
printf $out "Parsing stream 0x%.4x (%s) %d bytes\n", $pid, $pidName, length($$dataPt);
|
282
297
|
$et->VerboseDump($dataPt);
|
283
298
|
}
|
284
299
|
my $more = 0;
|
@@ -303,6 +318,16 @@ sub ParsePID($$$$$)
|
|
303
318
|
} elsif ($type == 0x81 or $type == 0x87 or $type == 0x91) {
|
304
319
|
# AC-3 audio
|
305
320
|
ParseAC3Audio($et, $dataPt);
|
321
|
+
} elsif ($type == 0x15) {
|
322
|
+
# packetized metadata (look for MISB code starting after 5-byte header)
|
323
|
+
if ($$dataPt =~ /^.{5}\x06\x0e\x2b\x34/s) {
|
324
|
+
$more = Image::ExifTool::MISB::ParseMISB($et, $dataPt, GetTagTable('Image::ExifTool::MISB::Main'));
|
325
|
+
if (not $$et{OPTIONS}{ExtractEmbedded}) {
|
326
|
+
$more = 0; # extract from only the first packet unless ExtractEmbedded is used
|
327
|
+
} elsif ($$et{OPTIONS}{ExtractEmbedded} > 2) {
|
328
|
+
$more = 1; # read past unknown 0x15 packets if ExtractEmbedded > 2
|
329
|
+
}
|
330
|
+
}
|
306
331
|
} elsif ($type < 0) {
|
307
332
|
if ($$dataPt =~ /^(.{164})?(.{24})A[NS][EW]/s) {
|
308
333
|
# (Blueskysea B4K, Novatek NT96670)
|
@@ -390,6 +415,48 @@ sub ParsePID($$$$$)
|
|
390
415
|
}
|
391
416
|
}
|
392
417
|
$more = 1;
|
418
|
+
} elsif ($$dataPt =~ /\$GPRMC,/) {
|
419
|
+
# Jomise T860S-GM dashcam
|
420
|
+
# $GPRMC,hhmmss.ss,A,ddmm.mmmmm,N,dddmm.mmmmm,W,spd-kts,dir-dg,DDMMYY,,*cs
|
421
|
+
# $GPRMC,172255.00,A,:985.95194,N,17170.14674,W,029.678,170.68,240822,,,D*7B
|
422
|
+
# $GPRMC,172355.00,A,:984.76779,N,17170.00473,W,032.219,172.04,240822,,,D*7B
|
423
|
+
# ddmm.mmmm: from 4742.2568 12209.2028 (should be)
|
424
|
+
# to 4741.7696 12209.1056
|
425
|
+
# stamped on video: 47.70428N, 122.15338W, 35mph (dd.ddddd)
|
426
|
+
# to 47.69616N, 122.15176W, 37mph
|
427
|
+
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
428
|
+
while ($$dataPt =~ /\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(.{2})(\d{2}\.\d+),([NS]),(.{3})(\d{2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/g and
|
429
|
+
# do some basic sanity checks on the date
|
430
|
+
$13 <= 31 and $14 <= 12 and $15 <= 99)
|
431
|
+
{
|
432
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
433
|
+
my $year = $15 + ($15 >= 70 ? 1900 : 2000);
|
434
|
+
$et->HandleTag($tagTbl, GPSDateTime => sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ', $year, $14, $13, $1, $2, $3));
|
435
|
+
#(not this simple)
|
436
|
+
#$et->HandleTag($tagTbl, GPSLatitude => (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1));
|
437
|
+
#$et->HandleTag($tagTbl, GPSLongitude => (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1));
|
438
|
+
$et->HandleTag($tagTbl, GPSSpeed => $11 * $knotsToKph) if length $11;
|
439
|
+
$et->HandleTag($tagTbl, GPSTrack => $12) if length $12;
|
440
|
+
# it looks like maybe the degrees are xor-ed with something,
|
441
|
+
# and the minutes have some scaling factor and offset?
|
442
|
+
# (the code below is approximately correct for my only sample)
|
443
|
+
my @chars = unpack('C*', $5 . $8);
|
444
|
+
my @xor = (0x0e,0x0e,0x00,0x05,0x03); # (empirical based on 1 sample; may be completely off base)
|
445
|
+
my $bad;
|
446
|
+
foreach (@chars) {
|
447
|
+
$_ ^= shift(@xor);
|
448
|
+
$bad = 1 if $_ < 0x30 or $_ > 0x39;
|
449
|
+
}
|
450
|
+
if ($bad) {
|
451
|
+
$et->WarnOnce('Error decrypting GPS degrees');
|
452
|
+
} else {
|
453
|
+
my $la = pack('C*', @chars[0,1]);
|
454
|
+
my $lo = pack('C*', @chars[2,3,4]);
|
455
|
+
$et->WarnOnce('Decryption of this GPS is highly experimental. More testing samples are required');
|
456
|
+
$et->HandleTag($tagTbl, GPSLatitude => (($la || 0) + (($6-85.95194)/2.43051724137931+42.2568)/60) * ($7 eq 'N' ? 1 : -1));
|
457
|
+
$et->HandleTag($tagTbl, GPSLongitude => (($lo || 0) + (($9-70.14674)/1.460987654320988+9.2028)/60) * ($10 eq 'E' ? 1 : -1));
|
458
|
+
}
|
459
|
+
}
|
393
460
|
} elsif ($$dataPt =~ /^.{44}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s and length($$dataPt) >= 84) {
|
394
461
|
#forum11320
|
395
462
|
SetByteOrder('II');
|
@@ -426,7 +493,7 @@ sub ProcessM2TS($$)
|
|
426
493
|
my ($et, $dirInfo) = @_;
|
427
494
|
my $raf = $$dirInfo{RAF};
|
428
495
|
my ($buff, $pLen, $upkPrefix, $j, $fileType, $eof);
|
429
|
-
my (%pmt, %pidType, %data, %sectLen);
|
496
|
+
my (%pmt, %pidType, %data, %sectLen, %packLen, %fromStart);
|
430
497
|
my ($startTime, $endTime, $fwdTime, $backScan, $maxBack);
|
431
498
|
my $verbose = $et->Options('Verbose');
|
432
499
|
my $out = $et->Options('TextOut');
|
@@ -468,6 +535,7 @@ sub ProcessM2TS($$)
|
|
468
535
|
my %gpsPID = (
|
469
536
|
0x0300 => 1, # Novatek INNOVV
|
470
537
|
0x01e4 => 1, # vsys a6l dashcam
|
538
|
+
0x0e1b => 1, # Jomise T860S-GM dashcam
|
471
539
|
);
|
472
540
|
my $pEnd = 0;
|
473
541
|
|
@@ -610,6 +678,7 @@ sub ProcessM2TS($$)
|
|
610
678
|
$buf2 = $data{$pid};
|
611
679
|
$pos = 0;
|
612
680
|
delete $data{$pid};
|
681
|
+
delete $fromStart{$pid};
|
613
682
|
delete $sectLen{$pid};
|
614
683
|
}
|
615
684
|
my $slen = length($buf2); # section length
|
@@ -736,6 +805,7 @@ sub ProcessM2TS($$)
|
|
736
805
|
my $more = ParsePID($et, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
|
737
806
|
# start fresh even if we couldn't process this PID yet
|
738
807
|
delete $data{$pid};
|
808
|
+
delete $fromStart{$pid};
|
739
809
|
unless ($more) {
|
740
810
|
delete $needPID{$pid};
|
741
811
|
$didPID{$pid} = 1;
|
@@ -749,8 +819,8 @@ sub ProcessM2TS($$)
|
|
749
819
|
my $start_code = Get32u(\$buff, $pos);
|
750
820
|
next unless ($start_code & 0xffffff00) == 0x00000100;
|
751
821
|
my $stream_id = $start_code & 0xff;
|
822
|
+
my $pes_packet_length = Get16u(\$buff, $pos + 4);
|
752
823
|
if ($verbose > 1) {
|
753
|
-
my $pes_packet_length = Get16u(\$buff, $pos + 4);
|
754
824
|
printf $out " Stream ID: 0x%.2x\n", $stream_id;
|
755
825
|
print $out " Packet Len: $pes_packet_length\n";
|
756
826
|
}
|
@@ -766,6 +836,14 @@ sub ProcessM2TS($$)
|
|
766
836
|
next if $pos >= $pEnd;
|
767
837
|
}
|
768
838
|
$data{$pid} = substr($buff, $pos, $pEnd-$pos);
|
839
|
+
# set flag that we read this payload from the start
|
840
|
+
$fromStart{$pid} = 1;
|
841
|
+
# save the packet length
|
842
|
+
if ($pes_packet_length > 8) {
|
843
|
+
$packLen{$pid} = $pes_packet_length - 8; # (where are the 8 extra bytes? - PH)
|
844
|
+
} else {
|
845
|
+
delete $packLen{$pid};
|
846
|
+
}
|
769
847
|
} else {
|
770
848
|
unless (defined $data{$pid}) {
|
771
849
|
# (vsys a6l dashcam GPS record doesn't have a start indicator)
|
@@ -776,12 +854,24 @@ sub ProcessM2TS($$)
|
|
776
854
|
$data{$pid} .= substr($buff, $pos, $pEnd-$pos);
|
777
855
|
}
|
778
856
|
# save only the first 256 bytes of most streams, except for
|
779
|
-
# unknown
|
780
|
-
my $saveLen
|
857
|
+
# unknown, H.264 or metadata streams where we save up to 1 kB
|
858
|
+
my $saveLen;
|
859
|
+
if (not $pidType{$pid} or $pidType{$pid} == 0x1b) {
|
860
|
+
$saveLen = 1024;
|
861
|
+
} elsif ($pidType{$pid} == 0x15) {
|
862
|
+
# use 1024 or actual size of metadata packet if smaller
|
863
|
+
$saveLen = 1024;
|
864
|
+
$saveLen = $packLen{$pid} if defined $packLen{$pid} and $saveLen > $packLen{$pid};
|
865
|
+
} else {
|
866
|
+
$saveLen = 256;
|
867
|
+
}
|
781
868
|
if (length($data{$pid}) >= $saveLen) {
|
782
869
|
my $more = ParsePID($et, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
|
783
870
|
next if $more < 0; # wait for program map table (hopefully not too long)
|
871
|
+
# don't stop parsing if we weren't successful and may have missed the start
|
872
|
+
$more = 1 if not $more and not $fromStart{$pid};
|
784
873
|
delete $data{$pid};
|
874
|
+
delete $fromStart{$pid};
|
785
875
|
$more and $needPID{$pid} = -1, next; # parse more of these
|
786
876
|
delete $needPID{$pid};
|
787
877
|
$didPID{$pid} = 1;
|
@@ -14,7 +14,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
14
14
|
use Image::ExifTool::Exif;
|
15
15
|
use Image::ExifTool::GPS;
|
16
16
|
|
17
|
-
$VERSION = '1.
|
17
|
+
$VERSION = '1.50';
|
18
18
|
|
19
19
|
sub ProcessMIE($$);
|
20
20
|
sub ProcessMIEGroup($$$);
|
@@ -448,6 +448,13 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
|
|
448
448
|
Notes => 'string composed of R, G, B, Y, Cb and Cr',
|
449
449
|
},
|
450
450
|
Compression => { Name => 'CompressionRatio', Writable => 'rational32u' },
|
451
|
+
OriginalImageSize => { # PH added 2022-09-28
|
452
|
+
Writable => 'int16u',
|
453
|
+
Count => -1,
|
454
|
+
Notes => 'size of original image before cropping',
|
455
|
+
PrintConv => '$val=~tr/ /x/;$val',
|
456
|
+
PrintConvInv => '$val=~tr/x/ /;$val',
|
457
|
+
},
|
451
458
|
ImageSize => {
|
452
459
|
Writable => 'int16u',
|
453
460
|
Count => -1,
|
@@ -1253,8 +1260,7 @@ sub WriteMIEGroup($$$)
|
|
1253
1260
|
# join multiple values into a single string
|
1254
1261
|
$newVal = join "\0", @newVals;
|
1255
1262
|
# write string as UTF-8,16 or 32 if value contains valid UTF-8 codes
|
1256
|
-
|
1257
|
-
my $isUTF8 = Image::ExifTool::XMP::IsUTF8(\$newVal);
|
1263
|
+
my $isUTF8 = Image::ExifTool::IsUTF8(\$newVal);
|
1258
1264
|
if ($isUTF8 > 0) {
|
1259
1265
|
$writable = 'utf8';
|
1260
1266
|
# write UTF-16 or UTF-32 if it is more compact
|