exiftool_vendored 13.30.0 → 13.33.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 +57 -1
- data/bin/MANIFEST +5 -0
- data/bin/META.json +4 -3
- data/bin/META.yml +3 -2
- data/bin/README +47 -46
- data/bin/exiftool +88 -60
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +7 -5
- data/bin/lib/Image/ExifTool/Canon.pm +16 -5
- data/bin/lib/Image/ExifTool/Exif.pm +7 -4
- data/bin/lib/Image/ExifTool/FlashPix.pm +4 -159
- data/bin/lib/Image/ExifTool/FujiFilm.pm +13 -3
- data/bin/lib/Image/ExifTool/Geotag.pm +5 -3
- data/bin/lib/Image/ExifTool/GoPro.pm +23 -4
- data/bin/lib/Image/ExifTool/LNK.pm +24 -3
- data/bin/lib/Image/ExifTool/Lang/cs.pm +0 -1
- data/bin/lib/Image/ExifTool/Lang/de.pm +2 -2
- data/bin/lib/Image/ExifTool/Lang/fr.pm +2 -2
- data/bin/lib/Image/ExifTool/Lang/it.pm +0 -1
- data/bin/lib/Image/ExifTool/Lang/ja.pm +0 -1
- data/bin/lib/Image/ExifTool/Lang/nl.pm +0 -1
- data/bin/lib/Image/ExifTool/Lang/pl.pm +0 -1
- data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +0 -1
- data/bin/lib/Image/ExifTool/LigoGPS.pm +14 -6
- data/bin/lib/Image/ExifTool/Microsoft.pm +158 -1
- data/bin/lib/Image/ExifTool/Minolta.pm +1 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +80 -39
- data/bin/lib/Image/ExifTool/NikonCustom.pm +40 -10
- data/bin/lib/Image/ExifTool/Olympus.pm +240 -35
- data/bin/lib/Image/ExifTool/PDF.pm +1 -0
- data/bin/lib/Image/ExifTool/Panasonic.pm +4 -4
- data/bin/lib/Image/ExifTool/Parrot.pm +1 -1
- data/bin/lib/Image/ExifTool/Pentax.pm +276 -56
- data/bin/lib/Image/ExifTool/Plot.pm +2 -3
- data/bin/lib/Image/ExifTool/QuickTime.pm +13 -5
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +41 -17
- data/bin/lib/Image/ExifTool/Sigma.pm +19 -1
- data/bin/lib/Image/ExifTool/Sony.pm +5 -2
- data/bin/lib/Image/ExifTool/TNEF.pm +487 -0
- data/bin/lib/Image/ExifTool/TagLookup.pm +4374 -4262
- data/bin/lib/Image/ExifTool/TagNames.pod +259 -22
- data/bin/lib/Image/ExifTool/WriteExif.pl +14 -12
- data/bin/lib/Image/ExifTool/WritePDF.pl +1 -0
- data/bin/lib/Image/ExifTool/Writer.pl +142 -139
- data/bin/lib/Image/ExifTool/XMPStruct.pl +1 -1
- data/bin/lib/Image/ExifTool.pm +16 -7
- data/bin/lib/Image/ExifTool.pod +45 -44
- data/bin/perl-Image-ExifTool.spec +46 -45
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
@@ -1907,7 +1907,7 @@ sub RestoreNewValues($)
|
|
1907
1907
|
#------------------------------------------------------------------------------
|
1908
1908
|
# Set alternate file for extracting information
|
1909
1909
|
# Inputs: 0) ExifTool ref, 1) family 8 group name (of the form "File#" where # is any number)
|
1910
|
-
# 2) alternate file name, or undef to reset
|
1910
|
+
# 2) alternate file name (may contain tag names with leading "$"), or undef to reset
|
1911
1911
|
# Returns: 1 on success, or 0 on invalid group name
|
1912
1912
|
sub SetAlternateFile($$$)
|
1913
1913
|
{
|
@@ -1917,7 +1917,9 @@ sub SetAlternateFile($$$)
|
|
1917
1917
|
# keep the same file if already initialized (possibly has metadata extracted)
|
1918
1918
|
if (not defined $file) {
|
1919
1919
|
delete $$self{ALT_EXIFTOOL}{$g8};
|
1920
|
-
} elsif (not ($$self{ALT_EXIFTOOL}{$g8} and
|
1920
|
+
} elsif (not ($$self{ALT_EXIFTOOL}{$g8} and $file !~ /\$/ and
|
1921
|
+
$$self{ALT_EXIFTOOL}{$g8}{ALT_FILE} eq $file))
|
1922
|
+
{
|
1921
1923
|
my $altExifTool = Image::ExifTool->new;
|
1922
1924
|
$$altExifTool{ALT_FILE} = $file;
|
1923
1925
|
$$self{ALT_EXIFTOOL}{$g8} = $altExifTool;
|
@@ -3201,7 +3203,7 @@ sub InsertTagValues($$;$$$$)
|
|
3201
3203
|
my ($docNum, $tag);
|
3202
3204
|
|
3203
3205
|
if ($docGrp) {
|
3204
|
-
$docNum = $docGrp =~ /(\d+)$/ ? $1 : 0;
|
3206
|
+
$docNum = $docGrp =~ /(\d+(-\d+)*)$/ ? $1 : 0;
|
3205
3207
|
} else {
|
3206
3208
|
undef $cache; # no cache if no document groups
|
3207
3209
|
}
|
@@ -3269,25 +3271,25 @@ sub InsertTagValues($$;$$$$)
|
|
3269
3271
|
# (similar to code in BuildCompositeTags(), but this is case-insensitive)
|
3270
3272
|
my $cacheTag = $$cache{$lcTag};
|
3271
3273
|
unless ($cacheTag) {
|
3272
|
-
$cacheTag = $$cache{$lcTag} =
|
3274
|
+
$cacheTag = $$cache{$lcTag} = { };
|
3273
3275
|
# find all matching keys, organize into groups, and store in cache
|
3274
3276
|
my $ex = $$self{TAG_EXTRA};
|
3275
3277
|
my @matches = grep /^$tag(\s|$)/i, @$foundTags;
|
3276
3278
|
@matches = $self->GroupMatches($group, \@matches) if defined $group;
|
3277
3279
|
foreach (@matches) {
|
3278
3280
|
my $doc = $$ex{$_}{G3} || 0;
|
3279
|
-
if (defined $$cacheTag
|
3280
|
-
next unless $$cacheTag
|
3281
|
+
if (defined $$cacheTag{$doc}) {
|
3282
|
+
next unless $$cacheTag{$doc} =~ / \((\d+)\)$/;
|
3281
3283
|
my $cur = $1;
|
3282
3284
|
# keep the most recently extracted tag
|
3283
3285
|
next if / \((\d+)\)$/ and $1 < $cur;
|
3284
3286
|
}
|
3285
|
-
$$cacheTag
|
3287
|
+
$$cacheTag{$doc} = $_;
|
3286
3288
|
}
|
3287
3289
|
}
|
3288
|
-
my $doc = $lcTag =~ /\b(main|doc(\d+)):/ ? ($2 || 0) : $docNum;
|
3289
|
-
if ($$cacheTag
|
3290
|
-
$tag = $$cacheTag
|
3290
|
+
my $doc = $lcTag =~ /\b(main|doc(\d+(-\d+)*)):/ ? ($2 || 0) : $docNum;
|
3291
|
+
if ($$cacheTag{$doc}) {
|
3292
|
+
$tag = $$cacheTag{$doc};
|
3291
3293
|
$val = $self->GetValue($tag, $type);
|
3292
3294
|
}
|
3293
3295
|
} else {
|
@@ -4741,10 +4743,11 @@ sub DumpUnknownTrailer($$)
|
|
4741
4743
|
my $pos = $$dirInfo{DataPos};
|
4742
4744
|
my $endPos = $pos + $$dirInfo{DirLen};
|
4743
4745
|
# account for preview/MPF image trailer
|
4744
|
-
my $
|
4745
|
-
my $
|
4746
|
-
my $
|
4747
|
-
my $
|
4746
|
+
my $value = $$self{VALUE};
|
4747
|
+
my $prePos = $$value{PreviewImageStart} || $$self{PreviewImageStart};
|
4748
|
+
my $preLen = $$value{PreviewImageLength} || $$self{PreviewImageLength};
|
4749
|
+
my $hidPos = $$value{HiddenDataOffset};
|
4750
|
+
my $hidLen = $$value{HiddenDataLength};
|
4748
4751
|
my $tag = 'PreviewImage';
|
4749
4752
|
my $mpImageNum = 0;
|
4750
4753
|
my (%image, $lastOne);
|
@@ -4761,12 +4764,12 @@ sub DumpUnknownTrailer($$)
|
|
4761
4764
|
last if $lastOne; # checked all images
|
4762
4765
|
# look for MPF images (in the proper order)
|
4763
4766
|
++$mpImageNum;
|
4764
|
-
$prePos = $$
|
4767
|
+
$prePos = $$value{"MPImageStart ($mpImageNum)"};
|
4765
4768
|
if (defined $prePos) {
|
4766
|
-
$preLen = $$
|
4769
|
+
$preLen = $$value{"MPImageLength ($mpImageNum)"};
|
4767
4770
|
} else {
|
4768
|
-
$prePos = $$
|
4769
|
-
$preLen = $$
|
4771
|
+
$prePos = $$value{MPImageStart};
|
4772
|
+
$preLen = $$value{MPImageLength};
|
4770
4773
|
$lastOne = 1;
|
4771
4774
|
}
|
4772
4775
|
$tag = "MPImage$mpImageNum";
|
@@ -5887,10 +5890,10 @@ sub WriteJPEG($$)
|
|
5887
5890
|
$writeBuffer = '';
|
5888
5891
|
$oldOutfile = $outfile;
|
5889
5892
|
$outfile = \$writeBuffer;
|
5890
|
-
# account for segment, EXIF and TIFF headers
|
5891
|
-
|
5892
|
-
|
5893
|
-
|
5893
|
+
# must account for segment, EXIF and TIFF headers
|
5894
|
+
foreach (qw(PREVIEW_INFO LeicaTrailer HiddenData)) {
|
5895
|
+
$$self{$_}{Fixup}{Start} += 18 if $$self{$_};
|
5896
|
+
}
|
5894
5897
|
}
|
5895
5898
|
# write as multi-segment
|
5896
5899
|
my $n = WriteMultiSegment($outfile, 0xe1, $exifAPP1hdr, \$buff, 'EXIF');
|
@@ -6036,8 +6039,8 @@ sub WriteJPEG($$)
|
|
6036
6039
|
my $delPreview = $$self{DEL_PREVIEW};
|
6037
6040
|
$trailInfo = $self->IdentifyTrailer($raf) unless $$delGroup{Trailer};
|
6038
6041
|
my $nvTrail = $self->GetNewValueHash($Image::ExifTool::Extra{Trailer});
|
6039
|
-
unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer} or
|
6040
|
-
$$self{HiddenData})
|
6042
|
+
unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer} or
|
6043
|
+
$nvTrail or $$self{HiddenData})
|
6041
6044
|
{
|
6042
6045
|
# blindly copy the rest of the file
|
6043
6046
|
while ($raf->Read($buff, 65536)) {
|
@@ -6082,35 +6085,7 @@ sub WriteJPEG($$)
|
|
6082
6085
|
}
|
6083
6086
|
last; # all done
|
6084
6087
|
}
|
6085
|
-
#
|
6086
|
-
if ($$self{HiddenData}) {
|
6087
|
-
my $pad;
|
6088
|
-
my $hd = $$self{HiddenData};
|
6089
|
-
my $hdOff = $$hd{Offset} + $$hd{Base};
|
6090
|
-
require Image::ExifTool::Sony;
|
6091
|
-
# read HiddenData, updating $hdOff with actual offset if necessary
|
6092
|
-
my $dataPt = Image::ExifTool::Sony::ReadHiddenData($self, $hdOff, $$hd{Size});
|
6093
|
-
if ($dataPt) {
|
6094
|
-
# preserve padding to avoid invalidating MPF pointers (yuk!)
|
6095
|
-
my $padLen = $hdOff - $endPos;
|
6096
|
-
unless ($padLen >= 0 and $raf->Seek($endPos,0) and $raf->Read($pad,$padLen)==$padLen) {
|
6097
|
-
$self->Error('Error reading HiddenData padding',1);
|
6098
|
-
$pad = '';
|
6099
|
-
}
|
6100
|
-
$endPos += length($pad) + length($$dataPt); # update end position
|
6101
|
-
} else {
|
6102
|
-
$$dataPt = $pad = '';
|
6103
|
-
}
|
6104
|
-
my $fixup = $$self{HiddenData}{Fixup};
|
6105
|
-
# set MakerNote pointer and size (subtract 10 for segment and EXIF headers)
|
6106
|
-
$fixup->SetMarkerPointers($outfile, 'HiddenData', length($$outfile) + length($pad) - 10);
|
6107
|
-
# clean up and write the buffered data
|
6108
|
-
$outfile = $oldOutfile;
|
6109
|
-
undef $oldOutfile;
|
6110
|
-
Write($outfile, $writeBuffer, $pad, $$dataPt) or $err = 1;
|
6111
|
-
undef $writeBuffer;
|
6112
|
-
}
|
6113
|
-
# rewrite existing trailers
|
6088
|
+
# rewrite existing trailers into buffer
|
6114
6089
|
if ($trailInfo) {
|
6115
6090
|
my $tbuf = '';
|
6116
6091
|
$raf->Seek(-length($buff), 1); # seek back to just after EOI
|
@@ -6118,100 +6093,126 @@ sub WriteJPEG($$)
|
|
6118
6093
|
$$trailInfo{ScanForTrailer} = 1;# scan if necessary
|
6119
6094
|
$self->ProcessTrailers($trailInfo) or undef $trailInfo;
|
6120
6095
|
}
|
6121
|
-
if (
|
6122
|
-
|
6123
|
-
|
6124
|
-
|
6125
|
-
|
6126
|
-
$
|
6127
|
-
|
6128
|
-
|
6129
|
-
|
6130
|
-
|
6131
|
-
|
6132
|
-
|
6133
|
-
|
6134
|
-
|
6135
|
-
|
6136
|
-
|
6137
|
-
|
6138
|
-
|
6139
|
-
|
6140
|
-
|
6141
|
-
|
6142
|
-
|
6143
|
-
|
6144
|
-
|
6145
|
-
|
6146
|
-
$$fixup{Start} += 4; $$fixup{Shift} -= 4;
|
6147
|
-
# clean up and write the buffered data
|
6148
|
-
$outfile = $oldOutfile;
|
6149
|
-
undef $oldOutfile;
|
6150
|
-
Write($outfile, $writeBuffer) or $err = 1;
|
6151
|
-
undef $writeBuffer;
|
6152
|
-
if (defined $dat) {
|
6153
|
-
Write($outfile, $dat) or $err = 1; # write new Leica trailer
|
6154
|
-
$delPreview = 1; # delete existing Leica trailer
|
6096
|
+
if ($oldOutfile) {
|
6097
|
+
my $previewInfo;
|
6098
|
+
# copy HiddenData if necessary
|
6099
|
+
if ($$self{HiddenData}) {
|
6100
|
+
my $pad;
|
6101
|
+
my $hd = $$self{HiddenData};
|
6102
|
+
my $hdOff = $$hd{Offset} + $$hd{Base};
|
6103
|
+
require Image::ExifTool::Sony;
|
6104
|
+
# read HiddenData, updating $hdOff with actual offset if necessary
|
6105
|
+
my $dataPt = Image::ExifTool::Sony::ReadHiddenData($self, $hdOff, $$hd{Size});
|
6106
|
+
if ($dataPt) {
|
6107
|
+
# preserve padding to avoid invalidating MPF pointers (yuk!)
|
6108
|
+
my $padLen = $hdOff - $endPos;
|
6109
|
+
unless ($padLen >= 0 and $raf->Seek($endPos,0) and $raf->Read($pad,$padLen)==$padLen) {
|
6110
|
+
$self->Error('Error reading HiddenData padding',1);
|
6111
|
+
$pad = '';
|
6112
|
+
}
|
6113
|
+
$endPos += length($pad) + length($$dataPt); # update end position
|
6114
|
+
} else {
|
6115
|
+
$$dataPt = $pad = '';
|
6116
|
+
}
|
6117
|
+
my $fixup = $$self{HiddenData}{Fixup};
|
6118
|
+
# set MakerNote pointer and size (subtract 10 for segment and EXIF headers)
|
6119
|
+
$fixup->SetMarkerPointers($outfile, 'HiddenData', length($$outfile) + length($pad) - 10);
|
6120
|
+
$writeBuffer .= $pad . $$dataPt; # keep padding for now
|
6155
6121
|
}
|
6156
|
-
|
6157
|
-
|
6158
|
-
|
6159
|
-
|
6160
|
-
|
6161
|
-
|
6122
|
+
if ($$self{LeicaTrailer}) {
|
6123
|
+
my $trailLen;
|
6124
|
+
if ($trailInfo) {
|
6125
|
+
$trailLen = $$trailInfo{DataPos} - $endPos;
|
6126
|
+
} else {
|
6127
|
+
$raf->Seek(0, 2) or $err = 1;
|
6128
|
+
$trailLen = $raf->Tell() - $endPos;
|
6129
|
+
}
|
6130
|
+
my $fixup = $$self{LeicaTrailer}{Fixup};
|
6131
|
+
$$self{LeicaTrailer}{TrailPos} = $endPos;
|
6132
|
+
$$self{LeicaTrailer}{TrailLen} = $trailLen;
|
6133
|
+
# get _absolute_ position of new Leica trailer
|
6134
|
+
my $absPos = Tell($oldOutfile) + length($$outfile);
|
6135
|
+
require Image::ExifTool::Panasonic;
|
6136
|
+
my $dat = Image::ExifTool::Panasonic::ProcessLeicaTrailer($self, $absPos);
|
6137
|
+
# allow some junk before Leica trailer (just in case)
|
6138
|
+
my $junk = $$self{LeicaTrailerPos} - $endPos;
|
6139
|
+
# set MakerNote pointer and size (subtract 10 for segment and EXIF headers)
|
6140
|
+
$fixup->SetMarkerPointers($outfile, 'LeicaTrailer', length($$outfile) - 10 + $junk);
|
6141
|
+
# use this fixup to set the size too (sneaky)
|
6142
|
+
my $trailSize = defined($dat) ? length($dat) - $junk : $$self{LeicaTrailer}{Size};
|
6143
|
+
$$fixup{Start} -= 4; $$fixup{Shift} += 4;
|
6144
|
+
$fixup->SetMarkerPointers($outfile, 'LeicaTrailer', $trailSize) if defined $trailSize;
|
6145
|
+
$$fixup{Start} += 4; $$fixup{Shift} -= 4;
|
6146
|
+
if (defined $dat) {
|
6147
|
+
Write($outfile, $dat) or $err = 1; # write new Leica trailer
|
6148
|
+
$delPreview = 1; # delete existing Leica trailer
|
6149
|
+
}
|
6162
6150
|
}
|
6163
|
-
#
|
6164
|
-
|
6165
|
-
|
6166
|
-
|
6167
|
-
|
6168
|
-
|
6169
|
-
|
6170
|
-
|
6171
|
-
|
6172
|
-
|
6173
|
-
|
6174
|
-
|
6175
|
-
|
6176
|
-
|
6177
|
-
|
6178
|
-
|
6179
|
-
|
6180
|
-
|
6181
|
-
|
6182
|
-
|
6183
|
-
|
6151
|
+
# handle preview image last
|
6152
|
+
if ($$self{PREVIEW_INFO}) {
|
6153
|
+
# locate preview image and fix up preview offsets
|
6154
|
+
my $scanLen = $$self{Make} =~ /^SONY/i ? 65536 : 1024;
|
6155
|
+
if (length($buff) < $scanLen) { # make sure we have enough trailer to scan
|
6156
|
+
my $buf2;
|
6157
|
+
$buff .= $buf2 if $raf->Read($buf2, $scanLen - length($buff));
|
6158
|
+
}
|
6159
|
+
# get new preview image position, relative to EXIF base
|
6160
|
+
my $newPos = length($$outfile) - 10; # (subtract 10 for segment and EXIF headers)
|
6161
|
+
my $junkLen;
|
6162
|
+
# adjust position if image isn't at the start (eg. Olympus E-1/E-300)
|
6163
|
+
if ($buff =~ /(\xff\xd8\xff.|.\xd8\xff\xdb)(..)/sg) {
|
6164
|
+
my ($jpegHdr, $segLen) = ($1, $2);
|
6165
|
+
$junkLen = pos($buff) - 6;
|
6166
|
+
# Sony previewimage trailer has a 32 byte header
|
6167
|
+
if ($$self{Make} =~ /^SONY/i and $junkLen > 32) {
|
6168
|
+
# with some newer Sony models, the makernotes preview pointer
|
6169
|
+
# points to JPEG at end of EXIF inside MPImage preview (what a pain!)
|
6170
|
+
if ($jpegHdr eq "\xff\xd8\xff\xe1") { # is the first segment EXIF?
|
6171
|
+
$segLen = unpack('n', $segLen); # the EXIF segment length
|
6172
|
+
# Sony PreviewImage starts with last 2 bytes of EXIF segment
|
6173
|
+
# (and first byte is usually "\0", not "\xff", so don't check this)
|
6174
|
+
if (length($buff) > $junkLen + $segLen + 6 and
|
6175
|
+
substr($buff, $junkLen + $segLen + 3, 3) eq "\xd8\xff\xdb")
|
6176
|
+
{
|
6177
|
+
$junkLen += $segLen + 2;
|
6178
|
+
# (note: this will not copy the trailer after PreviewImage,
|
6179
|
+
# which is a 14kB block full of zeros for the A77)
|
6180
|
+
}
|
6184
6181
|
}
|
6182
|
+
$junkLen -= 32;
|
6185
6183
|
}
|
6186
|
-
$
|
6184
|
+
$newPos += $junkLen;
|
6185
|
+
}
|
6186
|
+
# fix up the preview offsets to point to the start of the new image
|
6187
|
+
$previewInfo = $$self{PREVIEW_INFO};
|
6188
|
+
delete $$self{PREVIEW_INFO};
|
6189
|
+
my $fixup = $$previewInfo{Fixup};
|
6190
|
+
$newPos += ($$previewInfo{BaseShift} || 0);
|
6191
|
+
# adjust to absolute file offset if necessary (Samsung STMN)
|
6192
|
+
$newPos += Tell($oldOutfile) + 10 if $$previewInfo{Absolute};
|
6193
|
+
if ($$previewInfo{Relative}) {
|
6194
|
+
# adjust for our base by looking at how far the pointer got shifted
|
6195
|
+
$newPos -= ($fixup->GetMarkerPointers($outfile, 'PreviewImage') || 0);
|
6196
|
+
} elsif ($$previewInfo{ChangeBase}) {
|
6197
|
+
# Leica S2 uses relative offsets for the preview only (leica sucks)
|
6198
|
+
my $makerOffset = $fixup->GetMarkerPointers($outfile, 'LeicaTrailer');
|
6199
|
+
$newPos -= $makerOffset if $makerOffset;
|
6200
|
+
}
|
6201
|
+
$fixup->SetMarkerPointers($outfile, 'PreviewImage', $newPos);
|
6202
|
+
if ($$previewInfo{Data} ne 'LOAD_PREVIEW') {
|
6203
|
+
# write any junk that existed before the preview image
|
6204
|
+
$$previewInfo{Junk} = substr($buff,0,$junkLen) if $junkLen;
|
6187
6205
|
}
|
6188
|
-
$newPos += $junkLen;
|
6189
|
-
}
|
6190
|
-
# fix up the preview offsets to point to the start of the new image
|
6191
|
-
my $previewInfo = $$self{PREVIEW_INFO};
|
6192
|
-
delete $$self{PREVIEW_INFO};
|
6193
|
-
my $fixup = $$previewInfo{Fixup};
|
6194
|
-
$newPos += ($$previewInfo{BaseShift} || 0);
|
6195
|
-
# adjust to absolute file offset if necessary (Samsung STMN)
|
6196
|
-
$newPos += Tell($oldOutfile) + 10 if $$previewInfo{Absolute};
|
6197
|
-
if ($$previewInfo{Relative}) {
|
6198
|
-
# adjust for our base by looking at how far the pointer got shifted
|
6199
|
-
$newPos -= ($fixup->GetMarkerPointers($outfile, 'PreviewImage') || 0);
|
6200
|
-
} elsif ($$previewInfo{ChangeBase}) {
|
6201
|
-
# Leica S2 uses relative offsets for the preview only (leica sucks)
|
6202
|
-
my $makerOffset = $fixup->GetMarkerPointers($outfile, 'LeicaTrailer');
|
6203
|
-
$newPos -= $makerOffset if $makerOffset;
|
6204
6206
|
}
|
6205
|
-
$fixup->SetMarkerPointers($outfile, 'PreviewImage', $newPos);
|
6206
6207
|
# clean up and write the buffered data
|
6207
6208
|
$outfile = $oldOutfile;
|
6208
6209
|
undef $oldOutfile;
|
6209
6210
|
Write($outfile, $writeBuffer) or $err = 1;
|
6210
6211
|
undef $writeBuffer;
|
6211
6212
|
# write preview image
|
6212
|
-
if ($$previewInfo{Data} ne 'LOAD_PREVIEW') {
|
6213
|
+
if ($previewInfo and $$previewInfo{Data} ne 'LOAD_PREVIEW') {
|
6213
6214
|
# write any junk that existed before the preview image
|
6214
|
-
Write($outfile,
|
6215
|
+
Write($outfile, $$previewInfo{Junk}) or $err = 1 if defined $$previewInfo{Junk};
|
6215
6216
|
# write the saved preview image
|
6216
6217
|
Write($outfile, $$previewInfo{Data}) or $err = 1;
|
6217
6218
|
delete $$previewInfo{Data};
|
@@ -6224,7 +6225,7 @@ sub WriteJPEG($$)
|
|
6224
6225
|
my $extra;
|
6225
6226
|
if ($trailInfo) {
|
6226
6227
|
# copy everything up to start of first processed trailer
|
6227
|
-
$extra = $$trailInfo{DataPos} - $endPos;
|
6228
|
+
$extra = defined $$trailInfo{DataPos} ? ($$trailInfo{DataPos} - $endPos) : 0;
|
6228
6229
|
} else {
|
6229
6230
|
# copy everything up to end of file
|
6230
6231
|
$raf->Seek(0, 2) or $err = 1;
|
@@ -6393,9 +6394,9 @@ sub WriteJPEG($$)
|
|
6393
6394
|
$oldOutfile = $outfile;
|
6394
6395
|
$outfile = \$writeBuffer;
|
6395
6396
|
# must account for segment, EXIF and TIFF headers
|
6396
|
-
|
6397
|
-
|
6398
|
-
|
6397
|
+
foreach (qw(PREVIEW_INFO LeicaTrailer HiddenData)) {
|
6398
|
+
$$self{$_}{Fixup}{Start} += 18 if $$self{$_};
|
6399
|
+
}
|
6399
6400
|
}
|
6400
6401
|
# write as multi-segment
|
6401
6402
|
my $n = WriteMultiSegment($outfile, $marker, $exifAPP1hdr, $segDataPt, 'EXIF');
|
@@ -6922,7 +6923,7 @@ sub CheckBinaryData($$$)
|
|
6922
6923
|
$format = $1;
|
6923
6924
|
$count = $2;
|
6924
6925
|
# can't evaluate $count now because we don't know $size yet
|
6925
|
-
|
6926
|
+
$count = -1 if $count =~ /\$size/; # (-1 = any count allowed)
|
6926
6927
|
}
|
6927
6928
|
return CheckValue($valPtr, $format, $count);
|
6928
6929
|
}
|
@@ -7248,6 +7249,8 @@ sub WriteBinaryData($$$)
|
|
7248
7249
|
$self->VerboseValue("- $dirName:$$tagInfo{Name}", $val);
|
7249
7250
|
$self->VerboseValue("+ $dirName:$$tagInfo{Name}", $newVal);
|
7250
7251
|
++$$self{CHANGED};
|
7252
|
+
} else {
|
7253
|
+
$self->Warn("Error packing $$tagInfo{Name} value");
|
7251
7254
|
}
|
7252
7255
|
}
|
7253
7256
|
# add necessary fixups for any offsets
|
@@ -86,7 +86,7 @@ sub InflateStruct($$;$)
|
|
86
86
|
my %struct;
|
87
87
|
for (;;) {
|
88
88
|
last unless $sfmt ? $$obj =~ s/^\s*"(.*?)"\s*://s :
|
89
|
-
$$obj =~ s/^\s*([-\w
|
89
|
+
$$obj =~ s/^\s*([-\w:.]+#?)\s*=//s;
|
90
90
|
my $tag = $1;
|
91
91
|
my ($v, $w) = InflateStruct($et, $obj, '}');
|
92
92
|
$warn = $w if $w and not $warn;
|
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 $advFmtSelf $configFile @configFiles $noConfig);
|
31
31
|
|
32
|
-
$VERSION = '13.
|
32
|
+
$VERSION = '13.33';
|
33
33
|
$RELEASE = '';
|
34
34
|
@ISA = qw(Exporter);
|
35
35
|
%EXPORT_TAGS = (
|
@@ -42,7 +42,7 @@ $RELEASE = '';
|
|
42
42
|
# exports not part of the public API, but used by ExifTool modules:
|
43
43
|
DataAccess => [qw(
|
44
44
|
ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u
|
45
|
-
Get16s Get32u Get32s Get64u GetFloat GetDouble GetFixed32s Write
|
45
|
+
Get16s Get32u Get32s Get64u Get64s GetFloat GetDouble GetFixed32s Write
|
46
46
|
WriteValue Tell Set8u Set8s Set16u Set32u Set64u Set64s
|
47
47
|
)],
|
48
48
|
Utils => [qw(GetTagTable TagTableKeys GetTagInfoList AddTagToTable HexDump)],
|
@@ -152,8 +152,8 @@ sub ReadValue($$$;$$$);
|
|
152
152
|
APE::OldHeader Audible MPC MPEG::Audio MPEG::Video MPEG::Xing M2TS QuickTime
|
153
153
|
QuickTime::ImageFile QuickTime::Stream QuickTime::Tags360Fly Matroska
|
154
154
|
Matroska::StdTag MOI MXF DV Flash Flash::FLV Real::Media Real::Audio
|
155
|
-
Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS XISF MIE JSON HTML
|
156
|
-
Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion EXE::PEString
|
155
|
+
Real::Metafile Red RIFF AIFF ASF TNEF WTV DICOM FITS XISF MIE JSON HTML
|
156
|
+
XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion EXE::PEString
|
157
157
|
EXE::DebugRSDS EXE::DebugNB10 EXE::Misc EXE::MachO EXE::PEF EXE::ELF EXE::AR
|
158
158
|
EXE::CHM LNK PCAP Font VCard Text VCard::VCalendar VCard::VNote RSRC Rawzor
|
159
159
|
ZIP ZIP::GZIP ZIP::RAR ZIP::RAR5 RTF OOXML iWork ISO FLIR::AFF FLIR::FPF
|
@@ -200,7 +200,7 @@ $defaultLang = 'en'; # default language
|
|
200
200
|
RAR 7Z BZ2 CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font
|
201
201
|
JUMBF RSRC M2TS MacOS PHP PCX DCX DWF DWG DXF WTV Torrent VCard
|
202
202
|
LRI R3D AA PDB PFM2 MRC LIF JXL MOI ISO ALIAS PCAP JSON MP3
|
203
|
-
DICOM PCD NKA ICO TXT AAC);
|
203
|
+
TNEF DICOM PCD NKA ICO TXT AAC);
|
204
204
|
|
205
205
|
# file types that we can write (edit)
|
206
206
|
my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS
|
@@ -536,6 +536,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
536
536
|
THMX => [['ZIP','FPX'], 'Office Open XML Theme'],
|
537
537
|
TIF => 'TIFF',
|
538
538
|
TIFF => ['TIFF', 'Tagged Image File Format'],
|
539
|
+
TNEF => ['TNEF', 'Transport Neural Encapsulation Format'], # (actual extension is .DAT)
|
539
540
|
TORRENT => ['Torrent', 'BitTorrent description file'],
|
540
541
|
TS => 'M2TS',
|
541
542
|
TTC => ['Font', 'True Type Font Collection'],
|
@@ -802,6 +803,7 @@ my %fileDescription = (
|
|
802
803
|
TAR => 'application/x-tar',
|
803
804
|
THMX => 'application/vnd.ms-officetheme',
|
804
805
|
TIFF => 'image/tiff',
|
806
|
+
TNEF => 'application/vnd.ms-tnef',
|
805
807
|
Torrent => 'application/x-bittorrent',
|
806
808
|
TTC => 'application/font-ttf',
|
807
809
|
TTF => 'application/font-ttf',
|
@@ -1012,6 +1014,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
1012
1014
|
RWZ => 'rawzor',
|
1013
1015
|
SWF => '[FC]WS[^\0]',
|
1014
1016
|
TAR => '.{257}ustar( )?\0', # (this doesn't catch old-style tar files)
|
1017
|
+
TNEF => '\x78\x9f\x3e\x22..\x01\x06\x90\x08\0',
|
1015
1018
|
TXT => '(\xff\xfe|(\0\0)?\xfe\xff|(\xef\xbb\xbf)?[\x07-\x0d\x20-\x7e\x80-\xfe]*$)',
|
1016
1019
|
TIFF => '(II|MM)', # don't test magic number (some raw formats are different)
|
1017
1020
|
VCard=> '(?i)BEGIN:(VCARD|VCALENDAR|VNOTE)\r\n',
|
@@ -4292,6 +4295,7 @@ sub Init($)
|
|
4292
4295
|
$$self{LOW_PRIORITY_DIR} = { PreviewIFD => 1 }; # names of priority 0 directories
|
4293
4296
|
$$self{TIFF_TYPE} = ''; # type of TIFF data (APP1, TIFF, NEF, etc...)
|
4294
4297
|
$$self{FMT_EXPR} = undef; # current advanced formatting expression
|
4298
|
+
$$self{HAS_DOC} = { }; # lookup for all document numbers in this file
|
4295
4299
|
$$self{Make} = ''; # camera make
|
4296
4300
|
$$self{Model} = ''; # camera model
|
4297
4301
|
$$self{CameraType} = ''; # Olympus camera type
|
@@ -6582,6 +6586,8 @@ sub ConvertDateTime($$)
|
|
6582
6586
|
}
|
6583
6587
|
$a[5] -= 1900; # strftime year starts from 1900
|
6584
6588
|
$date = POSIX::strftime($fmt, @a); # generate the formatted date/time
|
6589
|
+
# apparently strftime can set the UTF-8 flag (argh!), so reset this if necessary
|
6590
|
+
$self->Sanitize(\$date) if $fmt =~ /[\x80-\xff]/;
|
6585
6591
|
} elsif ($$self{OPTIONS}{StrictDate}) {
|
6586
6592
|
undef $date;
|
6587
6593
|
}
|
@@ -9480,6 +9486,7 @@ sub FoundTag($$$;@)
|
|
9480
9486
|
$$self{TAG_EXTRA}{$tag}{G1} = $grps[1] if $grps[1];
|
9481
9487
|
if ($$self{DOC_NUM}) {
|
9482
9488
|
$$self{TAG_EXTRA}{$tag}{G3} = $$self{DOC_NUM};
|
9489
|
+
$$self{HAS_DOC}{$$self{DOC_NUM}} = 1;
|
9483
9490
|
if ($$self{DOC_NUM} =~ /^(\d+)/) {
|
9484
9491
|
# keep track of maximum 1st-level sub-document number
|
9485
9492
|
$$self{DOC_COUNT} = $1 unless $$self{DOC_COUNT} >= $1;
|
@@ -9719,8 +9726,10 @@ sub ExtractBinary($$$;$)
|
|
9719
9726
|
$isPreview = 1;
|
9720
9727
|
}
|
9721
9728
|
my $lcTag = lc $tag;
|
9722
|
-
|
9723
|
-
|
9729
|
+
my $options = $$self{OPTIONS};
|
9730
|
+
if ((not $$options{Binary} or $$self{EXCL_TAG_LOOKUP}{$lcTag}) and
|
9731
|
+
not $$options{Verbose} and not $$options{Validate} and
|
9732
|
+
not $$self{REQ_TAG_LOOKUP}{$lcTag})
|
9724
9733
|
{
|
9725
9734
|
return "Binary data $length bytes";
|
9726
9735
|
}
|
data/bin/lib/Image/ExifTool.pod
CHANGED
@@ -65,50 +65,51 @@ supported by ExifTool (r = read, w = write, c = create):
|
|
65
65
|
|
66
66
|
File Types
|
67
67
|
------------+-------------+-------------+-------------+------------
|
68
|
-
360 r/w |
|
69
|
-
3FR r |
|
70
|
-
3G2 r/w |
|
71
|
-
3GP r/w |
|
72
|
-
7Z r |
|
73
|
-
A r |
|
74
|
-
AA r |
|
75
|
-
AAC r |
|
76
|
-
AAE r |
|
77
|
-
AAX r/w |
|
78
|
-
ACR r |
|
79
|
-
AFM r |
|
80
|
-
AI r/w |
|
81
|
-
AIFF r |
|
82
|
-
APE r |
|
83
|
-
ARQ r/w |
|
84
|
-
ARW r/w |
|
85
|
-
ASF r |
|
86
|
-
AVI r |
|
87
|
-
AVIF r/w |
|
88
|
-
AZW r |
|
89
|
-
BMP r |
|
90
|
-
BPG r |
|
91
|
-
BTF r |
|
92
|
-
C2PA r |
|
93
|
-
CHM r |
|
94
|
-
COS r |
|
95
|
-
CR2 r/w |
|
96
|
-
CR3 r/w |
|
97
|
-
CRM r/w |
|
98
|
-
CRW r/w |
|
99
|
-
CS1 r/w |
|
100
|
-
CSV r |
|
101
|
-
CUR r |
|
102
|
-
CZI r |
|
103
|
-
DCM r |
|
104
|
-
DCP r/w |
|
105
|
-
DCR r |
|
106
|
-
DFONT r |
|
107
|
-
DIVX r |
|
108
|
-
DJVU r |
|
109
|
-
DLL r |
|
110
|
-
DNG r/w |
|
111
|
-
DOC r |
|
68
|
+
360 r/w | DPX r | JNG r/w | ODP r | RSRC r
|
69
|
+
3FR r | DR4 r/w/c | JP2 r/w | ODS r | RTF r
|
70
|
+
3G2 r/w | DSS r | JPEG r/w | ODT r | RW2 r/w
|
71
|
+
3GP r/w | DV r | JSON r | OFR r | RWL r/w
|
72
|
+
7Z r | DVB r/w | JXL r/w | OGG r | RWZ r
|
73
|
+
A r | DVR-MS r | K25 r | OGV r | RM r
|
74
|
+
AA r | DYLIB r | KDC r | ONP r | SEQ r
|
75
|
+
AAC r | EIP r | KEY r | OPUS r | SKETCH r
|
76
|
+
AAE r | EPS r/w | LA r | ORF r/w | SO r
|
77
|
+
AAX r/w | EPUB r | LFP r | ORI r/w | SR2 r/w
|
78
|
+
ACR r | ERF r/w | LIF r | OTF r | SRF r
|
79
|
+
AFM r | EXE r | LNK r | PAC r | SRW r/w
|
80
|
+
AI r/w | EXIF r/w/c | LRV r/w | PAGES r | SVG r
|
81
|
+
AIFF r | EXR r | M2TS r | PBM r/w | SWF r
|
82
|
+
APE r | EXV r/w/c | M4A/V r/w | PCAP r | THM r/w
|
83
|
+
ARQ r/w | F4A/V r/w | MACOS r | PCAPNG r | TIFF r/w
|
84
|
+
ARW r/w | FFF r/w | MAX r | PCD r | TNEF r
|
85
|
+
ASF r | FITS r | MEF r/w | PCX r | TORRENT r
|
86
|
+
AVI r | FLA r | MIE r/w/c | PDB r | TTC r
|
87
|
+
AVIF r/w | FLAC r | MIFF r | PDF r/w | TTF r
|
88
|
+
AZW r | FLIF r/w | MKA r | PEF r/w | TXT r
|
89
|
+
BMP r | FLV r | MKS r | PFA r | VCF r
|
90
|
+
BPG r | FPF r | MKV r | PFB r | VNT r
|
91
|
+
BTF r | FPX r | MNG r/w | PFM r | VRD r/w/c
|
92
|
+
C2PA r | GIF r/w | MOBI r | PGF r | VSD r
|
93
|
+
CHM r | GLV r/w | MODD r | PGM r/w | WAV r
|
94
|
+
COS r | GPR r/w | MOI r | PLIST r | WDP r/w
|
95
|
+
CR2 r/w | GZ r | MOS r/w | PICT r | WEBP r/w
|
96
|
+
CR3 r/w | HDP r/w | MOV r/w | PMP r | WEBM r
|
97
|
+
CRM r/w | HDR r | MP3 r | PNG r/w | WMA r
|
98
|
+
CRW r/w | HEIC r/w | MP4 r/w | PPM r/w | WMV r
|
99
|
+
CS1 r/w | HEIF r/w | MPC r | PPT r | WPG r
|
100
|
+
CSV r | HTML r | MPG r | PPTX r | WTV r
|
101
|
+
CUR r | ICC r/w/c | MPO r/w | PS r/w | WV r
|
102
|
+
CZI r | ICO r | MQV r/w | PSB r/w | X3F r/w
|
103
|
+
DCM r | ICS r | MRC r | PSD r/w | XCF r
|
104
|
+
DCP r/w | IDML r | MRW r/w | PSP r | XISF r
|
105
|
+
DCR r | IIQ r/w | MXF r | QTIF r/w | XLS r
|
106
|
+
DFONT r | IND r/w | NEF r/w | R3D r | XLSX r
|
107
|
+
DIVX r | INSP r/w | NKA r | RA r | XMP r/w/c
|
108
|
+
DJVU r | INSV r | NKSC r/w | RAF r/w | ZIP r
|
109
|
+
DLL r | INX r | NRW r/w | RAM r |
|
110
|
+
DNG r/w | ISO r | NUMBERS r | RAR r |
|
111
|
+
DOC r | ITC r | NXD r | RAW r/w |
|
112
|
+
DOCX r | J2C r | O r | RIFF r |
|
112
113
|
|
113
114
|
Meta Information
|
114
115
|
----------------------+----------------------+---------------------
|