exiftool-vendored.exe 13.17.0 → 13.26.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/README.txt +14 -14
- package/bin/exiftool.exe +0 -0
- package/bin/exiftool_files/exiftool.pl +117 -46
- package/bin/exiftool_files/lib/Image/ExifTool/Apple.pm +12 -2
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +3 -2
- package/bin/exiftool_files/lib/Image/ExifTool/CanonRaw.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/DJI.pm +190 -29
- package/bin/exiftool_files/lib/Image/ExifTool/DarwinCore.pm +22 -11
- package/bin/exiftool_files/lib/Image/ExifTool/EXE.pm +2 -9
- package/bin/exiftool_files/lib/Image/ExifTool/GM.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/exiftool_files/lib/Image/ExifTool/GoPro.pm +86 -48
- package/bin/exiftool_files/lib/Image/ExifTool/ICC_Profile.pm +1 -0
- package/bin/exiftool_files/lib/Image/ExifTool/ICO.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/JPEG.pm +5 -1
- package/bin/exiftool_files/lib/Image/ExifTool/JSON.pm +5 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Kodak.pm +3 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +944 -1237
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +3 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PCAP.pm +462 -0
- package/bin/exiftool_files/lib/Image/ExifTool/PDF.pm +10 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PLIST.pm +92 -29
- package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +7 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Photoshop.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Plot.pm +713 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Protobuf.pm +24 -11
- package/bin/exiftool_files/lib/Image/ExifTool/Qualcomm.pm +78 -1
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +371 -324
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +75 -27
- package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +15 -6
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +33 -14
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +5067 -4967
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +457 -336
- package/bin/exiftool_files/lib/Image/ExifTool/Trailer.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Validate.pm +4 -4
- package/bin/exiftool_files/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WriteExif.pl +9 -4
- package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +58 -5
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +14 -13
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +55 -20
- package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +7 -1
- package/bin/exiftool_files/lib/Image/ExifTool.pm +63 -29
- package/bin/exiftool_files/lib/Image/ExifTool.pod +84 -86
- package/bin/exiftool_files/windows_exiftool.txt +96 -72
- package/package.json +4 -4
|
@@ -12,7 +12,7 @@ use strict;
|
|
|
12
12
|
use vars qw($VERSION);
|
|
13
13
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
14
14
|
|
|
15
|
-
$VERSION = '1.
|
|
15
|
+
$VERSION = '1.01';
|
|
16
16
|
|
|
17
17
|
%Image::ExifTool::Trailer::Vivo = (
|
|
18
18
|
GROUPS => { 0 => 'Trailer', 1 => 'Vivo', 2 => 'Image' },
|
|
@@ -214,7 +214,7 @@ sub ProcessGoogle($$)
|
|
|
214
214
|
|
|
215
215
|
delete $$et{ProcessGoogleTrailer}; # reset flag to process the Google trailer
|
|
216
216
|
|
|
217
|
-
return -1 if $$dirInfo{OutFile};
|
|
217
|
+
return -1 if $$dirInfo{OutFile}; # let caller handle the writing
|
|
218
218
|
|
|
219
219
|
# sometimes DirectoryItemLength is missing the Primary entry
|
|
220
220
|
$len = [ $len ] unless ref $len eq 'ARRAY';
|
|
@@ -271,7 +271,7 @@ sub ProcessGoogle($$)
|
|
|
271
271
|
DataPos => $start + $pos,
|
|
272
272
|
DirLen => $$len[$i],
|
|
273
273
|
});
|
|
274
|
-
$et->HandleTag($tagTable, $$tag[$i], \$buff,
|
|
274
|
+
$et->HandleTag($tagTable, $$tag[$i], \$buff, DataPos => $start + $pos, DataPt => \$buff);
|
|
275
275
|
# (haven't seen non-zero padding, but I assume this is how it works
|
|
276
276
|
$pos += $$len[$i] + (($pad and $$pad[$i]) ? $$pad[$i] : 0);
|
|
277
277
|
}
|
|
@@ -188,10 +188,10 @@ my %validValue = (
|
|
|
188
188
|
0x115 => undef, # SamplesPerPixel
|
|
189
189
|
0x116 => undef, # RowsPerStrip
|
|
190
190
|
0x117 => undef, # StripByteCounts
|
|
191
|
-
0x11a => 'defined $val', # XResolution
|
|
192
|
-
0x11b => 'defined $val', # YResolution
|
|
191
|
+
# (optional as of 3.0) 0x11a => 'defined $val', # XResolution
|
|
192
|
+
# (optional as of 3.0) 0x11b => 'defined $val', # YResolution
|
|
193
193
|
0x11c => undef, # PlanarConfiguration
|
|
194
|
-
0x128 => '$val =~ /^[123]$/', # ResolutionUnit
|
|
194
|
+
# (optional as of 3.0) 0x128 => '$val =~ /^[123]$/', # ResolutionUnit
|
|
195
195
|
0x201 => undef, # JPEGInterchangeFormat
|
|
196
196
|
0x202 => undef, # JPEGInterchangeFormatLength
|
|
197
197
|
0x212 => undef, # YCbCrSubSampling
|
|
@@ -218,7 +218,7 @@ my %validValue = (
|
|
|
218
218
|
ExifIFD => {
|
|
219
219
|
0x9000 => 'defined $val and $val =~ /^\d{4}$/', # ExifVersion
|
|
220
220
|
0x9101 => 'defined $val', # ComponentsConfiguration
|
|
221
|
-
0xa000 => 'defined $val', # FlashpixVersion
|
|
221
|
+
# (optional as of 3.0) 0xa000 => 'defined $val', # FlashpixVersion
|
|
222
222
|
0xa001 => '$val == 1 or $val == 0xffff', # ColorSpace
|
|
223
223
|
0xa002 => 'defined $val', # PixelXDimension
|
|
224
224
|
0xa003 => 'defined $val', # PixelYDimension
|
|
@@ -566,7 +566,7 @@ sub WriteCRW($$)
|
|
|
566
566
|
my $trailPt;
|
|
567
567
|
while ($success) {
|
|
568
568
|
# check to see if trailer(s) exist(s)
|
|
569
|
-
my $trailInfo =
|
|
569
|
+
my $trailInfo = $et->IdentifyTrailer($raf) or last;
|
|
570
570
|
# rewrite the trailer(s)
|
|
571
571
|
$buff = '';
|
|
572
572
|
$$trailInfo{OutFile} = \$buff;
|
|
@@ -25,9 +25,9 @@ my %crossDelete = (
|
|
|
25
25
|
# mandatory tag default values
|
|
26
26
|
my %mandatory = (
|
|
27
27
|
IFD0 => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
# (optional as of 3.0) 0x011a => 72, # XResolution
|
|
29
|
+
# (optional as of 3.0) 0x011b => 72, # YResolution
|
|
30
|
+
# (optional as of 3.0) 0x0128 => 2, # ResolutionUnit (inches)
|
|
31
31
|
0x0213 => 1, # YCbCrPositioning (centered)
|
|
32
32
|
# 0x8769 => ????, # ExifOffset
|
|
33
33
|
},
|
|
@@ -40,7 +40,7 @@ my %mandatory = (
|
|
|
40
40
|
ExifIFD => {
|
|
41
41
|
0x9000 => '0232', # ExifVersion
|
|
42
42
|
0x9101 => "1 2 3 0",# ComponentsConfiguration
|
|
43
|
-
|
|
43
|
+
# (optional as of 3.0) 0xa000 => '0100', # FlashpixVersion
|
|
44
44
|
0xa001 => 0xffff, # ColorSpace (uncalibrated)
|
|
45
45
|
# 0xa002 => ????, # ExifImageWidth
|
|
46
46
|
# 0xa003 => ????, # ExifImageHeight
|
|
@@ -2269,6 +2269,11 @@ NoOverwrite: next if $isNew > 0;
|
|
|
2269
2269
|
# build list of offsets to process
|
|
2270
2270
|
my @offsetList;
|
|
2271
2271
|
if ($ifd >= 0) {
|
|
2272
|
+
$dirName = $$dirInfo{DirName} || 'unknown';
|
|
2273
|
+
if ($ifd) {
|
|
2274
|
+
$dirName =~ s/\d+$//;
|
|
2275
|
+
$dirName .= $ifd;
|
|
2276
|
+
}
|
|
2272
2277
|
my $offsetInfo = $offsetInfo[$ifd] or next;
|
|
2273
2278
|
if ($$offsetInfo{0x111} and $$offsetInfo{0x144}) {
|
|
2274
2279
|
# SubIFD may contain double-referenced data as both strips and tiles
|
|
@@ -891,7 +891,7 @@ sub WriteQuickTime($$$)
|
|
|
891
891
|
$et or return 1; # allow dummy access to autoload this package
|
|
892
892
|
my ($mdat, @mdat, @mdatEdit, $edit, $track, $outBuff, $co, $term, $delCount);
|
|
893
893
|
my (%langTags, $canCreate, $delGrp, %boxPos, %didDir, $writeLast, $err, $atomCount);
|
|
894
|
-
my ($tag, $lastTag, $lastPos, $errStr, $trailer, $buf2, $keysGrp, $keysPath);
|
|
894
|
+
my ($tag, $lastTag, $lastPos, $errStr, $trailer, $buf2, $keysGrp, $keysPath, $itemIndex);
|
|
895
895
|
my $outfile = $$dirInfo{OutFile} || return 0;
|
|
896
896
|
my $raf = $$dirInfo{RAF}; # (will be null for lower-level atoms)
|
|
897
897
|
my $dataPt = $$dirInfo{DataPt}; # (will be null for top-level atoms)
|
|
@@ -982,8 +982,25 @@ sub WriteQuickTime($$$)
|
|
|
982
982
|
$atomCount = $$tagTablePtr{VARS}{ATOM_COUNT} if $$tagTablePtr{VARS};
|
|
983
983
|
|
|
984
984
|
$tag = $lastTag = '';
|
|
985
|
-
|
|
985
|
+
$itemIndex = 0 if $dirName eq 'ItemPropertyContainer';
|
|
986
|
+
|
|
987
|
+
# read ahead to parse item property associations if this is 'iprp' ItemProperties
|
|
988
|
+
# (necessary to determine which properties belong to primary item in HEIC file)
|
|
989
|
+
if ($dirName eq 'ItemProperties') {
|
|
990
|
+
my $pos = $raf->Tell();
|
|
991
|
+
for (;;) {
|
|
992
|
+
$raf->Read($buf2, 8) == 8 or last;
|
|
993
|
+
my $size = Get32u(\$buf2, 0) - 8; # (atom size without 8-byte header)
|
|
994
|
+
$tag = substr($buf2, 4, 4);
|
|
995
|
+
last if $size < 0;
|
|
996
|
+
$tag eq 'ipma' or $raf->Seek($size, 1), next;
|
|
997
|
+
ParseItemPropAssoc($buf2,$et) if $raf->Read($buf2,$size) == $size;
|
|
998
|
+
last;
|
|
999
|
+
}
|
|
1000
|
+
$raf->Seek($pos);
|
|
1001
|
+
}
|
|
986
1002
|
for (;;) { # loop through all atoms at this level
|
|
1003
|
+
++$itemIndex if defined $itemIndex;
|
|
987
1004
|
$lastPos = $raf->Tell();
|
|
988
1005
|
# stop processing if we reached a known trailer
|
|
989
1006
|
if ($trailer and $lastPos >= $$trailer[1]) {
|
|
@@ -1186,6 +1203,36 @@ sub WriteQuickTime($$$)
|
|
|
1186
1203
|
}
|
|
1187
1204
|
undef $tagInfo if $tagInfo and $$tagInfo{AddedUnknown};
|
|
1188
1205
|
|
|
1206
|
+
# don't write this tag unless associated with the primary item
|
|
1207
|
+
# (Note: This relies on iinf and dimg coming before iprp)
|
|
1208
|
+
if (defined $itemIndex and $$et{ItemInfo}) {
|
|
1209
|
+
my $items = $$et{ItemInfo};
|
|
1210
|
+
my ($id, $prop, $isPrimary);
|
|
1211
|
+
my $primary = $$et{PrimaryItem};
|
|
1212
|
+
unless (defined $primary) {
|
|
1213
|
+
($primary) = sort { $a <=> $b } keys %{$$et{ItemInfo}} if $$et{ItemInfo};
|
|
1214
|
+
$primary = 0 unless defined $primary;
|
|
1215
|
+
}
|
|
1216
|
+
my $pitem = $$items{$primary} || { };
|
|
1217
|
+
$$pitem{RefersTo} or $$pitem{RefersTo} = { };
|
|
1218
|
+
ItemID2: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
1219
|
+
next unless $$items{$id}{Association};
|
|
1220
|
+
my $item = $$items{$id};
|
|
1221
|
+
foreach $prop (@{$$item{Association}}) {
|
|
1222
|
+
next unless $prop == $itemIndex;
|
|
1223
|
+
my $dont = $dontInherit{$tag} || 0;
|
|
1224
|
+
last unless $id == $primary or (not $dont and
|
|
1225
|
+
($$item{RefersTo} and $$item{RefersTo}{$primary})) or
|
|
1226
|
+
# special case to assume this property belongs to the primary
|
|
1227
|
+
# image if it belongs to an item referred to by the primary
|
|
1228
|
+
($dont != 1 and $$pitem{RefersTo}{$id});
|
|
1229
|
+
$isPrimary = 1;
|
|
1230
|
+
last ItemID2;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
undef $tagInfo unless $isPrimary;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1189
1236
|
if ($tagInfo and (not defined $$tagInfo{Writable} or $$tagInfo{Writable})) {
|
|
1190
1237
|
my $subdir = $$tagInfo{SubDirectory};
|
|
1191
1238
|
my ($newData, @chunkOffset);
|
|
@@ -1225,6 +1272,7 @@ sub WriteQuickTime($$$)
|
|
|
1225
1272
|
OutFile => $outfile,
|
|
1226
1273
|
NoRefTest=> 1, # don't check directory references
|
|
1227
1274
|
WriteGroup => $$tagInfo{WriteGroup},
|
|
1275
|
+
Permanent => $$tagInfo{Permanent},
|
|
1228
1276
|
# initialize array to hold details about chunk offset table
|
|
1229
1277
|
# (each entry has 3-5 items: 0=atom type, 1=table offset, 2=table size,
|
|
1230
1278
|
# 3=optional base offset, 4=optional item ID)
|
|
@@ -1468,7 +1516,10 @@ sub WriteQuickTime($$$)
|
|
|
1468
1516
|
++$$et{CHANGED};
|
|
1469
1517
|
my $grp = $et->GetGroup($langInfo, 1);
|
|
1470
1518
|
$et->VerboseValue("- $grp:$$langInfo{Name}", $val);
|
|
1471
|
-
|
|
1519
|
+
unless (defined $newData and not $$didTag{$nvHash}) {
|
|
1520
|
+
# must not delete items from iprp because it will mess up the ordering
|
|
1521
|
+
next unless defined $itemIndex;
|
|
1522
|
+
}
|
|
1472
1523
|
$et->VerboseValue("+ $grp:$$langInfo{Name}", $newData);
|
|
1473
1524
|
# add back necessary header and encode as necessary
|
|
1474
1525
|
if (defined $lang) {
|
|
@@ -1497,7 +1548,7 @@ sub WriteQuickTime($$$)
|
|
|
1497
1548
|
$newData = $et->Encode($newData, 'UTF8');
|
|
1498
1549
|
} elsif ($format and not $$tagInfo{Binary}) {
|
|
1499
1550
|
# format new value for writing
|
|
1500
|
-
$newData = WriteValue($newData, $format);
|
|
1551
|
+
$newData = WriteValue($newData, $format, $$tagInfo{Count});
|
|
1501
1552
|
}
|
|
1502
1553
|
}
|
|
1503
1554
|
$$didTag{$nvHash} = 1; # set flag so we don't add this tag again
|
|
@@ -1564,7 +1615,9 @@ sub WriteQuickTime($$$)
|
|
|
1564
1615
|
}
|
|
1565
1616
|
if ($msg) {
|
|
1566
1617
|
# (allow empty sample description for non-audio/video handler types, eg. 'url ', 'meta')
|
|
1567
|
-
|
|
1618
|
+
# (also, incorrectly written 'mett' SampleEntry by Google phones,
|
|
1619
|
+
# see https://exiftool.org/forum/index.php?msg=91158)
|
|
1620
|
+
if ($avType{$$et{MediaType}}) {
|
|
1568
1621
|
my $grp = $$et{CUR_WRITE_GROUP} || $parent;
|
|
1569
1622
|
$et->Error("$msg for $grp");
|
|
1570
1623
|
return $rtnErr;
|
|
@@ -1296,15 +1296,15 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1296
1296
|
# ! option to decide how it is handled here. !
|
|
1297
1297
|
# +------------------------------------------+
|
|
1298
1298
|
foreach (qw(ByteUnit Charset CharsetEXIF CharsetFileName CharsetID3 CharsetIPTC
|
|
1299
|
-
CharsetPhotoshop Composite DateFormat Debug EncodeHangs Escape
|
|
1300
|
-
ExtractEmbedded FastScan Filter FixBase Geolocation
|
|
1301
|
-
GeolocFeature GeolocMinPop GeolocMaxDist
|
|
1302
|
-
HexTagIDs IgnoreGroups IgnoreMinorErrors
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
TimeZone Unknown UserParam
|
|
1307
|
-
XAttrTags XMPAutoConv))
|
|
1299
|
+
CharsetPhotoshop Composite DateFormat Debug EncodeHangs Escape
|
|
1300
|
+
ExtendedXMP ExtractEmbedded FastScan Filter FixBase Geolocation
|
|
1301
|
+
GeolocAltNames GeolocFeature GeolocMinPop GeolocMaxDist
|
|
1302
|
+
GlobalTimeShift GPSQuadrant HexTagIDs IgnoreGroups IgnoreMinorErrors
|
|
1303
|
+
IgnoreTags ImageHashType KeepUTCTime Lang LargeFileSupport
|
|
1304
|
+
LigoGPSScale ListItem ListSep MDItemTags MissingTagValue NoPDFList
|
|
1305
|
+
NoWarning Password PrintConv QuickTimeUTC RequestTags SaveFormat
|
|
1306
|
+
SavePath ScanForXMP StructFormat SystemTags TimeZone Unknown UserParam
|
|
1307
|
+
Validate WindowsLongPath WindowsWideFile XAttrTags XMPAutoConv))
|
|
1308
1308
|
{
|
|
1309
1309
|
$srcExifTool->Options($_ => $$options{$_});
|
|
1310
1310
|
}
|
|
@@ -4262,9 +4262,11 @@ sub WriteDirectory($$$;$)
|
|
|
4262
4262
|
if ($permanentDir{$grp0} and not ($$dirInfo{TagInfo} and $$dirInfo{TagInfo}{Deletable})) {
|
|
4263
4263
|
undef $delFlag;
|
|
4264
4264
|
}
|
|
4265
|
-
# (never delete an entire QuickTime group)
|
|
4266
4265
|
if ($delFlag) {
|
|
4267
|
-
if (
|
|
4266
|
+
if ($$dirInfo{Permanent}) {
|
|
4267
|
+
$self->Warn("Not deleting permanent $dirName directory");
|
|
4268
|
+
undef $grp1;
|
|
4269
|
+
} elsif (($grp0 =~ /^(MakerNotes)$/ or $grp1 =~ /^(IFD0|ExifIFD|MakerNotes)$/) and
|
|
4268
4270
|
$self->IsRawType() and
|
|
4269
4271
|
# allow non-permanent MakerNote directories to be deleted (ie. NikonCapture)
|
|
4270
4272
|
(not $$dirInfo{TagInfo} or not defined $$dirInfo{TagInfo}{Permanent} or
|
|
@@ -5044,7 +5046,6 @@ TryLib: for ($lib=$strptimeLib; ; $lib='') {
|
|
|
5044
5046
|
last;
|
|
5045
5047
|
}
|
|
5046
5048
|
if (not $lib) {
|
|
5047
|
-
last unless $$self{OPTIONS}{StrictDate};
|
|
5048
5049
|
warn $wrn || "Install POSIX::strptime or Time::Piece for inverse date/time conversions\n";
|
|
5049
5050
|
return undef;
|
|
5050
5051
|
} elsif ($lib eq 'POSIX::strptime') {
|
|
@@ -6027,7 +6028,7 @@ sub WriteJPEG($$)
|
|
|
6027
6028
|
Write($outfile, $hdr, $s, $segData) or $err = 1;
|
|
6028
6029
|
my ($buff, $endPos, $trailInfo);
|
|
6029
6030
|
my $delPreview = $$self{DEL_PREVIEW};
|
|
6030
|
-
$trailInfo = IdentifyTrailer($raf) unless $$delGroup{Trailer};
|
|
6031
|
+
$trailInfo = $self->IdentifyTrailer($raf) unless $$delGroup{Trailer};
|
|
6031
6032
|
my $nvTrail = $self->GetNewValueHash($Image::ExifTool::Extra{Trailer});
|
|
6032
6033
|
unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer} or $nvTrail or
|
|
6033
6034
|
$$self{HiddenData})
|
|
@@ -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.73';
|
|
54
54
|
@ISA = qw(Exporter);
|
|
55
55
|
@EXPORT_OK = qw(EscapeXML UnescapeXML);
|
|
56
56
|
|
|
@@ -165,7 +165,7 @@ my %xmpNS = (
|
|
|
165
165
|
#
|
|
166
166
|
plus => 'http://ns.useplus.org/ldf/xmp/1.0/',
|
|
167
167
|
# (prism recommendations from http://www.prismstandard.org/specifications/3.0/Image_Guide_3.0.htm)
|
|
168
|
-
prism => 'http://prismstandard.org/namespaces/basic/2.0/',
|
|
168
|
+
prism => 'http://prismstandard.org/namespaces/basic/2.0/', # (maybe left at 2.0 to avoid compatibility issues -- think hard before changing this)
|
|
169
169
|
prl => 'http://prismstandard.org/namespaces/prl/2.1/',
|
|
170
170
|
pur => 'http://prismstandard.org/namespaces/prismusagerights/2.1/',
|
|
171
171
|
pmi => 'http://prismstandard.org/namespaces/pmi/2.2/',
|
|
@@ -1247,8 +1247,22 @@ my %sPantryItem = (
|
|
|
1247
1247
|
NAMESPACE => 'pdfx',
|
|
1248
1248
|
NOTES => q{
|
|
1249
1249
|
PDF extension tags. This namespace is used to store application-defined PDF
|
|
1250
|
-
information, so there are
|
|
1251
|
-
created to enable writing of XMP-pdfx information.
|
|
1250
|
+
information, so there are few pre-defined tags. User-defined tags must be
|
|
1251
|
+
created to enable writing of other XMP-pdfx information.
|
|
1252
|
+
},
|
|
1253
|
+
SourceModified => {
|
|
1254
|
+
Name => 'SourceModified',
|
|
1255
|
+
Groups => { 2 => 'Time' },
|
|
1256
|
+
Shift => 'Time',
|
|
1257
|
+
ValueConv => 'require Image::ExifTool::PDF; $val = Image::ExifTool::PDF::ConvertPDFDate($val)',
|
|
1258
|
+
ValueConvInv => q{
|
|
1259
|
+
require Image::ExifTool::PDF;
|
|
1260
|
+
$val = Image::ExifTool::PDF::WritePDFValue($self,$val,"date");
|
|
1261
|
+
$val =~ tr/()//d;
|
|
1262
|
+
return $val;
|
|
1263
|
+
},
|
|
1264
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
|
1265
|
+
PrintConvInv => '$self->InverseDateTime($val)',
|
|
1252
1266
|
},
|
|
1253
1267
|
);
|
|
1254
1268
|
|
|
@@ -3525,14 +3539,19 @@ NoLoop:
|
|
|
3525
3539
|
}
|
|
3526
3540
|
last unless $sti;
|
|
3527
3541
|
}
|
|
3528
|
-
#
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3542
|
+
# use existing definition if we already added this tag
|
|
3543
|
+
if ($$tagTablePtr{$tagID}) {
|
|
3544
|
+
$tagInfo = $$tagTablePtr{$tagID};
|
|
3545
|
+
} else {
|
|
3546
|
+
# generate new tagInfo hash based on existing top-level tag
|
|
3547
|
+
$tagInfo = { %$sti, Name => $flat . $$sti{Name} };
|
|
3548
|
+
# be careful not to copy elements we shouldn't...
|
|
3549
|
+
delete $$tagInfo{Description}; # Description will be different
|
|
3550
|
+
# can't copy group hash because group 1 will be different and
|
|
3551
|
+
# we need to check this when writing tag to a specific group
|
|
3552
|
+
delete $$tagInfo{Groups};
|
|
3553
|
+
$$tagInfo{Groups}{2} = $$sti{Groups}{2} if $$sti{Groups};
|
|
3554
|
+
}
|
|
3536
3555
|
last;
|
|
3537
3556
|
}
|
|
3538
3557
|
}
|
|
@@ -3578,13 +3597,15 @@ NoLoop:
|
|
|
3578
3597
|
#} elsif (grep / /, @$props) {
|
|
3579
3598
|
# $$tagInfo{List} = 1;
|
|
3580
3599
|
}
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
$$
|
|
3600
|
+
unless ($$tagTablePtr{$tagID} and $$tagTablePtr{$tagID} eq $tagInfo) {
|
|
3601
|
+
# save property list for verbose "adding" message unless this tag already exists
|
|
3602
|
+
$added = \@tagList unless $$tagTablePtr{$tagID};
|
|
3603
|
+
# if this is an empty structure, we must add a Struct field
|
|
3604
|
+
if (not length $val and $$attrs{'rdf:parseType'} and $$attrs{'rdf:parseType'} eq 'Resource') {
|
|
3605
|
+
$$tagInfo{Struct} = { STRUCT_NAME => 'XMP Unknown' } unless $$tagInfo{Struct};
|
|
3606
|
+
}
|
|
3607
|
+
AddTagToTable($tagTablePtr, $tagID, $tagInfo);
|
|
3586
3608
|
}
|
|
3587
|
-
AddTagToTable($tagTablePtr, $tagID, $tagInfo);
|
|
3588
3609
|
last;
|
|
3589
3610
|
}
|
|
3590
3611
|
# decode value if necessary (et:encoding was used before exiftool 7.71)
|
|
@@ -3804,8 +3825,22 @@ sub ParseXMPElement($$$;$$$$)
|
|
|
3804
3825
|
my ($parseResource, %attrs, @attrs);
|
|
3805
3826
|
# this hangs Perl (v5.18.4) for a specific capture string [patched in ExifTool 12.98]
|
|
3806
3827
|
# while ($attrs =~ m/(\S+?)\s*=\s*(['"])(.*?)\2/sg) {
|
|
3807
|
-
|
|
3808
|
-
|
|
3828
|
+
# this may hang Perl v5.26.3 (but not v5.18.4) if there is lots of garbage in the XMP [patched in 13.23]
|
|
3829
|
+
# while ($attrs =~ /(\S+?)\s*=\s*(['"])/g) {
|
|
3830
|
+
for (;;) {
|
|
3831
|
+
my ($attr, $quote);
|
|
3832
|
+
if (length($attrs) < 2000) { # (do it the easy way if attributes aren't stupid long)
|
|
3833
|
+
last unless $attrs =~ /(\S+)\s*=\s*(['"])/g;
|
|
3834
|
+
($attr, $quote) = ($1, $2);
|
|
3835
|
+
} else {
|
|
3836
|
+
# 13.23 patch to avoid capturing tons of garbage if XMP is corrupted
|
|
3837
|
+
last unless $attrs =~ /=\s*(['"])/g;
|
|
3838
|
+
$quote = $1;
|
|
3839
|
+
my $p = pos($attrs) > 1000 ? pos($attrs) - 1000 : 0;
|
|
3840
|
+
my $tmp = substr($attrs, $p, pos($attrs)-$p);
|
|
3841
|
+
last unless $tmp =~ /(\S+)\s*=\s*$quote$/;
|
|
3842
|
+
$attr = $1;
|
|
3843
|
+
}
|
|
3809
3844
|
my $p0 = pos($attrs);
|
|
3810
3845
|
last unless $attrs =~ /$quote/g;
|
|
3811
3846
|
my $val = substr($attrs, $p0, pos($attrs)-$p0-1);
|
|
@@ -170,7 +170,11 @@ my %sAppInfo = (
|
|
|
170
170
|
%xmpTableDefaults,
|
|
171
171
|
GROUPS => { 1 => 'XMP-xmpDM', 2 => 'Image' },
|
|
172
172
|
NAMESPACE => 'xmpDM',
|
|
173
|
-
NOTES =>
|
|
173
|
+
NOTES => q{
|
|
174
|
+
XMP Dynamic Media namespace tags. See
|
|
175
|
+
L<https://developer.adobe.com/xmp/docs/XMPNamespaces/xmpDM/> for the
|
|
176
|
+
specification.
|
|
177
|
+
},
|
|
174
178
|
absPeakAudioFilePath=> { },
|
|
175
179
|
album => { },
|
|
176
180
|
altTapeName => { },
|
|
@@ -402,6 +406,7 @@ my %sLocationDetails = (
|
|
|
402
406
|
STRUCT_NAME => 'LocationDetails',
|
|
403
407
|
NAMESPACE => 'Iptc4xmpExt',
|
|
404
408
|
GROUPS => { 2 => 'Location' },
|
|
409
|
+
NOTES => 'Note that the GPS elements of this structure are in the "exif" namespace.',
|
|
405
410
|
Identifier => { List => 'Bag', Namespace => 'xmp' },
|
|
406
411
|
City => { },
|
|
407
412
|
CountryCode => { },
|
|
@@ -420,6 +425,7 @@ my %sLocationDetails = (
|
|
|
420
425
|
PrintConvInv => '$val=~s/\s*m$//;$val',
|
|
421
426
|
},
|
|
422
427
|
GPSAltitudeRef => {
|
|
428
|
+
Namespace => 'exif',
|
|
423
429
|
Writable => 'integer',
|
|
424
430
|
PrintConv => {
|
|
425
431
|
OTHER => sub {
|