exiftool_vendored 12.62.0 → 12.64.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 +50 -1
- data/bin/MANIFEST +4 -0
- data/bin/META.json +4 -1
- data/bin/META.yml +4 -1
- data/bin/Makefile.PL +7 -1
- data/bin/README +50 -46
- data/bin/config_files/guano.config +161 -0
- data/bin/exiftool +88 -62
- data/bin/lib/Image/ExifTool/7Z.pm +793 -0
- data/bin/lib/Image/ExifTool/Apple.pm +6 -3
- data/bin/lib/Image/ExifTool/Canon.pm +1 -0
- data/bin/lib/Image/ExifTool/CanonRaw.pm +4 -4
- data/bin/lib/Image/ExifTool/CanonVRD.pm +4 -1
- data/bin/lib/Image/ExifTool/Exif.pm +31 -14
- data/bin/lib/Image/ExifTool/FujiFilm.pm +3 -3
- data/bin/lib/Image/ExifTool/GPS.pm +5 -2
- data/bin/lib/Image/ExifTool/Geotag.pm +4 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +226 -28
- data/bin/lib/Image/ExifTool/Lang/fr.pm +1467 -202
- data/bin/lib/Image/ExifTool/MPF.pm +2 -1
- data/bin/lib/Image/ExifTool/Matroska.pm +16 -1
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +419 -5
- data/bin/lib/Image/ExifTool/NikonCustom.pm +13 -3
- data/bin/lib/Image/ExifTool/PDF.pm +9 -1
- data/bin/lib/Image/ExifTool/PLIST.pm +8 -1
- data/bin/lib/Image/ExifTool/PNG.pm +6 -6
- data/bin/lib/Image/ExifTool/PhaseOne.pm +5 -5
- data/bin/lib/Image/ExifTool/QuickTime.pm +74 -21
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +20 -19
- data/bin/lib/Image/ExifTool/README +2 -2
- data/bin/lib/Image/ExifTool/RIFF.pm +11 -9
- data/bin/lib/Image/ExifTool/Shortcuts.pm +2 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +4 -4
- data/bin/lib/Image/ExifTool/Sony.pm +103 -8
- data/bin/lib/Image/ExifTool/TagLookup.pm +4738 -4630
- data/bin/lib/Image/ExifTool/TagNames.pod +249 -5
- data/bin/lib/Image/ExifTool/Validate.pm +17 -1
- data/bin/lib/Image/ExifTool/WriteExif.pl +9 -7
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +21 -9
- data/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
- data/bin/lib/Image/ExifTool/Writer.pl +28 -10
- data/bin/lib/Image/ExifTool/XMP.pm +14 -2
- data/bin/lib/Image/ExifTool/XMP2.pl +32 -0
- data/bin/lib/Image/ExifTool/XMPStruct.pl +96 -28
- data/bin/lib/Image/ExifTool/ZIP.pm +5 -5
- data/bin/lib/Image/ExifTool.pm +67 -39
- data/bin/lib/Image/ExifTool.pod +83 -52
- data/bin/perl-Image-ExifTool.spec +44 -44
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +4 -2
@@ -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);
|
@@ -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,
|
@@ -47,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
47
47
|
use Image::ExifTool::Exif;
|
48
48
|
use Image::ExifTool::GPS;
|
49
49
|
|
50
|
-
$VERSION = '2.
|
50
|
+
$VERSION = '2.86';
|
51
51
|
|
52
52
|
sub ProcessMOV($$;$);
|
53
53
|
sub ProcessKeys($$$);
|
@@ -224,6 +224,9 @@ my %ftypLookup = (
|
|
224
224
|
'crx ' => 'Canon Raw (.CRX)', #PH (CR3 or CRM; use Canon CompressorVersion to decide)
|
225
225
|
);
|
226
226
|
|
227
|
+
# use extension to determine file type
|
228
|
+
my %useExt = ( GLV => 'MP4' );
|
229
|
+
|
227
230
|
# information for int32u date/time tags (time zero is Jan 1, 1904)
|
228
231
|
my %timeInfo = (
|
229
232
|
Notes => 'converted from UTC to local time if the QuickTimeUTC option is set',
|
@@ -447,8 +450,8 @@ my %dupDirOK = ( ipco => 1, '----' => 1 );
|
|
447
450
|
my %eeStd = ( stco => 'stbl', co64 => 'stbl', stsz => 'stbl', stz2 => 'stbl',
|
448
451
|
stsc => 'stbl', stts => 'stbl' );
|
449
452
|
|
450
|
-
# atoms required for generating
|
451
|
-
my %
|
453
|
+
# atoms required for generating ImageDataHash
|
454
|
+
my %hashBox = ( vide => { %eeStd }, soun => { %eeStd } );
|
452
455
|
|
453
456
|
# boxes and their containers for the various handler types that we want to save
|
454
457
|
# when the ExtractEmbedded is enabled (currently only the 'gps ' container name is
|
@@ -1006,7 +1009,8 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
1006
1009
|
0 => 'Monoscopic',
|
1007
1010
|
1 => 'Stereoscopic Top-Bottom',
|
1008
1011
|
2 => 'Stereoscopic Left-Right',
|
1009
|
-
3 => 'Stereoscopic Stereo-Custom',
|
1012
|
+
3 => 'Stereoscopic Stereo-Custom',
|
1013
|
+
4 => 'Stereoscopic Right-Left',
|
1010
1014
|
},
|
1011
1015
|
},
|
1012
1016
|
sv3d => {
|
@@ -2070,8 +2074,8 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
2070
2074
|
ValueConv => 'substr($val, 4)',
|
2071
2075
|
ValueConvInv => '"\0\0\0\x01$val"',
|
2072
2076
|
},
|
2073
|
-
# hmtp - "\0\0\0\x01"
|
2074
|
-
# vrin - "\0\0\0\x01" followed by 8 bytes of zero
|
2077
|
+
# hmtp - 412 bytes: "\0\0\0\x01" then maybe "\0\0\0\x64" and the rest zeros
|
2078
|
+
# vrin - 12 bytes: "\0\0\0\x01" followed by 8 bytes of zero
|
2075
2079
|
# ---- GoPro ---- (ref PH)
|
2076
2080
|
GoPr => 'GoProType', # (Hero3+)
|
2077
2081
|
FIRM => { Name => 'FirmwareVersion', Avoid => 1 }, # (Hero4)
|
@@ -2867,6 +2871,25 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
2867
2871
|
Name => 'AV1Configuration',
|
2868
2872
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::AV1Config' },
|
2869
2873
|
},
|
2874
|
+
clli => {
|
2875
|
+
Name => 'ContentLightLevel',
|
2876
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ContentLightLevel' },
|
2877
|
+
},
|
2878
|
+
# ref https://nokiatech.github.io/heif/technical.html
|
2879
|
+
# cclv - Content Color Volume
|
2880
|
+
# mdcv - Mastering Display Color Volume
|
2881
|
+
# rrtp - Required reference types
|
2882
|
+
# crtt - Creation time information
|
2883
|
+
# mdft - Modification time information
|
2884
|
+
# udes - User description
|
2885
|
+
# altt - Accessibility text
|
2886
|
+
# aebr - Auto exposure information
|
2887
|
+
# wbbr - White balance information
|
2888
|
+
# fobr - Focus information
|
2889
|
+
# afbr - Flash exposure information
|
2890
|
+
# dobr - Depth of field information
|
2891
|
+
# pano - Panorama information
|
2892
|
+
# iscl - Image Scaling
|
2870
2893
|
);
|
2871
2894
|
|
2872
2895
|
# ref https://aomediacodec.github.io/av1-spec/av1-spec.pdf
|
@@ -2901,8 +2924,8 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
2901
2924
|
1 => 'BT.709',
|
2902
2925
|
2 => 'Unspecified',
|
2903
2926
|
3 => 'For future use (3)',
|
2904
|
-
4 => 'BT.470 System M (historical)',
|
2905
|
-
5 => 'BT.470 System B, G (historical)',
|
2927
|
+
4 => 'BT.470 System M (historical)', # Gamma 2.2? (ref forum14960)
|
2928
|
+
5 => 'BT.470 System B, G (historical)', # Gamma 2.8? (ref forum14960)
|
2906
2929
|
6 => 'BT.601',
|
2907
2930
|
7 => 'SMPTE 240 M',
|
2908
2931
|
8 => 'Linear',
|
@@ -3128,6 +3151,16 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
3128
3151
|
},
|
3129
3152
|
);
|
3130
3153
|
|
3154
|
+
# ref https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/MPEG4Writer.cpp
|
3155
|
+
%Image::ExifTool::QuickTime::ContentLightLevel = (
|
3156
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
3157
|
+
GROUPS => { 2 => 'Video' },
|
3158
|
+
FIRST_ENTRY => 0,
|
3159
|
+
FORMAT => 'int16u',
|
3160
|
+
0 => 'MaxContentLightLevel',
|
3161
|
+
1 => 'MaxPicAverageLightLevel',
|
3162
|
+
);
|
3163
|
+
|
3131
3164
|
%Image::ExifTool::QuickTime::ItemRef = (
|
3132
3165
|
PROCESS_PROC => \&ProcessMOV,
|
3133
3166
|
WRITE_PROC => \&WriteQuickTime,
|
@@ -7187,7 +7220,7 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
7187
7220
|
#
|
7188
7221
|
# AudioFormat Offset Child atoms
|
7189
7222
|
# ----------- ------ ----------------
|
7190
|
-
# mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?,also GoPro Max)
|
7223
|
+
# mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?,also GoPro Max and Garmin VIRB 360)
|
7191
7224
|
# in24 52 wave, chan
|
7192
7225
|
# "ms\0\x11" 52 wave
|
7193
7226
|
# sowt 52 chan
|
@@ -7220,11 +7253,14 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
7220
7253
|
chan => {
|
7221
7254
|
Name => 'AudioChannelLayout',
|
7222
7255
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ChannelLayout' },
|
7223
|
-
}
|
7256
|
+
},
|
7257
|
+
SA3D => { # written by Garmin VIRB360
|
7258
|
+
Name => 'SpatialAudio',
|
7259
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SpatialAudio' },
|
7260
|
+
},
|
7224
7261
|
# alac - 28 bytes
|
7225
7262
|
# adrm - AAX DRM atom? 148 bytes
|
7226
7263
|
# aabd - AAX unknown 17kB (contains 'aavd' strings)
|
7227
|
-
# SA3D - written by Garmin VIRB360
|
7228
7264
|
);
|
7229
7265
|
|
7230
7266
|
# AMR decode config box (ref 3)
|
@@ -7572,6 +7608,20 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
7572
7608
|
# (arbitrarily decode only first 8 channels)
|
7573
7609
|
);
|
7574
7610
|
|
7611
|
+
# spatial audio (ref https://github.com/google/spatial-media/blob/master/docs/spatial-audio-rfc.md)
|
7612
|
+
%Image::ExifTool::QuickTime::SpatialAudio = (
|
7613
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
7614
|
+
GROUPS => { 2 => 'Audio' },
|
7615
|
+
NOTES => 'Spatial Audio tags.',
|
7616
|
+
0 => 'SpatialAudioVersion',
|
7617
|
+
1 => { Name => 'AmbisonicType', PrintConv => { 0 => 'Periphonic' } },
|
7618
|
+
2 => { Name => 'AmbisonicOrder', Format => 'int32u' },
|
7619
|
+
6 => { Name => 'AmbisonicChannelOrdering', PrintConv => { 0 => 'ACN' } },
|
7620
|
+
7 => { Name => 'AmbisonicNormalization', PrintConv => { 0 => 'SN3D' } },
|
7621
|
+
8 => { Name => 'AmbisonicChannels', Format => 'int32u' },
|
7622
|
+
12 => { Name => 'AmbisonicChannelMap', Format => 'int32u[$val{8}]' },
|
7623
|
+
);
|
7624
|
+
|
7575
7625
|
# scheme type atom
|
7576
7626
|
# ref http://xhelmboyx.tripod.com/formats/mp4-layout.txt
|
7577
7627
|
%Image::ExifTool::QuickTime::SchemeType = (
|
@@ -8787,15 +8837,15 @@ sub HandleItemInfo($)
|
|
8787
8837
|
$et->VPrint(0, "$$et{INDENT} [snip $snip bytes]\n") if $snip;
|
8788
8838
|
}
|
8789
8839
|
}
|
8790
|
-
# do
|
8791
|
-
if ($isImageData{$type} and $$et{
|
8792
|
-
my $
|
8840
|
+
# do hash of AVIF "av01" and HEIC image data
|
8841
|
+
if ($isImageData{$type} and $$et{ImageDataHash}) {
|
8842
|
+
my $hash = $$et{ImageDataHash};
|
8793
8843
|
my $tot = 0;
|
8794
8844
|
foreach $extent (@{$$item{Extents}}) {
|
8795
8845
|
$raf->Seek($$extent[1] + $base, 0) or $et->Warn("Seek error in $type image data"), last;
|
8796
|
-
$tot += $et->
|
8846
|
+
$tot += $et->ImageDataHash($raf, $$extent[2], "$type image", 1);
|
8797
8847
|
}
|
8798
|
-
$et->VPrint(0, "$$et{INDENT}(
|
8848
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataHash: $tot bytes of $type data)\n") if $tot;
|
8799
8849
|
}
|
8800
8850
|
next unless $name;
|
8801
8851
|
# assemble the data for this item
|
@@ -9285,6 +9335,9 @@ sub ProcessMOV($$;$)
|
|
9285
9335
|
}
|
9286
9336
|
}
|
9287
9337
|
$fileType or $fileType = 'MP4'; # default to MP4
|
9338
|
+
# set file type from extension if appropriate
|
9339
|
+
my $ext = $$et{FILE_EXT};
|
9340
|
+
$fileType = $ext if $ext and $useExt{$ext} and $fileType eq $useExt{$ext};
|
9288
9341
|
$et->SetFileType($fileType, $mimeLookup{$fileType} || 'video/mp4');
|
9289
9342
|
# temporarily set ExtractEmbedded option for CRX files
|
9290
9343
|
$saveOptions{ExtractEmbedded} = $et->Options(ExtractEmbedded => 1) if $fileType eq 'CRX';
|
@@ -9299,8 +9352,8 @@ sub ProcessMOV($$;$)
|
|
9299
9352
|
$$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode
|
9300
9353
|
|
9301
9354
|
my $ee = $$et{OPTIONS}{ExtractEmbedded};
|
9302
|
-
my $
|
9303
|
-
if ($ee or $
|
9355
|
+
my $hash = $$et{ImageDataHash};
|
9356
|
+
if ($ee or $hash) {
|
9304
9357
|
$unkOpt = $$et{OPTIONS}{Unknown};
|
9305
9358
|
require 'Image/ExifTool/QuickTimeStream.pl';
|
9306
9359
|
}
|
@@ -9382,7 +9435,7 @@ sub ProcessMOV($$;$)
|
|
9382
9435
|
# set flag to store additional information for ExtractEmbedded option
|
9383
9436
|
my $handlerType = $$et{HandlerType};
|
9384
9437
|
if ($eeBox{$handlerType} and $eeBox{$handlerType}{$tag}) {
|
9385
|
-
if ($ee or $
|
9438
|
+
if ($ee or $hash) {
|
9386
9439
|
# (there is another 'gps ' box with a track log that doesn't contain offsets)
|
9387
9440
|
if ($tag ne 'gps ' or $eeBox{$handlerType}{$tag} eq $dirID) {
|
9388
9441
|
$eeTag = 1;
|
@@ -9394,7 +9447,7 @@ sub ProcessMOV($$;$)
|
|
9394
9447
|
} elsif ($ee and $ee > 1 and $eeBox2{$handlerType} and $eeBox2{$handlerType}{$tag}) {
|
9395
9448
|
$eeTag = 1;
|
9396
9449
|
$$et{OPTIONS}{Unknown} = 1;
|
9397
|
-
} elsif ($
|
9450
|
+
} elsif ($hash and $hashBox{$handlerType} and $hashBox{$handlerType}{$tag}) {
|
9398
9451
|
$eeTag = 1;
|
9399
9452
|
$$et{OPTIONS}{Unknown} = 1;
|
9400
9453
|
}
|
@@ -9629,7 +9682,7 @@ ItemID: foreach $id (keys %$items) {
|
|
9629
9682
|
}
|
9630
9683
|
if ($tag eq 'stbl') {
|
9631
9684
|
# process sample data when exiting SampleTable box if extracting embedded
|
9632
|
-
ProcessSamples($et) if $ee or $
|
9685
|
+
ProcessSamples($et) if $ee or $hash;
|
9633
9686
|
} elsif ($tag eq 'minf') {
|
9634
9687
|
$$et{HandlerType} = ''; # reset handler type at end of media info box
|
9635
9688
|
}
|
@@ -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
|
}
|
@@ -412,7 +412,7 @@ numerical, and generated automatically otherwise.
|
|
412
412
|
'IsComposite' - flag set for Composite tags
|
413
413
|
|
414
414
|
'IsImageData' - flag set if this is an image data offset to
|
415
|
-
be included in
|
415
|
+
be included in ImageDataHash calculation. Must have an
|
416
416
|
OffsetPair entry which is the ID of the corresponding size.
|
417
417
|
|
418
418
|
'IsOffset' - flag set if the tag represents an offset to some
|
@@ -637,7 +637,7 @@ numerical, and generated automatically otherwise.
|
|
637
637
|
RawConv instead to return undef if it is necessary to test the
|
638
638
|
value for validity, otherwise an undef tag may hide a
|
639
639
|
previously defined value when the Duplicates option is not
|
640
|
-
enabled.
|
640
|
+
enabled. If this isn't possible (as with Composite tags where
|
641
641
|
the converted values of the source tags are needed), set the
|
642
642
|
Priority to 0 to avoid taking priority over a valid tag. If
|
643
643
|
ValueConv is not specified, the Raw value is not converted.
|
@@ -30,7 +30,7 @@ use strict;
|
|
30
30
|
use vars qw($VERSION $AUTOLOAD);
|
31
31
|
use Image::ExifTool qw(:DataAccess :Utils);
|
32
32
|
|
33
|
-
$VERSION = '1.
|
33
|
+
$VERSION = '1.65';
|
34
34
|
|
35
35
|
sub ConvertTimecode($);
|
36
36
|
sub ProcessSGLT($$$);
|
@@ -38,7 +38,7 @@ sub ProcessSLLT($$$);
|
|
38
38
|
sub ProcessLucas($$$);
|
39
39
|
sub WriteRIFF($$);
|
40
40
|
|
41
|
-
# RIFF chunks containing image data (to include in
|
41
|
+
# RIFF chunks containing image data (to include in ImageDataHash digest)
|
42
42
|
my %isImageData = (
|
43
43
|
LIST_movi => 1, # (AVI: contains ##db, ##dc, ##wb)
|
44
44
|
data => 1, # (WAV)
|
@@ -652,6 +652,7 @@ my %code2charset = (
|
|
652
652
|
Name => 'Acidizer',
|
653
653
|
SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Acidizer' },
|
654
654
|
},
|
655
|
+
guan => 'Guano', #forum14831
|
655
656
|
);
|
656
657
|
|
657
658
|
# the maker notes used by some digital cameras
|
@@ -1987,7 +1988,7 @@ sub ProcessRIFF($$)
|
|
1987
1988
|
my $unknown = $et->Options('Unknown');
|
1988
1989
|
my $validate = $et->Options('Validate');
|
1989
1990
|
my $ee = $et->Options('ExtractEmbedded');
|
1990
|
-
my $
|
1991
|
+
my $hash = $$et{ImageDataHash};
|
1991
1992
|
|
1992
1993
|
# verify this is a valid RIFF file
|
1993
1994
|
return 0 unless $raf->Read($buff, 12) == 12;
|
@@ -2045,6 +2046,7 @@ sub ProcessRIFF($$)
|
|
2045
2046
|
} else {
|
2046
2047
|
next;
|
2047
2048
|
}
|
2049
|
+
last;
|
2048
2050
|
}
|
2049
2051
|
# stop when we hit the audio data or AVI index or AVI movie data
|
2050
2052
|
# --> no more because Adobe Bridge stores XMP after this!!
|
@@ -2067,9 +2069,9 @@ sub ProcessRIFF($$)
|
|
2067
2069
|
# (in LIST_movi chunk: ##db = uncompressed DIB, ##dc = compressed DIB, ##wb = audio data)
|
2068
2070
|
if ($tagInfo or (($verbose or $unknown) and $tag !~ /^(data|idx1|LIST_movi|RIFF|\d{2}(db|dc|wb))$/)) {
|
2069
2071
|
$raf->Read($buff, $len2) == $len2 or $err=1, last;
|
2070
|
-
if ($
|
2071
|
-
$
|
2072
|
-
$et->VPrint(0, "$$et{INDENT}(
|
2072
|
+
if ($hash and $isImageData{$tag}) {
|
2073
|
+
$hash->add($buff);
|
2074
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataHash: '${tag}' chunk, $len2 bytes)\n");
|
2073
2075
|
}
|
2074
2076
|
my $setGroups;
|
2075
2077
|
if ($tagInfo and ref $tagInfo eq 'HASH' and $$tagInfo{SetGroups}) {
|
@@ -2099,10 +2101,10 @@ sub ProcessRIFF($$)
|
|
2099
2101
|
next; # (must not increment $pos)
|
2100
2102
|
} else {
|
2101
2103
|
my $rewind;
|
2102
|
-
# do
|
2103
|
-
if ($
|
2104
|
+
# do hash if required
|
2105
|
+
if ($hash and $isImageData{$tag}) {
|
2104
2106
|
$rewind = $raf->Tell();
|
2105
|
-
$et->
|
2107
|
+
$et->ImageDataHash($raf, $len2, "'${tag}' chunk");
|
2106
2108
|
}
|
2107
2109
|
if ($tag eq 'LIST_movi' and $ee) {
|
2108
2110
|
$raf->Seek($rewind, 0) or $err = 1, last if $rewind;
|
@@ -19,7 +19,7 @@ package Image::ExifTool::Shortcuts;
|
|
19
19
|
use strict;
|
20
20
|
use vars qw($VERSION);
|
21
21
|
|
22
|
-
$VERSION = '1.
|
22
|
+
$VERSION = '1.68';
|
23
23
|
|
24
24
|
# this is a special table used to define command-line shortcuts
|
25
25
|
# (documentation Notes may be added for these via %shortcutNotes in BuildTagLookup.pm)
|
@@ -276,6 +276,7 @@ $VERSION = '1.67';
|
|
276
276
|
'FileModifyDate',
|
277
277
|
'FileName',
|
278
278
|
],
|
279
|
+
ImageDataMD5 => [ 'ImageDataHash' ], # (for backward compatibilty)
|
279
280
|
);
|
280
281
|
|
281
282
|
#------------------------------------------------------------------------------
|
@@ -16,7 +16,7 @@ use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
17
17
|
use Image::ExifTool::Sigma;
|
18
18
|
|
19
|
-
$VERSION = '1.
|
19
|
+
$VERSION = '1.31';
|
20
20
|
|
21
21
|
sub ProcessX3FHeader($$$);
|
22
22
|
sub ProcessX3FDirectory($$$);
|
@@ -549,9 +549,9 @@ sub ProcessX3FDirectory($$$)
|
|
549
549
|
$len -= 28;
|
550
550
|
# ignore all image data but JPEG compressed (version 2.0, type 2, format 18)
|
551
551
|
unless ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/) {
|
552
|
-
# do
|
553
|
-
if ($$et{
|
554
|
-
$et->
|
552
|
+
# do hash on non-preview data if requested
|
553
|
+
if ($$et{ImageDataHash} and substr($buff,8,1) ne "\x02") {
|
554
|
+
$et->ImageDataHash($raf, $len, 'SigmaRaw IMAG');
|
555
555
|
}
|
556
556
|
next;
|
557
557
|
}
|