exiftool_vendored 12.56.0 → 12.58.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 +35 -2
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/config_files/rotate_regions.config +1 -1
- data/bin/exiftool +95 -47
- data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
- data/bin/lib/Image/ExifTool/APE.pm +2 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +19 -15
- data/bin/lib/Image/ExifTool/Canon.pm +26 -6
- data/bin/lib/Image/ExifTool/DJI.pm +28 -2
- data/bin/lib/Image/ExifTool/Exif.pm +24 -5
- data/bin/lib/Image/ExifTool/FlashPix.pm +6 -2
- data/bin/lib/Image/ExifTool/FujiFilm.pm +1 -0
- data/bin/lib/Image/ExifTool/GPS.pm +7 -2
- data/bin/lib/Image/ExifTool/JPEG.pm +14 -2
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +5 -5
- data/bin/lib/Image/ExifTool/LNK.pm +5 -4
- data/bin/lib/Image/ExifTool/MIE.pm +3 -3
- data/bin/lib/Image/ExifTool/MPEG.pm +2 -2
- data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -2
- data/bin/lib/Image/ExifTool/Minolta.pm +6 -7
- data/bin/lib/Image/ExifTool/Nikon.pm +998 -903
- data/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
- data/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
- data/bin/lib/Image/ExifTool/Olympus.pm +3 -1
- data/bin/lib/Image/ExifTool/Pentax.pm +8 -5
- data/bin/lib/Image/ExifTool/Photoshop.pm +38 -7
- data/bin/lib/Image/ExifTool/QuickTime.pm +23 -7
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +3 -1
- data/bin/lib/Image/ExifTool/README +19 -2
- data/bin/lib/Image/ExifTool/RIFF.pm +3 -3
- data/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
- data/bin/lib/Image/ExifTool/Sigma.pm +5 -4
- data/bin/lib/Image/ExifTool/Sony.pm +23 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +4670 -4628
- data/bin/lib/Image/ExifTool/TagNames.pod +261 -89
- data/bin/lib/Image/ExifTool/Validate.pm +5 -5
- data/bin/lib/Image/ExifTool/WriteExif.pl +42 -0
- data/bin/lib/Image/ExifTool/Writer.pl +39 -17
- data/bin/lib/Image/ExifTool/XMP.pm +2 -2
- data/bin/lib/Image/ExifTool.pm +94 -33
- data/bin/lib/Image/ExifTool.pod +4 -4
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
@@ -1419,6 +1419,8 @@ sub SetNewValuesFromFile($$;@)
|
|
1419
1419
|
$tag =~ s/(.+?)\s*(>|<) ?//;
|
1420
1420
|
$$opts{EXPR} = 1; # flag this expression
|
1421
1421
|
} else {
|
1422
|
+
# (not sure why this is here because sign should be before '<')
|
1423
|
+
# (--> allows "<+" or "<-", which is an undocumented feature)
|
1422
1424
|
$opt = $1 if $tag =~ s/^([-+])\s*//;
|
1423
1425
|
}
|
1424
1426
|
}
|
@@ -2727,8 +2729,10 @@ sub GetAllGroups($;$)
|
|
2727
2729
|
|
2728
2730
|
my @tableNames = keys %allTables;
|
2729
2731
|
|
2730
|
-
# loop through all tag tables and get all group names
|
2731
2732
|
my %allGroups;
|
2733
|
+
# add family 1 groups not in tables
|
2734
|
+
$family == 1 and map { $allGroups{$_} = 1 } qw(Garmin);
|
2735
|
+
# loop through all tag tables and get all group names
|
2732
2736
|
while (@tableNames) {
|
2733
2737
|
my $table = GetTagTable(pop @tableNames);
|
2734
2738
|
my ($grps, $grp, $tag, $tagInfo);
|
@@ -4202,7 +4206,7 @@ sub WriteDirectory($$$;$)
|
|
4202
4206
|
return '' unless $dataPt or $$dirInfo{RAF}; # nothing to do if block never existed
|
4203
4207
|
# don't allow MakerNotes to be removed from RAW files
|
4204
4208
|
if ($blockName eq 'MakerNotes' and $rawType{$$self{FileType}}) {
|
4205
|
-
$self->Warn("Can't delete MakerNotes from $$self{
|
4209
|
+
$self->Warn("Can't delete MakerNotes from $$self{FileType}",1);
|
4206
4210
|
return undef;
|
4207
4211
|
}
|
4208
4212
|
$verb = 'Deleting';
|
@@ -4267,7 +4271,7 @@ sub WriteDirectory($$$;$)
|
|
4267
4271
|
if ($out) {
|
4268
4272
|
print $out " Deleting $name\n" if defined $newData and not length $newData;
|
4269
4273
|
if ($$self{CHANGED} == $oldChanged and $$self{OPTIONS}{Verbose} > 2) {
|
4270
|
-
print $out "$$self{INDENT} [nothing changed in $
|
4274
|
+
print $out "$$self{INDENT} [nothing changed in $name]\n";
|
4271
4275
|
}
|
4272
4276
|
}
|
4273
4277
|
return $newData;
|
@@ -5432,7 +5436,6 @@ sub WriteJPEG($$)
|
|
5432
5436
|
my $verbose = $$self{OPTIONS}{Verbose};
|
5433
5437
|
my $out = $$self{OPTIONS}{TextOut};
|
5434
5438
|
my $rtnVal = 0;
|
5435
|
-
my %dumpParms = ( Out => $out );
|
5436
5439
|
my ($writeBuffer, $oldOutfile); # used to buffer writing until PreviewImage position is known
|
5437
5440
|
|
5438
5441
|
# check to be sure this is a valid JPG or EXV file
|
@@ -5447,7 +5450,6 @@ sub WriteJPEG($$)
|
|
5447
5450
|
Write($outfile,"\xff\x01") or $err = 1;
|
5448
5451
|
$isEXV = 1;
|
5449
5452
|
}
|
5450
|
-
$dumpParms{MaxLen} = 128 unless $verbose > 3;
|
5451
5453
|
|
5452
5454
|
delete $$self{PREVIEW_INFO}; # reset preview information
|
5453
5455
|
delete $$self{DEL_PREVIEW}; # reset flag to delete preview
|
@@ -6017,12 +6019,7 @@ sub WriteJPEG($$)
|
|
6017
6019
|
#
|
6018
6020
|
my $segDataPt = \$segData;
|
6019
6021
|
$length = length($segData);
|
6020
|
-
|
6021
|
-
print $out "JPEG $markerName ($length bytes):\n";
|
6022
|
-
if ($verbose > 2 and $markerName =~ /^APP/) {
|
6023
|
-
HexDump($segDataPt, undef, %dumpParms);
|
6024
|
-
}
|
6025
|
-
}
|
6022
|
+
print $out "JPEG $markerName ($length bytes)\n" if $verbose;
|
6026
6023
|
# group delete of APP segments
|
6027
6024
|
if ($$delGroup{$dirName}) {
|
6028
6025
|
$verbose and print $out " Deleting $dirName segment\n";
|
@@ -6870,6 +6867,7 @@ sub WriteBinaryData($$$)
|
|
6870
6867
|
|
6871
6868
|
# get default format ('int8u' unless specified)
|
6872
6869
|
my $dataPt = $$dirInfo{DataPt} or return undef;
|
6870
|
+
my $dataLen = length $$dataPt;
|
6873
6871
|
my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u';
|
6874
6872
|
my $increment = FormatSize($defaultFormat);
|
6875
6873
|
unless ($increment) {
|
@@ -6886,7 +6884,8 @@ sub WriteBinaryData($$$)
|
|
6886
6884
|
delete $$dirInfo{VarFormatData};
|
6887
6885
|
}
|
6888
6886
|
my $dirStart = $$dirInfo{DirStart} || 0;
|
6889
|
-
my $dirLen = $$dirInfo{DirLen}
|
6887
|
+
my $dirLen = $$dirInfo{DirLen};
|
6888
|
+
$dirLen = $dataLen - $dirStart if not defined $dirLen or $dirLen > $dataLen - $dirStart;
|
6890
6889
|
my $newData = substr($$dataPt, $dirStart, $dirLen) or return undef;
|
6891
6890
|
my $dirName = $$dirInfo{DirName};
|
6892
6891
|
my $varSize = 0;
|
@@ -7022,11 +7021,34 @@ sub WriteBinaryData($$$)
|
|
7022
7021
|
$tagInfo = $self->GetTagInfo($tagTablePtr, $tagID, \$v);
|
7023
7022
|
next unless $tagInfo;
|
7024
7023
|
}
|
7025
|
-
|
7026
|
-
my
|
7027
|
-
my $
|
7028
|
-
|
7029
|
-
|
7024
|
+
my $subdir = $$tagInfo{SubDirectory} or next;
|
7025
|
+
my $start = $$subdir{Start};
|
7026
|
+
my $len;
|
7027
|
+
if (not $start) {
|
7028
|
+
$start = $entry;
|
7029
|
+
$len = $dirLen - $start;
|
7030
|
+
} elsif ($start =~ /\$/) {
|
7031
|
+
my $count = 1;
|
7032
|
+
my $format = $$tagInfo{Format} || $defaultFormat;
|
7033
|
+
$format =~ /(.*)\[(.*)\]/ and ($format, $count) = ($1, $2);
|
7034
|
+
my $val = ReadValue($dataPt, $entry, $format, $count, $dirLen - $entry);
|
7035
|
+
# ignore directories with a zero offset (ie. missing Nikon ShotInfo entries)
|
7036
|
+
next unless $val;
|
7037
|
+
my $dirStart = 0;
|
7038
|
+
#### eval Start ($val, $dirStart)
|
7039
|
+
$start = eval($start);
|
7040
|
+
next if $start < $dirStart or $start > $dataLen;
|
7041
|
+
$len = $$subdir{DirLen};
|
7042
|
+
$len = $dataLen - $start unless $len and $len <= $dataLen - $start;
|
7043
|
+
}
|
7044
|
+
my %subdirInfo = (
|
7045
|
+
DataPt => \$newData,
|
7046
|
+
DirStart => $start,
|
7047
|
+
DirLen => $len,
|
7048
|
+
TagInfo => $tagInfo,
|
7049
|
+
);
|
7050
|
+
my $dat = $self->WriteDirectory(\%subdirInfo, GetTagTable($$subdir{TagTable}));
|
7051
|
+
substr($newData, $start, $len) = $dat if defined $dat and length $dat;
|
7030
7052
|
}
|
7031
7053
|
}
|
7032
7054
|
return $newData;
|
@@ -50,7 +50,7 @@ use Image::ExifTool::Exif;
|
|
50
50
|
use Image::ExifTool::GPS;
|
51
51
|
require Exporter;
|
52
52
|
|
53
|
-
$VERSION = '3.
|
53
|
+
$VERSION = '3.57';
|
54
54
|
@ISA = qw(Exporter);
|
55
55
|
@EXPORT_OK = qw(EscapeXML UnescapeXML);
|
56
56
|
|
@@ -3097,7 +3097,7 @@ sub ScanForXMP($$)
|
|
3097
3097
|
undef $buff;
|
3098
3098
|
}
|
3099
3099
|
}
|
3100
|
-
unless ($$et{
|
3100
|
+
unless ($$et{FileType}) {
|
3101
3101
|
$$et{FILE_TYPE} = $$et{FILE_EXT};
|
3102
3102
|
$et->SetFileType('<unknown file containing XMP>', undef, '');
|
3103
3103
|
}
|
data/bin/lib/Image/ExifTool.pm
CHANGED
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
|
30
30
|
%static_vars);
|
31
31
|
|
32
|
-
$VERSION = '12.
|
32
|
+
$VERSION = '12.58';
|
33
33
|
$RELEASE = '';
|
34
34
|
@ISA = qw(Exporter);
|
35
35
|
%EXPORT_TAGS = (
|
@@ -1821,6 +1821,13 @@ my %systemTagsNotes = (
|
|
1821
1821
|
if specifically requested
|
1822
1822
|
},
|
1823
1823
|
},
|
1824
|
+
ImageDataMD5 => {
|
1825
|
+
Notes => q{
|
1826
|
+
MD5 of image data. Generated only if specifically requested for JPEG and
|
1827
|
+
TIFF-based images, except Panasonic raw for now. Includes image data,
|
1828
|
+
OtherImage and JpgFromRaw in the MD5, but not ThumbnailImage or PreviewImage
|
1829
|
+
},
|
1830
|
+
},
|
1824
1831
|
);
|
1825
1832
|
|
1826
1833
|
# tags defined by UserParam option (added at runtime)
|
@@ -2043,6 +2050,7 @@ sub new
|
|
2043
2050
|
$$self{DEL_GROUP} = { }; # lookup for groups to delete when writing
|
2044
2051
|
$$self{SAVE_COUNT} = 0; # count calls to SaveNewValues()
|
2045
2052
|
$$self{FILE_SEQUENCE} = 0; # sequence number for files when reading
|
2053
|
+
$$self{FILES_WRITTEN} = 0; # count of files successfully written
|
2046
2054
|
$$self{INDENT2} = ''; # indentation of verbose messages from SetNewValue
|
2047
2055
|
|
2048
2056
|
# initialize our new groups for writing
|
@@ -2478,7 +2486,15 @@ sub ExtractInfo($;@)
|
|
2478
2486
|
$self->WarnOnce('Install Time::HiRes to generate ProcessingTime');
|
2479
2487
|
}
|
2480
2488
|
}
|
2481
|
-
|
2489
|
+
|
2490
|
+
# create MD5 object if ImageDataMD5 is requested
|
2491
|
+
if ($$req{imagedatamd5} and not $$self{ImageDataMD5}) {
|
2492
|
+
if (require Digest::MD5) {
|
2493
|
+
$$self{ImageDataMD5} = Digest::MD5->new;
|
2494
|
+
} else {
|
2495
|
+
$self->WarnOnce('Install Digest::MD5 to calculate image data MD5');
|
2496
|
+
}
|
2497
|
+
}
|
2482
2498
|
++$$self{FILE_SEQUENCE}; # count files read
|
2483
2499
|
}
|
2484
2500
|
|
@@ -2869,6 +2885,10 @@ sub ExtractInfo($;@)
|
|
2869
2885
|
# restore necessary members when exiting re-entrant code
|
2870
2886
|
$$self{$_} = $$reEntry{$_} foreach keys %$reEntry;
|
2871
2887
|
SetByteOrder($saveOrder);
|
2888
|
+
} elsif ($$self{ImageDataMD5}) {
|
2889
|
+
my $digest = $$self{ImageDataMD5}->hexdigest;
|
2890
|
+
# (don't store empty digest)
|
2891
|
+
$self->FoundTag(ImageDataMD5 => $digest) unless $digest eq 'd41d8cd98f00b204e9800998ecf8427e';
|
2872
2892
|
}
|
2873
2893
|
|
2874
2894
|
# ($type may be undef without an Error when processing sub-documents)
|
@@ -4296,9 +4316,9 @@ sub GetFileTime($$)
|
|
4296
4316
|
# on Windows, try to work around incorrect file times when daylight saving time is in effect
|
4297
4317
|
if ($^O eq 'MSWin32') {
|
4298
4318
|
if (not eval { require Win32::API }) {
|
4299
|
-
$self->WarnOnce('Install Win32::API for proper handling of Windows file times');
|
4319
|
+
$self->WarnOnce('Install Win32::API for proper handling of Windows file times', 1);
|
4300
4320
|
} elsif (not eval { require Win32API::File }) {
|
4301
|
-
$self->WarnOnce('Install Win32API::File for proper handling of Windows file times');
|
4321
|
+
$self->WarnOnce('Install Win32API::File for proper handling of Windows file times', 1);
|
4302
4322
|
} else {
|
4303
4323
|
# get Win32 handle, needed for GetFileTime
|
4304
4324
|
my $win32Handle = eval { Win32API::File::GetOsFHandle($file) };
|
@@ -5867,7 +5887,8 @@ sub ConvertTimeSpan($;$)
|
|
5867
5887
|
#------------------------------------------------------------------------------
|
5868
5888
|
# Patched timelocal() that fixes ActivePerl timezone bug
|
5869
5889
|
# Inputs/Returns: same as timelocal()
|
5870
|
-
# Notes: must 'require Time::Local' before calling this routine
|
5890
|
+
# Notes: must 'require Time::Local' before calling this routine.
|
5891
|
+
# Also note that year should be full year, and not relative to 1900 as with localtime
|
5871
5892
|
sub TimeLocal(@)
|
5872
5893
|
{
|
5873
5894
|
my $tm = Time::Local::timelocal(@_);
|
@@ -6337,7 +6358,10 @@ sub ProcessJPEG($$)
|
|
6337
6358
|
my %dumpParms = ( Out => $out );
|
6338
6359
|
my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
|
6339
6360
|
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
|
6340
|
-
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
|
6361
|
+
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP, $md5);
|
6362
|
+
|
6363
|
+
# get pointer to MD5 object if it exists and we are the top-level JPEG
|
6364
|
+
$md5 = $$self{ImageDataMD5} if $$self{FILE_TYPE} eq 'JPEG' and not $$self{DOC_NUM};
|
6341
6365
|
|
6342
6366
|
# check to be sure this is a valid JPG (or J2C, or EXV) file
|
6343
6367
|
return 0 unless $raf->Read($s, 2) == 2 and $s =~ /^\xff[\xd8\x4f\x01]/;
|
@@ -6385,7 +6409,9 @@ sub ProcessJPEG($$)
|
|
6385
6409
|
#
|
6386
6410
|
# read ahead to the next segment unless we have reached EOI, SOS or SOD
|
6387
6411
|
#
|
6388
|
-
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer
|
6412
|
+
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $md5) or
|
6413
|
+
$marker==0x93))
|
6414
|
+
{
|
6389
6415
|
# read up to next marker (JPEG markers begin with 0xff)
|
6390
6416
|
my $buff;
|
6391
6417
|
$raf->ReadLine($buff) or last;
|
@@ -6415,6 +6441,8 @@ sub ProcessJPEG($$)
|
|
6415
6441
|
$nextSegPos = $raf->Tell();
|
6416
6442
|
$len -= 4; # subtract size of length word
|
6417
6443
|
last unless $raf->Seek($len, 1);
|
6444
|
+
} elsif ($md5 and defined $marker and ($marker == 0x00 or $marker == 0xda)) {
|
6445
|
+
$md5->add($buff); # (note: this includes the terminating 0xff's)
|
6418
6446
|
}
|
6419
6447
|
# read second segment too if this was the first
|
6420
6448
|
next unless defined $marker;
|
@@ -6625,7 +6653,7 @@ sub ProcessJPEG($$)
|
|
6625
6653
|
next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
|
6626
6654
|
}
|
6627
6655
|
# must scan to EOI if Validate or JpegCompressionFactor used
|
6628
|
-
next if $$options{Validate} or $calcImageLen or $$req{trailer};
|
6656
|
+
next if $$options{Validate} or $calcImageLen or $$req{trailer} or $md5;
|
6629
6657
|
# nothing interesting to parse after start of scan (SOS)
|
6630
6658
|
$success = 1;
|
6631
6659
|
last; # all done parsing file
|
@@ -7008,7 +7036,7 @@ sub ProcessJPEG($$)
|
|
7008
7036
|
$self->FoundTag('PreviewImage', $preview);
|
7009
7037
|
undef $preview;
|
7010
7038
|
}
|
7011
|
-
} elsif ($marker == 0xe4) { # APP4 (InfiRay, "SCALADO", FPXR, PreviewImage)
|
7039
|
+
} elsif ($marker == 0xe4) { # APP4 (InfiRay, "SCALADO", FPXR, DJI, PreviewImage)
|
7012
7040
|
if ($$segDataPt =~ /^SCALADO\0/ and $length >= 16) {
|
7013
7041
|
$dumpType = 'SCALADO';
|
7014
7042
|
my ($num, $idx, $len) = unpack('x8n2N', $$segDataPt);
|
@@ -7039,6 +7067,16 @@ sub ProcessJPEG($$)
|
|
7039
7067
|
DirStart(\%dirInfo, 0, 0);
|
7040
7068
|
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalParams');
|
7041
7069
|
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
7070
|
+
} elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^(.{32})?.{32}\x2c\x01\x20\0/s) {
|
7071
|
+
$dumpType = 'DJI ThermalParams2';
|
7072
|
+
DirStart(\%dirInfo, $1 ? 32 : 0, 0);
|
7073
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalParams2');
|
7074
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
7075
|
+
} elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^.{32}\xaa\x55\x38\0/s) {
|
7076
|
+
$dumpType = 'DJI ThermalParams3';
|
7077
|
+
DirStart(\%dirInfo, 32, 0);
|
7078
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalParams3');
|
7079
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
7042
7080
|
} elsif ($$self{HasIJPEG} and $length >= 120) {
|
7043
7081
|
$dumpType = 'InfiRay Factory';
|
7044
7082
|
SetByteOrder('II');
|
@@ -7152,6 +7190,13 @@ sub ProcessJPEG($$)
|
|
7152
7190
|
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
7153
7191
|
delete $$self{SET_GROUP0};
|
7154
7192
|
delete $$self{SET_GROUP1};
|
7193
|
+
} elsif ($$segDataPt =~ /^DJI-DBG\0/) {
|
7194
|
+
$dumpType = 'DJI Info';
|
7195
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::Info');
|
7196
|
+
DirStart(\%dirInfo, 8, 0);
|
7197
|
+
$$self{SET_GROUP0} = 'APP7';
|
7198
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
7199
|
+
delete $$self{SET_GROUP0};
|
7155
7200
|
} elsif ($$segDataPt =~ /^\x1aQualcomm Camera Attributes/) {
|
7156
7201
|
# found in HP iPAQ_VoiceMessenger
|
7157
7202
|
$dumpType = 'Qualcomm';
|
@@ -7680,7 +7725,7 @@ sub DoProcessTIFF($$;$)
|
|
7680
7725
|
}
|
7681
7726
|
}
|
7682
7727
|
# update FileType if necessary now that we know more about the file
|
7683
|
-
if ($$self{DNGVersion} and $$self{
|
7728
|
+
if ($$self{DNGVersion} and $$self{FileType} !~ /^(DNG|GPR)$/) {
|
7684
7729
|
# override whatever FileType we set since we now know it is DNG
|
7685
7730
|
$self->OverrideFileType($$self{TIFF_TYPE} = 'DNG');
|
7686
7731
|
}
|
@@ -7988,7 +8033,7 @@ sub ProcessDirectory($$$;$)
|
|
7988
8033
|
# patch for bug in Windows phone 7.5 O/S that writes incorrect InteropIFD pointer
|
7989
8034
|
return 0 unless $dirName eq 'GPS' and $$self{PROCESSED}{$addr} eq 'InteropIFD';
|
7990
8035
|
}
|
7991
|
-
$$self{PROCESSED}{$addr} = $dirName;
|
8036
|
+
$$self{PROCESSED}{$addr} = $dirName unless $$tagTablePtr{VARS} and $$tagTablePtr{VARS}{ALLOW_REPROCESS};
|
7992
8037
|
}
|
7993
8038
|
my $oldOrder = GetByteOrder();
|
7994
8039
|
my @save = @$self{'INDENT','DIR_NAME','Compression','SubfileType'};
|
@@ -8566,7 +8611,7 @@ sub DoEscape($$)
|
|
8566
8611
|
sub SetFileType($;$$$)
|
8567
8612
|
{
|
8568
8613
|
my ($self, $fileType, $mimeType, $normExt) = @_;
|
8569
|
-
unless ($$self{
|
8614
|
+
unless ($$self{FileType} and not $$self{DOC_NUM}) {
|
8570
8615
|
my $baseType = $$self{FILE_TYPE};
|
8571
8616
|
my $ext = $$self{FILE_EXT};
|
8572
8617
|
$fileType or $fileType = $baseType;
|
@@ -8585,7 +8630,8 @@ sub SetFileType($;$$$)
|
|
8585
8630
|
$normExt = $fileTypeExt{$fileType};
|
8586
8631
|
$normExt = $fileType unless defined $normExt;
|
8587
8632
|
}
|
8588
|
-
$$self{FileType}
|
8633
|
+
# ($$self{FileType} is the file type of the main document)
|
8634
|
+
$$self{FileType} = $fileType unless $$self{DOC_NUM};
|
8589
8635
|
$self->FoundTag('FileType', $fileType);
|
8590
8636
|
$self->FoundTag('FileTypeExtension', uc $normExt);
|
8591
8637
|
$self->FoundTag('MIMEType', $mimeType || 'application/unknown');
|
@@ -8749,13 +8795,16 @@ sub ProcessBinaryData($$$)
|
|
8749
8795
|
{
|
8750
8796
|
my ($self, $dirInfo, $tagTablePtr) = @_;
|
8751
8797
|
my $dataPt = $$dirInfo{DataPt};
|
8752
|
-
my $
|
8753
|
-
my $
|
8798
|
+
my $dataLen = length $$dataPt;
|
8799
|
+
my $dirStart = $$dirInfo{DirStart} || 0;
|
8800
|
+
my $maxLen = $dataLen - $dirStart;
|
8801
|
+
my $size = $$dirInfo{DirLen};
|
8754
8802
|
my $base = $$dirInfo{Base} || 0;
|
8755
8803
|
my $verbose = $$self{OPTIONS}{Verbose};
|
8756
8804
|
my $unknown = $$self{OPTIONS}{Unknown};
|
8757
8805
|
my $dataPos = $$dirInfo{DataPos} || 0;
|
8758
8806
|
|
8807
|
+
$size = $maxLen if not defined $size or $size > $maxLen;
|
8759
8808
|
# get default format ('int8u' unless specified)
|
8760
8809
|
my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u';
|
8761
8810
|
my $increment = $formatSize{$defaultFormat};
|
@@ -8797,6 +8846,7 @@ sub ProcessBinaryData($$$)
|
|
8797
8846
|
$tagInfo = $self->GetTagInfo($tagTablePtr, $index);
|
8798
8847
|
unless ($tagInfo) {
|
8799
8848
|
next unless defined $tagInfo;
|
8849
|
+
# $entry = offset of value relative to directory start (or end if negative)
|
8800
8850
|
my $entry = int($index) * $increment + $varSize;
|
8801
8851
|
if ($entry < 0) {
|
8802
8852
|
$entry += $size;
|
@@ -8805,7 +8855,7 @@ sub ProcessBinaryData($$$)
|
|
8805
8855
|
next if $entry >= $size;
|
8806
8856
|
my $more = $size - $entry;
|
8807
8857
|
$more = 128 if $more > 128;
|
8808
|
-
my $v = substr($$dataPt, $entry+$
|
8858
|
+
my $v = substr($$dataPt, $entry+$dirStart, $more);
|
8809
8859
|
$tagInfo = $self->GetTagInfo($tagTablePtr, $index, \$v);
|
8810
8860
|
next unless $tagInfo;
|
8811
8861
|
}
|
@@ -8838,7 +8888,7 @@ sub ProcessBinaryData($$$)
|
|
8838
8888
|
$count = $more;
|
8839
8889
|
} elsif ($format eq 'pstring') {
|
8840
8890
|
$format = 'string';
|
8841
|
-
$count = Get8u($dataPt, ($entry++)+$
|
8891
|
+
$count = Get8u($dataPt, ($entry++)+$dirStart);
|
8842
8892
|
--$more;
|
8843
8893
|
} elsif (not $formatSize{$format}) {
|
8844
8894
|
if ($format =~ /(.*)\[(.*)\]/) {
|
@@ -8867,17 +8917,17 @@ sub ProcessBinaryData($$$)
|
|
8867
8917
|
} elsif ($format =~ /^var_/) {
|
8868
8918
|
# handle variable-length string formats
|
8869
8919
|
$format = substr($format, 4);
|
8870
|
-
pos($$dataPt) = $entry + $
|
8920
|
+
pos($$dataPt) = $entry + $dirStart;
|
8871
8921
|
undef $count;
|
8872
8922
|
if ($format eq 'ustring') {
|
8873
|
-
$count = pos($$dataPt) - ($entry+$
|
8923
|
+
$count = pos($$dataPt) - ($entry+$dirStart) if $$dataPt =~ /\G(..)*?\0\0/sg;
|
8874
8924
|
$varSize -= 2; # ($count includes base size of 2 bytes)
|
8875
8925
|
} elsif ($format eq 'pstring') {
|
8876
|
-
$count = Get8u($dataPt, ($entry++)+$
|
8926
|
+
$count = Get8u($dataPt, ($entry++)+$dirStart);
|
8877
8927
|
--$more;
|
8878
8928
|
} elsif ($format eq 'pstr32' or $format eq 'ustr32') {
|
8879
8929
|
last if $more < 4;
|
8880
|
-
$count = Get32u($dataPt, $entry + $
|
8930
|
+
$count = Get32u($dataPt, $entry + $dirStart);
|
8881
8931
|
$count *= 2 if $format eq 'ustr32';
|
8882
8932
|
$entry += 4;
|
8883
8933
|
$more -= 4;
|
@@ -8885,22 +8935,22 @@ sub ProcessBinaryData($$$)
|
|
8885
8935
|
} elsif ($format eq 'int16u') {
|
8886
8936
|
# int16u size of binary data to follow
|
8887
8937
|
last if $more < 2;
|
8888
|
-
$count = Get16u($dataPt, $entry + $
|
8938
|
+
$count = Get16u($dataPt, $entry + $dirStart) + 2;
|
8889
8939
|
$varSize -= 2; # ($count includes size word)
|
8890
8940
|
$format = 'undef';
|
8891
8941
|
} elsif ($format eq 'ue7') {
|
8892
8942
|
require Image::ExifTool::BPG;
|
8893
|
-
($val, $count) = Image::ExifTool::BPG::Get_ue7($dataPt, $entry + $
|
8943
|
+
($val, $count) = Image::ExifTool::BPG::Get_ue7($dataPt, $entry + $dirStart);
|
8894
8944
|
last unless defined $val;
|
8895
8945
|
--$varSize; # ($count includes base size of 1 byte)
|
8896
8946
|
} elsif ($$dataPt =~ /\0/g) {
|
8897
|
-
$count = pos($$dataPt) - ($entry+$
|
8947
|
+
$count = pos($$dataPt) - ($entry+$dirStart);
|
8898
8948
|
--$varSize; # ($count includes base size of 1 byte)
|
8899
8949
|
}
|
8900
8950
|
$count = $more if not defined $count or $count > $more;
|
8901
8951
|
$varSize += $count; # shift subsequent indices
|
8902
8952
|
unless (defined $val) {
|
8903
|
-
$val = substr($$dataPt, $entry+$
|
8953
|
+
$val = substr($$dataPt, $entry+$dirStart, $count);
|
8904
8954
|
$val = $self->Decode($val, 'UCS2') if $format eq 'ustring' or $format eq 'ustr32';
|
8905
8955
|
$val =~ s/\0.*//s unless $format eq 'undef'; # truncate at null
|
8906
8956
|
}
|
@@ -8914,7 +8964,7 @@ sub ProcessBinaryData($$$)
|
|
8914
8964
|
# hook to allow format, etc to be set dynamically
|
8915
8965
|
if (defined $$tagInfo{Hook}) {
|
8916
8966
|
my $oldVarSize = $varSize;
|
8917
|
-
my $pos = $entry + $
|
8967
|
+
my $pos = $entry + $dirStart;
|
8918
8968
|
#### eval Hook ($format, $varSize, $size, $dataPt, $pos)
|
8919
8969
|
eval $$tagInfo{Hook};
|
8920
8970
|
# save variable size data if required for writing (in case changed by Hook)
|
@@ -8939,7 +8989,7 @@ sub ProcessBinaryData($$$)
|
|
8939
8989
|
next if $$tagInfo{LargeTag} and $$self{EXCL_TAG_LOOKUP}{lc $$tagInfo{Name}};
|
8940
8990
|
# read value now if necessary
|
8941
8991
|
unless (defined $val and not $$tagInfo{SubDirectory}) {
|
8942
|
-
$val = ReadValue($dataPt, $entry+$
|
8992
|
+
$val = ReadValue($dataPt, $entry+$dirStart, $format, $count, $more, \$rational);
|
8943
8993
|
next unless defined $val;
|
8944
8994
|
$mask = $$tagInfo{Mask};
|
8945
8995
|
$val = ($val & $mask) >> $$tagInfo{BitShift} if $mask;
|
@@ -8956,8 +9006,8 @@ sub ProcessBinaryData($$$)
|
|
8956
9006
|
Value => $val,
|
8957
9007
|
DataPt => $dataPt,
|
8958
9008
|
Size => $len,
|
8959
|
-
Start => $entry+$
|
8960
|
-
Addr => $entry+$
|
9009
|
+
Start => $entry+$dirStart,
|
9010
|
+
Addr => $entry+$dirStart+$base+$dataPos,
|
8961
9011
|
Format => $format,
|
8962
9012
|
Count => $count,
|
8963
9013
|
Extra => $mask ? sprintf(', mask 0x%.2x',$mask) : undef,
|
@@ -8983,16 +9033,27 @@ sub ProcessBinaryData($$$)
|
|
8983
9033
|
my $subdirBase = $base;
|
8984
9034
|
if (defined $$subdir{Base}) {
|
8985
9035
|
#### eval Base ($start,$base)
|
8986
|
-
my $start = $entry + $
|
9036
|
+
my $start = $entry + $dirStart + $dataPos;
|
8987
9037
|
$subdirBase = eval($$subdir{Base}) + $base;
|
8988
9038
|
}
|
8989
9039
|
my $start = $$subdir{Start} || 0;
|
9040
|
+
if ($start =~ /\$/) {
|
9041
|
+
# ignore directories with a zero offset (ie. missing Nikon ShotInfo entries)
|
9042
|
+
next unless $val;
|
9043
|
+
#### eval Start ($val, $dirStart)
|
9044
|
+
$start = eval($start);
|
9045
|
+
next if $start < $dirStart or $start > $dataLen;
|
9046
|
+
$len = $$subdir{DirLen};
|
9047
|
+
$len = $dataLen - $start unless $len and $len <= $dataLen - $start;
|
9048
|
+
} else {
|
9049
|
+
$start += $dirStart + $entry;
|
9050
|
+
}
|
8990
9051
|
my %subdirInfo = (
|
8991
9052
|
DataPt => $dataPt,
|
8992
9053
|
DataPos => $dataPos,
|
8993
|
-
DataLen =>
|
8994
|
-
DirStart => $
|
8995
|
-
DirLen => $len
|
9054
|
+
DataLen => $dataLen,
|
9055
|
+
DirStart => $start,
|
9056
|
+
DirLen => $len,
|
8996
9057
|
Base => $subdirBase,
|
8997
9058
|
);
|
8998
9059
|
delete $$self{NO_UNKNOWN};
|
data/bin/lib/Image/ExifTool.pod
CHANGED
@@ -2327,9 +2327,9 @@ CBOR, CIFF, CameraIFD, Canon, CanonCustom, CanonDR4, CanonRaw, CanonVRD,
|
|
2327
2327
|
Casio, Chapter#, Composite, DICOM, DJI, DNG, DV, DjVu, DjVu-Meta, Ducky,
|
2328
2328
|
EPPIM, EXE, EXIF, ExifIFD, ExifTool, FITS, FLAC, FLIR, File, Flash,
|
2329
2329
|
FlashPix, Font, FotoStation, FujiFilm, FujiIFD, GE, GIF, GIMP, GPS,
|
2330
|
-
GSpherical, GeoTiff, GlobParamIFD, GoPro, GraphConv, H264, HP, HTC,
|
2331
|
-
HTML-dc, HTML-ncc, HTML-office, HTML-prod, HTML-vw96, HTTP-equiv,
|
2332
|
-
ICC-clrt, ICC-header, ICC-meas, ICC-meta, ICC-view, ICC_Profile,
|
2330
|
+
GSpherical, Garmin, GeoTiff, GlobParamIFD, GoPro, GraphConv, H264, HP, HTC,
|
2331
|
+
HTML, HTML-dc, HTML-ncc, HTML-office, HTML-prod, HTML-vw96, HTTP-equiv,
|
2332
|
+
ICC-chrm, ICC-clrt, ICC-header, ICC-meas, ICC-meta, ICC-view, ICC_Profile,
|
2333
2333
|
ICC_Profile#, ID3, ID3v1, ID3v1_Enh, ID3v2_2, ID3v2_3, ID3v2_4, IFD0, IFD1,
|
2334
2334
|
IPTC, IPTC#, ISO, ITC, InfiRay, Insta360, InteropIFD, ItemList, JFIF, JFXX,
|
2335
2335
|
JPEG, JPEG-HDR, JPS, JSON, JUMBF, JVC, Jpeg2000, KDC_IFD, Keys, Kodak,
|
@@ -2349,7 +2349,7 @@ RMETA, RSRC, RTF, Radiance, Rawzor, Real, Real-CONT, Real-MDPR, Real-PROP,
|
|
2349
2349
|
Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Reconyx, Red, Ricoh, SPIFF, SR2,
|
2350
2350
|
SR2DataIFD, SR2SubIFD, SRF#, SVG, Samsung, Sanyo, Scalado, Sigma, SigmaRaw,
|
2351
2351
|
Sony, SonyIDC, Stim, SubIFD, System, Theora, Torrent, Track#, UserData,
|
2352
|
-
VCalendar, VCard,
|
2352
|
+
VCalendar, VCard, VNote, Version0, Vorbis, WTV, XML, XMP, XMP-DICOM,
|
2353
2353
|
XMP-Device, XMP-GAudio, XMP-GCamera, XMP-GCreations, XMP-GDepth, XMP-GFocus,
|
2354
2354
|
XMP-GImage, XMP-GPano, XMP-GSpherical, XMP-LImage, XMP-MP, XMP-MP1,
|
2355
2355
|
XMP-PixelLive, XMP-aas, XMP-acdsee, XMP-album, XMP-apple-fi, XMP-ast,
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exiftool_vendored
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 12.
|
4
|
+
version: 12.58.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew McEachen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-03-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: exiftool
|