exiftool-vendored.pl 12.80.0 → 12.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/Changes +81 -0
- package/bin/MANIFEST +6 -18
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +4 -2
- package/bin/build_geolocation +872 -0
- package/bin/config_files/example.config +2 -2
- package/bin/exiftool +61 -17
- package/bin/fmt_files/gpx.fmt +2 -1
- package/bin/fmt_files/gpx_wpt.fmt +2 -1
- package/bin/lib/Image/ExifTool/Apple.pm +51 -7
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +47 -31
- package/bin/lib/Image/ExifTool/CanonVRD.pm +19 -6
- package/bin/lib/Image/ExifTool/DJI.pm +29 -0
- package/bin/lib/Image/ExifTool/Exif.pm +19 -2
- package/bin/lib/Image/ExifTool/FujiFilm.pm +20 -7
- package/bin/lib/Image/ExifTool/GM.pm +552 -0
- package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/lib/Image/ExifTool/Geolocation.pm +423 -178
- package/bin/lib/Image/ExifTool/Geotag.pm +26 -13
- package/bin/lib/Image/ExifTool/M2TS.pm +32 -4
- package/bin/lib/Image/ExifTool/MakerNotes.pm +2 -2
- package/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
- package/bin/lib/Image/ExifTool/Nikon.pm +337 -27
- package/bin/lib/Image/ExifTool/NikonCustom.pm +55 -1
- package/bin/lib/Image/ExifTool/Olympus.pm +1 -0
- package/bin/lib/Image/ExifTool/OpenEXR.pm +21 -3
- package/bin/lib/Image/ExifTool/PNG.pm +3 -3
- package/bin/lib/Image/ExifTool/QuickTime.pm +45 -24
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +66 -30
- package/bin/lib/Image/ExifTool/README +2 -0
- package/bin/lib/Image/ExifTool/Sony.pm +16 -7
- package/bin/lib/Image/ExifTool/TagLookup.pm +4827 -4778
- package/bin/lib/Image/ExifTool/TagNames.pod +953 -620
- package/bin/lib/Image/ExifTool/WriteQuickTime.pl +32 -9
- package/bin/lib/Image/ExifTool/Writer.pl +169 -130
- package/bin/lib/Image/ExifTool/XMP.pm +4 -2
- package/bin/lib/Image/ExifTool/XMP2.pl +3 -0
- package/bin/lib/Image/ExifTool.pm +106 -48
- package/bin/lib/Image/ExifTool.pod +47 -25
- package/bin/perl-Image-ExifTool.spec +1 -1
- package/bin/pp_build_exe.args +4 -4
- package/package.json +3 -3
|
@@ -168,7 +168,8 @@ sub ConvInvISO6709($)
|
|
|
168
168
|
# requires at least 3 digits after the decimal point
|
|
169
169
|
# (and as of Apr 2021, Google Photos doesn't accept coordinats
|
|
170
170
|
# with more than 5 digits after the decimal place:
|
|
171
|
-
# https://exiftool.org/forum/index.php?topic=11055.msg67171#msg67171
|
|
171
|
+
# https://exiftool.org/forum/index.php?topic=11055.msg67171#msg67171
|
|
172
|
+
# still a problem Apr 2024: https://exiftool.org/forum/index.php?msg=85761)
|
|
172
173
|
my @fmt = ('%s%02d.%s%s','%s%03d.%s%s','%s%d.%s%s');
|
|
173
174
|
my @limit = (90,180);
|
|
174
175
|
foreach (@a) {
|
|
@@ -785,6 +786,7 @@ sub WriteQuickTime($$$)
|
|
|
785
786
|
$et or return 1; # allow dummy access to autoload this package
|
|
786
787
|
my ($mdat, @mdat, @mdatEdit, $edit, $track, $outBuff, $co, $term, $delCount);
|
|
787
788
|
my (%langTags, $canCreate, $delGrp, %boxPos, %didDir, $writeLast, $err, $atomCount);
|
|
789
|
+
my ($tag, $lastTag, $errStr);
|
|
788
790
|
my $outfile = $$dirInfo{OutFile} || return 0;
|
|
789
791
|
my $raf = $$dirInfo{RAF}; # (will be null for lower-level atoms)
|
|
790
792
|
my $dataPt = $$dirInfo{DataPt}; # (will be null for top-level atoms)
|
|
@@ -857,7 +859,10 @@ sub WriteQuickTime($$$)
|
|
|
857
859
|
}
|
|
858
860
|
$atomCount = $$tagTablePtr{VARS}{ATOM_COUNT} if $$tagTablePtr{VARS};
|
|
859
861
|
|
|
862
|
+
$tag = $lastTag = '';
|
|
863
|
+
|
|
860
864
|
for (;;) { # loop through all atoms at this level
|
|
865
|
+
$lastTag = $tag if $$tagTablePtr{$tag}; # keep track of last known tag
|
|
861
866
|
if (defined $atomCount and --$atomCount < 0 and $dataPt) {
|
|
862
867
|
# stop processing now and just copy the rest of the atom
|
|
863
868
|
Write($outfile, substr($$dataPt, $raf->Tell())) or $rtnVal=$rtnErr, $err=1;
|
|
@@ -876,15 +881,15 @@ sub WriteQuickTime($$$)
|
|
|
876
881
|
last;
|
|
877
882
|
}
|
|
878
883
|
my $size = Get32u(\$hdr, 0) - 8; # (atom size without 8-byte header)
|
|
879
|
-
|
|
884
|
+
$tag = substr($hdr, 4, 4);
|
|
880
885
|
if ($size == -7) {
|
|
881
886
|
# read the extended size
|
|
882
|
-
$raf->Read($buff, 8) == 8 or $
|
|
887
|
+
$raf->Read($buff, 8) == 8 or $errStr = 'Truncated extended atom', last;
|
|
883
888
|
$hdr .= $buff;
|
|
884
889
|
my ($hi, $lo) = unpack('NN', $buff);
|
|
885
890
|
if ($hi or $lo > 0x7fffffff) {
|
|
886
891
|
if ($hi > 0x7fffffff) {
|
|
887
|
-
$
|
|
892
|
+
$errStr = 'Invalid atom size';
|
|
888
893
|
last;
|
|
889
894
|
} elsif (not $et->Options('LargeFileSupport')) {
|
|
890
895
|
$et->Error('End of processing at large atom (LargeFileSupport not enabled)');
|
|
@@ -892,7 +897,7 @@ sub WriteQuickTime($$$)
|
|
|
892
897
|
}
|
|
893
898
|
}
|
|
894
899
|
$size = $hi * 4294967296 + $lo - 16;
|
|
895
|
-
$size < 0 and $
|
|
900
|
+
$size < 0 and $errStr = 'Invalid extended atom size', last;
|
|
896
901
|
} elsif ($size == -8) {
|
|
897
902
|
if ($dataPt) {
|
|
898
903
|
last if $$dirInfo{DirName} eq 'CanonCNTH'; # (this is normal for Canon CNTH atom)
|
|
@@ -908,7 +913,7 @@ sub WriteQuickTime($$$)
|
|
|
908
913
|
}
|
|
909
914
|
last;
|
|
910
915
|
} elsif ($size < 0) {
|
|
911
|
-
$
|
|
916
|
+
$errStr = 'Invalid atom size';
|
|
912
917
|
last;
|
|
913
918
|
}
|
|
914
919
|
|
|
@@ -952,11 +957,11 @@ sub WriteQuickTime($$$)
|
|
|
952
957
|
$tag = PrintableTagID($tag,3);
|
|
953
958
|
if ($size > $maxReadLen and $got == 0x10000) {
|
|
954
959
|
my $mb = int($size / 0x100000 + 0.5);
|
|
955
|
-
$
|
|
960
|
+
$errStr = "'${tag}' atom is too large for rewriting ($mb MB)";
|
|
956
961
|
} else {
|
|
957
|
-
$
|
|
962
|
+
$errStr = "Truncated '${tag}' atom";
|
|
958
963
|
}
|
|
959
|
-
|
|
964
|
+
last;
|
|
960
965
|
}
|
|
961
966
|
}
|
|
962
967
|
# save the handler type for this track
|
|
@@ -1446,6 +1451,24 @@ sub WriteQuickTime($$$)
|
|
|
1446
1451
|
Write($outfile, $hdr, $buff) or $rtnVal=$rtnErr, $err=1, last;
|
|
1447
1452
|
}
|
|
1448
1453
|
}
|
|
1454
|
+
# ($errStr is set if there was an error that could possibly be due to an unknown trailer)
|
|
1455
|
+
if ($errStr) {
|
|
1456
|
+
if (($lastTag eq 'mdat' or $lastTag eq 'moov') and not $dataPt and (not $$tagTablePtr{$tag} or
|
|
1457
|
+
ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown}))
|
|
1458
|
+
{
|
|
1459
|
+
my $nvTrail = $et->GetNewValueHash($Image::ExifTool::Extra{Trailer});
|
|
1460
|
+
if ($$et{DEL_GROUP}{Trailer} or ($nvTrail and not ($$nvTrail{Value} and $$nvTrail{Value}[0]))) {
|
|
1461
|
+
$errStr =~ s/ is too large.*//;
|
|
1462
|
+
$et->Warn('Deleted unknown trailer with ' . lcfirst($errStr));
|
|
1463
|
+
} else {
|
|
1464
|
+
$et->Warn('Unknown trailer with ' . lcfirst($errStr));
|
|
1465
|
+
$et->Error('Use "-trailer=" to delete unknown trailer');
|
|
1466
|
+
}
|
|
1467
|
+
} else {
|
|
1468
|
+
$et->Error($errStr);
|
|
1469
|
+
return $dataPt ? undef : 1;
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1449
1472
|
$et->VPrint(0, " [deleting $delCount $dirName tag".($delCount==1 ? '' : 's')."]\n") if $delCount;
|
|
1450
1473
|
|
|
1451
1474
|
$createKeys &= ~0x01 unless $$addDirs{Keys}; # (Keys may have been written)
|
|
@@ -1234,7 +1234,8 @@ WriteAlso:
|
|
|
1234
1234
|
|
|
1235
1235
|
#------------------------------------------------------------------------------
|
|
1236
1236
|
# set new values from information in specified file
|
|
1237
|
-
# Inputs: 0) ExifTool object reference, 1) source file name or reference, etc
|
|
1237
|
+
# Inputs: 0) ExifTool object reference, 1) source file name or reference, etc,
|
|
1238
|
+
# or ExifTool ref to use already-extracted tags from an ExifTool object,
|
|
1238
1239
|
# 2-N) List of tags to set (or all if none specified), or reference(s) to
|
|
1239
1240
|
# hash for options to pass to SetNewValue. The Replace option defaults
|
|
1240
1241
|
# to 1 for SetNewValuesFromFile -- set this to 0 to allow multiple tags
|
|
@@ -1245,11 +1246,12 @@ WriteAlso:
|
|
|
1245
1246
|
# be used to represent all tags in a group. An optional destination tag
|
|
1246
1247
|
# may be specified with '>DSTTAG' ('DSTTAG<TAG' also works, but in this
|
|
1247
1248
|
# case the source tag may also be an expression involving tag names).
|
|
1249
|
+
# Simple assignments are also allowed: 'DSTTAG[#][+-][^]=[string]'
|
|
1248
1250
|
sub SetNewValuesFromFile($$;@)
|
|
1249
1251
|
{
|
|
1250
1252
|
local $_;
|
|
1251
1253
|
my ($self, $srcFile, @setTags) = @_;
|
|
1252
|
-
my ($key, $tag, @exclude, @reqTags);
|
|
1254
|
+
my ($srcExifTool, $key, $tag, @exclude, @reqTags, $info);
|
|
1253
1255
|
|
|
1254
1256
|
# get initial SetNewValuesFromFile options
|
|
1255
1257
|
my %opts = ( Replace => 1 ); # replace existing list items by default
|
|
@@ -1261,119 +1263,131 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1261
1263
|
}
|
|
1262
1264
|
# expand shortcuts
|
|
1263
1265
|
@setTags and ExpandShortcuts(\@setTags);
|
|
1264
|
-
my $srcExifTool = Image::ExifTool->new;
|
|
1265
|
-
# set flag to indicate we are being called from inside SetNewValuesFromFile()
|
|
1266
|
-
$$srcExifTool{TAGS_FROM_FILE} = 1;
|
|
1267
|
-
# synchronize and increment the file sequence number
|
|
1268
|
-
$$srcExifTool{FILE_SEQUENCE} = $$self{FILE_SEQUENCE}++;
|
|
1269
1266
|
# set options for our extraction tool
|
|
1270
1267
|
my $options = $$self{OPTIONS};
|
|
1271
|
-
# copy both structured and flattened tags by default (but flattened tags are "unsafe")
|
|
1272
|
-
my $structOpt = defined $$options{Struct} ? $$options{Struct} : 2;
|
|
1273
|
-
# copy structures only if no tags specified (since flattened tags are "unsafe")
|
|
1274
|
-
$structOpt = 1 if $structOpt eq '2' and not @setTags;
|
|
1275
|
-
# +------------------------------------------+
|
|
1276
|
-
# ! DON'T FORGET!! Must consider each new !
|
|
1277
|
-
# ! option to decide how it is handled here. !
|
|
1278
|
-
# +------------------------------------------+
|
|
1279
|
-
$srcExifTool->Options(
|
|
1280
|
-
Binary => 1,
|
|
1281
|
-
ByteUnit => $$options{ByteUnit},
|
|
1282
|
-
Charset => $$options{Charset},
|
|
1283
|
-
CharsetEXIF => $$options{CharsetEXIF},
|
|
1284
|
-
CharsetFileName => $$options{CharsetFileName},
|
|
1285
|
-
CharsetID3 => $$options{CharsetID3},
|
|
1286
|
-
CharsetIPTC => $$options{CharsetIPTC},
|
|
1287
|
-
CharsetPhotoshop=> $$options{CharsetPhotoshop},
|
|
1288
|
-
Composite => $$options{Composite},
|
|
1289
|
-
CoordFormat => $$options{CoordFormat} || '%d %d %.8f', # copy coordinates at high resolution unless otherwise specified
|
|
1290
|
-
DateFormat => $$options{DateFormat},
|
|
1291
|
-
Duplicates => 1,
|
|
1292
|
-
Escape => $$options{Escape},
|
|
1293
|
-
# Exclude (set below)
|
|
1294
|
-
ExtendedXMP => $$options{ExtendedXMP},
|
|
1295
|
-
ExtractEmbedded => $$options{ExtractEmbedded},
|
|
1296
|
-
FastScan => $$options{FastScan},
|
|
1297
|
-
Filter => $$options{Filter},
|
|
1298
|
-
FixBase => $$options{FixBase},
|
|
1299
|
-
Geolocation => $$options{Geolocation},
|
|
1300
|
-
GeolocFeature => $$options{GeolocFeature},
|
|
1301
|
-
GeolocMinPop => $$options{GeolocMinPop},
|
|
1302
|
-
GeolocMaxDist => $$options{GeolocMaxDist},
|
|
1303
|
-
GlobalTimeShift => $$options{GlobalTimeShift},
|
|
1304
|
-
HexTagIDs => $$options{HexTagIDs},
|
|
1305
|
-
IgnoreMinorErrors=>$$options{IgnoreMinorErrors},
|
|
1306
|
-
IgnoreTags => $$options{IgnoreTags},
|
|
1307
|
-
ImageHashType => $$options{ImageHashType},
|
|
1308
|
-
Lang => $$options{Lang},
|
|
1309
|
-
LargeFileSupport=> $$options{LargeFileSupport},
|
|
1310
|
-
LimitLongValues => 10000000, # (10 MB)
|
|
1311
|
-
List => 1,
|
|
1312
|
-
ListItem => $$options{ListItem},
|
|
1313
|
-
ListSep => $$options{ListSep},
|
|
1314
|
-
MakerNotes => $$options{FastScan} && $$options{FastScan} > 1 ? undef : 1,
|
|
1315
|
-
MDItemTags => $$options{MDItemTags},
|
|
1316
|
-
MissingTagValue => $$options{MissingTagValue},
|
|
1317
|
-
NoPDFList => $$options{NoPDFList},
|
|
1318
|
-
NoWarning => $$options{NoWarning},
|
|
1319
|
-
Password => $$options{Password},
|
|
1320
|
-
PrintConv => $$options{PrintConv},
|
|
1321
|
-
QuickTimeUTC => $$options{QuickTimeUTC},
|
|
1322
|
-
RequestAll => $$options{RequestAll} || 1, # (is this still necessary now that RequestTags are being set?)
|
|
1323
|
-
RequestTags => $$options{RequestTags},
|
|
1324
|
-
SaveFormat => $$options{SaveFormat},
|
|
1325
|
-
SavePath => $$options{SavePath},
|
|
1326
|
-
ScanForXMP => $$options{ScanForXMP},
|
|
1327
|
-
StrictDate => defined $$options{StrictDate} ? $$options{StrictDate} : 1,
|
|
1328
|
-
Struct => $structOpt,
|
|
1329
|
-
StructFormat => $$options{StructFormat},
|
|
1330
|
-
SystemTags => $$options{SystemTags},
|
|
1331
|
-
TimeZone => $$options{TimeZone},
|
|
1332
|
-
Unknown => $$options{Unknown},
|
|
1333
|
-
UserParam => $$options{UserParam},
|
|
1334
|
-
Validate => $$options{Validate},
|
|
1335
|
-
WindowsWideFile => $$options{WindowsWideFile},
|
|
1336
|
-
XAttrTags => $$options{XAttrTags},
|
|
1337
|
-
XMPAutoConv => $$options{XMPAutoConv},
|
|
1338
|
-
);
|
|
1339
|
-
$$srcExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
|
|
1340
|
-
$$srcExifTool{ALT_EXIFTOOL} = $$self{ALT_EXIFTOOL};
|
|
1341
|
-
foreach $tag (@setTags) {
|
|
1342
|
-
next if ref $tag;
|
|
1343
|
-
if ($tag =~ /^-(.*)/) {
|
|
1344
|
-
# avoid extracting tags that are excluded
|
|
1345
|
-
push @exclude, $1;
|
|
1346
|
-
next;
|
|
1347
|
-
}
|
|
1348
|
-
# add specified tags to list of requested tags
|
|
1349
|
-
$_ = $tag;
|
|
1350
|
-
if (/(.+?)\s*(>|<)\s*(.+)/) {
|
|
1351
|
-
if ($2 eq '>') {
|
|
1352
|
-
$_ = $1;
|
|
1353
|
-
} else {
|
|
1354
|
-
$_ = $3;
|
|
1355
|
-
/\$/ and push(@reqTags, /\$\{?(?:[-\w]+:)*([-\w?*]+)/g), next;
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
push @reqTags, $2 if /(^|:)([-\w?*]+)#?$/;
|
|
1359
|
-
}
|
|
1360
|
-
if (@exclude) {
|
|
1361
|
-
ExpandShortcuts(\@exclude, 1);
|
|
1362
|
-
$srcExifTool->Options(Exclude => \@exclude);
|
|
1363
|
-
}
|
|
1364
|
-
$srcExifTool->Options(RequestTags => \@reqTags) if @reqTags;
|
|
1365
1268
|
my $printConv = $$options{PrintConv};
|
|
1366
1269
|
if ($opts{Type}) {
|
|
1367
1270
|
# save source type separately because it may be different than dst Type
|
|
1368
1271
|
$opts{SrcType} = $opts{Type};
|
|
1369
1272
|
# override PrintConv option with initial Type if given
|
|
1370
1273
|
$printConv = ($opts{Type} eq 'PrintConv' ? 1 : 0);
|
|
1371
|
-
$srcExifTool->Options(PrintConv => $printConv);
|
|
1372
1274
|
}
|
|
1373
1275
|
my $srcType = $printConv ? 'PrintConv' : 'ValueConv';
|
|
1276
|
+
my $structOpt = defined $$options{Struct} ? $$options{Struct} : 2;
|
|
1374
1277
|
|
|
1375
|
-
|
|
1376
|
-
|
|
1278
|
+
if (ref $srcFile and UNIVERSAL::isa($srcFile,'Image::ExifTool')) {
|
|
1279
|
+
$srcExifTool = $srcFile;
|
|
1280
|
+
$info = $srcExifTool->GetInfo({ PrintConv => $printConv });
|
|
1281
|
+
} else {
|
|
1282
|
+
$srcExifTool = Image::ExifTool->new;
|
|
1283
|
+
$srcExifTool->Options(PrintConv => $printConv);
|
|
1284
|
+
# set flag to indicate we are being called from inside SetNewValuesFromFile()
|
|
1285
|
+
$$srcExifTool{TAGS_FROM_FILE} = 1;
|
|
1286
|
+
# synchronize and increment the file sequence number
|
|
1287
|
+
$$srcExifTool{FILE_SEQUENCE} = $$self{FILE_SEQUENCE}++;
|
|
1288
|
+
# copy both structured and flattened tags by default (but flattened tags are "unsafe")
|
|
1289
|
+
# copy structures only if no tags specified (since flattened tags are "unsafe")
|
|
1290
|
+
$structOpt = 1 if $structOpt eq '2' and not @setTags;
|
|
1291
|
+
# +------------------------------------------+
|
|
1292
|
+
# ! DON'T FORGET!! Must consider each new !
|
|
1293
|
+
# ! option to decide how it is handled here. !
|
|
1294
|
+
# +------------------------------------------+
|
|
1295
|
+
$srcExifTool->Options(
|
|
1296
|
+
Binary => 1,
|
|
1297
|
+
ByteUnit => $$options{ByteUnit},
|
|
1298
|
+
Charset => $$options{Charset},
|
|
1299
|
+
CharsetEXIF => $$options{CharsetEXIF},
|
|
1300
|
+
CharsetFileName => $$options{CharsetFileName},
|
|
1301
|
+
CharsetID3 => $$options{CharsetID3},
|
|
1302
|
+
CharsetIPTC => $$options{CharsetIPTC},
|
|
1303
|
+
CharsetPhotoshop=> $$options{CharsetPhotoshop},
|
|
1304
|
+
Composite => $$options{Composite},
|
|
1305
|
+
CoordFormat => $$options{CoordFormat} || '%d %d %.8f', # copy coordinates at high resolution unless otherwise specified
|
|
1306
|
+
DateFormat => $$options{DateFormat},
|
|
1307
|
+
Duplicates => 1,
|
|
1308
|
+
Escape => $$options{Escape},
|
|
1309
|
+
# Exclude (set below)
|
|
1310
|
+
ExtendedXMP => $$options{ExtendedXMP},
|
|
1311
|
+
ExtractEmbedded => $$options{ExtractEmbedded},
|
|
1312
|
+
FastScan => $$options{FastScan},
|
|
1313
|
+
Filter => $$options{Filter},
|
|
1314
|
+
FixBase => $$options{FixBase},
|
|
1315
|
+
Geolocation => $$options{Geolocation},
|
|
1316
|
+
GeolocAltNames => $$options{GeolocAltNames},
|
|
1317
|
+
GeolocFeature => $$options{GeolocFeature},
|
|
1318
|
+
GeolocMinPop => $$options{GeolocMinPop},
|
|
1319
|
+
GeolocMaxDist => $$options{GeolocMaxDist},
|
|
1320
|
+
GlobalTimeShift => $$options{GlobalTimeShift},
|
|
1321
|
+
HexTagIDs => $$options{HexTagIDs},
|
|
1322
|
+
IgnoreGroups => $$options{IgnoreGroups},
|
|
1323
|
+
IgnoreMinorErrors=>$$options{IgnoreMinorErrors},
|
|
1324
|
+
IgnoreTags => $$options{IgnoreTags},
|
|
1325
|
+
ImageHashType => $$options{ImageHashType},
|
|
1326
|
+
Lang => $$options{Lang},
|
|
1327
|
+
LargeFileSupport=> $$options{LargeFileSupport},
|
|
1328
|
+
LimitLongValues => 10000000, # (10 MB)
|
|
1329
|
+
List => 1,
|
|
1330
|
+
ListItem => $$options{ListItem},
|
|
1331
|
+
ListSep => $$options{ListSep},
|
|
1332
|
+
MakerNotes => $$options{FastScan} && $$options{FastScan} > 1 ? undef : 1,
|
|
1333
|
+
MDItemTags => $$options{MDItemTags},
|
|
1334
|
+
MissingTagValue => $$options{MissingTagValue},
|
|
1335
|
+
NoPDFList => $$options{NoPDFList},
|
|
1336
|
+
NoWarning => $$options{NoWarning},
|
|
1337
|
+
Password => $$options{Password},
|
|
1338
|
+
PrintConv => $$options{PrintConv},
|
|
1339
|
+
QuickTimeUTC => $$options{QuickTimeUTC},
|
|
1340
|
+
RequestAll => $$options{RequestAll} || 1, # (is this still necessary now that RequestTags are being set?)
|
|
1341
|
+
RequestTags => $$options{RequestTags},
|
|
1342
|
+
SaveFormat => $$options{SaveFormat},
|
|
1343
|
+
SavePath => $$options{SavePath},
|
|
1344
|
+
ScanForXMP => $$options{ScanForXMP},
|
|
1345
|
+
StrictDate => defined $$options{StrictDate} ? $$options{StrictDate} : 1,
|
|
1346
|
+
Struct => $structOpt,
|
|
1347
|
+
StructFormat => $$options{StructFormat},
|
|
1348
|
+
SystemTags => $$options{SystemTags},
|
|
1349
|
+
TimeZone => $$options{TimeZone},
|
|
1350
|
+
Unknown => $$options{Unknown},
|
|
1351
|
+
UserParam => $$options{UserParam},
|
|
1352
|
+
Validate => $$options{Validate},
|
|
1353
|
+
WindowsWideFile => $$options{WindowsWideFile},
|
|
1354
|
+
XAttrTags => $$options{XAttrTags},
|
|
1355
|
+
XMPAutoConv => $$options{XMPAutoConv},
|
|
1356
|
+
);
|
|
1357
|
+
# reset Geolocation option if we aren't copying any geolocation tags
|
|
1358
|
+
if ($$options{Geolocation} and not grep /\bGeolocation/i, @setTags) {
|
|
1359
|
+
$self->VPrint(0, '(resetting unnecessary Geolocation option)');
|
|
1360
|
+
$$srcExifTool{OPTIONS}{Geolocation} = undef;
|
|
1361
|
+
}
|
|
1362
|
+
$$srcExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
|
|
1363
|
+
$$srcExifTool{ALT_EXIFTOOL} = $$self{ALT_EXIFTOOL};
|
|
1364
|
+
foreach $tag (@setTags) {
|
|
1365
|
+
next if ref $tag;
|
|
1366
|
+
if ($tag =~ /^-(.*)/) {
|
|
1367
|
+
# avoid extracting tags that are excluded
|
|
1368
|
+
push @exclude, $1;
|
|
1369
|
+
next;
|
|
1370
|
+
}
|
|
1371
|
+
# add specified tags to list of requested tags
|
|
1372
|
+
$_ = $tag;
|
|
1373
|
+
if (/(.+?)\s*(>|<)\s*(.+)/) {
|
|
1374
|
+
if ($2 eq '>') {
|
|
1375
|
+
$_ = $1;
|
|
1376
|
+
} else {
|
|
1377
|
+
$_ = $3;
|
|
1378
|
+
/\$/ and push(@reqTags, /\$\{?(?:[-\w]+:)*([-\w?*]+)/g), next;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
push @reqTags, $2 if /(^|:)([-\w?*]+)#?$/;
|
|
1382
|
+
}
|
|
1383
|
+
if (@exclude) {
|
|
1384
|
+
ExpandShortcuts(\@exclude, 1);
|
|
1385
|
+
$srcExifTool->Options(Exclude => \@exclude);
|
|
1386
|
+
}
|
|
1387
|
+
$srcExifTool->Options(RequestTags => \@reqTags) if @reqTags;
|
|
1388
|
+
# get all tags from source file (including MakerNotes block)
|
|
1389
|
+
$info = $srcExifTool->ImageInfo($srcFile);
|
|
1390
|
+
}
|
|
1377
1391
|
return $info if $$info{Error} and $$info{Error} eq 'Error opening file';
|
|
1378
1392
|
delete $$srcExifTool{VALUE}{Error}; # delete so we can check this later
|
|
1379
1393
|
|
|
@@ -1408,6 +1422,7 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1408
1422
|
#
|
|
1409
1423
|
# 1) loop through input list of tags to set, and build @setList
|
|
1410
1424
|
my (@setList, $set, %setMatches, $t, %altFiles);
|
|
1425
|
+
my $assign = 0;
|
|
1411
1426
|
foreach $t (@setTags) {
|
|
1412
1427
|
if (ref $t eq 'HASH') {
|
|
1413
1428
|
# update current options
|
|
@@ -1422,18 +1437,22 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1422
1437
|
$tag = lc $t; # change tag/group names to all lower case
|
|
1423
1438
|
my (@fg, $grp, $dst, $dstGrp, $dstTag, $isExclude);
|
|
1424
1439
|
# handle redirection to another tag
|
|
1425
|
-
if ($tag =~ /(.+?)\s*(
|
|
1440
|
+
if ($tag =~ /(.+?)\s*(>|<|=)(\s*)(.*)/) {
|
|
1426
1441
|
$dstGrp = '';
|
|
1427
|
-
my $opt;
|
|
1442
|
+
my ($opt, $op, $spc);
|
|
1428
1443
|
if ($2 eq '>') {
|
|
1429
|
-
($tag, $dstTag) = ($1, $
|
|
1444
|
+
($tag, $dstTag) = ($1, $4);
|
|
1430
1445
|
# flag add and delete (eg. '+<' and '-<') redirections
|
|
1431
1446
|
$opt = $1 if $tag =~ s/\s*([-+])$// or $dstTag =~ s/^([-+])\s*//;
|
|
1432
1447
|
} else {
|
|
1433
|
-
($
|
|
1448
|
+
($dstTag, $op, $spc, $tag) = ($1, $2, $3, $4);
|
|
1434
1449
|
$opt = $1 if $dstTag =~ s/\s*([-+])$//;
|
|
1435
|
-
|
|
1436
|
-
|
|
1450
|
+
if ($op eq '=') {
|
|
1451
|
+
# simple assignment ($tag will be the new value)
|
|
1452
|
+
$tag = $spc . $tag;
|
|
1453
|
+
undef $tag unless $dstTag =~ s/\^$// or length $tag;
|
|
1454
|
+
$$opts{ASSIGN} = ++$assign;
|
|
1455
|
+
} elsif ($tag =~ /\$/) { # handle expressions
|
|
1437
1456
|
$tag = $t; # restore original case
|
|
1438
1457
|
# recover leading whitespace (except for initial single space)
|
|
1439
1458
|
$tag =~ s/(.+?)\s*(>|<) ?//;
|
|
@@ -1446,7 +1465,7 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1446
1465
|
}
|
|
1447
1466
|
$$opts{Replace} = 0 if $dstTag =~ s/^\+//;
|
|
1448
1467
|
# validate tag name(s)
|
|
1449
|
-
unless ($$opts{EXPR} or ValidTagName($tag)) {
|
|
1468
|
+
unless ($$opts{EXPR} or $$opts{ASSIGN} or ValidTagName($tag)) {
|
|
1450
1469
|
$self->Warn("Invalid tag name '${tag}'. Use '=' not '<' to assign a tag value");
|
|
1451
1470
|
next;
|
|
1452
1471
|
}
|
|
@@ -1464,7 +1483,7 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1464
1483
|
} else {
|
|
1465
1484
|
$$opts{Replace} = 0 if $tag =~ s/^\+//;
|
|
1466
1485
|
}
|
|
1467
|
-
unless ($$opts{EXPR}) {
|
|
1486
|
+
unless ($$opts{EXPR} or $$opts{ASSIGN}) {
|
|
1468
1487
|
$isExclude = ($tag =~ s/^-//);
|
|
1469
1488
|
if ($tag =~ /(.*):(.+)/) {
|
|
1470
1489
|
($grp, $tag) = ($1, $2);
|
|
@@ -1534,6 +1553,8 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1534
1553
|
foreach $set (@setList) {
|
|
1535
1554
|
$$set[2] and $setMatches{$set} = [ ];
|
|
1536
1555
|
}
|
|
1556
|
+
# no need to search source tags if doing only assignments
|
|
1557
|
+
undef @tags if $assign == @setList;
|
|
1537
1558
|
# 3) loop through all tags in source image and save tags matching each setTag
|
|
1538
1559
|
my (%rtnInfo, $isAlt);
|
|
1539
1560
|
foreach $tag (@tags) {
|
|
@@ -1586,21 +1607,26 @@ SET: foreach $set (@setList) {
|
|
|
1586
1607
|
# get options for SetNewValue
|
|
1587
1608
|
my $opts = $$set[3];
|
|
1588
1609
|
# handle expressions
|
|
1589
|
-
if ($$opts{EXPR}) {
|
|
1590
|
-
my $val
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
($
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1610
|
+
if ($$opts{EXPR} or $$opts{ASSIGN}) {
|
|
1611
|
+
my $val;
|
|
1612
|
+
if ($$opts{EXPR}) {
|
|
1613
|
+
$val = $srcExifTool->InsertTagValues($$set[1], \@tags, 'Error');
|
|
1614
|
+
my $err = $$srcExifTool{VALUE}{Error};
|
|
1615
|
+
if ($err) {
|
|
1616
|
+
# pass on any error as a warning unless it is suppressed
|
|
1617
|
+
my $noWarn = $$srcExifTool{OPTIONS}{NoWarning};
|
|
1618
|
+
unless ($noWarn and (eval { $err =~ /$noWarn/ } or
|
|
1619
|
+
# (also apply expression to warning without "[minor] " prefix)
|
|
1620
|
+
($err =~ s/^\[minor\] //i and eval { $err =~ /$noWarn/ })))
|
|
1621
|
+
{
|
|
1622
|
+
$tag = NextFreeTagKey(\%rtnInfo, 'Warning');
|
|
1623
|
+
$rtnInfo{$tag} = $$srcExifTool{VALUE}{Error};
|
|
1624
|
+
}
|
|
1625
|
+
delete $$srcExifTool{VALUE}{Error};
|
|
1626
|
+
next unless defined $val;
|
|
1601
1627
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1628
|
+
} else {
|
|
1629
|
+
$val = $$set[1];
|
|
1604
1630
|
}
|
|
1605
1631
|
my ($dstGrp, $dstTag) = @{$$set[2]};
|
|
1606
1632
|
$$opts{Protected} = 1 unless $dstTag =~ /[?*]/ and $dstTag ne '*';
|
|
@@ -3161,8 +3187,8 @@ sub PushValue($$$;$)
|
|
|
3161
3187
|
# Inputs: 0) ExifTool object ref, 1) string with embedded tag names,
|
|
3162
3188
|
# 2) reference to list of found tags or undef to use FOUND_TAGS, 3) Options:
|
|
3163
3189
|
# undef - set missing tags to ''
|
|
3164
|
-
# 'Error' - issue minor error on missing tag (and return undef)
|
|
3165
|
-
# 'Warn' - issue minor warning on missing tag (and return undef)
|
|
3190
|
+
# 'Error' - issue minor error on missing tag (and return undef if error sent)
|
|
3191
|
+
# 'Warn' - issue minor warning on missing tag (and return undef if warning sent)
|
|
3166
3192
|
# 'Silent' - just return undef on missing tag (no errors/warnings)
|
|
3167
3193
|
# Hash ref - defined to interpolate as variables in string instead of values
|
|
3168
3194
|
# --> receives tag/value pairs for interpolation of the variables
|
|
@@ -3448,6 +3474,19 @@ sub NoDups
|
|
|
3448
3474
|
$_ = ($_[0] and $new eq $_) ? undef : $new;
|
|
3449
3475
|
}
|
|
3450
3476
|
|
|
3477
|
+
#------------------------------------------------------------------------------
|
|
3478
|
+
# Utility routine to set in $_ image from current object
|
|
3479
|
+
# Inputs: 0-N) list of tags to copy
|
|
3480
|
+
# Returns: Return value from WriteInfo
|
|
3481
|
+
# Notes: - for use only in advanced formatting expressions
|
|
3482
|
+
sub SetTags(@)
|
|
3483
|
+
{
|
|
3484
|
+
my $self = $advFmtSelf;
|
|
3485
|
+
my $et = Image::ExifTool->new;
|
|
3486
|
+
$et->SetNewValuesFromFile($self, @_);
|
|
3487
|
+
return $et->WriteInfo(\$_);
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3451
3490
|
#------------------------------------------------------------------------------
|
|
3452
3491
|
# Is specified tag writable
|
|
3453
3492
|
# Inputs: 0) tag name, case insensitive (optional group name currently ignored)
|
|
@@ -3806,7 +3845,7 @@ sub GetGeolocateTags($$;$)
|
|
|
3806
3845
|
'iptc' => [ qw(City Province-State Country-PrimaryLocationCode Country-PrimaryLocationName) ],
|
|
3807
3846
|
'gps' => [ qw(GPSLatitude GPSLongitude GPSLatitudeRef GPSLongitudeRef) ],
|
|
3808
3847
|
'xmp-exif' => [ qw(GPSLatitude GPSLongitude) ],
|
|
3809
|
-
'keys' => [ 'GPSCoordinates' ],
|
|
3848
|
+
'keys' => [ 'GPSCoordinates', 'LocationName' ],
|
|
3810
3849
|
'itemlist' => [ 'GPSCoordinates' ],
|
|
3811
3850
|
'userdata' => [ 'GPSCoordinates' ],
|
|
3812
3851
|
# more general groups not in this lookup: XMP and QuickTime
|
|
@@ -3818,7 +3857,7 @@ sub GetGeolocateTags($$;$)
|
|
|
3818
3857
|
}
|
|
3819
3858
|
# set default XMP City tags if necessary
|
|
3820
3859
|
if (not $writeGPS and ($grps{xmp} or (not @tags and not $grps{quicktime}))) {
|
|
3821
|
-
push @tags, qw(XMP:City XMP:State XMP:CountryCode XMP:Country);
|
|
3860
|
+
push @tags, qw(XMP:City XMP:State XMP:CountryCode XMP:Country Keys:LocationName);
|
|
3822
3861
|
}
|
|
3823
3862
|
$writeGPS = 1 unless defined $writeGPS; # (delete both City and GPS)
|
|
3824
3863
|
# set default QuickTime tag if necessary
|
|
@@ -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.65';
|
|
54
54
|
@ISA = qw(Exporter);
|
|
55
55
|
@EXPORT_OK = qw(EscapeXML UnescapeXML);
|
|
56
56
|
|
|
@@ -283,11 +283,12 @@ my %recognizedAttrs = (
|
|
|
283
283
|
# NOTE: this lookup is duplicated in TagLookup.pm!!
|
|
284
284
|
%specialStruct = (
|
|
285
285
|
STRUCT_NAME => 1, # [optional] name of structure
|
|
286
|
-
NAMESPACE => 1, # [mandatory] namespace prefix used for fields of this structure
|
|
286
|
+
NAMESPACE => 1, # [mandatory for XMP] namespace prefix used for fields of this structure
|
|
287
287
|
NOTES => 1, # [optional] notes for documentation about this structure
|
|
288
288
|
TYPE => 1, # [optional] rdf:type resource for struct (if used, the StructType flag
|
|
289
289
|
# will be set automatically for all derived flattened tags when writing)
|
|
290
290
|
GROUPS => 1, # [optional] specifies family group 2 name for the structure
|
|
291
|
+
SORT_ORDER => 1, # [optional] order for sorting fields in documentation
|
|
291
292
|
);
|
|
292
293
|
# XMP structures (each structure is similar to a tag table so we can
|
|
293
294
|
# recurse through them in SetPropertyPath() as if they were tag tables)
|
|
@@ -2587,6 +2588,7 @@ my %sPantryItem = (
|
|
|
2587
2588
|
EnhanceDenoiseAlreadyApplied => { Writable => 'boolean' }, #forum14760
|
|
2588
2589
|
EnhanceDenoiseVersion => { }, #forum14760 integer?
|
|
2589
2590
|
EnhanceDenoiseLumaAmount => { }, #forum14760 integer?
|
|
2591
|
+
# FujiRatingAlreadyApplied - boolean written by LR classic 13.2 (forum15815)
|
|
2590
2592
|
);
|
|
2591
2593
|
|
|
2592
2594
|
# IPTC Core namespace properties (Iptc4xmpCore) (ref 4)
|
|
@@ -1941,6 +1941,9 @@ my %sACDSeeRegionStruct = (
|
|
|
1941
1941
|
ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
|
|
1942
1942
|
ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
|
|
1943
1943
|
},
|
|
1944
|
+
MotionPhoto => { Writable => 'integer' },
|
|
1945
|
+
MotionPhotoVersion => { Writable => 'integer' },
|
|
1946
|
+
MotionPhotoPresentationTimestampUs => { Writable => 'integer' },
|
|
1944
1947
|
);
|
|
1945
1948
|
|
|
1946
1949
|
# Google creations namespace (ref PH)
|