exiftool-vendored.pl 12.56.0 → 12.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/Changes +115 -5
- package/bin/LICENSE +674 -0
- package/bin/MANIFEST +11 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +45 -44
- package/bin/config_files/example.config +1 -0
- package/bin/config_files/rotate_regions.config +1 -1
- package/bin/exiftool +262 -160
- package/bin/lib/Image/ExifTool/AIFF.pm +2 -2
- package/bin/lib/Image/ExifTool/APE.pm +2 -2
- package/bin/lib/Image/ExifTool/BMP.pm +0 -1
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -19
- package/bin/lib/Image/ExifTool/Canon.pm +26 -6
- package/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
- package/bin/lib/Image/ExifTool/DJI.pm +28 -2
- package/bin/lib/Image/ExifTool/Exif.pm +77 -19
- package/bin/lib/Image/ExifTool/FlashPix.pm +33 -10
- package/bin/lib/Image/ExifTool/FujiFilm.pm +7 -3
- package/bin/lib/Image/ExifTool/GPS.pm +7 -2
- package/bin/lib/Image/ExifTool/Geotag.pm +30 -7
- package/bin/lib/Image/ExifTool/JPEG.pm +14 -2
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +36 -11
- package/bin/lib/Image/ExifTool/LIF.pm +10 -2
- package/bin/lib/Image/ExifTool/LNK.pm +5 -4
- package/bin/lib/Image/ExifTool/MIE.pm +3 -3
- package/bin/lib/Image/ExifTool/MPEG.pm +2 -2
- package/bin/lib/Image/ExifTool/MakerNotes.pm +3 -2
- package/bin/lib/Image/ExifTool/Minolta.pm +6 -7
- package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
- package/bin/lib/Image/ExifTool/Nikon.pm +1005 -909
- package/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
- package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
- package/bin/lib/Image/ExifTool/Olympus.pm +88 -6
- package/bin/lib/Image/ExifTool/PDF.pm +17 -8
- package/bin/lib/Image/ExifTool/PNG.pm +10 -2
- package/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
- package/bin/lib/Image/ExifTool/Pentax.pm +8 -5
- package/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
- package/bin/lib/Image/ExifTool/Photoshop.pm +38 -7
- package/bin/lib/Image/ExifTool/QuickTime.pm +48 -14
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +91 -27
- package/bin/lib/Image/ExifTool/README +19 -2
- package/bin/lib/Image/ExifTool/RIFF.pm +34 -13
- package/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
- package/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
- package/bin/lib/Image/ExifTool/Sigma.pm +5 -4
- package/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
- package/bin/lib/Image/ExifTool/Sony.pm +39 -10
- package/bin/lib/Image/ExifTool/TagLookup.pm +4687 -4628
- package/bin/lib/Image/ExifTool/TagNames.pod +338 -117
- package/bin/lib/Image/ExifTool/Validate.pm +5 -5
- package/bin/lib/Image/ExifTool/WPG.pm +296 -0
- package/bin/lib/Image/ExifTool/WriteExif.pl +42 -0
- package/bin/lib/Image/ExifTool/WritePDF.pl +7 -8
- package/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
- package/bin/lib/Image/ExifTool/Writer.pl +162 -40
- package/bin/lib/Image/ExifTool/XMP.pm +35 -8
- package/bin/lib/Image/ExifTool/XMP2.pl +2 -1
- package/bin/lib/Image/ExifTool/ZIP.pm +159 -41
- package/bin/lib/Image/ExifTool.pm +286 -65
- package/bin/lib/Image/ExifTool.pod +95 -51
- package/bin/perl-Image-ExifTool.spec +44 -43
- package/bin/pp_build_exe.args +5 -4
- package/package.json +3 -3
|
@@ -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.85';
|
|
51
51
|
|
|
52
52
|
sub ProcessMOV($$;$);
|
|
53
53
|
sub ProcessKeys($$$);
|
|
@@ -419,6 +419,18 @@ my %channelLabel = (
|
|
|
419
419
|
0x1ffff => 'Discrete_65535',
|
|
420
420
|
);
|
|
421
421
|
|
|
422
|
+
my %qtFlags = ( #12
|
|
423
|
+
0 => 'undef', 22 => 'unsigned int', 71 => 'float[2] size',
|
|
424
|
+
1 => 'UTF-8', 23 => 'float', 72 => 'float[4] rect',
|
|
425
|
+
2 => 'UTF-16', 24 => 'double', 74 => 'int64s',
|
|
426
|
+
3 => 'ShiftJIS', 27 => 'BMP', 75 => 'int8u',
|
|
427
|
+
4 => 'UTF-8 sort', 28 => 'QT atom', 76 => 'int16u',
|
|
428
|
+
5 => 'UTF-16 sort', 65 => 'int8s', 77 => 'int32u',
|
|
429
|
+
13 => 'JPEG', 66 => 'int16s', 78 => 'int64u',
|
|
430
|
+
14 => 'PNG', 67 => 'int32s', 79 => 'double[3][3]',
|
|
431
|
+
21 => 'signed int', 70 => 'float[2] point',
|
|
432
|
+
);
|
|
433
|
+
|
|
422
434
|
# properties which don't get inherited from the parent
|
|
423
435
|
my %dontInherit = (
|
|
424
436
|
ispe => 1, # size of parent may be different
|
|
@@ -435,15 +447,16 @@ my %dupDirOK = ( ipco => 1, '----' => 1 );
|
|
|
435
447
|
my %eeStd = ( stco => 'stbl', co64 => 'stbl', stsz => 'stbl', stz2 => 'stbl',
|
|
436
448
|
stsc => 'stbl', stts => 'stbl' );
|
|
437
449
|
|
|
450
|
+
# atoms required for generating ImageDataMD5
|
|
451
|
+
my %md5Box = ( vide => { %eeStd }, soun => { %eeStd } );
|
|
452
|
+
|
|
438
453
|
# boxes and their containers for the various handler types that we want to save
|
|
439
454
|
# when the ExtractEmbedded is enabled (currently only the 'gps ' container name is
|
|
440
455
|
# used, but others have been checked against all available sample files and may be
|
|
441
456
|
# useful in the future if the names are used for different boxes on other locations)
|
|
442
457
|
my %eeBox = (
|
|
443
458
|
# (note: vide is only processed if specific atoms exist in the VideoSampleDesc)
|
|
444
|
-
vide => { %eeStd,
|
|
445
|
-
JPEG => 'stsd',
|
|
446
|
-
},
|
|
459
|
+
vide => { %eeStd, JPEG => 'stsd' },
|
|
447
460
|
text => { %eeStd },
|
|
448
461
|
meta => { %eeStd },
|
|
449
462
|
sbtl => { %eeStd },
|
|
@@ -457,6 +470,9 @@ my %eeBox2 = (
|
|
|
457
470
|
vide => { avcC => 'stsd' }, # (parses H264 video stream)
|
|
458
471
|
);
|
|
459
472
|
|
|
473
|
+
# image types in AVIF and HEIC files
|
|
474
|
+
my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
475
|
+
|
|
460
476
|
# QuickTime atoms
|
|
461
477
|
%Image::ExifTool::QuickTime::Main = (
|
|
462
478
|
PROCESS_PROC => \&ProcessMOV,
|
|
@@ -1159,7 +1175,10 @@ my %eeBox2 = (
|
|
|
1159
1175
|
},
|
|
1160
1176
|
{
|
|
1161
1177
|
Name => 'GarminGPS',
|
|
1162
|
-
Condition =>
|
|
1178
|
+
Condition => q{
|
|
1179
|
+
$$valPt=~/^\x9b\x63\x0f\x8d\x63\x74\x40\xec\x82\x04\xbc\x5f\xf5\x09\x17\x28/ and
|
|
1180
|
+
$$self{OPTIONS}{ExtractEmbedded}
|
|
1181
|
+
},
|
|
1163
1182
|
SubDirectory => {
|
|
1164
1183
|
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
|
1165
1184
|
ProcessProc => \&ProcessGarminGPS,
|
|
@@ -1961,7 +1980,7 @@ my %eeBox2 = (
|
|
|
1961
1980
|
Name => 'SanyoMOV',
|
|
1962
1981
|
Condition => q{
|
|
1963
1982
|
$$valPt =~ /^SANYO DIGITAL CAMERA\0/ and
|
|
1964
|
-
|
|
1983
|
+
$$self{FileType} eq "MOV"
|
|
1965
1984
|
},
|
|
1966
1985
|
SubDirectory => {
|
|
1967
1986
|
TagTable => 'Image::ExifTool::Sanyo::MOV',
|
|
@@ -1972,7 +1991,7 @@ my %eeBox2 = (
|
|
|
1972
1991
|
Name => 'SanyoMP4',
|
|
1973
1992
|
Condition => q{
|
|
1974
1993
|
$$valPt =~ /^SANYO DIGITAL CAMERA\0/ and
|
|
1975
|
-
|
|
1994
|
+
$$self{FileType} eq "MP4"
|
|
1976
1995
|
},
|
|
1977
1996
|
SubDirectory => {
|
|
1978
1997
|
TagTable => 'Image::ExifTool::Sanyo::MP4',
|
|
@@ -2868,7 +2887,7 @@ my %eeBox2 = (
|
|
|
2868
2887
|
7 => 'SMPTE 240',
|
|
2869
2888
|
8 => 'Generic film (color filters using illuminant C)',
|
|
2870
2889
|
9 => 'BT.2020, BT.2100',
|
|
2871
|
-
10 => 'SMPTE 428 (CIE
|
|
2890
|
+
10 => 'SMPTE 428 (CIE 1931 XYZ)', #forum14766
|
|
2872
2891
|
11 => 'SMPTE RP 431-2',
|
|
2873
2892
|
12 => 'SMPTE EG 432-1',
|
|
2874
2893
|
22 => 'EBU Tech. 3213-E',
|
|
@@ -7146,7 +7165,7 @@ my %eeBox2 = (
|
|
|
7146
7165
|
$$self{AudioFormat} = $val;
|
|
7147
7166
|
return undef unless $val =~ /^[\w ]{4}$/i;
|
|
7148
7167
|
# check for protected audio format
|
|
7149
|
-
$self->OverrideFileType('M4P') if $val eq 'drms' and $$self{
|
|
7168
|
+
$self->OverrideFileType('M4P') if $val eq 'drms' and $$self{FileType} eq 'M4A';
|
|
7150
7169
|
return $val;
|
|
7151
7170
|
},
|
|
7152
7171
|
# see this link for print conversions (not complete):
|
|
@@ -8768,6 +8787,16 @@ sub HandleItemInfo($)
|
|
|
8768
8787
|
$et->VPrint(0, "$$et{INDENT} [snip $snip bytes]\n") if $snip;
|
|
8769
8788
|
}
|
|
8770
8789
|
}
|
|
8790
|
+
# do MD5 checksum of AVIF "av01" and HEIC image data
|
|
8791
|
+
if ($isImageData{$type} and $$et{ImageDataMD5}) {
|
|
8792
|
+
my $md5 = $$et{ImageDataMD5};
|
|
8793
|
+
my $tot = 0;
|
|
8794
|
+
foreach $extent (@{$$item{Extents}}) {
|
|
8795
|
+
$raf->Seek($$extent[1] + $base, 0) or $et->Warn("Seek error in $type image data"), last;
|
|
8796
|
+
$tot += $et->ImageDataMD5($raf, $$extent[2], "$type image", 1);
|
|
8797
|
+
}
|
|
8798
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataMD5: $tot bytes of $type data)\n") if $tot;
|
|
8799
|
+
}
|
|
8771
8800
|
next unless $name;
|
|
8772
8801
|
# assemble the data for this item
|
|
8773
8802
|
undef $buff;
|
|
@@ -9270,7 +9299,8 @@ sub ProcessMOV($$;$)
|
|
|
9270
9299
|
$$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode
|
|
9271
9300
|
|
|
9272
9301
|
my $ee = $$et{OPTIONS}{ExtractEmbedded};
|
|
9273
|
-
|
|
9302
|
+
my $md5 = $$et{ImageDataMD5};
|
|
9303
|
+
if ($ee or $md5) {
|
|
9274
9304
|
$unkOpt = $$et{OPTIONS}{Unknown};
|
|
9275
9305
|
require 'Image/ExifTool/QuickTimeStream.pl';
|
|
9276
9306
|
}
|
|
@@ -9352,7 +9382,7 @@ sub ProcessMOV($$;$)
|
|
|
9352
9382
|
# set flag to store additional information for ExtractEmbedded option
|
|
9353
9383
|
my $handlerType = $$et{HandlerType};
|
|
9354
9384
|
if ($eeBox{$handlerType} and $eeBox{$handlerType}{$tag}) {
|
|
9355
|
-
if ($ee) {
|
|
9385
|
+
if ($ee or $md5) {
|
|
9356
9386
|
# (there is another 'gps ' box with a track log that doesn't contain offsets)
|
|
9357
9387
|
if ($tag ne 'gps ' or $eeBox{$handlerType}{$tag} eq $dirID) {
|
|
9358
9388
|
$eeTag = 1;
|
|
@@ -9364,6 +9394,9 @@ sub ProcessMOV($$;$)
|
|
|
9364
9394
|
} elsif ($ee and $ee > 1 and $eeBox2{$handlerType} and $eeBox2{$handlerType}{$tag}) {
|
|
9365
9395
|
$eeTag = 1;
|
|
9366
9396
|
$$et{OPTIONS}{Unknown} = 1;
|
|
9397
|
+
} elsif ($md5 and $md5Box{$handlerType} and $md5Box{$handlerType}{$tag}) {
|
|
9398
|
+
$eeTag = 1;
|
|
9399
|
+
$$et{OPTIONS}{Unknown} = 1;
|
|
9367
9400
|
}
|
|
9368
9401
|
my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
|
|
9369
9402
|
|
|
@@ -9596,7 +9629,7 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9596
9629
|
}
|
|
9597
9630
|
if ($tag eq 'stbl') {
|
|
9598
9631
|
# process sample data when exiting SampleTable box if extracting embedded
|
|
9599
|
-
ProcessSamples($et) if $ee;
|
|
9632
|
+
ProcessSamples($et) if $ee or $md5;
|
|
9600
9633
|
} elsif ($tag eq 'minf') {
|
|
9601
9634
|
$$et{HandlerType} = ''; # reset handler type at end of media info box
|
|
9602
9635
|
}
|
|
@@ -9656,6 +9689,7 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9656
9689
|
}
|
|
9657
9690
|
}
|
|
9658
9691
|
$langInfo or $langInfo = $tagInfo;
|
|
9692
|
+
my $str = $qtFlags{$flags} ? " ($qtFlags{$flags})" : '';
|
|
9659
9693
|
$et->VerboseInfo($tag, $langInfo,
|
|
9660
9694
|
Value => ref $value ? $$value : $value,
|
|
9661
9695
|
DataPt => \$val,
|
|
@@ -9664,7 +9698,7 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9664
9698
|
Size => $len,
|
|
9665
9699
|
Format => $format,
|
|
9666
9700
|
Index => $index,
|
|
9667
|
-
Extra => sprintf(", Type='${type}', Flags=0x%x, Lang=0x%.4x",$flags,$lang),
|
|
9701
|
+
Extra => sprintf(", Type='${type}', Flags=0x%x%s, Lang=0x%.4x",$flags,$str,$lang),
|
|
9668
9702
|
) if $verbose;
|
|
9669
9703
|
# use "Keys" in path instead of ItemList if this was defined by a Keys tag
|
|
9670
9704
|
my $isKey = $$tagInfo{Groups} && $$tagInfo{Groups}{1} && $$tagInfo{Groups}{1} eq 'Keys';
|
|
@@ -9793,7 +9827,7 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9793
9827
|
++$index if defined $index;
|
|
9794
9828
|
}
|
|
9795
9829
|
# tweak file type based on track content ("iso*" and "dash" ftyp only)
|
|
9796
|
-
if ($topLevel and $$et{
|
|
9830
|
+
if ($topLevel and $$et{FileType} and $$et{FileType} eq 'MP4' and
|
|
9797
9831
|
$$et{save_ftyp} and $$et{HasHandler} and $$et{save_ftyp} =~ /^(iso|dash)/ and
|
|
9798
9832
|
$$et{HasHandler}{soun} and not $$et{HasHandler}{vide})
|
|
9799
9833
|
{
|
|
@@ -28,7 +28,7 @@ sub Process360Fly($$$);
|
|
|
28
28
|
sub ProcessFMAS($$$);
|
|
29
29
|
sub ProcessCAMM($$$);
|
|
30
30
|
|
|
31
|
-
my $debug; # set to
|
|
31
|
+
my $debug; # set to 'tEST' (all caps) for extra debugging messages
|
|
32
32
|
|
|
33
33
|
# QuickTime data types that have ExifTool equivalents
|
|
34
34
|
# (ref https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW35)
|
|
@@ -89,6 +89,7 @@ my %insvDataLen = (
|
|
|
89
89
|
0x600 => 8, # timestamps (ref 6)
|
|
90
90
|
0x700 => 53, # GPS
|
|
91
91
|
# 0x900 => 48, # ? (Insta360 X3)
|
|
92
|
+
# 0xa00 => 5?, # ? (Insta360 ONE RS)
|
|
92
93
|
# 0xb00 => 10, # ? (Insta360 X3)
|
|
93
94
|
);
|
|
94
95
|
|
|
@@ -599,6 +600,8 @@ my %insvLimit = (
|
|
|
599
600
|
0x1a => 'Firmware',
|
|
600
601
|
0x2a => {
|
|
601
602
|
Name => 'Parameters',
|
|
603
|
+
# (see https://exiftool.org/forum/index.php?msg=78942)
|
|
604
|
+
Notes => 'number of lenses, 6-axis orientation of each lens, raw resolution',
|
|
602
605
|
ValueConv => '$val =~ tr/_/ /; $val',
|
|
603
606
|
},
|
|
604
607
|
);
|
|
@@ -1125,23 +1128,38 @@ sub Process_text($$$;$)
|
|
|
1125
1128
|
# Inputs: 0) ExifTool ref
|
|
1126
1129
|
# Notes: Also accesses ExifTool RAF*, SET_GROUP1, HandlerType, MetaFormat,
|
|
1127
1130
|
# ee*, and avcC elements (* = must exist)
|
|
1131
|
+
# - may be called either due to ExtractEmbedded option, or ImageDataMD5 requested
|
|
1132
|
+
# - MD5 includes only video and audio data
|
|
1128
1133
|
sub ProcessSamples($)
|
|
1129
1134
|
{
|
|
1130
1135
|
my $et = shift;
|
|
1131
1136
|
my ($raf, $ee) = @$et{qw(RAF ee)};
|
|
1132
|
-
my ($i, $buff, $pos, $hdrLen, $hdrFmt, @time, @dur, $oldIndent);
|
|
1137
|
+
my ($i, $buff, $pos, $hdrLen, $hdrFmt, @time, @dur, $oldIndent, $md5);
|
|
1138
|
+
my ($mdatOffset, $mdatSize); # (for range-checking samples when MD5 is done)
|
|
1133
1139
|
|
|
1134
1140
|
return unless $ee;
|
|
1135
1141
|
delete $$et{ee}; # use only once
|
|
1136
1142
|
|
|
1137
|
-
|
|
1143
|
+
my $eeOpt = $et->Options('ExtractEmbedded');
|
|
1138
1144
|
my $type = $$et{HandlerType} || '';
|
|
1139
1145
|
if ($type eq 'vide') {
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1146
|
+
# only process specific types of video streams
|
|
1147
|
+
$md5 = $$et{ImageDataMD5};
|
|
1148
|
+
# only process specific video types if ExtractEmbedded was used
|
|
1149
|
+
# (otherwise we are only here to calculate the audio/video MD5)
|
|
1150
|
+
if ($eeOpt) {
|
|
1151
|
+
if ($$ee{avcC}) { $type = 'avcC' }
|
|
1152
|
+
elsif ($$ee{JPEG}) { $type = 'JPEG' }
|
|
1153
|
+
else { return unless $md5 }
|
|
1154
|
+
}
|
|
1155
|
+
} elsif ($type eq 'soun') {
|
|
1156
|
+
$md5 = $$et{ImageDataMD5};
|
|
1157
|
+
return unless $md5;
|
|
1158
|
+
} else {
|
|
1159
|
+
return unless $eeOpt; # (don't do MD5 on other types)
|
|
1143
1160
|
}
|
|
1144
1161
|
|
|
1162
|
+
my $md5size = 0;
|
|
1145
1163
|
my ($start, $size) = @$ee{qw(start size)};
|
|
1146
1164
|
#
|
|
1147
1165
|
# determine sample start offsets from chunk offsets (stco) and sample-to-chunk table (stsc),
|
|
@@ -1160,13 +1178,16 @@ sub ProcessSamples($)
|
|
|
1160
1178
|
$timeDelta = shift @$stts;
|
|
1161
1179
|
}
|
|
1162
1180
|
my $ts = $$et{MediaTS} || 1;
|
|
1181
|
+
my @chunkSize; # total size of each chunk
|
|
1163
1182
|
foreach $chunkStart (@$stco) {
|
|
1164
1183
|
if ($iChunk >= $nextChunk and @$stsc) {
|
|
1165
1184
|
($startChunk, $samplesPerChunk, $descIdx) = @{shift @$stsc};
|
|
1166
1185
|
$nextChunk = $$stsc[0][0] if @$stsc;
|
|
1167
1186
|
}
|
|
1168
1187
|
@$size < @$start + $samplesPerChunk and $et->WarnOnce('Sample size error'), last;
|
|
1188
|
+
last unless defined $chunkStart and length $chunkStart;
|
|
1169
1189
|
my $sampleStart = $chunkStart;
|
|
1190
|
+
my $chunkSize = 0;
|
|
1170
1191
|
Sample: for ($i=0; ; ) {
|
|
1171
1192
|
push @$start, $sampleStart;
|
|
1172
1193
|
if (defined $time) {
|
|
@@ -1184,12 +1205,19 @@ Sample: for ($i=0; ; ) {
|
|
|
1184
1205
|
--$timeCount;
|
|
1185
1206
|
}
|
|
1186
1207
|
# (eventually should use the description indices: $descIdx)
|
|
1208
|
+
$chunkSize += $$size[$#$start];
|
|
1187
1209
|
last if ++$i >= $samplesPerChunk;
|
|
1188
1210
|
$sampleStart += $$size[$#$start];
|
|
1189
1211
|
}
|
|
1212
|
+
push @chunkSize, $chunkSize;
|
|
1190
1213
|
++$iChunk;
|
|
1191
1214
|
}
|
|
1192
1215
|
@$start == @$size or $et->WarnOnce('Incorrect sample start/size count'), return;
|
|
1216
|
+
# process as chunks if we are only interested in calculating MD5
|
|
1217
|
+
if ($type eq 'soun' or $type eq 'vide') {
|
|
1218
|
+
$start = $stco;
|
|
1219
|
+
$size = \@chunkSize;
|
|
1220
|
+
}
|
|
1193
1221
|
}
|
|
1194
1222
|
#
|
|
1195
1223
|
# extract and parse the sample data
|
|
@@ -1204,6 +1232,10 @@ Sample: for ($i=0; ; ) {
|
|
|
1204
1232
|
$oldIndent = $$et{INDENT};
|
|
1205
1233
|
$$et{INDENT} = '';
|
|
1206
1234
|
}
|
|
1235
|
+
if ($md5) {
|
|
1236
|
+
$mdatSize = $$et{MediaDataSize};
|
|
1237
|
+
$mdatOffset = $$et{MediaDataOffset} if defined $mdatSize;
|
|
1238
|
+
}
|
|
1207
1239
|
# get required information from avcC box if parsing video data
|
|
1208
1240
|
if ($type eq 'avcC') {
|
|
1209
1241
|
$hdrLen = (Get8u(\$$ee{avcC}, 4) & 0x03) + 1;
|
|
@@ -1217,10 +1249,29 @@ Sample: for ($i=0; ; ) {
|
|
|
1217
1249
|
delete $$et{FoundGPSLatitude};
|
|
1218
1250
|
delete $$et{FoundGPSDateTime};
|
|
1219
1251
|
|
|
1220
|
-
#
|
|
1252
|
+
# range check the sample data for MD5 if necessary
|
|
1221
1253
|
my $size = $$size[$i];
|
|
1222
|
-
|
|
1223
|
-
|
|
1254
|
+
if (defined $mdatOffset) {
|
|
1255
|
+
if ($$start[$i] < $mdatOffset) {
|
|
1256
|
+
$et->Warn("Sample $i for '${type}' data is before start of mdat");
|
|
1257
|
+
} elsif ($$start[$i] + $size > $mdatOffset + $mdatSize) {
|
|
1258
|
+
$et->Warn("Sample $i for '${type}' data runs off end of mdat");
|
|
1259
|
+
$size = $mdatOffset + $mdatSize - $$start[$i];
|
|
1260
|
+
$size = 0 if $size < 0;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
# read the sample data
|
|
1264
|
+
$raf->Seek($$start[$i], 0) or $et->WarnOnce("Seek error in $type data"), next;
|
|
1265
|
+
my $n = $raf->Read($buff, $size);
|
|
1266
|
+
unless ($n == $size) {
|
|
1267
|
+
$et->WarnOnce("Error reading $type data");
|
|
1268
|
+
next unless $n;
|
|
1269
|
+
$size = $n;
|
|
1270
|
+
}
|
|
1271
|
+
if ($md5) {
|
|
1272
|
+
$md5->add($buff);
|
|
1273
|
+
$md5size += length $buff;
|
|
1274
|
+
}
|
|
1224
1275
|
if ($type eq 'avcC') {
|
|
1225
1276
|
next if length($buff) <= $hdrLen;
|
|
1226
1277
|
# scan through all NAL units and send them to ParseH264Video()
|
|
@@ -1347,6 +1398,8 @@ Sample: for ($i=0; ; ) {
|
|
|
1347
1398
|
SetGPSDateTime($et, $tagTbl, $time[$i]) if $$et{FoundGPSLatitude} and not $$et{FoundGPSDateTime};
|
|
1348
1399
|
}
|
|
1349
1400
|
if ($verbose) {
|
|
1401
|
+
my $str = $type eq 'soun' ? 'Audio' : 'Video';
|
|
1402
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataMD5: $md5size bytes of $str data)\n") if $md5size;
|
|
1350
1403
|
$$et{INDENT} = $oldIndent;
|
|
1351
1404
|
$et->VPrint(0, "--------------------------\n");
|
|
1352
1405
|
}
|
|
@@ -1423,16 +1476,15 @@ sub ProcessFreeGPS($$$)
|
|
|
1423
1476
|
$et->VerboseDump(\$buf2);
|
|
1424
1477
|
}
|
|
1425
1478
|
# (extract longitude as 9 digits, not 8, ref PH)
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
push @xtra, UserLabel => $lbl if length $lbl;
|
|
1479
|
+
if ($buf2 =~ /^.{8}(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}).(.{15})([NS])(\d{8})([EW])(\d{9})(\d{8})?/s) {
|
|
1480
|
+
($yr,$mon,$day,$hr,$min,$sec,$lbl,$latRef,$lat,$lonRef,$lon,$spd) = ($1,$2,$3,$4,$5,$6,$7,$8,$9/1e4,$10,$11/1e4,$12);
|
|
1481
|
+
if (defined $spd) { # (Azdome)
|
|
1482
|
+
$spd += 0; # remove leading 0's
|
|
1483
|
+
} elsif ($buf2 =~ /^.{57}([-+]\d{4})(\d{3})/s) { # (EEEkit)
|
|
1484
|
+
# $alt = $1 + 0; (doesn't look right for my sample, but the Ambarella A12 text has this)
|
|
1485
|
+
$spd = $2 + 0;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1436
1488
|
# extract accelerometer data (ref PH)
|
|
1437
1489
|
if ($buf2 =~ /^.{65}(([-+]\d{3})([-+]\d{3})([-+]\d{3})([-+]\d{3})*)/s) {
|
|
1438
1490
|
$_ = $1;
|
|
@@ -1440,7 +1492,15 @@ sub ProcessFreeGPS($$$)
|
|
|
1440
1492
|
s/([-+])/ $1/g; s/^ //;
|
|
1441
1493
|
push @xtra, AccelerometerData => $_;
|
|
1442
1494
|
} elsif ($buf2 =~ /^.{173}([-+]\d{3})([-+]\d{3})([-+]\d{3})/s) { # (Azdome)
|
|
1495
|
+
# (Adzome may contain acc and date/time/label even if GPS doesn't exist)
|
|
1443
1496
|
@acc = ($1/100, $2/100, $3/100);
|
|
1497
|
+
if (not defined $yr and $buf2 =~ /^.{8}(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}).(.{15})/s) {
|
|
1498
|
+
($yr,$mon,$day,$hr,$min,$sec,$lbl) = ($1,$2,$3,$4,$5,$6,$7);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
if (defined $lbl) {
|
|
1502
|
+
$lbl =~ s/\0.*//s; $lbl =~ s/\s+$//; # truncate at null and remove trailing spaces
|
|
1503
|
+
push @xtra, UserLabel => $lbl if length $lbl;
|
|
1444
1504
|
}
|
|
1445
1505
|
|
|
1446
1506
|
} elsif ($$dataPt =~ /^.{52}(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/s) {
|
|
@@ -1488,7 +1548,7 @@ sub ProcessFreeGPS($$$)
|
|
|
1488
1548
|
# Kenwood dashcam sometimes stores absolute year and local time
|
|
1489
1549
|
# (but sometimes year since 2000 and UTC time in same video!)
|
|
1490
1550
|
require Time::Local;
|
|
1491
|
-
my $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$yr
|
|
1551
|
+
my $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$yr);
|
|
1492
1552
|
($sec,$min,$hr,$day,$mon,$yr) = gmtime($time);
|
|
1493
1553
|
$yr += 1900;
|
|
1494
1554
|
++$mon;
|
|
@@ -1709,8 +1769,6 @@ sub ProcessFreeGPS($$$)
|
|
|
1709
1769
|
# save tag values extracted by above code
|
|
1710
1770
|
#
|
|
1711
1771
|
FoundSomething($et, $tagTbl, $$dirInfo{SampleTime}, $$dirInfo{SampleDuration});
|
|
1712
|
-
# lat/long are in DDDMM.MMMM format
|
|
1713
|
-
ConvertLatLon($lat, $lon) unless $ddd;
|
|
1714
1772
|
$sec = '0' . $sec unless $sec =~ /^\d{2}/; # pad integer part of seconds to 2 digits
|
|
1715
1773
|
if (defined $yr) {
|
|
1716
1774
|
my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%sZ',$yr,$mon,$day,$hr,$min,$sec);
|
|
@@ -1719,8 +1777,12 @@ sub ProcessFreeGPS($$$)
|
|
|
1719
1777
|
my $time = sprintf('%.2d:%.2d:%sZ',$hr,$min,$sec);
|
|
1720
1778
|
$et->HandleTag($tagTbl, GPSTimeStamp => $time);
|
|
1721
1779
|
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1780
|
+
if (defined $lat) {
|
|
1781
|
+
# lat/long are in DDDMM.MMMM format unless $ddd is set
|
|
1782
|
+
ConvertLatLon($lat, $lon) unless $ddd;
|
|
1783
|
+
$et->HandleTag($tagTbl, GPSLatitude => $lat * ($latRef eq 'S' ? -1 : 1));
|
|
1784
|
+
$et->HandleTag($tagTbl, GPSLongitude => $lon * ($lonRef eq 'W' ? -1 : 1));
|
|
1785
|
+
}
|
|
1724
1786
|
$et->HandleTag($tagTbl, GPSAltitude => $alt) if defined $alt;
|
|
1725
1787
|
$et->HandleTag($tagTbl, GPSSpeed => $spd) if defined $spd;
|
|
1726
1788
|
$et->HandleTag($tagTbl, GPSTrack => $trk) if defined $trk;
|
|
@@ -2803,7 +2865,7 @@ sub ProcessInsta360($;$)
|
|
|
2803
2865
|
$raf->Read($buff, $len) == $len or last;
|
|
2804
2866
|
$et->VerboseDump(\$buff) if $verbose > 2;
|
|
2805
2867
|
if ($dlen) {
|
|
2806
|
-
if ($len % $dlen) {
|
|
2868
|
+
if ($len % $dlen and $id != 0x700) { # (have seen one 0x700 record which was expected format but not multiple of 53 bytes)
|
|
2807
2869
|
$et->Warn(sprintf('Unexpected Insta360 record 0x%x length',$id));
|
|
2808
2870
|
} elsif ($id == 0x200) {
|
|
2809
2871
|
$et->FoundTag(PreviewImage => $buff);
|
|
@@ -2833,10 +2895,9 @@ sub ProcessInsta360($;$)
|
|
|
2833
2895
|
$et->HandleTag($tagTbl, VideoTimeStamp => sprintf('%.3f', Get64u(\$buff, $p) / 1000));
|
|
2834
2896
|
}
|
|
2835
2897
|
} elsif ($id == 0x700) {
|
|
2836
|
-
for ($p=0; $p
|
|
2898
|
+
for ($p=0; $p+$dlen<=$len; $p+=$dlen) {
|
|
2837
2899
|
my $tmp = substr($buff, $p, $dlen);
|
|
2838
2900
|
my @a = unpack('VVvaa8aa8aa8a8a8', $tmp);
|
|
2839
|
-
next unless $a[3] eq 'A'; # (ignore void fixes)
|
|
2840
2901
|
unless (($a[5] eq 'N' or $a[5] eq 'S') and # (quick validation)
|
|
2841
2902
|
($a[7] eq 'E' or $a[7] eq 'W' or
|
|
2842
2903
|
# (odd, but I've seen "O" instead of "W". Perhaps
|
|
@@ -2846,6 +2907,7 @@ sub ProcessInsta360($;$)
|
|
|
2846
2907
|
$et->Warn('Unrecognized INSV GPS format');
|
|
2847
2908
|
last;
|
|
2848
2909
|
}
|
|
2910
|
+
next unless $a[3] eq 'A'; # (ignore void fixes)
|
|
2849
2911
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
|
2850
2912
|
$a[$_] = GetDouble(\$a[$_], 0) foreach 4,6,8,9,10;
|
|
2851
2913
|
$a[4] = -abs($a[4]) if $a[5] eq 'S'; # (abs just in case it was already signed)
|
|
@@ -2924,6 +2986,7 @@ sub ProcessGarminGPS($$$)
|
|
|
2924
2986
|
my $epoch = (66 * 365 + 17) * 24 * 3600; # time is relative to Jan 1, 1904
|
|
2925
2987
|
my $scl = 180 / (32768 * 65536); # scaling factor for lat/lon
|
|
2926
2988
|
$et->VerboseDir('GarminGPS');
|
|
2989
|
+
$$et{SET_GROUP1} = 'Garmin';
|
|
2927
2990
|
while ($pos + 20 <= $dataLen) {
|
|
2928
2991
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
|
2929
2992
|
my $time = Image::ExifTool::ConvertUnixTime(Get32u($dataPt, $pos) - $epoch) . 'Z';
|
|
@@ -2938,6 +3001,7 @@ sub ProcessGarminGPS($$$)
|
|
|
2938
3001
|
$pos += 20;
|
|
2939
3002
|
}
|
|
2940
3003
|
delete $$et{DOC_NUM};
|
|
3004
|
+
delete $$et{SET_GROUP1};
|
|
2941
3005
|
return 1;
|
|
2942
3006
|
}
|
|
2943
3007
|
|
|
@@ -249,6 +249,13 @@ key:
|
|
|
249
249
|
within this atom. Currently used only for Canon CNTH atom,
|
|
250
250
|
which contains garbage after the first contained atom.
|
|
251
251
|
|
|
252
|
+
NIKON_OFFSETS [Nikon Encrypted tables only] Pointer to int32u NumberOffsets
|
|
253
|
+
for offset-type encrypted Nikon directories. When set,
|
|
254
|
+
directory and decryption lengths are calculated automatically.
|
|
255
|
+
|
|
256
|
+
ALLOW_REPROCESS Flag to allow reprocessing of another directory at this
|
|
257
|
+
same location in the file, bypassing recursion avoidance test.
|
|
258
|
+
|
|
252
259
|
DATAMEMBER : BinaryData tables only. A reference to a list of sorted tag ID's
|
|
253
260
|
which must be extracted as data members when writing. Must also list "var_"
|
|
254
261
|
format tags and tags with Hook so offsets are properly calculated if the table
|
|
@@ -404,6 +411,10 @@ numerical, and generated automatically otherwise.
|
|
|
404
411
|
|
|
405
412
|
'IsComposite' - flag set for Composite tags
|
|
406
413
|
|
|
414
|
+
'IsImageData' - flag set if this is an image data offset to
|
|
415
|
+
be included in ImageDataMD5 calculation. Must have an
|
|
416
|
+
OffsetPair entry which is the ID of the corresponding size.
|
|
417
|
+
|
|
407
418
|
'IsOffset' - flag set if the tag represents an offset to some
|
|
408
419
|
data, and causes value will be adjusted to an absolute file
|
|
409
420
|
offset. If set to 2, the offset base of the parent directory
|
|
@@ -465,6 +476,10 @@ numerical, and generated automatically otherwise.
|
|
|
465
476
|
documentation, padded to the number of digits given by the
|
|
466
477
|
PrintHex value.
|
|
467
478
|
|
|
479
|
+
'PrintInt' - remove decimal part of tag ID in HTML tag name
|
|
480
|
+
documentation. (To avoid confusing ExifTool users because
|
|
481
|
+
the LensType decimal numbers are for internal use only.)
|
|
482
|
+
|
|
468
483
|
'PrintSort' - causes PrintConv values to be sorted by value
|
|
469
484
|
rather than key in the HTML tag name documentation.
|
|
470
485
|
|
|
@@ -713,7 +728,7 @@ numerical, and generated automatically otherwise.
|
|
|
713
728
|
BitShift are applied before evaluating RawConv.
|
|
714
729
|
|
|
715
730
|
BitShift : [Mask tags only] Bit shift for Mask-ed values. If not
|
|
716
|
-
specified, set to the number of trailing bits in
|
|
731
|
+
specified, set to the number of trailing zero bits in Mask.
|
|
717
732
|
When reading, the value is shifted right by this number of
|
|
718
733
|
bits after the Mask is applied.
|
|
719
734
|
|
|
@@ -1003,7 +1018,9 @@ numerical, and generated automatically otherwise.
|
|
|
1003
1018
|
current Base. This is a Perl expression which may use
|
|
1004
1019
|
$valuePtr to represent the location of the tag value in the
|
|
1005
1020
|
file, or $val for the value itself. If not specified, a Start
|
|
1006
|
-
of '$valuePtr' is assumed.
|
|
1021
|
+
of '$valuePtr' is assumed. Subdirectories in BinaryData may
|
|
1022
|
+
also use $dirStart to represent the offset of the current
|
|
1023
|
+
directory start relative to the start of the data block.
|
|
1007
1024
|
|
|
1008
1025
|
OffsetPt : [EXIF directories only] If specified, this is a Perl
|
|
1009
1026
|
expression that gives the position of a 32-bit word in the
|
|
@@ -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.64';
|
|
34
34
|
|
|
35
35
|
sub ConvertTimecode($);
|
|
36
36
|
sub ProcessSGLT($$$);
|
|
@@ -38,6 +38,13 @@ sub ProcessSLLT($$$);
|
|
|
38
38
|
sub ProcessLucas($$$);
|
|
39
39
|
sub WriteRIFF($$);
|
|
40
40
|
|
|
41
|
+
# RIFF chunks containing image data (to include in ImageDataMD5 digest)
|
|
42
|
+
my %isImageData = (
|
|
43
|
+
LIST_movi => 1, # (AVI: contains ##db, ##dc, ##wb)
|
|
44
|
+
data => 1, # (WAV)
|
|
45
|
+
'VP8 '=>1, VP8L=>1, ANIM=>1, ANMF=>1, ALPH=>1, # (WebP)
|
|
46
|
+
);
|
|
47
|
+
|
|
41
48
|
# recognized RIFF variants
|
|
42
49
|
my %riffType = (
|
|
43
50
|
'WAVE' => 'WAV', 'AVI ' => 'AVI', 'WEBP' => 'WEBP',
|
|
@@ -1522,7 +1529,7 @@ my %code2charset = (
|
|
|
1522
1529
|
},
|
|
1523
1530
|
# (can't calculate duration like this for compressed audio types)
|
|
1524
1531
|
RawConv => q{
|
|
1525
|
-
return undef if $$self{
|
|
1532
|
+
return undef if $$self{FileType} =~ /^(LA|OFR|PAC|WV)$/;
|
|
1526
1533
|
return(($val[0] and not ($val[2] or $val[3])) ? $val[1] / $val[0] : undef);
|
|
1527
1534
|
},
|
|
1528
1535
|
PrintConv => 'ConvertDuration($val)',
|
|
@@ -1980,6 +1987,7 @@ sub ProcessRIFF($$)
|
|
|
1980
1987
|
my $unknown = $et->Options('Unknown');
|
|
1981
1988
|
my $validate = $et->Options('Validate');
|
|
1982
1989
|
my $ee = $et->Options('ExtractEmbedded');
|
|
1990
|
+
my $md5 = $$et{ImageDataMD5};
|
|
1983
1991
|
|
|
1984
1992
|
# verify this is a valid RIFF file
|
|
1985
1993
|
return 0 unless $raf->Read($buff, 12) == 12;
|
|
@@ -1996,7 +2004,7 @@ sub ProcessRIFF($$)
|
|
|
1996
2004
|
$$raf{NoBuffer} = 1 if $et->Options('FastScan'); # disable buffering in FastScan mode
|
|
1997
2005
|
$mime = $riffMimeType{$type} if $type;
|
|
1998
2006
|
$et->SetFileType($type, $mime);
|
|
1999
|
-
$$et{VALUE}{FileType} .= ' (RF64)' if $rf64;
|
|
2007
|
+
$$et{VALUE}{FileType} .= ' (RF64)' if $rf64 and $$et{VALUE}{FileType};
|
|
2000
2008
|
$$et{RIFFStreamType} = ''; # initialize stream type
|
|
2001
2009
|
$$et{RIFFStreamCodec} = []; # initialize codec array
|
|
2002
2010
|
SetByteOrder('II');
|
|
@@ -2059,6 +2067,10 @@ sub ProcessRIFF($$)
|
|
|
2059
2067
|
# (in LIST_movi chunk: ##db = uncompressed DIB, ##dc = compressed DIB, ##wb = audio data)
|
|
2060
2068
|
if ($tagInfo or (($verbose or $unknown) and $tag !~ /^(data|idx1|LIST_movi|RIFF|\d{2}(db|dc|wb))$/)) {
|
|
2061
2069
|
$raf->Read($buff, $len2) == $len2 or $err=1, last;
|
|
2070
|
+
if ($md5 and $isImageData{$tag}) {
|
|
2071
|
+
$md5->add($buff);
|
|
2072
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataMD5: '${tag}' chunk, $len2 bytes)\n");
|
|
2073
|
+
}
|
|
2062
2074
|
my $setGroups;
|
|
2063
2075
|
if ($tagInfo and ref $tagInfo eq 'HASH' and $$tagInfo{SetGroups}) {
|
|
2064
2076
|
$setGroups = $$et{SET_GROUP0} = $$et{SET_GROUP1} = $$tagInfo{SetGroups};
|
|
@@ -2085,18 +2097,27 @@ sub ProcessRIFF($$)
|
|
|
2085
2097
|
# extract information from remaining file as an embedded file
|
|
2086
2098
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
|
2087
2099
|
next; # (must not increment $pos)
|
|
2088
|
-
} elsif ($tag eq 'LIST_movi' and $ee) {
|
|
2089
|
-
next; # parse into movi chunk
|
|
2090
2100
|
} else {
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2101
|
+
my $rewind;
|
|
2102
|
+
# do MD5 if required
|
|
2103
|
+
if ($md5 and $isImageData{$tag}) {
|
|
2104
|
+
$rewind = $raf->Tell();
|
|
2105
|
+
$et->ImageDataMD5($raf, $len2, "'${tag}' chunk");
|
|
2094
2106
|
}
|
|
2095
|
-
if ($
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
}
|
|
2099
|
-
|
|
2107
|
+
if ($tag eq 'LIST_movi' and $ee) {
|
|
2108
|
+
$raf->Seek($rewind, 0) or $err = 1, last if $rewind;
|
|
2109
|
+
next; # parse into movi chunk
|
|
2110
|
+
} elsif (not $rewind) {
|
|
2111
|
+
if ($len > 0x7fffffff and not $et->Options('LargeFileSupport')) {
|
|
2112
|
+
$et->Warn("Stopped parsing at large $tag chunk (LargeFileSupport not set)");
|
|
2113
|
+
last;
|
|
2114
|
+
}
|
|
2115
|
+
if ($validate and $len2) {
|
|
2116
|
+
# (must actually try to read something after seeking to detect error)
|
|
2117
|
+
$raf->Seek($len2-1, 1) and $raf->Read($buff, 1) == 1 or $err = 1, last;
|
|
2118
|
+
} else {
|
|
2119
|
+
$raf->Seek($len2, 1) or $err=1, last;
|
|
2120
|
+
}
|
|
2100
2121
|
}
|
|
2101
2122
|
}
|
|
2102
2123
|
$pos += $len2;
|
|
@@ -14,7 +14,7 @@ use strict;
|
|
|
14
14
|
use vars qw($VERSION);
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.06';
|
|
18
18
|
|
|
19
19
|
# currently support this version Rawzor images
|
|
20
20
|
my $implementedRawzorVersion = 199; # (up to version 1.99)
|
|
@@ -138,7 +138,7 @@ sub ProcessRWZ($$)
|
|
|
138
138
|
}
|
|
139
139
|
# set OriginalFileType from FileType of original file
|
|
140
140
|
# then change FileType and MIMEType to indicate a Rawzor image
|
|
141
|
-
my $origFileType = $$et{
|
|
141
|
+
my $origFileType = $$et{FileType};
|
|
142
142
|
if ($origFileType) {
|
|
143
143
|
$et->HandleTag($tagTablePtr, OriginalFileType => $origFileType);
|
|
144
144
|
$et->OverrideFileType('RWZ');
|
|
@@ -19,7 +19,7 @@ use vars qw($VERSION);
|
|
|
19
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
20
20
|
use Image::ExifTool::Exif;
|
|
21
21
|
|
|
22
|
-
$VERSION = '1.
|
|
22
|
+
$VERSION = '1.36';
|
|
23
23
|
|
|
24
24
|
sub ProcessRicohText($$$);
|
|
25
25
|
sub ProcessRicohRMETA($$$);
|
|
@@ -949,6 +949,7 @@ sub ProcessRicohText($$$)
|
|
|
949
949
|
|
|
950
950
|
my $data = substr($$dataPt, $dirStart, $dirLen);
|
|
951
951
|
return 1 if $data =~ /^\0/; # blank Ricoh maker notes
|
|
952
|
+
$et->VerboseDir('RicohText', undef, $dirLen);
|
|
952
953
|
# validate text maker notes
|
|
953
954
|
unless ($data =~ /^(Rev|Rv)/) {
|
|
954
955
|
$et->Warn('Bad Ricoh maker notes');
|