exiftool_vendored 13.38.0 → 13.41.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.
data/bin/exiftool CHANGED
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '13.38';
14
+ my $version = '13.41';
15
15
 
16
16
  $^W = 1; # enable global warnings
17
17
 
@@ -97,6 +97,7 @@ END {
97
97
  # declare all static file-scope variables
98
98
  my @commonArgs; # arguments common to all commands
99
99
  my @condition; # conditional processing of files
100
+ my @csvExclude; # list of tags excluded from CSV import
100
101
  my @csvFiles; # list of files when reading with CSV option (in ExifTool Charset)
101
102
  my @csvTags; # order of tags for first file with CSV option (lower case)
102
103
  my @delFiles; # list of files to delete
@@ -441,6 +442,7 @@ if ($stayOpen >= 2) {
441
442
  # (not done: @commonArgs, @moreArgs, $critical, $binaryStdout, $helped,
442
443
  # $interrupted, $mt, $pause, $rtnValApp, $rtnValPrev, $stayOpen, $stayOpenBuff, $stayOpenFile)
443
444
  undef @condition;
445
+ undef @csvExclude;
444
446
  undef @csvFiles;
445
447
  undef @csvTags;
446
448
  undef @delFiles;
@@ -578,6 +580,7 @@ my $escapeXML; # flag to escape printed values for xml
578
580
  my $setTagsFile; # filename for last TagsFromFile option
579
581
  my $sortOpt; # sort option is used
580
582
  my $srcStdin; # one of the source files is STDIN
583
+ my $tagsFrom = ''; # tags on command line come from 'csv' or 'file'
581
584
  my $useMWG; # flag set if we are using any MWG tag
582
585
 
583
586
  my ($argsLeft, @nextPass, $badCmd);
@@ -812,6 +815,7 @@ for (;;) {
812
815
  }
813
816
  # create necessary lists, etc for this new -tagsFromFile file
814
817
  AddSetTagsFile($setTagsFile, { Replace => ($1 and lc($1) eq 'add') ? 0 : 1 } );
818
+ $tagsFrom = 'file';
815
819
  next;
816
820
  }
817
821
  if ($a eq '@') {
@@ -927,6 +931,7 @@ for (;;) {
927
931
  if ($csvFile) {
928
932
  push @newValues, { SaveCount => ++$saveCount }; # marker to save new values now
929
933
  $csvSaveCount = $saveCount;
934
+ $tagsFrom = 'csv';
930
935
  }
931
936
  next;
932
937
  }
@@ -1117,6 +1122,7 @@ for (;;) {
1117
1122
  push @nextPass, "-$_";
1118
1123
  push @newValues, { SaveCount => ++$saveCount }; # marker to save new values now
1119
1124
  $csvSaveCount = $saveCount;
1125
+ $tagsFrom = 'csv';
1120
1126
  next;
1121
1127
  }
1122
1128
  my $jsonFile = $2;
@@ -1365,10 +1371,12 @@ for (;;) {
1365
1371
  my $tag = shift;
1366
1372
  defined $tag or Error("Expecting tag name for -x option\n"), $badCmd=1, next;
1367
1373
  $tag =~ s/\ball\b/\*/ig; # replace 'all' with '*' in tag names
1368
- if ($setTagsFile) {
1369
- push @{$setTags{$setTagsFile}}, "-$tag";
1370
- } else {
1374
+ if (not $tagsFrom) {
1371
1375
  push @exclude, $tag;
1376
+ } elsif ($tagsFrom eq 'csv') {
1377
+ push @csvExclude, $tag;
1378
+ } else {
1379
+ push @{$setTags{$setTagsFile}}, "-$tag";
1372
1380
  }
1373
1381
  next;
1374
1382
  }
@@ -1411,9 +1419,15 @@ for (;;) {
1411
1419
  }
1412
1420
  } else {
1413
1421
  # assume '-tagsFromFile @' if tags are being redirected
1414
- # and -tagsFromFile hasn't already been specified
1415
- AddSetTagsFile($setTagsFile = '@') if not $setTagsFile and /(<|>)/;
1416
- if ($setTagsFile) {
1422
+ # and not from CSV and -tagsFromFile hasn't already been specified
1423
+ if (not $setTagsFile and $tagsFrom ne 'csv' and /(<|>)/) {
1424
+ AddSetTagsFile($setTagsFile = '@');
1425
+ $tagsFrom = 'file';
1426
+ }
1427
+ if ($tagsFrom eq 'csv') {
1428
+ my $lst = s/^-// ? \@csvExclude : \@tags;
1429
+ push @$lst, $_;
1430
+ } elsif ($setTagsFile) {
1417
1431
  push @{$setTags{$setTagsFile}}, $_;
1418
1432
  if ($1 eq '>') {
1419
1433
  $useMWG = 1 if /^(.*>\s*)?([-_0-9A-Z]+:)*1?mwg:/si;
@@ -1794,11 +1808,9 @@ if (@newValues) {
1794
1808
  $wrn and Warning($mt, $wrn);
1795
1809
  }
1796
1810
  # exclude specified tags
1797
- unless ($csv) {
1798
- foreach (@exclude) {
1799
- $mt->SetNewValue($_, undef, Replace => 2);
1800
- $needSave = 1;
1801
- }
1811
+ foreach (@exclude) {
1812
+ $mt->SetNewValue($_, undef, Replace => 2);
1813
+ $needSave = 1;
1802
1814
  }
1803
1815
  unless ($isWriting or $outOpt or @tags) {
1804
1816
  Error "Nothing to do.\n";
@@ -1935,7 +1947,7 @@ if (@fileOrder) {
1935
1947
  # set file count for progress message
1936
1948
  $progressMax = scalar @files if defined $progress;
1937
1949
 
1938
- # store duplicate database information under absolute path
1950
+ # store duplicate database information under absolute path and with standardized case
1939
1951
  my @dbKeys = keys %database;
1940
1952
  if (@dbKeys) {
1941
1953
  if (eval { require Cwd }) {
@@ -1944,6 +1956,7 @@ if (@dbKeys) {
1944
1956
  foreach (@dbKeys) {
1945
1957
  my $db = $database{$_};
1946
1958
  tr/\\/\// and $database{$_} = $db; # allow for backslashes in SourceFile
1959
+ $database{lc} = $db unless $database{lc}; # duplicate entry with lower case
1947
1960
  # (punt on using ConvertFileName here, so $absPath may be a mix of encodings)
1948
1961
  my $absPath = AbsPath($_);
1949
1962
  if (defined $absPath) {
@@ -1951,6 +1964,7 @@ if (@dbKeys) {
1951
1964
  if ($verbose and $verbose > 1) {
1952
1965
  print $vout "Imported entry for '${_}' (full path: '${absPath}')\n";
1953
1966
  }
1967
+ $database{lc $absPath} = $db unless $database{lc $absPath};
1954
1968
  } elsif ($verbose and $verbose > 1) {
1955
1969
  print $vout "Imported entry for '${_}' (no full path)\n";
1956
1970
  }
@@ -3248,7 +3262,7 @@ sub SetImageInfo($$$)
3248
3262
  next;
3249
3263
  } elsif (ref $dyFile eq 'SCALAR') {
3250
3264
  # set new values from CSV or JSON database
3251
- my ($f, $found, $csvTag, $tryTag, $tg);
3265
+ my ($f, $found, $csvTag, $tg, $csvExifTool);
3252
3266
  undef $evalWarning;
3253
3267
  local $SIG{'__WARN__'} = sub { $evalWarning = $_[0] };
3254
3268
  # force UTF-8 if the database was JSON
@@ -3259,48 +3273,68 @@ sub SetImageInfo($$$)
3259
3273
  my $csvInfo = $database{$f};
3260
3274
  unless ($csvInfo) {
3261
3275
  next if $f eq '*';
3262
- # check absolute path
3276
+ # check absolute path and case-insensitive name
3263
3277
  # (punt on using ConvertFileName here, so $absPath may be a mix of encodings)
3264
3278
  my $absPath = AbsPath($f);
3265
- next unless defined $absPath and $csvInfo = $database{$absPath};
3279
+ if (defined $absPath and $database{$absPath}) {
3280
+ $csvInfo = $database{$absPath};
3281
+ } elsif ($database{lc $f}) {
3282
+ $csvInfo = $database{lc $f};
3283
+ } elsif (defined $absPath and $database{lc $absPath}) {
3284
+ $csvInfo = $database{lc $absPath};
3285
+ } else {
3286
+ next;
3287
+ }
3266
3288
  }
3267
3289
  $found = 1;
3268
3290
  if ($verbose) {
3269
3291
  print $vout "Setting new values from $csv database\n";
3270
3292
  print $vout 'Including tags: ',join(' ',@tags),"\n" if @tags;
3271
- print $vout 'Excluding tags: ',join(' ',@exclude),"\n" if @exclude;
3293
+ print $vout 'Excluding tags: ',join(' ',@csvExclude),"\n" if @csvExclude;
3272
3294
  }
3273
- my @tryTags = (@exclude, @tags); # (exclude first because it takes priority)
3274
- foreach (@tryTags) {
3295
+ if (@tags) {
3296
+ # prepare a dummy ExifTool object to hold appropriate tags from the database
3297
+ $csvExifTool = Image::ExifTool->new unless $csvExifTool;
3298
+ foreach $csvTag (OrderedKeys($csvInfo)) {
3299
+ next if $csvTag =~ /^([-_0-9A-Z]+:)*(SourceFile|Directory|FileName)$/i;
3300
+ my @grps = split /:/, $csvTag;
3301
+ my $name = pop @grps;
3302
+ unshift @grps, 'Unknown' while @grps < 2;
3303
+ $csvExifTool->FoundTag($name, $$csvInfo{$csvTag}, @grps);
3304
+ }
3305
+ next;
3306
+ }
3307
+ my @exclTags = @csvExclude;
3308
+ foreach (@exclTags) {
3275
3309
  tr/-0-9a-zA-Z_:#?*//dc; # remove illegal characters
3276
3310
  s/(^|:)(all:)+/$1/ig; # remove 'all' group names
3277
3311
  s/(^|:)all(#?)$/$1*$2/i; # convert 'all' tag name to '*'
3278
3312
  tr/?/./; s/\*/.*/g; # convert wildcards for regex
3279
3313
  }
3314
+ # run through tags in database order
3280
3315
  foreach $csvTag (OrderedKeys($csvInfo)) {
3281
3316
  # don't write SourceFile, Directory or FileName
3282
3317
  next if $csvTag =~ /^([-_0-9A-Z]+:)*(SourceFile|Directory|FileName)$/i;
3283
- if (@tryTags) {
3284
- my ($i, $tryGrp, $matched);
3285
- TryMatch: for ($i=0; $i<@tryTags; ++$i) {
3286
- $tryTag = $tryTags[$i];
3287
- if ($tryTag =~ /:/) {
3318
+ if (@exclTags) {
3319
+ my ($exclTag, $exclGrp, $excluded);
3320
+ ExclMatch: foreach $exclTag (@exclTags) {
3321
+ if ($exclTag =~ /:/) {
3288
3322
  next unless $csvTag =~ /:/; # db entry must also specify group
3289
3323
  my @csvGrps = split /:/, $csvTag;
3290
- my @tryGrps = split /:/, $tryTag;
3291
- my $tryName = pop @tryGrps;
3292
- next unless pop(@csvGrps) =~ /^$tryName$/i; # tag name must match
3293
- foreach $tryGrp (@tryGrps) {
3324
+ my @exclGrps = split /:/, $exclTag;
3325
+ my $exclName = pop @exclGrps;
3326
+ next unless pop(@csvGrps) =~ /^$exclName$/i; # tag name must match
3327
+ foreach $exclGrp (@exclGrps) {
3294
3328
  # each specified group name must match db entry
3295
- next TryMatch unless grep /^$tryGrp$/i, @csvGrps;
3329
+ next ExclMatch unless grep /^$exclGrp$/i, @csvGrps;
3296
3330
  }
3297
- $matched = 1;
3331
+ $excluded = 1;
3298
3332
  last;
3299
3333
  }
3300
3334
  # no group specified, so match by tag name only
3301
- $csvTag =~ /^([-_0-9A-Z]+:)*$tryTag$/i and $matched = 1, last;
3335
+ $csvTag =~ /^([-_0-9A-Z]+:)*$exclTag$/i and $excluded = 1, last;
3302
3336
  }
3303
- next if $matched ? $i < @exclude : @tags;
3337
+ next if $excluded;
3304
3338
  }
3305
3339
  my ($rtn, $wrn) = $et->SetNewValue($csvTag, $$csvInfo{$csvTag},
3306
3340
  Protected => 1, AddValue => $csvAdd,
@@ -3308,6 +3342,11 @@ TryMatch: for ($i=0; $i<@tryTags; ++$i) {
3308
3342
  $wrn and Warn "$wrn\n" if $verbose;
3309
3343
  }
3310
3344
  }
3345
+ # set specified tags now
3346
+ if ($csvExifTool) {
3347
+ my @excl = map "-$_", @csvExclude; # add back leading dashes
3348
+ $et->SetNewValuesFromFile($csvExifTool, @tags, @excl);
3349
+ }
3311
3350
  $et->Options(Charset => $old) if $csv eq 'JSON';
3312
3351
  unless ($found) {
3313
3352
  Warn("No SourceFile '${file}' in imported $csv database\n");
@@ -5079,51 +5118,52 @@ supported by ExifTool (r = read, w = write, c = create):
5079
5118
 
5080
5119
  File Types
5081
5120
  ------------+-------------+-------------+-------------+------------
5082
- 360 r/w | DPX r | J2C r | O r | RIFF r
5083
- 3FR r | DR4 r/w/c | JNG r/w | ODP r | RSRC r
5084
- 3G2 r/w | DSF r | JP2 r/w | ODS r | RTF r
5085
- 3GP r/w | DSS r | JPEG r/w | ODT r | RW2 r/w
5086
- 7Z r | DV r | JSON r | OFR r | RWL r/w
5087
- A r | DVB r/w | JXL r/w | OGG r | RWZ r
5088
- AA r | DVR-MS r | K25 r | OGV r | RM r
5089
- AAC r | DYLIB r | KDC r | ONP r | SEQ r
5090
- AAE r | EIP r | KEY r | OPUS r | SKETCH r
5091
- AAX r/w | EPS r/w | LA r | ORF r/w | SO r
5092
- ACR r | EPUB r | LFP r | ORI r/w | SR2 r/w
5093
- AFM r | ERF r/w | LIF r | OTF r | SRF r
5094
- AI r/w | EXE r | LNK r | PAC r | SRW r/w
5095
- AIFF r | EXIF r/w/c | LRV r/w | PAGES r | SVG r
5096
- APE r | EXR r | M2TS r | PBM r/w | SWF r
5097
- ARQ r/w | EXV r/w/c | M4A/V r/w | PCAP r | THM r/w
5098
- ARW r/w | F4A/V r/w | MACOS r | PCAPNG r | TIFF r/w
5099
- ASF r | FFF r/w | MAX r | PCD r | TNEF r
5100
- AVI r | FITS r | MEF r/w | PCX r | TORRENT r
5101
- AVIF r/w | FLA r | MIE r/w/c | PDB r | TTC r
5102
- AZW r | FLAC r | MIFF r | PDF r/w | TTF r
5103
- BMP r | FLIF r/w | MKA r | PEF r/w | TXT r
5104
- BPG r | FLV r | MKS r | PFA r | VCF r
5105
- BTF r | FPF r | MKV r | PFB r | VNT r
5106
- C2PA r | FPX r | MNG r/w | PFM r | VRD r/w/c
5107
- CHM r | GIF r/w | MOBI r | PGF r | VSD r
5108
- COS r | GLV r/w | MODD r | PGM r/w | WAV r
5109
- CR2 r/w | GPR r/w | MOI r | PLIST r | WDP r/w
5110
- CR3 r/w | GZ r | MOS r/w | PICT r | WEBP r/w
5111
- CRM r/w | HDP r/w | MOV r/w | PMP r | WEBM r
5112
- CRW r/w | HDR r | MP3 r | PNG r/w | WMA r
5113
- CS1 r/w | HEIC r/w | MP4 r/w | PPM r/w | WMV r
5114
- CSV r | HEIF r/w | MPC r | PPT r | WPG r
5115
- CUR r | HTML r | MPG r | PPTX r | WTV r
5116
- CZI r | ICC r/w/c | MPO r/w | PS r/w | WV r
5117
- DCM r | ICO r | MQV r/w | PSB r/w | X3F r/w
5118
- DCP r/w | ICS r | MRC r | PSD r/w | XCF r
5119
- DCR r | IDML r | MRW r/w | PSP r | XISF r
5120
- DFONT r | IIQ r/w | MXF r | QTIF r/w | XLS r
5121
- DIVX r | IND r/w | NEF r/w | R3D r | XLSX r
5122
- DJVU r | INSP r/w | NKA r | RA r | XMP r/w/c
5123
- DLL r | INSV r | NKSC r/w | RAF r/w | ZIP r
5124
- DNG r/w | INX r | NRW r/w | RAM r |
5125
- DOC r | ISO r | NUMBERS r | RAR r |
5126
- DOCX r | ITC r | NXD r | RAW r/w |
5121
+ 360 r/w | DR4 r/w/c | JP2 r/w | ODT r | RWL r/w
5122
+ 3FR r | DSF r | JPEG r/w | OFR r | RWZ r
5123
+ 3G2 r/w | DSS r | JSON r | OGG r | RM r
5124
+ 3GP r/w | DV r | JXL r/w | OGV r | SEQ r
5125
+ 7Z r | DVB r/w | K25 r | ONP r | SKETCH r
5126
+ A r | DVR-MS r | KDC r | OPUS r | SO r
5127
+ AA r | DYLIB r | KEY r | ORF r/w | SR2 r/w
5128
+ AAC r | EIP r | LA r | ORI r/w | SRF r
5129
+ AAE r | EPS r/w | LFP r | OTF r | SRW r/w
5130
+ AAX r/w | EPUB r | LIF r | PAC r | SVG r
5131
+ ACR r | ERF r/w | LNK r | PAGES r | SWF r
5132
+ AFM r | EXE r | LRV r/w | PBM r/w | THM r/w
5133
+ AI r/w | EXIF r/w/c | M2TS r | PCAP r | TIFF r/w
5134
+ AIFF r | EXR r | M4A/V r/w | PCAPNG r | TNEF r
5135
+ APE r | EXV r/w/c | MACOS r | PCD r | TORRENT r
5136
+ ARQ r/w | F4A/V r/w | MAX r | PCX r | TTC r
5137
+ ARW r/w | FFF r/w | MEF r/w | PDB r | TTF r
5138
+ ASF r | FITS r | MIE r/w/c | PDF r/w | TXT r
5139
+ AVI r | FLA r | MIFF r | PEF r/w | URL r
5140
+ AVIF r/w | FLAC r | MKA r | PFA r | VCF r
5141
+ AZW r | FLIF r/w | MKS r | PFB r | VNT r
5142
+ BMP r | FLV r | MKV r | PFM r | VRD r/w/c
5143
+ BPG r | FPF r | MNG r/w | PGF r | VSD r
5144
+ BTF r | FPX r | MOBI r | PGM r/w | VSDX r
5145
+ C2PA r | GIF r/w | MODD r | PLIST r | WAV r
5146
+ CHM r | GLV r/w | MOI r | PICT r | WDP r/w
5147
+ COS r | GPR r/w | MOS r/w | PMP r | WEBP r/w
5148
+ CR2 r/w | GZ r | MOV r/w | PNG r/w | WEBM r
5149
+ CR3 r/w | HDP r/w | MP3 r | PPM r/w | WMA r
5150
+ CRM r/w | HDR r | MP4 r/w | PPT r | WMV r
5151
+ CRW r/w | HEIC r/w | MPC r | PPTX r | WOFF r
5152
+ CS1 r/w | HEIF r/w | MPG r | PS r/w | WOFF2 r
5153
+ CSV r | HTML r | MPO r/w | PSB r/w | WPG r
5154
+ CUR r | ICC r/w/c | MQV r/w | PSD r/w | WTV r
5155
+ CZI r | ICO r | MRC r | PSP r | WV r
5156
+ DCM r | ICS r | MRW r/w | QTIF r/w | X3F r/w
5157
+ DCP r/w | IDML r | MXF r | R3D r | XCF r
5158
+ DCR r | IIQ r/w | NEF r/w | RA r | XISF r
5159
+ DFONT r | IND r/w | NKA r | RAF r/w | XLS r
5160
+ DIVX r | INSP r/w | NKSC r/w | RAM r | XLSX r
5161
+ DJVU r | INSV r | NRW r/w | RAR r | XMP r/w/c
5162
+ DLL r | INX r | NUMBERS r | RAW r/w | ZIP r
5163
+ DNG r/w | ISO r | NXD r | RIFF r |
5164
+ DOC r | ITC r | O r | RSRC r |
5165
+ DOCX r | J2C r | ODP r | RTF r |
5166
+ DPX r | JNG r/w | ODS r | RW2 r/w |
5127
5167
 
5128
5168
  Meta Information
5129
5169
  ----------------------+----------------------+---------------------
@@ -5747,10 +5787,13 @@ if this API option was used). Multiple databases may be imported in a
5747
5787
  single command.
5748
5788
 
5749
5789
  Specific tags may be imported from the CSV database by adding B<->I<TAG>
5750
- options to the command, or excluded with B<-->I<TAG>, with exclusions taking
5751
- priority. Group names and wildcards are allowed. If no tags are specified,
5752
- then all except FileName and Directory are used. Tags are imported in the
5753
- same order as the database entries.
5790
+ options to the command after B<-csv=>I<CSVFILE>, or excluded with
5791
+ B<-->I<TAG>, with exclusions taking priority. Group names and wildcards are
5792
+ allowed, and tags from the CSV may be redirected and written to different
5793
+ tags in the target file with support for advanced-formatting expressions
5794
+ using the same syntax as the B<-tagsFromFile> feature. If no tags are
5795
+ specified, then all tags except FileName, Directory and excluded tags are
5796
+ imported (in the same order as the database entries).
5754
5797
 
5755
5798
  When exporting a CSV file, the B<-g> or B<-G> option adds group names to the
5756
5799
  tag headings. If the B<-a> option is used to allow duplicate tag names, the
@@ -5940,10 +5983,13 @@ compatible, and use B<-G> instead of B<-g>). Additionally, tag names in the
5940
5983
  input JSON file may be suffixed with a C<#> to disable print conversion.
5941
5984
 
5942
5985
  Specific tags may be imported from the JSON database by adding B<->I<TAG>
5943
- options to the command, or excluded with B<-->I<TAG>, with exclusions taking
5944
- priority. Group names and wildcards are allowed. If no tags are specified,
5945
- then all except FileName and Directory are used. Tags are imported in the
5946
- same order as the database entries.
5986
+ options to the command after B<-j=>I<JSONFILE>, or excluded with
5987
+ B<-->I<TAG>, with exclusions taking priority. Group names and wildcards are
5988
+ allowed, and tags from JSON may be redirected and written to different tags
5989
+ in the target file with support for advanced-formatting expressions using
5990
+ the same syntax as the B<-tagsFromFile> feature. If no tags are specified,
5991
+ then all tags except FileName, Directory and excluded tags are imported (in
5992
+ the same order as the database entries).
5947
5993
 
5948
5994
  Unlike CSV import, empty values are not ignored, and will cause an empty
5949
5995
  value to be written if supported by the specific metadata type. Tags are
@@ -6084,7 +6130,7 @@ with this command:
6084
6130
 
6085
6131
  produces output like this:
6086
6132
 
6087
- -- Generated by ExifTool 13.38 --
6133
+ -- Generated by ExifTool 13.41 --
6088
6134
  File: a.jpg - 2003:10:31 15:44:19
6089
6135
  (f/5.6, 1/60s, ISO 100)
6090
6136
  File: b.jpg - 2006:05:23 11:57:38
@@ -7337,7 +7383,7 @@ used in file names.)
7337
7383
 
7338
7384
  Note that function names are case sensitive.
7339
7385
 
7340
- C<DateFmt>
7386
+ B<C<DateFmt>>
7341
7387
 
7342
7388
  Simplifies reformatting of individual date/time values. This function acts
7343
7389
  on a standard EXIF-formatted date/time value in C<$_> and formats it
@@ -7348,7 +7394,7 @@ used. For example:
7348
7394
 
7349
7395
  exiftool -p '${createdate#;DateFmt("%Y-%m-%d_%H%M%S")}' a.jpg
7350
7396
 
7351
- C<ShiftTime>
7397
+ B<C<ShiftTime>>
7352
7398
 
7353
7399
  Shifts EXIF-formatted date/time string by a specified amount. Start with a
7354
7400
  leading minus sign to shift backwards in time. See
@@ -7357,7 +7403,7 @@ shift syntax. For example, to shift a date/time value back by one year:
7357
7403
 
7358
7404
  exiftool -p '${createdate;ShiftTime("-1:0:0 0")}' a.jpg
7359
7405
 
7360
- C<NoDups>
7406
+ B<C<NoDups>>
7361
7407
 
7362
7408
  Removes duplicate items from a list with a separator specified by the
7363
7409
  B<-sep> option. This function is most useful when copying list-type tags.
@@ -7382,7 +7428,7 @@ sources. An equivalent to the above commands using this feature would be:
7382
7428
 
7383
7429
  exiftool -tagsfromfile @ -keywords -api nodups a.jpg
7384
7430
 
7385
- C<SetTags>
7431
+ B<C<SetTags>>
7386
7432
 
7387
7433
  Used to set tags in extracted images. With no arguments, copies all tags
7388
7434
  from the source file to the embedded image:
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.97';
91
+ $VERSION = '4.98';
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)
@@ -562,6 +562,7 @@ $VERSION = '4.97';
562
562
  4160 => 'Canon EF-S 35mm f/2.8 Macro IS STM', #42
563
563
  4208 => 'Sigma 56mm f/1.4 DC DN | C or other Sigma Lens', #forum10603
564
564
  4208.1 => 'Sigma 30mm F1.4 DC DN | C', #github#83 (016)
565
+ 4976 => 'Sigma 16-300mm F3.5-6.7 DC OS | C (025)', #50
565
566
  6512 => 'Sigma 12mm F1.4 DC | C', #github#352 (025)
566
567
  # (Nano USM lenses - 0x90xx)
567
568
  36910 => 'Canon EF 70-300mm f/4-5.6 IS II USM', #42
@@ -1995,12 +1996,12 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
1995
1996
  SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData10' },
1996
1997
  },
1997
1998
  { # (int16u[3973]) - R3 ref IB
1998
- Condition => '$count == 3973 or $count == 3778',
1999
+ Condition => '($count == 3973 or $count == 3778) and $$valPt !~ /^\x41\0/',
1999
2000
  Name => 'ColorData11',
2000
2001
  SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData11' },
2001
2002
  },
2002
- { # (int16u[4528]) - R1/R5mkII ref forum16406
2003
- Condition => '$count == 4528',
2003
+ { # (int16u[4528]) - R1/R5mkII (4528) ref forum16406, R50V (3778) ref PH
2004
+ Condition => '$count == 4528 or $count == 3778',
2004
2005
  Name => 'ColorData12',
2005
2006
  SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData12' },
2006
2007
  },
@@ -8321,8 +8322,8 @@ my %ciMaxFocal = (
8321
8322
  RawConv => '$$self{ColorDataVersion} = $val',
8322
8323
  PrintConv => {
8323
8324
  16 => '16 (M50)',
8324
- 17 => '17 (EOS R)', # (and PowerShot SX740HS)
8325
- 18 => '18 (EOS RP/250D)', # (and PowerShot SX70HS)
8325
+ 17 => '17 (R)', # (and PowerShot SX740HS)
8326
+ 18 => '18 (RP/250D)', # (and PowerShot SX70HS)
8326
8327
  19 => '19 (90D/850D/M6mkII/M200)',# (and PowerShot G7XmkIII)
8327
8328
  },
8328
8329
  },
@@ -8553,10 +8554,10 @@ my %ciMaxFocal = (
8553
8554
  },
8554
8555
  );
8555
8556
 
8556
- # Color data (MakerNotes tag 0x4001, count=3973, ref IB)
8557
+ # Color data (MakerNotes tag 0x4001, count=3973/3778, ref IB)
8557
8558
  %Image::ExifTool::Canon::ColorData11 = (
8558
8559
  %binaryDataAttrs,
8559
- NOTES => 'These tags are used by the EOS R3, R7 and R6mkII',
8560
+ NOTES => 'These tags are used by the EOS R3, R7, R50 and R6mkII',
8560
8561
  FORMAT => 'int16s',
8561
8562
  FIRST_ENTRY => 0,
8562
8563
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
@@ -8568,7 +8569,7 @@ my %ciMaxFocal = (
8568
8569
  RawConv => '$$self{ColorDataVersion} = $val',
8569
8570
  PrintConv => {
8570
8571
  34 => '34 (R3)', #IB
8571
- 48 => '48 (R7, R10, R6 Mark II)', #IB
8572
+ 48 => '48 (R7/R10/R50/R6mkII)', #IB
8572
8573
  },
8573
8574
  },
8574
8575
  0x69 => { Name => 'WB_RGGBLevelsAsShot', Format => 'int16s[4]' },
@@ -8673,10 +8674,10 @@ my %ciMaxFocal = (
8673
8674
  },
8674
8675
  );
8675
8676
 
8676
- # Color data (MakerNotes tag 0x4001, count=4528, ref PH)
8677
+ # Color data (MakerNotes tag 0x4001, count=4528/3778, ref PH)
8677
8678
  %Image::ExifTool::Canon::ColorData12 = (
8678
8679
  %binaryDataAttrs,
8679
- NOTES => 'These tags are used by the EOS R1 and R5mkII',
8680
+ NOTES => 'These tags are used by the EOS R1, R5mkII and R50V',
8680
8681
  FORMAT => 'int16s',
8681
8682
  FIRST_ENTRY => 0,
8682
8683
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
@@ -8687,7 +8688,8 @@ my %ciMaxFocal = (
8687
8688
  DataMember => 'ColorDataVersion',
8688
8689
  RawConv => '$$self{ColorDataVersion} = $val',
8689
8690
  PrintConv => {
8690
- 64 => '64 (R1, R5 Mark II)',
8691
+ 64 => '64 (R1/R5mkII)',
8692
+ 65 => '65 (R50V)',
8691
8693
  },
8692
8694
  },
8693
8695
  0x69 => { Name => 'WB_RGGBLevelsAsShot', Format => 'int16s[4]' }, # (NC)
@@ -8778,6 +8780,7 @@ my %ciMaxFocal = (
8778
8780
  Name => 'PerChannelBlackLevel',
8779
8781
  Format => 'int16u[4]',
8780
8782
  },
8783
+ # 0x290 - PerChannelBlackLevel again
8781
8784
  0x294 => {
8782
8785
  Name => 'NormalWhiteLevel',
8783
8786
  Format => 'int16u',