exiftool_vendored 12.56.0 → 12.58.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.
- 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
|