exiftool-vendored.pl 13.41.0 → 13.43.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 +27 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +2 -2
- package/bin/exiftool +97 -95
- package/bin/lib/Image/ExifTool/Canon.pm +27 -2
- package/bin/lib/Image/ExifTool/JSON.pm +7 -6
- package/bin/lib/Image/ExifTool/Panasonic.pm +13 -5
- package/bin/lib/Image/ExifTool/QuickTime.pm +26 -4
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +1 -1
- package/bin/lib/Image/ExifTool/RIFF.pm +2 -1
- package/bin/lib/Image/ExifTool/Samsung.pm +137 -4
- package/bin/lib/Image/ExifTool/Sony.pm +5 -2
- package/bin/lib/Image/ExifTool/TagLookup.pm +7178 -7107
- package/bin/lib/Image/ExifTool/TagNames.pod +127 -3
- package/bin/lib/Image/ExifTool/WriteQuickTime.pl +17 -2
- package/bin/lib/Image/ExifTool.pm +3 -3
- package/bin/perl-Image-ExifTool.spec +1 -1
- package/package.json +4 -4
package/bin/Changes
CHANGED
|
@@ -7,6 +7,33 @@ RSS feed: https://exiftool.org/rss.xml
|
|
|
7
7
|
Note: The most recent production release is Version 13.36. (Other versions are
|
|
8
8
|
considered development releases, and are not uploaded to MetaCPAN.)
|
|
9
9
|
|
|
10
|
+
Dec. 4, 2025 - Version 13.43
|
|
11
|
+
|
|
12
|
+
- Added support for a couple of new Android QuickTime Keys tags
|
|
13
|
+
- Added date/time formatting for RIFF DateCreated
|
|
14
|
+
- Added ability to read/write (but not create/delete) the HEIF Mirroring tag
|
|
15
|
+
- Added a new SonyModelID
|
|
16
|
+
- Added a new Canon LensType (thanks Matthias)
|
|
17
|
+
- Decode ShutterCount for the Canon EOS R6 Mark III
|
|
18
|
+
- Decode another Samsung trailer tag
|
|
19
|
+
- Convert invalid Panasonic AFPointPosition to 'n/a'
|
|
20
|
+
- Fixed issue extracting timed GPS from some Wolfbox G900 MP4 videos
|
|
21
|
+
|
|
22
|
+
Nov. 17, 2025 - Version 13.42
|
|
23
|
+
|
|
24
|
+
- Added warning if tag arguments come before -csv= or -json= in a command
|
|
25
|
+
- Added a new CanonModelID and RFLensType (thanks Norbert Wasser)
|
|
26
|
+
- Added ability to read XML as a block from Sony MP4 videos
|
|
27
|
+
- Added "EOS" to the R5 Mark II CanonModelID string
|
|
28
|
+
- Decode ReEditData in Samsung trailer
|
|
29
|
+
- Decode a couple more Sony rtmd tags from MP4 videos
|
|
30
|
+
- Tolerate some types of trailer corruption as caused by Samsung Gallery
|
|
31
|
+
- Restrict decoding of MetaImageSize to HEIC files only
|
|
32
|
+
- Fixed issue writing Keys tags to Sony PMW-EX1R videos
|
|
33
|
+
- Fixed behaviour of CSV/JSON import when specifying tags to import into an
|
|
34
|
+
existing list, or when importing ValueConv values (ie. "TAG#"), or when
|
|
35
|
+
specifying a group name of "All"
|
|
36
|
+
|
|
10
37
|
Nov. 5, 2025 - Version 13.41
|
|
11
38
|
|
|
12
39
|
- Added a new Canon LensType
|
package/bin/META.json
CHANGED
package/bin/META.yml
CHANGED
package/bin/README
CHANGED
|
@@ -111,8 +111,8 @@ your home directory, then you would type the following commands in a
|
|
|
111
111
|
terminal window to extract and run ExifTool:
|
|
112
112
|
|
|
113
113
|
cd ~/Desktop
|
|
114
|
-
gzip -dc Image-ExifTool-13.
|
|
115
|
-
cd Image-ExifTool-13.
|
|
114
|
+
gzip -dc Image-ExifTool-13.43.tar.gz | tar -xf -
|
|
115
|
+
cd Image-ExifTool-13.43
|
|
116
116
|
./exiftool t/images/ExifTool.jpg
|
|
117
117
|
|
|
118
118
|
Note: These commands extract meta information from one of the test images.
|
package/bin/exiftool
CHANGED
|
@@ -11,7 +11,7 @@ use strict;
|
|
|
11
11
|
use warnings;
|
|
12
12
|
require 5.004;
|
|
13
13
|
|
|
14
|
-
my $version = '13.
|
|
14
|
+
my $version = '13.43';
|
|
15
15
|
|
|
16
16
|
$^W = 1; # enable global warnings
|
|
17
17
|
|
|
@@ -152,9 +152,9 @@ my $countNewDir; # count of directories created
|
|
|
152
152
|
my $countSameWr; # count files written OK but not changed
|
|
153
153
|
my $critical; # flag for critical operations (disable CTRL-C)
|
|
154
154
|
my $csv; # flag for CSV option (set to "CSV", or maybe "JSON" when writing)
|
|
155
|
-
my $csvAdd; # flag to add CSV information to existing lists
|
|
156
155
|
my $csvDelim; # delimiter for CSV files
|
|
157
|
-
my $
|
|
156
|
+
my $dbAdd; # flag to add CSV/JSON information to existing lists
|
|
157
|
+
my $dbSaveCount; # save counter for last CSV/JSON file loaded
|
|
158
158
|
my $deleteOrig; # 0=restore original files, 1=delete originals, 2=delete w/o asking
|
|
159
159
|
my $diff; # file name for comparing differences
|
|
160
160
|
my $disableOutput; # flag to disable normal output
|
|
@@ -485,7 +485,7 @@ undef $binSep;
|
|
|
485
485
|
undef $binTerm;
|
|
486
486
|
undef $comma;
|
|
487
487
|
undef $csv;
|
|
488
|
-
undef $
|
|
488
|
+
undef $dbAdd;
|
|
489
489
|
undef $deleteOrig;
|
|
490
490
|
undef $diff;
|
|
491
491
|
undef $disableOutput;
|
|
@@ -550,7 +550,7 @@ $countGoodWr = 0;
|
|
|
550
550
|
$countNewDir = 0;
|
|
551
551
|
$countSameWr = 0;
|
|
552
552
|
$csvDelim = ',';
|
|
553
|
-
$
|
|
553
|
+
$dbSaveCount = 0;
|
|
554
554
|
$fileTrailer = '';
|
|
555
555
|
$filterFlag = 0;
|
|
556
556
|
$html = 0;
|
|
@@ -580,7 +580,7 @@ my $escapeXML; # flag to escape printed values for xml
|
|
|
580
580
|
my $setTagsFile; # filename for last TagsFromFile option
|
|
581
581
|
my $sortOpt; # sort option is used
|
|
582
582
|
my $srcStdin; # one of the source files is STDIN
|
|
583
|
-
my $tagsFrom = ''; # tags on command line come from '
|
|
583
|
+
my $tagsFrom = ''; # tags on command line come from 'CSV' or 'File'
|
|
584
584
|
my $useMWG; # flag set if we are using any MWG tag
|
|
585
585
|
|
|
586
586
|
my ($argsLeft, @nextPass, $badCmd);
|
|
@@ -815,7 +815,7 @@ for (;;) {
|
|
|
815
815
|
}
|
|
816
816
|
# create necessary lists, etc for this new -tagsFromFile file
|
|
817
817
|
AddSetTagsFile($setTagsFile, { Replace => ($1 and lc($1) eq 'add') ? 0 : 1 } );
|
|
818
|
-
$tagsFrom = '
|
|
818
|
+
$tagsFrom = 'File';
|
|
819
819
|
next;
|
|
820
820
|
}
|
|
821
821
|
if ($a eq '@') {
|
|
@@ -923,36 +923,50 @@ for (;;) {
|
|
|
923
923
|
next;
|
|
924
924
|
}
|
|
925
925
|
/^config$/i and Warn("Ignored -config option (not first on command line)\n"), shift, next;
|
|
926
|
-
if (/^csv(\+?=.*)?$/i) {
|
|
927
|
-
my $
|
|
926
|
+
if (/^(csv|j(son)?)(\+?=.*)?$/i) {
|
|
927
|
+
my $dbFile = $3;
|
|
928
|
+
my $dbType = lc($1) eq 'csv' ? 'CSV' : 'JSON';
|
|
929
|
+
unless ($dbFile) {
|
|
930
|
+
if ($dbType eq 'CSV') {
|
|
931
|
+
$csv = $dbType;
|
|
932
|
+
} else {
|
|
933
|
+
$json = 1;
|
|
934
|
+
$html = $xml = 0;
|
|
935
|
+
$mt->Options(Duplicates => 1);
|
|
936
|
+
require Image::ExifTool::XMP; # for FixUTF8()
|
|
937
|
+
}
|
|
938
|
+
next;
|
|
939
|
+
}
|
|
928
940
|
# must process on 2nd pass so -f and -charset options are available
|
|
929
941
|
unless ($pass) {
|
|
942
|
+
@tags and Warn("Tag arguments should come after the -$1= option\n");
|
|
930
943
|
push @nextPass, "-$_";
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
$tagsFrom = 'csv';
|
|
935
|
-
}
|
|
944
|
+
push @newValues, { SaveCount => ++$saveCount }; # marker to save new values now
|
|
945
|
+
$dbSaveCount = $saveCount;
|
|
946
|
+
$tagsFrom = 'CSV';
|
|
936
947
|
next;
|
|
937
948
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
949
|
+
$dbFile =~ s/^(\+?=)//;
|
|
950
|
+
$dbAdd = 2 if $1 eq '+=';
|
|
951
|
+
$vout = \*STDERR if $srcStdin;
|
|
952
|
+
$verbose and print $vout "Reading $dbType file $dbFile\n";
|
|
953
|
+
my $msg;
|
|
954
|
+
if ($mt->Open(\*CSVFILE, $dbFile)) {
|
|
955
|
+
binmode CSVFILE;
|
|
956
|
+
require Image::ExifTool::Import;
|
|
957
|
+
if ($dbType eq 'CSV') {
|
|
947
958
|
$msg = Image::ExifTool::Import::ReadCSV(\*CSVFILE, \%database, $forcePrint, $csvDelim);
|
|
948
|
-
close(CSVFILE);
|
|
949
959
|
} else {
|
|
950
|
-
$
|
|
960
|
+
my $chset = $mt->Options('Charset');
|
|
961
|
+
$msg = Image::ExifTool::Import::ReadJSON(\*CSVFILE, \%database, $forcePrint, $chset);
|
|
951
962
|
}
|
|
952
|
-
|
|
953
|
-
|
|
963
|
+
close(CSVFILE);
|
|
964
|
+
} else {
|
|
965
|
+
$msg = "Error opening $dbType file '${dbFile}'";
|
|
954
966
|
}
|
|
955
|
-
$
|
|
967
|
+
$msg and Warn("$msg\n");
|
|
968
|
+
$isWriting = 1;
|
|
969
|
+
$csv = $dbType;
|
|
956
970
|
next;
|
|
957
971
|
}
|
|
958
972
|
if (/^csvdelim$/i) {
|
|
@@ -1115,42 +1129,6 @@ for (;;) {
|
|
|
1115
1129
|
push @condition, $cond;
|
|
1116
1130
|
next;
|
|
1117
1131
|
}
|
|
1118
|
-
if (/^j(son)?(\+?=.*)?$/i) {
|
|
1119
|
-
if ($2) {
|
|
1120
|
-
# must process on 2nd pass because we need -f and -charset options
|
|
1121
|
-
unless ($pass) {
|
|
1122
|
-
push @nextPass, "-$_";
|
|
1123
|
-
push @newValues, { SaveCount => ++$saveCount }; # marker to save new values now
|
|
1124
|
-
$csvSaveCount = $saveCount;
|
|
1125
|
-
$tagsFrom = 'csv';
|
|
1126
|
-
next;
|
|
1127
|
-
}
|
|
1128
|
-
my $jsonFile = $2;
|
|
1129
|
-
$jsonFile =~ s/^(\+?=)//;
|
|
1130
|
-
$csvAdd = 2 if $1 eq '+=';
|
|
1131
|
-
$vout = \*STDERR if $srcStdin;
|
|
1132
|
-
$verbose and print $vout "Reading JSON file $jsonFile\n";
|
|
1133
|
-
my $chset = $mt->Options('Charset');
|
|
1134
|
-
my $msg;
|
|
1135
|
-
if ($mt->Open(\*JSONFILE, $jsonFile)) {
|
|
1136
|
-
binmode JSONFILE;
|
|
1137
|
-
require Image::ExifTool::Import;
|
|
1138
|
-
$msg = Image::ExifTool::Import::ReadJSON(\*JSONFILE, \%database, $forcePrint, $chset);
|
|
1139
|
-
close(JSONFILE);
|
|
1140
|
-
} else {
|
|
1141
|
-
$msg = "Error opening JSON file '${jsonFile}'";
|
|
1142
|
-
}
|
|
1143
|
-
$msg and Warn("$msg\n");
|
|
1144
|
-
$isWriting = 1;
|
|
1145
|
-
$csv = 'JSON';
|
|
1146
|
-
} else {
|
|
1147
|
-
$json = 1;
|
|
1148
|
-
$html = $xml = 0;
|
|
1149
|
-
$mt->Options(Duplicates => 1);
|
|
1150
|
-
require Image::ExifTool::XMP; # for FixUTF8()
|
|
1151
|
-
}
|
|
1152
|
-
next;
|
|
1153
|
-
}
|
|
1154
1132
|
/^(k|pause)$/i and $pause = 1, next;
|
|
1155
1133
|
(/^l$/ or $a eq 'long') and --$outFormat, next;
|
|
1156
1134
|
(/^L$/ or $a eq 'latin') and $mt->Options(Charset => 'Latin'), next;
|
|
@@ -1373,7 +1351,7 @@ for (;;) {
|
|
|
1373
1351
|
$tag =~ s/\ball\b/\*/ig; # replace 'all' with '*' in tag names
|
|
1374
1352
|
if (not $tagsFrom) {
|
|
1375
1353
|
push @exclude, $tag;
|
|
1376
|
-
} elsif ($tagsFrom eq '
|
|
1354
|
+
} elsif ($tagsFrom eq 'CSV') {
|
|
1377
1355
|
push @csvExclude, $tag;
|
|
1378
1356
|
} else {
|
|
1379
1357
|
push @{$setTags{$setTagsFile}}, "-$tag";
|
|
@@ -1420,11 +1398,11 @@ for (;;) {
|
|
|
1420
1398
|
} else {
|
|
1421
1399
|
# assume '-tagsFromFile @' if tags are being redirected
|
|
1422
1400
|
# and not from CSV and -tagsFromFile hasn't already been specified
|
|
1423
|
-
if (not $setTagsFile and $tagsFrom ne '
|
|
1401
|
+
if (not $setTagsFile and $tagsFrom ne 'CSV' and /(<|>)/) {
|
|
1424
1402
|
AddSetTagsFile($setTagsFile = '@');
|
|
1425
|
-
$tagsFrom = '
|
|
1403
|
+
$tagsFrom = 'File';
|
|
1426
1404
|
}
|
|
1427
|
-
if ($tagsFrom eq '
|
|
1405
|
+
if ($tagsFrom eq 'CSV') {
|
|
1428
1406
|
my $lst = s/^-// ? \@csvExclude : \@tags;
|
|
1429
1407
|
push @$lst, $_;
|
|
1430
1408
|
} elsif ($setTagsFile) {
|
|
@@ -1732,7 +1710,7 @@ if (@newValues) {
|
|
|
1732
1710
|
$saveCount = $mt->SaveNewValues();
|
|
1733
1711
|
$needSave = 0;
|
|
1734
1712
|
# insert marker to load values from CSV file now if this was the CSV file
|
|
1735
|
-
push @dynamicFiles, \$csv if $$_{SaveCount} == $
|
|
1713
|
+
push @dynamicFiles, \$csv if $$_{SaveCount} == $dbSaveCount;
|
|
1736
1714
|
}
|
|
1737
1715
|
next;
|
|
1738
1716
|
}
|
|
@@ -3262,7 +3240,7 @@ sub SetImageInfo($$$)
|
|
|
3262
3240
|
next;
|
|
3263
3241
|
} elsif (ref $dyFile eq 'SCALAR') {
|
|
3264
3242
|
# set new values from CSV or JSON database
|
|
3265
|
-
my ($f, $found, $csvTag, $tg, $
|
|
3243
|
+
my ($f, $found, $csvTag, $tg, $csvEtPrt, $csvEtVal);
|
|
3266
3244
|
undef $evalWarning;
|
|
3267
3245
|
local $SIG{'__WARN__'} = sub { $evalWarning = $_[0] };
|
|
3268
3246
|
# force UTF-8 if the database was JSON
|
|
@@ -3294,13 +3272,19 @@ sub SetImageInfo($$$)
|
|
|
3294
3272
|
}
|
|
3295
3273
|
if (@tags) {
|
|
3296
3274
|
# prepare a dummy ExifTool object to hold appropriate tags from the database
|
|
3297
|
-
$
|
|
3275
|
+
$csvEtPrt = Image::ExifTool->new unless $csvEtPrt;
|
|
3298
3276
|
foreach $csvTag (OrderedKeys($csvInfo)) {
|
|
3299
3277
|
next if $csvTag =~ /^([-_0-9A-Z]+:)*(SourceFile|Directory|FileName)$/i;
|
|
3300
3278
|
my @grps = split /:/, $csvTag;
|
|
3301
3279
|
my $name = pop @grps;
|
|
3302
|
-
unshift @grps, '
|
|
3303
|
-
|
|
3280
|
+
unshift @grps, 'All' while @grps < 2;
|
|
3281
|
+
if ($name =~ s/#$//) {
|
|
3282
|
+
# handle ValueConv tags separately
|
|
3283
|
+
$csvEtVal = Image::ExifTool->new unless $csvEtVal;
|
|
3284
|
+
$csvEtVal->FoundTag($name, $$csvInfo{$csvTag}, @grps);
|
|
3285
|
+
} else {
|
|
3286
|
+
$csvEtPrt->FoundTag($name, $$csvInfo{$csvTag}, @grps);
|
|
3287
|
+
}
|
|
3304
3288
|
}
|
|
3305
3289
|
next;
|
|
3306
3290
|
}
|
|
@@ -3337,15 +3321,20 @@ ExclMatch: foreach $exclTag (@exclTags) {
|
|
|
3337
3321
|
next if $excluded;
|
|
3338
3322
|
}
|
|
3339
3323
|
my ($rtn, $wrn) = $et->SetNewValue($csvTag, $$csvInfo{$csvTag},
|
|
3340
|
-
Protected => 1, AddValue => $
|
|
3341
|
-
ProtectSaved => $
|
|
3324
|
+
Protected => 1, AddValue => $dbAdd,
|
|
3325
|
+
ProtectSaved => $dbSaveCount);
|
|
3342
3326
|
$wrn and Warn "$wrn\n" if $verbose;
|
|
3343
3327
|
}
|
|
3344
3328
|
}
|
|
3345
3329
|
# set specified tags now
|
|
3346
|
-
if ($
|
|
3330
|
+
if ($csvEtPrt) {
|
|
3347
3331
|
my @excl = map "-$_", @csvExclude; # add back leading dashes
|
|
3348
|
-
$
|
|
3332
|
+
my $opts = { AddValue => $dbAdd, Replace => 0 };
|
|
3333
|
+
$et->SetNewValuesFromFile($csvEtPrt, $opts, @tags, @excl);
|
|
3334
|
+
if ($csvEtVal) {
|
|
3335
|
+
$$opts{Type} = 'ValueConv';
|
|
3336
|
+
$et->SetNewValuesFromFile($csvEtVal, $opts, @tags, @excl);
|
|
3337
|
+
}
|
|
3349
3338
|
}
|
|
3350
3339
|
$et->Options(Charset => $old) if $csv eq 'JSON';
|
|
3351
3340
|
unless ($found) {
|
|
@@ -5470,7 +5459,8 @@ option for more details). Note that quotes are required around this
|
|
|
5470
5459
|
argument to prevent shell redirection since it contains a C<E<lt>> symbol.
|
|
5471
5460
|
If I<DATFILE>/I<FMT> is not provided, the effect is the same as C<-TAG=>,
|
|
5472
5461
|
and the tag is simply deleted. C<+E<lt>=> or C<-E<lt>=> may also be used to
|
|
5473
|
-
add or delete specific list entries,
|
|
5462
|
+
add or delete specific list entries, to conditionally delete tags, or to
|
|
5463
|
+
shift date/time values.
|
|
5474
5464
|
|
|
5475
5465
|
=item B<-tagsFromFile> I<SRCFILE> or I<FMT>
|
|
5476
5466
|
|
|
@@ -5525,8 +5515,8 @@ destination group is specified, the information is written to the preferred
|
|
|
5525
5515
|
group. Whitespace around the C<E<gt>> or C<E<lt>> is ignored. As a
|
|
5526
5516
|
convenience, C<-tagsFromFile @> is assumed for any redirected tags which are
|
|
5527
5517
|
specified without a prior B<-tagsFromFile> option. Copied tags may also be
|
|
5528
|
-
added or deleted from a list with arguments of the
|
|
5529
|
-
E<quot>'-I<SRCTAG>+E<lt>I<DSTTAG>'E<quot> or
|
|
5518
|
+
added or deleted from a list, or conditionally deleted with arguments of the
|
|
5519
|
+
form E<quot>'-I<SRCTAG>+E<lt>I<DSTTAG>'E<quot> or
|
|
5530
5520
|
E<quot>'-I<SRCTAG>-E<lt>I<DSTTAG>'E<quot> (but see Note 5 below).
|
|
5531
5521
|
|
|
5532
5522
|
An extension of the redirection feature allows strings involving tag names
|
|
@@ -5788,12 +5778,15 @@ single command.
|
|
|
5788
5778
|
|
|
5789
5779
|
Specific tags may be imported from the CSV database by adding B<->I<TAG>
|
|
5790
5780
|
options to the command after B<-csv=>I<CSVFILE>, or excluded with
|
|
5791
|
-
B<-->I<TAG>, with exclusions taking priority. Group names and wildcards
|
|
5792
|
-
allowed,
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5781
|
+
B<-->I<TAG>, with exclusions taking priority. Group names and wildcards in
|
|
5782
|
+
tag names are allowed, but the group name must match exactly the group in
|
|
5783
|
+
the CSV file (eg. a C<XMP-dc:Subject> column in the CSV file won't match
|
|
5784
|
+
C<-XMP:Subject> on the command line. Also, tags from the CSV may be
|
|
5785
|
+
redirected and written to different tags in the target file with support for
|
|
5786
|
+
advanced-formatting expressions using the same syntax as the
|
|
5787
|
+
B<-tagsFromFile> feature. If no tags are specified, then all tags except
|
|
5788
|
+
FileName, Directory and excluded tags are imported (in the same order as the
|
|
5789
|
+
database entries).
|
|
5797
5790
|
|
|
5798
5791
|
When exporting a CSV file, the B<-g> or B<-G> option adds group names to the
|
|
5799
5792
|
tag headings. If the B<-a> option is used to allow duplicate tag names, the
|
|
@@ -5815,7 +5808,8 @@ List-type tags are stored as simple strings in a CSV file, but the B<-sep>
|
|
|
5815
5808
|
option may be used to split them back into separate items when importing.
|
|
5816
5809
|
|
|
5817
5810
|
Special feature: B<-csv>+=I<CSVFILE> may be used to add items to existing
|
|
5818
|
-
lists. This affects only list-type tags. Also applies to the
|
|
5811
|
+
lists in the file. This affects only list-type tags. Also applies to the
|
|
5812
|
+
B<-j> option.
|
|
5819
5813
|
|
|
5820
5814
|
Note that this and the B<-plot> options are fundamentally different than all
|
|
5821
5815
|
other output format options because they require information from all input
|
|
@@ -5984,18 +5978,22 @@ input JSON file may be suffixed with a C<#> to disable print conversion.
|
|
|
5984
5978
|
|
|
5985
5979
|
Specific tags may be imported from the JSON database by adding B<->I<TAG>
|
|
5986
5980
|
options to the command after B<-j=>I<JSONFILE>, or excluded with
|
|
5987
|
-
B<-->I<TAG>, with exclusions taking priority. Group names and wildcards
|
|
5988
|
-
allowed,
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
the same
|
|
5981
|
+
B<-->I<TAG>, with exclusions taking priority. Group names and wildcards in
|
|
5982
|
+
tag names are allowed, but the group name must match exactly the group in
|
|
5983
|
+
the JSON file (eg. a C<XMP-dc:Subject> entry in the JSON file won't match
|
|
5984
|
+
C<-XMP:Subject> on the command line. Also, tags from JSON may be redirected
|
|
5985
|
+
and written to different tags in the target file with support for
|
|
5986
|
+
advanced-formatting expressions using the same syntax as the
|
|
5987
|
+
B<-tagsFromFile> feature. If no tags are specified, then all tags except
|
|
5988
|
+
FileName, Directory and excluded tags are imported (in the same order as the
|
|
5989
|
+
database entries).
|
|
5993
5990
|
|
|
5994
5991
|
Unlike CSV import, empty values are not ignored, and will cause an empty
|
|
5995
5992
|
value to be written if supported by the specific metadata type. Tags are
|
|
5996
5993
|
deleted by using the B<-f> option and setting the tag value to "-" (or to
|
|
5997
5994
|
the MissingTagValue setting if this API option was used). Importing with
|
|
5998
|
-
B<-j>+=I<JSONFILE> causes new values to be added to existing lists
|
|
5995
|
+
B<-j>+=I<JSONFILE> causes new values to be added to existing lists in the
|
|
5996
|
+
target file.
|
|
5999
5997
|
|
|
6000
5998
|
=item B<-l> (B<-long>)
|
|
6001
5999
|
|
|
@@ -6130,7 +6128,7 @@ with this command:
|
|
|
6130
6128
|
|
|
6131
6129
|
produces output like this:
|
|
6132
6130
|
|
|
6133
|
-
-- Generated by ExifTool 13.
|
|
6131
|
+
-- Generated by ExifTool 13.43 --
|
|
6134
6132
|
File: a.jpg - 2003:10:31 15:44:19
|
|
6135
6133
|
(f/5.6, 1/60s, ISO 100)
|
|
6136
6134
|
File: b.jpg - 2006:05:23 11:57:38
|
|
@@ -7379,6 +7377,10 @@ expression is empty (ie. C<${TAG;}>). This removes the characters / \ ? * :
|
|
|
7379
7377
|
illegal in Windows file names, so this feature is useful if tag values are
|
|
7380
7378
|
used in file names.)
|
|
7381
7379
|
|
|
7380
|
+
Note that the expression is not evaluated for undefined (non-existant) tags,
|
|
7381
|
+
which may have other values if either the B<-m> or B<-f> command-line option
|
|
7382
|
+
or the API MissingTagValue option is used.
|
|
7383
|
+
|
|
7382
7384
|
=head4 Helper functions
|
|
7383
7385
|
|
|
7384
7386
|
Note that function names are case sensitive.
|
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
|
88
88
|
sub ProcessExifInfo($$$);
|
|
89
89
|
sub SwapWords($);
|
|
90
90
|
|
|
91
|
-
$VERSION = '
|
|
91
|
+
$VERSION = '5.00';
|
|
92
92
|
|
|
93
93
|
# Note: Removed 'USM' from 'L' lenses since it is redundant - PH
|
|
94
94
|
# (or is it? Ref 32 shows 5 non-USM L-type lenses)
|
|
@@ -492,6 +492,7 @@ $VERSION = '4.98';
|
|
|
492
492
|
'368.12' => 'Sigma 18-35mm f/1.8 DC HSM | A', #50
|
|
493
493
|
'368.13' => 'Sigma 24-105mm f/4 DG OS HSM | A', #forum3833
|
|
494
494
|
'368.14' => 'Sigma 18-300mm f/3.5-6.3 DC Macro OS HSM | C', #forum15280 (014)
|
|
495
|
+
'368.15' => 'Sigma 24mm F1.4 DG HSM | A', #50 (015)
|
|
495
496
|
# Note: LensType 488 (0x1e8) is reported as 232 (0xe8) in 7D CameraSettings
|
|
496
497
|
488 => 'Canon EF-S 15-85mm f/3.5-5.6 IS USM', #PH
|
|
497
498
|
489 => 'Canon EF 70-300mm f/4-5.6L IS USM', #Gerald Kapounek
|
|
@@ -643,6 +644,7 @@ $VERSION = '4.98';
|
|
|
643
644
|
'61182.63' => 'Canon RF 24mm F1.4 L VCM', #42
|
|
644
645
|
'61182.64' => 'Canon RF 20mm F1.4 L VCM', #42
|
|
645
646
|
'61182.65' => 'Canon RF 85mm F1.4 L VCM', #github350
|
|
647
|
+
'61182.66' => 'Canon RF 45mm F1.2 STM', #42
|
|
646
648
|
65535 => 'n/a',
|
|
647
649
|
);
|
|
648
650
|
|
|
@@ -1009,10 +1011,11 @@ $VERSION = '4.98';
|
|
|
1009
1011
|
0x80000487 => 'EOS R8', #42
|
|
1010
1012
|
0x80000491 => 'PowerShot V10', #25
|
|
1011
1013
|
0x80000495 => 'EOS R1', #PH
|
|
1012
|
-
0x80000496 => 'R5 Mark II', #forum16406
|
|
1014
|
+
0x80000496 => 'EOS R5 Mark II', #forum16406
|
|
1013
1015
|
0x80000497 => 'PowerShot V1', #PH
|
|
1014
1016
|
0x80000498 => 'EOS R100', #25
|
|
1015
1017
|
0x80000516 => 'EOS R50 V', #42
|
|
1018
|
+
0x80000518 => 'EOS R6 Mark III', #42
|
|
1016
1019
|
0x80000520 => 'EOS D2000C', #IB
|
|
1017
1020
|
0x80000560 => 'EOS D6000C', #PH (guess)
|
|
1018
1021
|
);
|
|
@@ -1421,6 +1424,11 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
|
|
|
1421
1424
|
Condition => '$$self{Model} =~ /\bEOS (R6m2|R8|R50)$/',
|
|
1422
1425
|
SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoR6m2' },
|
|
1423
1426
|
},
|
|
1427
|
+
{
|
|
1428
|
+
Name => 'CanonCameraInfoR6m3',
|
|
1429
|
+
Condition => '$$self{Model} =~ /\bEOS R6 Mark III$/',
|
|
1430
|
+
SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoR6m3' },
|
|
1431
|
+
},
|
|
1424
1432
|
{
|
|
1425
1433
|
Name => 'CanonCameraInfoG5XII',
|
|
1426
1434
|
Condition => '$$self{Model} =~ /\bG5 X Mark II$/',
|
|
@@ -4792,6 +4800,22 @@ my %ciMaxFocal = (
|
|
|
4792
4800
|
},
|
|
4793
4801
|
);
|
|
4794
4802
|
|
|
4803
|
+
%Image::ExifTool::Canon::CameraInfoR6m3 = (
|
|
4804
|
+
%binaryDataAttrs,
|
|
4805
|
+
FIRST_ENTRY => 0,
|
|
4806
|
+
PRIORITY => 0,
|
|
4807
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
|
|
4808
|
+
NOTES => 'CameraInfo tags for the EOS R6 Mark II.',
|
|
4809
|
+
0x086d => { #forum17745
|
|
4810
|
+
Name => 'ShutterCount',
|
|
4811
|
+
Format => 'int32u',
|
|
4812
|
+
# (upper 2 bytes are currently unknown for this tag in JPEG images --
|
|
4813
|
+
# we need samples ideally spanning the 65536 count)
|
|
4814
|
+
RawConv => '$$self{PATH}[2] eq "UUID-Canon" ? $val : $val & 0xffff',
|
|
4815
|
+
Notes => 'includes electronic + mechanical shutter',
|
|
4816
|
+
},
|
|
4817
|
+
);
|
|
4818
|
+
|
|
4795
4819
|
# ref https://exiftool.org/forum/index.php?topic=15356.0
|
|
4796
4820
|
%Image::ExifTool::Canon::CameraInfoG5XII = (
|
|
4797
4821
|
%binaryDataAttrs,
|
|
@@ -7053,6 +7077,7 @@ my %ciMaxFocal = (
|
|
|
7053
7077
|
326 => 'Canon RF 24mm F1.4 L VCM', #42
|
|
7054
7078
|
327 => 'Canon RF 20mm F1.4 L VCM', #42
|
|
7055
7079
|
328 => 'Canon RF 85mm F1.4 L VCM', #42/github350
|
|
7080
|
+
330 => 'Canon RF 45mm F1.2 STM', #42
|
|
7056
7081
|
# Note: add new RF lenses to %canonLensTypes with ID 61182
|
|
7057
7082
|
},
|
|
7058
7083
|
},
|
|
@@ -14,9 +14,9 @@ use vars qw($VERSION);
|
|
|
14
14
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
15
15
|
use Image::ExifTool::Import;
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.11';
|
|
18
18
|
|
|
19
|
-
sub ProcessJSON(
|
|
19
|
+
sub ProcessJSON($$;$);
|
|
20
20
|
sub ProcessTag($$$$%);
|
|
21
21
|
|
|
22
22
|
%Image::ExifTool::JSON::Main = (
|
|
@@ -71,6 +71,7 @@ sub FoundTag($$$$%)
|
|
|
71
71
|
$name = Image::ExifTool::MakeTagName($name);
|
|
72
72
|
my $desc = Image::ExifTool::MakeDescription($name);
|
|
73
73
|
$desc =~ s/^C2 PA/C2PA/; # hack to get "C2PA" correct
|
|
74
|
+
$et->VPrint(0, $$et{INDENT}, "[adding $tag]\n");
|
|
74
75
|
AddTagToTable($tagTablePtr, $tag, {
|
|
75
76
|
Name => $name,
|
|
76
77
|
Description => $desc,
|
|
@@ -112,12 +113,12 @@ sub ProcessTag($$$$%)
|
|
|
112
113
|
|
|
113
114
|
#------------------------------------------------------------------------------
|
|
114
115
|
# Extract meta information from a JSON file
|
|
115
|
-
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
|
116
|
+
# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) tag table ref
|
|
116
117
|
# Returns: 1 on success, 0 if this wasn't a recognized JSON file
|
|
117
|
-
sub ProcessJSON(
|
|
118
|
+
sub ProcessJSON($$;$)
|
|
118
119
|
{
|
|
119
120
|
local $_;
|
|
120
|
-
my ($et, $dirInfo) = @_;
|
|
121
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
|
121
122
|
my $raf = $$dirInfo{RAF};
|
|
122
123
|
my $structOpt = $et->Options('Struct');
|
|
123
124
|
my (%database, $key, $tag, $dataPt);
|
|
@@ -149,7 +150,7 @@ sub ProcessJSON($$)
|
|
|
149
150
|
|
|
150
151
|
$et->SetFileType() unless $dataPt;
|
|
151
152
|
|
|
152
|
-
|
|
153
|
+
$tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::JSON::Main');
|
|
153
154
|
|
|
154
155
|
# remove any old tag definitions in case they change flags
|
|
155
156
|
foreach $key (TagTableKeys($tagTablePtr)) {
|
|
@@ -37,7 +37,7 @@ use vars qw($VERSION %leicaLensTypes);
|
|
|
37
37
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
38
38
|
use Image::ExifTool::Exif;
|
|
39
39
|
|
|
40
|
-
$VERSION = '2.
|
|
40
|
+
$VERSION = '2.27';
|
|
41
41
|
|
|
42
42
|
sub ProcessLeicaLEIC($$$);
|
|
43
43
|
sub WhiteBalanceConv($;$$);
|
|
@@ -916,13 +916,21 @@ my %shootingMode = (
|
|
|
916
916
|
Name => 'AFPointPosition',
|
|
917
917
|
Writable => 'rational64u',
|
|
918
918
|
Count => 2,
|
|
919
|
-
Notes =>
|
|
919
|
+
Notes => q{
|
|
920
|
+
X Y coordinates of primary AF area center, in the range 0.0 to 1.0, or
|
|
921
|
+
"n/a" or "none" for invalid values
|
|
922
|
+
},
|
|
920
923
|
PrintConv => q{
|
|
921
924
|
return 'none' if $val eq '16777216 16777216';
|
|
925
|
+
return 'n/a' if $val =~ /^4194303\.9/;
|
|
922
926
|
my @a = split ' ', $val;
|
|
923
927
|
sprintf("%.2g %.2g",@a);
|
|
924
928
|
},
|
|
925
|
-
PrintConvInv =>
|
|
929
|
+
PrintConvInv => q{
|
|
930
|
+
return '16777216 16777216' if $val eq 'none';
|
|
931
|
+
return '4294967295/1024 4294967295/1024' if $val eq 'n/a';
|
|
932
|
+
return $val;
|
|
933
|
+
},
|
|
926
934
|
},
|
|
927
935
|
0x4e => { #PH
|
|
928
936
|
Name => 'FaceDetInfo',
|
|
@@ -1441,8 +1449,8 @@ my %shootingMode = (
|
|
|
1441
1449
|
Writable => 'rational64u',
|
|
1442
1450
|
Notes => 'relative to size of image. "n/a" for manual focus',
|
|
1443
1451
|
Count => 2,
|
|
1444
|
-
PrintConv => '$val =~ /^4194303
|
|
1445
|
-
PrintConvInv => '$val eq "n/a" ? "
|
|
1452
|
+
PrintConv => '$val =~ /^4194303\.9/ ? "n/a" : $val',
|
|
1453
|
+
PrintConvInv => '$val eq "n/a" ? "4294967295/1024 4294967295/1024" : $val',
|
|
1446
1454
|
},
|
|
1447
1455
|
0xe4 => { #IB
|
|
1448
1456
|
Name => 'LensTypeModel',
|