exiftool-vendored.pl 12.56.0 → 12.62.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.
Files changed (65) hide show
  1. package/bin/Changes +115 -5
  2. package/bin/LICENSE +674 -0
  3. package/bin/MANIFEST +11 -0
  4. package/bin/META.json +1 -1
  5. package/bin/META.yml +1 -1
  6. package/bin/README +45 -44
  7. package/bin/config_files/example.config +1 -0
  8. package/bin/config_files/rotate_regions.config +1 -1
  9. package/bin/exiftool +262 -160
  10. package/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  11. package/bin/lib/Image/ExifTool/APE.pm +2 -2
  12. package/bin/lib/Image/ExifTool/BMP.pm +0 -1
  13. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -19
  14. package/bin/lib/Image/ExifTool/Canon.pm +26 -6
  15. package/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
  16. package/bin/lib/Image/ExifTool/DJI.pm +28 -2
  17. package/bin/lib/Image/ExifTool/Exif.pm +77 -19
  18. package/bin/lib/Image/ExifTool/FlashPix.pm +33 -10
  19. package/bin/lib/Image/ExifTool/FujiFilm.pm +7 -3
  20. package/bin/lib/Image/ExifTool/GPS.pm +7 -2
  21. package/bin/lib/Image/ExifTool/Geotag.pm +30 -7
  22. package/bin/lib/Image/ExifTool/JPEG.pm +14 -2
  23. package/bin/lib/Image/ExifTool/Jpeg2000.pm +36 -11
  24. package/bin/lib/Image/ExifTool/LIF.pm +10 -2
  25. package/bin/lib/Image/ExifTool/LNK.pm +5 -4
  26. package/bin/lib/Image/ExifTool/MIE.pm +3 -3
  27. package/bin/lib/Image/ExifTool/MPEG.pm +2 -2
  28. package/bin/lib/Image/ExifTool/MakerNotes.pm +3 -2
  29. package/bin/lib/Image/ExifTool/Minolta.pm +6 -7
  30. package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
  31. package/bin/lib/Image/ExifTool/Nikon.pm +1005 -909
  32. package/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
  33. package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
  34. package/bin/lib/Image/ExifTool/Olympus.pm +88 -6
  35. package/bin/lib/Image/ExifTool/PDF.pm +17 -8
  36. package/bin/lib/Image/ExifTool/PNG.pm +10 -2
  37. package/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
  38. package/bin/lib/Image/ExifTool/Pentax.pm +8 -5
  39. package/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
  40. package/bin/lib/Image/ExifTool/Photoshop.pm +38 -7
  41. package/bin/lib/Image/ExifTool/QuickTime.pm +48 -14
  42. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +91 -27
  43. package/bin/lib/Image/ExifTool/README +19 -2
  44. package/bin/lib/Image/ExifTool/RIFF.pm +34 -13
  45. package/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
  46. package/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
  47. package/bin/lib/Image/ExifTool/Sigma.pm +5 -4
  48. package/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
  49. package/bin/lib/Image/ExifTool/Sony.pm +39 -10
  50. package/bin/lib/Image/ExifTool/TagLookup.pm +4687 -4628
  51. package/bin/lib/Image/ExifTool/TagNames.pod +338 -117
  52. package/bin/lib/Image/ExifTool/Validate.pm +5 -5
  53. package/bin/lib/Image/ExifTool/WPG.pm +296 -0
  54. package/bin/lib/Image/ExifTool/WriteExif.pl +42 -0
  55. package/bin/lib/Image/ExifTool/WritePDF.pl +7 -8
  56. package/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  57. package/bin/lib/Image/ExifTool/Writer.pl +162 -40
  58. package/bin/lib/Image/ExifTool/XMP.pm +35 -8
  59. package/bin/lib/Image/ExifTool/XMP2.pl +2 -1
  60. package/bin/lib/Image/ExifTool/ZIP.pm +159 -41
  61. package/bin/lib/Image/ExifTool.pm +286 -65
  62. package/bin/lib/Image/ExifTool.pod +95 -51
  63. package/bin/perl-Image-ExifTool.spec +44 -43
  64. package/bin/pp_build_exe.args +5 -4
  65. package/package.json +3 -3
package/bin/exiftool CHANGED
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '12.56';
14
+ my $version = '12.62';
15
15
 
16
16
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
17
17
  BEGIN {
@@ -77,6 +77,7 @@ sub AcceptFile($);
77
77
  sub SlurpFile($$);
78
78
  sub FilterArgfileLine($);
79
79
  sub ReadStayOpen($);
80
+ sub Progress($$);
80
81
  sub PrintTagList($@);
81
82
  sub PrintErrors($$$);
82
83
 
@@ -102,6 +103,7 @@ my @newValues; # list of new tag values to set
102
103
  my @requestTags; # tags to request (for -p or -if option arguments)
103
104
  my @srcFmt; # source file name format strings
104
105
  my @tags; # list of tags to extract
106
+ my %altFile; # alternate files to extract information (keyed by lower-case family 8 group)
105
107
  my %appended; # list of files appended to
106
108
  my %countLink; # count hard and symbolic links made
107
109
  my %created; # list of files we created
@@ -114,6 +116,7 @@ my %outComma; # flag that output text file needs a comma
114
116
  my %outTrailer; # trailer for output text file
115
117
  my %preserveTime; # preserved timestamps for files
116
118
  my %printFmt; # the contents of the print format file
119
+ my %seqFileDir; # file sequence number in each directory
117
120
  my %setTags; # hash of list references for tags to set from files
118
121
  my %setTagsList; # list of other tag lists for multiple -tagsFromFile from the same file
119
122
  my %usedFileName; # lookup for file names we already used in TestName feature
@@ -182,7 +185,9 @@ my $pause; # pause before returning
182
185
  my $preserveTime; # flag to preserve times of updated files (2=preserve FileCreateDate only)
183
186
  my $progress; # flag to calculate total files to process (0=calculate but don't display)
184
187
  my $progressCount; # count of files processed
188
+ my $progressIncr; # increment for progress counter
185
189
  my $progressMax; # total number of files to process
190
+ my $progressNext; # next progress count to output
186
191
  my $progStr; # progress message string
187
192
  my $quiet; # flag to disable printing of informational messages / warnings
188
193
  my $rafStdin; # File::RandomAccess for stdin (if necessary to rewind)
@@ -193,7 +198,7 @@ my $saveCount; # count the number of times we will/did call SaveNewValues()
193
198
  my $scanWritable; # flag to process only writable file types
194
199
  my $sectHeader; # current section header for -p option
195
200
  my $sectTrailer; # section trailer for -p option
196
- my $seqFileBase; # sequential file number at start of directory
201
+ my $seqFileDir; # sequential file number used for %-C
197
202
  my $seqFileNum; # sequential file number used for %C
198
203
  my $setCharset; # character set setting ('default' if not set and -csv -b used)
199
204
  my $showGroup; # number of group to show (may be zero or '')
@@ -211,6 +216,7 @@ my $validFile; # flag indicating we processed a valid file
211
216
  my $verbose; # verbose setting
212
217
  my $vout; # verbose output file reference (\*STDOUT or \*STDERR)
213
218
  my $windowTitle; # title for console window
219
+ my %wroteHEAD; # list of output txt files to which we wrote HEAD
214
220
  my $xml; # flag for XML-formatted output
215
221
 
216
222
  # flag to keep the input -@ argfile open:
@@ -251,17 +257,15 @@ my %optArgs = (
251
257
  '-csvdelim' => 1,
252
258
  '-d' => 1, '-dateformat' => 1,
253
259
  '-D' => 0, # necessary to avoid matching lower-case equivalent
254
- '-echo' => 1, '-echo1' => 1, '-echo2' => 1, '-echo3' => 1, '-echo4' => 1,
255
- '-efile' => 1, '-efile1' => 1, '-efile2' => 1, '-efile3' => 1, '-efile4' => 1,
256
- '-efile!' => 1, '-efile1!' => 1, '-efile2!' => 1, '-efile3!' => 1, '-efile4!' => 1,
260
+ '-echo' => 1, '-echo#' => 1,
261
+ '-efile' => 1, '-efile#' => 1, '-efile!' => 1, '-efile#!' => 1,
257
262
  '-ext' => 1, '--ext' => 1, '-ext+' => 1, '--ext+' => 1,
258
263
  '-extension' => 1, '--extension' => 1, '-extension+' => 1, '--extension+' => 1,
259
- '-fileorder' => 1, '-fileorder0' => 1, '-fileorder1' => 1, '-fileorder2' => 1,
260
- '-fileorder3' => 1, '-fileorder4' => 1, '-fileorder5' => 1,
264
+ '-fileorder' => 1, '-fileorder#' => 1,
261
265
  '-geotag' => 1,
262
266
  '-globaltimeshift' => 1,
263
267
  '-i' => 1, '-ignore' => 1,
264
- '-if' => 1, '-if0' => 1, '-if1' => 1, '-if2' => 1, '-if3' => 1, '-if4' => 1, '-if5' => 1,
268
+ '-if' => 1, '-if#' => 1,
265
269
  '-lang' => 0, # (optional arg; cannot begin with "-")
266
270
  '-listitem' => 1,
267
271
  '-o' => 1, '-out' => 1,
@@ -361,13 +365,14 @@ sub Cleanup() {
361
365
 
362
366
  # isolate arguments common to all commands
363
367
  if (grep /^-common_args$/i, @ARGV) {
364
- my (@newArgs, $common);
368
+ my (@newArgs, $common, $end);
365
369
  foreach (@ARGV) {
366
- if (/^-common_args$/i) {
370
+ if (/^-common_args$/i and not $end) {
367
371
  $common = 1;
368
372
  } elsif ($common) {
369
373
  push @commonArgs, $_;
370
374
  } else {
375
+ $end = 1 if $_ eq '--';
371
376
  push @newArgs, $_;
372
377
  }
373
378
  }
@@ -448,6 +453,7 @@ undef %outComma;
448
453
  undef %outTrailer;
449
454
  undef %printFmt;
450
455
  undef %preserveTime;
456
+ undef %seqFileDir;
451
457
  undef %setTags;
452
458
  undef %setTagsList;
453
459
  undef %usedFileName;
@@ -489,7 +495,9 @@ undef $outOpt;
489
495
  undef $preserveTime;
490
496
  undef $progress;
491
497
  undef $progressCount;
498
+ undef $progressIncr;
492
499
  undef $progressMax;
500
+ undef $progressNext;
493
501
  undef $recurse;
494
502
  undef $scanWritable;
495
503
  undef $sectHeader;
@@ -532,7 +540,7 @@ $quiet = 0;
532
540
  $rtnVal = 0;
533
541
  $saveCount = 0;
534
542
  $sectTrailer = '';
535
- $seqFileBase = 0;
543
+ $seqFileDir = 0;
536
544
  $seqFileNum = 0;
537
545
  $tabFormat = 0;
538
546
  $vout = \*STDOUT;
@@ -829,7 +837,7 @@ for (;;) {
829
837
  $mt->Options(Charset => $charset);
830
838
  }
831
839
  if ($evalWarning) {
832
- warn $evalWarning;
840
+ Warn $evalWarning;
833
841
  } else {
834
842
  $setCharset = $mt->Options('Charset');
835
843
  }
@@ -915,12 +923,14 @@ for (;;) {
915
923
  $mt->Options(Duplicates => 1);
916
924
  next;
917
925
  }
918
- if (/^efile(\d)?(!)?$/i) {
926
+ if (/^efile(\d+)?(!)?$/i) {
919
927
  my $arg = shift;
920
928
  defined $arg or Error("Expecting file name for -$_ option\n"), $badCmd=1, next;
921
- $efile[0] = $arg if not $1 or $1 & 0x01;
922
- $efile[1] = $arg if $1 and $1 & 0x02;
923
- $efile[2] = $arg if $1 and $1 & 0x04;
929
+ $efile[0] = $arg if not $1 or $1 & 0x01;# error
930
+ $efile[1] = $arg if $1 and $1 & 0x02; # unchanged
931
+ $efile[2] = $arg if $1 and $1 & 0x04; # failed -if condition
932
+ $efile[3] = $arg if $1 and $1 & 0x08; # updated
933
+ $efile[4] = $arg if $1 and $1 & 0x016; # created
924
934
  unlink $arg if $2;
925
935
  next;
926
936
  }
@@ -946,6 +956,10 @@ for (;;) {
946
956
  $mt->Options(FastScan => (length $1 ? $1 : 1));
947
957
  next;
948
958
  }
959
+ if (/^(file\d+)$/i) {
960
+ $altFile{lc $1} = shift or Error("Expecting file name for -file option\n"), $badCmd=1, next;
961
+ next;
962
+ }
949
963
  if (/^fileorder(\d*)$/i) {
950
964
  push @fileOrder, shift if @ARGV;
951
965
  my $num = $1 || 0;
@@ -1119,9 +1133,11 @@ for (;;) {
1119
1133
  }
1120
1134
  (/^P$/ or $a eq 'preserve') and $preserveTime = 1, next;
1121
1135
  /^password$/i and $mt->Options(Password => shift), next;
1122
- if (/^progress(:.*)?$/i) {
1123
- if ($1) {
1124
- $windowTitle = substr $1, 1;
1136
+ if (/^progress(\d*)(:.*)?$/i) {
1137
+ $progressIncr = $1 || 1;
1138
+ $progressNext = 0; # start showing progress at the first file
1139
+ if ($2) {
1140
+ $windowTitle = substr $2, 1;
1125
1141
  $windowTitle = 'ExifTool %p%%' unless length $windowTitle;
1126
1142
  $windowTitle =~ /%\d*[bpr]/ and $progress = 0 unless defined $progress;
1127
1143
  } else {
@@ -1239,7 +1255,8 @@ for (;;) {
1239
1255
  next;
1240
1256
  }
1241
1257
  if (/^(w|textout|tagout)([!+]*)$/i) {
1242
- $textOut = shift || Warn("Expecting output extension for -$_ option\n");
1258
+ # (note: all logic ignores $textOut of 0 or '')
1259
+ $textOut = shift || Warn("Expecting argument for -$_ option\n");
1243
1260
  my ($t1, $t2) = ($1, $2);
1244
1261
  $textOverwrite = 0;
1245
1262
  $textOverwrite += 1 if $t2 =~ /!/; # overwrite
@@ -1323,7 +1340,7 @@ for (;;) {
1323
1340
  AddSetTagsFile($setTagsFile = '@') if not $setTagsFile and /(<|>)/;
1324
1341
  if ($setTagsFile) {
1325
1342
  push @{$setTags{$setTagsFile}}, $_;
1326
- if (/>/) {
1343
+ if ($1 eq '>') {
1327
1344
  $useMWG = 1 if /^(.*>\s*)?mwg:/si;
1328
1345
  if (/\b(filename|directory|testname)#?$/i) {
1329
1346
  $doSetFileName = 1;
@@ -1711,7 +1728,7 @@ if (defined $showGroup and not (@tags and $allGroup) and ($sortOpt or not define
1711
1728
  $mt->Options(Sort => "Group$showGroup");
1712
1729
  }
1713
1730
 
1714
- if (defined $textOut) {
1731
+ if ($textOut) {
1715
1732
  CleanFilename($textOut); # make all forward slashes
1716
1733
  # add '.' before output extension if necessary
1717
1734
  $textOut = ".$textOut" unless $textOut =~ /[.%]/ or defined $tagOut;
@@ -1721,7 +1738,8 @@ if (defined $textOut) {
1721
1738
  if ($outOpt) {
1722
1739
  my $type = GetFileType($outOpt);
1723
1740
  if ($type) {
1724
- unless (CanWrite($type)) {
1741
+ # (must test original file name because we can write .webp but not other RIFF types)
1742
+ unless (CanWrite($outOpt)) {
1725
1743
  Warn "Can't write $type files\n";
1726
1744
  $rtnVal = 1;
1727
1745
  next;
@@ -1932,25 +1950,34 @@ Exit $rtnValApp; # all done
1932
1950
  sub GetImageInfo($$)
1933
1951
  {
1934
1952
  my ($et, $orig) = @_;
1935
- my (@foundTags, $info, $file, $ind);
1953
+ my (@foundTags, $info, $file, $ind, $g8);
1936
1954
 
1937
1955
  # set window title for this file if necessary
1938
1956
  if (defined $windowTitle) {
1939
- my $prog = $progressMax ? "$progressCount/$progressMax" : '0/0';
1940
- my $title = $windowTitle;
1941
- my ($num, $denom) = split '/', $prog;
1942
- my $frac = $num / ($denom || 1);
1943
- my $n = $title =~ s/%(\d+)b/%b/ ? $1 : 20; # length of bar
1944
- my $bar = int($frac * $n + 0.5);
1945
- my %lkup = (
1946
- b => ('I' x $bar) . ('.' x ($n - $bar)), # (undocumented)
1947
- f => $orig,
1948
- p => int(100 * $frac + 0.5),
1949
- r => $prog,
1950
- '%'=> '%',
1951
- );
1952
- $title =~ s/%([%bfpr])/$lkup{$1}/eg;
1953
- SetWindowTitle($title);
1957
+ if ($progressCount >= $progressNext) {
1958
+ my $prog = $progressMax ? "$progressCount/$progressMax" : '0/0';
1959
+ my $title = $windowTitle;
1960
+ my ($num, $denom) = split '/', $prog;
1961
+ my $frac = $num / ($denom || 1);
1962
+ my $n = $title =~ s/%(\d+)b/%b/ ? $1 : 20; # length of bar
1963
+ my $bar = int($frac * $n + 0.5);
1964
+ my %lkup = (
1965
+ b => ('I' x $bar) . ('.' x ($n - $bar)),
1966
+ f => $orig,
1967
+ p => int(100 * $frac + 0.5),
1968
+ r => $prog,
1969
+ '%'=> '%',
1970
+ );
1971
+ $title =~ s/%([%bfpr])/$lkup{$1}/eg;
1972
+ SetWindowTitle($title);
1973
+ if (defined $progressMax) {
1974
+ undef $progressNext;
1975
+ } else {
1976
+ $progressNext += $progressIncr;
1977
+ }
1978
+ }
1979
+ # ($progressMax is not defined for "-progress:%f")
1980
+ ++$progressCount unless defined $progressMax;
1954
1981
  }
1955
1982
  unless (length $orig or $outOpt) {
1956
1983
  Warn qq(Error: Zero-length file name - ""\n);
@@ -1974,6 +2001,15 @@ sub GetImageInfo($$)
1974
2001
  } else {
1975
2002
  $file = $orig;
1976
2003
  }
2004
+ # set alternate file names
2005
+ foreach $g8 (sort keys %altFile) {
2006
+ my $altName = $orig;
2007
+ # must double any '$' symbols in the original file name because
2008
+ # they are used for tag names in a -fileNUM argument
2009
+ $altName =~ s/\$/\$\$/g;
2010
+ $altName = FilenameSPrintf($altFile{$g8}, $altName);
2011
+ $et->SetAlternateFile($g8, $altName);
2012
+ }
1977
2013
 
1978
2014
  my $pipe = $file;
1979
2015
  if ($doUnzip) {
@@ -2044,7 +2080,7 @@ sub GetImageInfo($$)
2044
2080
  undef @foundTags if $fastCondition; # ignore if we didn't get all tags
2045
2081
  }
2046
2082
  unless ($result) {
2047
- $verbose and print $vout "-------- $file (failed condition)$progStr\n";
2083
+ Progress($vout, "-------- $file (failed condition)") if $verbose;
2048
2084
  EFile($file, 2);
2049
2085
  ++$countFailed;
2050
2086
  return;
@@ -2054,7 +2090,7 @@ sub GetImageInfo($$)
2054
2090
  undef $info if $verbose or defined $fastCondition;
2055
2091
  }
2056
2092
  if (defined $deleteOrig) {
2057
- print $vout "======== $file$progStr\n" if defined $verbose;
2093
+ Progress($vout, "======== $file") if defined $verbose;
2058
2094
  ++$count;
2059
2095
  my $original = "${file}_original";
2060
2096
  $et->Exists($original) or return;
@@ -2063,6 +2099,7 @@ sub GetImageInfo($$)
2063
2099
  push @delFiles, $original;
2064
2100
  } elsif ($et->Rename($original, $file)) {
2065
2101
  $verbose and print $vout "Restored from $original\n";
2102
+ EFile($file, 3);
2066
2103
  ++$countGoodWr;
2067
2104
  } else {
2068
2105
  Warn "Error renaming $original\n";
@@ -2072,6 +2109,8 @@ sub GetImageInfo($$)
2072
2109
  return;
2073
2110
  }
2074
2111
  ++$seqFileNum; # increment our file counter
2112
+ my ($dir) = Image::ExifTool::SplitFileName($orig);
2113
+ $seqFileDir = $seqFileDir{$dir} = ($seqFileDir{$dir} || 0) + 1;
2075
2114
 
2076
2115
  my $lineCount = 0;
2077
2116
  my ($fp, $outfile, $append);
@@ -2084,12 +2123,12 @@ sub GetImageInfo($$)
2084
2123
  }
2085
2124
 
2086
2125
  if ($isWriting) {
2087
- print $vout "======== $file$progStr\n" if defined $verbose;
2126
+ Progress($vout, "======== $file") if defined $verbose;
2088
2127
  SetImageInfo($et, $file, $orig);
2089
2128
  $info = $et->GetInfo('Warning', 'Error');
2090
2129
  PrintErrors($et, $info, $file);
2091
2130
  # close output text file if necessary
2092
- if ($outfile) {
2131
+ if (defined $outfile) {
2093
2132
  undef $tmpText;
2094
2133
  close($fp);
2095
2134
  $et->Options(TextOut => $vout);
@@ -2108,7 +2147,7 @@ sub GetImageInfo($$)
2108
2147
  unless ($file eq '-' or $et->Exists($file)) {
2109
2148
  Warn "Error: File not found - $file\n";
2110
2149
  FileNotFound($file);
2111
- $outfile and close($fp), undef($tmpText), $et->Unlink($outfile);
2150
+ defined $outfile and close($fp), undef($tmpText), $et->Unlink($outfile);
2112
2151
  EFile($file);
2113
2152
  ++$countBad;
2114
2153
  return;
@@ -2125,7 +2164,7 @@ sub GetImageInfo($$)
2125
2164
  }
2126
2165
  }
2127
2166
  $o = \*STDERR if $progress and not $o;
2128
- $o and print $o "======== $file$progStr\n";
2167
+ Progress($o, "======== $file") if $o;
2129
2168
  if ($info) {
2130
2169
  # get the information we wanted
2131
2170
  if (@tags and not %printFmt) {
@@ -2147,7 +2186,7 @@ sub GetImageInfo($$)
2147
2186
  }
2148
2187
  # all done now if we already wrote output text file (eg. verbose option)
2149
2188
  if ($fp) {
2150
- if ($outfile) {
2189
+ if (defined $outfile) {
2151
2190
  $et->Options(TextOut => \*STDOUT);
2152
2191
  undef $tmpText;
2153
2192
  if ($info->{Error}) {
@@ -2176,7 +2215,7 @@ sub GetImageInfo($$)
2176
2215
  }
2177
2216
 
2178
2217
  # open output file (or stdout if no output file) if not done already
2179
- unless ($outfile or $tagOut) {
2218
+ unless (defined $outfile or $tagOut) {
2180
2219
  ($fp, $outfile, $append) = OpenOutputFile($orig);
2181
2220
  $fp or EFile($file), ++$countBad, return;
2182
2221
  $tmpText = $outfile unless $append;
@@ -2201,6 +2240,10 @@ sub GetImageInfo($$)
2201
2240
  my $skipBody;
2202
2241
  foreach $type (qw(HEAD SECT IF BODY ENDS TAIL)) {
2203
2242
  my $prf = $printFmt{$type} or next;
2243
+ if ($type eq 'HEAD' and defined $outfile) {
2244
+ next if $wroteHEAD{$outfile};
2245
+ $wroteHEAD{$outfile} = 1;
2246
+ }
2204
2247
  next if $type eq 'BODY' and $skipBody;
2205
2248
  if ($lastDoc) {
2206
2249
  if ($doc) {
@@ -2238,7 +2281,7 @@ sub GetImageInfo($$)
2238
2281
  }
2239
2282
  }
2240
2283
  }
2241
- delete $printFmt{HEAD} unless $outfile; # print header only once per output file
2284
+ delete $printFmt{HEAD} unless defined $outfile; # print header only once per output file
2242
2285
  my $errs = $et->GetInfo('Warning', 'Error');
2243
2286
  PrintErrors($et, $errs, $file) and EFile($file);
2244
2287
  } elsif (not $disableOutput) {
@@ -2394,7 +2437,7 @@ TAG: foreach $tag (@foundTags) {
2394
2437
  next TAG;
2395
2438
  }
2396
2439
  my @groups = $et->GetGroup($tag);
2397
- $outfile and close($fp), undef($tmpText); # (shouldn't happen)
2440
+ defined $outfile and close($fp), undef($tmpText); # (shouldn't happen)
2398
2441
  my $org = $et->GetValue('OriginalRawFileName') || $et->GetValue('OriginalFileName');
2399
2442
  ($fp, $outfile, $append) = OpenOutputFile($orig, $tagName, \@groups, $ext, $org);
2400
2443
  $fp or ++$countBad, next TAG;
@@ -2507,6 +2550,7 @@ TAG: foreach $tag (@foundTags) {
2507
2550
  $xtra .= " et:table='${table}'";
2508
2551
  $xtra .= " et:index='${index}'" if defined $index;
2509
2552
  }
2553
+ # Note: New $xtra attributes must be added to %ignoreEtProp in XMP.pm!
2510
2554
  my $lastVal = $val;
2511
2555
  for ($valNum=0; $valNum<2; ++$valNum) {
2512
2556
  $val = FormatXML($val, $ind, $group);
@@ -2700,7 +2744,7 @@ TAG: foreach $tag (@foundTags) {
2700
2744
  }
2701
2745
  }
2702
2746
  }
2703
- if ($outfile) {
2747
+ if (defined $outfile) {
2704
2748
  if ($textOverwrite & 0x02) {
2705
2749
  # save state of this file if we may be appending
2706
2750
  $outComma{$outfile} = $comma;
@@ -3016,6 +3060,7 @@ sub SetImageInfo($$$)
3016
3060
  $r3 = $et->SetSystemTags($file);
3017
3061
  }
3018
3062
  if ($r0 > 0 or $r1 > 0 or $r2 > 0 or $r3 > 0) {
3063
+ EFile($infile, 3);
3019
3064
  ++$countGoodWr;
3020
3065
  } elsif ($r0 < 0 or $r1 < 0 or $r2 < 0 or $r3 < 0) {
3021
3066
  EFile($infile);
@@ -3130,6 +3175,7 @@ sub SetImageInfo($$$)
3130
3175
  $preserveTime{$file} = [ $aTime, $mTime, $cTime ];
3131
3176
  }
3132
3177
  }
3178
+ EFile($infile, 3);
3133
3179
  ++$countGoodWr;
3134
3180
  } else {
3135
3181
  close(NEW_FILE);
@@ -3145,6 +3191,7 @@ sub SetImageInfo($$$)
3145
3191
  # simply rename temporary file to replace original
3146
3192
  # (if we didn't already rename it to add "_original")
3147
3193
  } elsif ($et->Rename($tmpFile, $dstFile)) {
3194
+ EFile($infile, 3);
3148
3195
  ++$countGoodWr;
3149
3196
  } else {
3150
3197
  my $newFile = $tmpFile;
@@ -3162,21 +3209,26 @@ sub SetImageInfo($$$)
3162
3209
  # (don't delete tmp file now because it is all we have left)
3163
3210
  ++$countBadWr;
3164
3211
  } else {
3212
+ EFile($infile, 3);
3165
3213
  ++$countGoodWr;
3166
3214
  }
3167
3215
  }
3168
3216
  } elsif ($overwriteOrig) {
3169
3217
  # erase original file
3218
+ EFile($infile, 3);
3170
3219
  $et->Unlink($file) or Warn "Error erasing original $file\n";
3171
3220
  ++$countGoodWr;
3172
3221
  } else {
3222
+ EFile($infile, 4);
3173
3223
  ++$countGoodCr;
3174
3224
  }
3175
3225
  } else {
3176
3226
  # this file was created from scratch, not edited
3227
+ EFile($infile, 4);
3177
3228
  ++$countGoodCr;
3178
3229
  }
3179
3230
  } else {
3231
+ EFile($infile, 3);
3180
3232
  ++$countGoodWr;
3181
3233
  }
3182
3234
  } elsif ($success) {
@@ -3661,8 +3713,19 @@ sub ProcessFiles($;$)
3661
3713
  foreach $file (@files) {
3662
3714
  $et->Options(CharsetFileName => 'UTF8') if $utf8FileName{$file};
3663
3715
  if (defined $progressMax) {
3716
+ unless (defined $progressNext) {
3717
+ $progressNext = $progressCount + $progressIncr;
3718
+ $progressNext -= $progressNext % $progressIncr; # (show even multiples)
3719
+ $progressNext = $progressMax if $progressNext > $progressMax;
3720
+ }
3664
3721
  ++$progressCount;
3665
- $progStr = " [$progressCount/$progressMax]" if $progress;
3722
+ if ($progress) {
3723
+ if ($progressCount >= $progressNext) {
3724
+ $progStr = " [$progressCount/$progressMax]";
3725
+ } else {
3726
+ undef $progStr; # don't update progress yet
3727
+ }
3728
+ }
3666
3729
  }
3667
3730
  if ($et->IsDirectory($file) and not $listDir) {
3668
3731
  $multiFile = $validFile = 1;
@@ -3670,7 +3733,7 @@ sub ProcessFiles($;$)
3670
3733
  } elsif ($filterFlag and not AcceptFile($file)) {
3671
3734
  if ($et->Exists($file)) {
3672
3735
  $filtered = 1;
3673
- $verbose and print $vout "-------- $file (wrong extension)$progStr\n";
3736
+ Progress($vout, "-------- $file (wrong extension)") if $verbose;
3674
3737
  } else {
3675
3738
  Warn "Error: File not found - $file\n";
3676
3739
  FileNotFound($file);
@@ -3718,8 +3781,6 @@ sub ScanDir($$;$)
3718
3781
  $utf8Name = 1;
3719
3782
  }
3720
3783
  return if $ignore{$dir};
3721
- my $oldBase = $seqFileBase;
3722
- $seqFileBase = $seqFileNum;
3723
3784
  # use Win32::FindFile on Windows if available
3724
3785
  # (ReadDir will croak if there is a wildcard, so check for this)
3725
3786
  if ($^O eq 'MSWin32' and $dir !~ /[*?]/) {
@@ -3751,7 +3812,6 @@ sub ScanDir($$;$)
3751
3812
  # use standard perl library routines to read directory
3752
3813
  unless (opendir(DIR_HANDLE, $dir)) {
3753
3814
  Warn("Error opening directory $dir\n");
3754
- $seqFileBase = $oldBase + ($seqFileNum - $seqFileBase);
3755
3815
  return;
3756
3816
  }
3757
3817
  @fileList = readdir(DIR_HANDLE);
@@ -3831,8 +3891,6 @@ sub ScanDir($$;$)
3831
3891
  }
3832
3892
  ++$countDir;
3833
3893
  $et->Options(CharsetFileName => $enc); # restore original setting
3834
- # update sequential file base for parent directory
3835
- $seqFileBase = $oldBase + ($seqFileNum - $seqFileBase);
3836
3894
  }
3837
3895
 
3838
3896
  #------------------------------------------------------------------------------
@@ -4128,16 +4186,15 @@ sub NextUnusedFilename($;$)
4128
4186
  return $fmt unless $fmt =~ /%[-+]?\d*\.?\d*[lun]?[cC]/;
4129
4187
  my %sep = ( '-' => '-', '+' => '_' );
4130
4188
  my ($copy, $alpha) = (0, 'a');
4131
- my $seq = $seqFileNum - 1;
4132
4189
  for (;;) {
4133
4190
  my ($filename, $pos) = ('', 0);
4134
4191
  while ($fmt =~ /(%([-+]?)(\d*)(\.?)(\d*)([lun]?)([cC]))/g) {
4135
4192
  $filename .= substr($fmt, $pos, pos($fmt) - $pos - length($1));
4136
4193
  $pos = pos($fmt);
4137
4194
  my ($sign, $wid, $dec, $wid2, $mod, $tok) = ($2, $3 || 0, $4, $5 || 0, $6, $7);
4138
- my $diff;
4195
+ my $seq;
4139
4196
  if ($tok eq 'C') {
4140
- $diff = $wid - ($sign eq '-' ? $seqFileBase : 0);
4197
+ $seq = $wid + ($sign eq '-' ? $seqFileDir : $seqFileNum) - 1;
4141
4198
  $wid = $wid2;
4142
4199
  } else {
4143
4200
  next unless $dec or $copy;
@@ -4146,13 +4203,13 @@ sub NextUnusedFilename($;$)
4146
4203
  $filename .= $sep{$sign} if $sign;
4147
4204
  }
4148
4205
  if ($mod and $mod ne 'n') {
4149
- my $a = $tok eq 'C' ? Num2Alpha($diff + $seq) : $alpha;
4206
+ my $a = $tok eq 'C' ? Num2Alpha($seq) : $alpha;
4150
4207
  my $str = ($wid and $wid > length $a) ? 'a' x ($wid - length($a)) : '';
4151
4208
  $str .= $a;
4152
4209
  $str = uc $str if $mod eq 'u';
4153
4210
  $filename .= $str;
4154
4211
  } else {
4155
- my $c = $tok eq 'C' ? ($diff + $seq) : $copy;
4212
+ my $c = $tok eq 'C' ? $seq : $copy;
4156
4213
  my $num = $c + ($mod ? 1 : 0);
4157
4214
  $filename .= $wid ? sprintf("%.${wid}d",$num) : $num;
4158
4215
  }
@@ -4167,7 +4224,6 @@ sub NextUnusedFilename($;$)
4167
4224
  }
4168
4225
  ++$copy;
4169
4226
  ++$alpha;
4170
- ++$seq;
4171
4227
  }
4172
4228
  }
4173
4229
 
@@ -4373,9 +4429,13 @@ sub ReadStayOpen($)
4373
4429
  undef $optArgs;
4374
4430
  next unless $lastOpt eq '-stay_open' or $lastOpt eq '-@';
4375
4431
  } else {
4376
- $optArgs = $optArgs{$arg};
4377
4432
  $lastOpt = lc $arg;
4378
- $optArgs = $optArgs{$lastOpt} unless defined $optArgs;
4433
+ $optArgs = $optArgs{$arg};
4434
+ unless (defined $optArgs) {
4435
+ $optArgs = $optArgs{$lastOpt};
4436
+ # handle options with trailing numbers
4437
+ $optArgs = $optArgs{"$1#$2"} if not defined $optArgs and $lastOpt =~ /^(.*?)\d+(!?)$/;
4438
+ }
4379
4439
  next unless $lastOpt =~ /^-execute\d*$/;
4380
4440
  }
4381
4441
  $processArgs = 1;
@@ -4405,7 +4465,7 @@ sub ReadStayOpen($)
4405
4465
 
4406
4466
  #------------------------------------------------------------------------------
4407
4467
  # Add new entry to -efile output file
4408
- # Inputs: 0) file name, 1) -efile option number (0=error, 1=same, 2=failed)
4468
+ # Inputs: 0) file name, 1) -efile option number (0=error, 1=same, 2=failed, 3=updated, 4=created)
4409
4469
  sub EFile($$)
4410
4470
  {
4411
4471
  my $entry = shift;
@@ -4426,6 +4486,18 @@ sub EFile($$)
4426
4486
  }
4427
4487
  }
4428
4488
 
4489
+ #------------------------------------------------------------------------------
4490
+ # Print progress message if it is time for it
4491
+ # Inputs: 0) file ref, 1) message
4492
+ sub Progress($$)
4493
+ {
4494
+ my ($file, $msg) = @_;
4495
+ if (defined $progStr) {
4496
+ print $file $msg, $progStr, "\n";
4497
+ undef $progressNext if defined $progressMax;
4498
+ }
4499
+ }
4500
+
4429
4501
  #------------------------------------------------------------------------------
4430
4502
  # Print list of tags
4431
4503
  # Inputs: 0) message, 1-N) list of tag names
@@ -4533,48 +4605,49 @@ supported by ExifTool (r = read, w = write, c = create):
4533
4605
 
4534
4606
  File Types
4535
4607
  ------------+-------------+-------------+-------------+------------
4536
- 360 r/w | DPX r | ITC r | NRW r/w | RAM r
4537
- 3FR r | DR4 r/w/c | J2C r | NUMBERS r | RAR r
4538
- 3G2 r/w | DSS r | JNG r/w | O r | RAW r/w
4539
- 3GP r/w | DV r | JP2 r/w | ODP r | RIFF r
4540
- A r | DVB r/w | JPEG r/w | ODS r | RSRC r
4541
- AA r | DVR-MS r | JSON r | ODT r | RTF r
4542
- AAE r | DYLIB r | JXL r | OFR r | RW2 r/w
4543
- AAX r/w | EIP r | K25 r | OGG r | RWL r/w
4544
- ACR r | EPS r/w | KDC r | OGV r | RWZ r
4545
- AFM r | EPUB r | KEY r | ONP r | RM r
4546
- AI r/w | ERF r/w | LA r | OPUS r | SEQ r
4547
- AIFF r | EXE r | LFP r | ORF r/w | SKETCH r
4548
- APE r | EXIF r/w/c | LIF r | ORI r/w | SO r
4549
- ARQ r/w | EXR r | LNK r | OTF r | SR2 r/w
4550
- ARW r/w | EXV r/w/c | LRV r/w | PAC r | SRF r
4551
- ASF r | F4A/V r/w | M2TS r | PAGES r | SRW r/w
4552
- AVI r | FFF r/w | M4A/V r/w | PBM r/w | SVG r
4553
- AVIF r/w | FITS r | MACOS r | PCD r | SWF r
4554
- AZW r | FLA r | MAX r | PCX r | THM r/w
4555
- BMP r | FLAC r | MEF r/w | PDB r | TIFF r/w
4556
- BPG r | FLIF r/w | MIE r/w/c | PDF r/w | TORRENT r
4557
- BTF r | FLV r | MIFF r | PEF r/w | TTC r
4558
- CHM r | FPF r | MKA r | PFA r | TTF r
4559
- COS r | FPX r | MKS r | PFB r | TXT r
4560
- CR2 r/w | GIF r/w | MKV r | PFM r | VCF r
4561
- CR3 r/w | GPR r/w | MNG r/w | PGF r | VNT r
4562
- CRM r/w | GZ r | MOBI r | PGM r/w | VRD r/w/c
4563
- CRW r/w | HDP r/w | MODD r | PLIST r | VSD r
4564
- CS1 r/w | HDR r | MOI r | PICT r | WAV r
4565
- CSV r | HEIC r/w | MOS r/w | PMP r | WDP r/w
4566
- CUR r | HEIF r/w | MOV r/w | PNG r/w | WEBP r/w
4567
- CZI r | HTML r | MP3 r | PPM r/w | WEBM r
4568
- DCM r | ICC r/w/c | MP4 r/w | PPT r | WMA r
4569
- DCP r/w | ICO r | MPC r | PPTX r | WMV r
4570
- DCR r | ICS r | MPG r | PS r/w | WTV r
4571
- DFONT r | IDML r | MPO r/w | PSB r/w | WV r
4572
- DIVX r | IIQ r/w | MQV r/w | PSD r/w | X3F r/w
4573
- DJVU r | IND r/w | MRC r | PSP r | XCF r
4574
- DLL r | INSP r/w | MRW r/w | QTIF r/w | XLS r
4575
- DNG r/w | INSV r | MXF r | R3D r | XLSX r
4576
- DOC r | INX r | NEF r/w | RA r | XMP r/w/c
4577
- DOCX r | ISO r | NKSC r/w | RAF r/w | ZIP r
4608
+ 360 r/w | DR4 r/w/c | JNG r/w | ODP r | RSRC r
4609
+ 3FR r | DSS r | JP2 r/w | ODS r | RTF r
4610
+ 3G2 r/w | DV r | JPEG r/w | ODT r | RW2 r/w
4611
+ 3GP r/w | DVB r/w | JSON r | OFR r | RWL r/w
4612
+ A r | DVR-MS r | JXL r | OGG r | RWZ r
4613
+ AA r | DYLIB r | K25 r | OGV r | RM r
4614
+ AAE r | EIP r | KDC r | ONP r | SEQ r
4615
+ AAX r/w | EPS r/w | KEY r | OPUS r | SKETCH r
4616
+ ACR r | EPUB r | LA r | ORF r/w | SO r
4617
+ AFM r | ERF r/w | LFP r | ORI r/w | SR2 r/w
4618
+ AI r/w | EXE r | LIF r | OTF r | SRF r
4619
+ AIFF r | EXIF r/w/c | LNK r | PAC r | SRW r/w
4620
+ APE r | EXR r | LRV r/w | PAGES r | SVG r
4621
+ ARQ r/w | EXV r/w/c | M2TS r | PBM r/w | SWF r
4622
+ ARW r/w | F4A/V r/w | M4A/V r/w | PCD r | THM r/w
4623
+ ASF r | FFF r/w | MACOS r | PCX r | TIFF r/w
4624
+ AVI r | FITS r | MAX r | PDB r | TORRENT r
4625
+ AVIF r/w | FLA r | MEF r/w | PDF r/w | TTC r
4626
+ AZW r | FLAC r | MIE r/w/c | PEF r/w | TTF r
4627
+ BMP r | FLIF r/w | MIFF r | PFA r | TXT r
4628
+ BPG r | FLV r | MKA r | PFB r | VCF r
4629
+ BTF r | FPF r | MKS r | PFM r | VNT r
4630
+ CHM r | FPX r | MKV r | PGF r | VRD r/w/c
4631
+ COS r | GIF r/w | MNG r/w | PGM r/w | VSD r
4632
+ CR2 r/w | GPR r/w | MOBI r | PLIST r | WAV r
4633
+ CR3 r/w | GZ r | MODD r | PICT r | WDP r/w
4634
+ CRM r/w | HDP r/w | MOI r | PMP r | WEBP r/w
4635
+ CRW r/w | HDR r | MOS r/w | PNG r/w | WEBM r
4636
+ CS1 r/w | HEIC r/w | MOV r/w | PPM r/w | WMA r
4637
+ CSV r | HEIF r/w | MP3 r | PPT r | WMV r
4638
+ CUR r | HTML r | MP4 r/w | PPTX r | WPG r
4639
+ CZI r | ICC r/w/c | MPC r | PS r/w | WTV r
4640
+ DCM r | ICO r | MPG r | PSB r/w | WV r
4641
+ DCP r/w | ICS r | MPO r/w | PSD r/w | X3F r/w
4642
+ DCR r | IDML r | MQV r/w | PSP r | XCF r
4643
+ DFONT r | IIQ r/w | MRC r | QTIF r/w | XLS r
4644
+ DIVX r | IND r/w | MRW r/w | R3D r | XLSX r
4645
+ DJVU r | INSP r/w | MXF r | RA r | XMP r/w/c
4646
+ DLL r | INSV r | NEF r/w | RAF r/w | ZIP r
4647
+ DNG r/w | INX r | NKSC r/w | RAM r |
4648
+ DOC r | ISO r | NRW r/w | RAR r |
4649
+ DOCX r | ITC r | NUMBERS r | RAW r/w |
4650
+ DPX r | J2C r | O r | RIFF r |
4578
4651
 
4579
4652
  Meta Information
4580
4653
  ----------------------+----------------------+---------------------
@@ -4612,7 +4685,7 @@ L<Tag operations|/Tag operations>
4612
4685
  -TAG or --TAG Extract or exclude specified tag
4613
4686
  -TAG[+-^]=[VALUE] Write new value for tag
4614
4687
  -TAG[+-]<=DATFILE Write tag value from contents of file
4615
- -TAG[+-]<SRCTAG Copy tag value (see -tagsFromFile)
4688
+ -[+]TAG[+-]<SRCTAG Copy tag value (see -tagsFromFile)
4616
4689
 
4617
4690
  -tagsFromFile SRCFILE Copy tag values from file
4618
4691
  -x TAG (-exclude) Exclude specified tag
@@ -4672,7 +4745,7 @@ L<Processing control|/Processing control>
4672
4745
  -overwrite_original_in_place Overwrite original by copying tmp file
4673
4746
  -P (-preserve) Preserve file modification date/time
4674
4747
  -password PASSWD Password for processing protected files
4675
- -progress[:[TITLE]] Show file progress count
4748
+ -progress[NUM][:[TITLE]] Show file progress count
4676
4749
  -q (-quiet) Quiet processing
4677
4750
  -r[.] (-recurse) Recursively process subdirectories
4678
4751
  -scanForXMP Brute force XMP scan
@@ -4708,6 +4781,7 @@ L<Advanced options|/Advanced options>
4708
4781
  -echo[NUM] TEXT Echo text to stdout or stderr
4709
4782
  -efile[NUM][!] ERRFILE Save names of files with errors
4710
4783
  -execute[NUM] Execute multiple commands on one line
4784
+ -fileNUM ALTFILE Load tags from alternate file
4711
4785
  -list_dir List directories, not their contents
4712
4786
  -srcfile FMT Process a different source file
4713
4787
  -stay_open FLAG Keep reading -@ argfile even after EOF
@@ -4728,8 +4802,9 @@ L<Image::ExifTool::TagNames|Image::ExifTool::TagNames> for documentation on
4728
4802
  available tag names. A tag name may include leading group names separated
4729
4803
  by colons (eg. C<-EXIF:CreateDate>, or C<-Doc1:XMP:Creator>), and each group
4730
4804
  name may be prefixed by a digit to specify family number (eg.
4731
- C<-1IPTC:City>). Use the B<-listg> option to list available group names by
4732
- family.
4805
+ C<-1IPTC:City>). (Note that the API SavePath and SaveFormat options must be
4806
+ used for the family 5 and 6 groups respectively to be available.) Use the
4807
+ B<-listg> option to list available group names by family.
4733
4808
 
4734
4809
  A special tag name of C<All> may be used to indicate all meta information
4735
4810
  (ie. B<-All>). This is particularly useful when a group name is specified
@@ -4737,10 +4812,11 @@ to extract all information in a group (but beware that unless the B<-a>
4737
4812
  option is also used, some tags in the group may be suppressed by same-named
4738
4813
  tags in other groups). The wildcard characters C<?> and C<*> may be used in
4739
4814
  a tag name to match any single character and zero or more characters
4740
- respectively. These may not be used in a group name, with the exception that
4741
- a group name of C<*> (or C<All>) may be used to extract all instances of a
4742
- tag (as if B<-a> was used). Note that arguments containing wildcards must
4743
- be quoted on the command line of most systems to prevent shell globbing.
4815
+ respectively. These may not be used in a group name, with the exception
4816
+ that a group name of C<*> (or C<All>) may be used to extract all instances
4817
+ of a tag (as if B<-a> was used). Note that arguments containing wildcards
4818
+ must be quoted on the command line of most systems to prevent shell
4819
+ globbing.
4744
4820
 
4745
4821
  A C<#> may be appended to the tag name to disable the print conversion on a
4746
4822
  per-tag basis (see the B<-n> option). This may also be used when writing or
@@ -4819,6 +4895,9 @@ are removed if the containing group is deleted:
4819
4895
  - Deleting EXIF only removes ExifIFD which also deletes
4820
4896
  InteropIFD and MakerNotes.
4821
4897
 
4898
+ MOV/MP4 Video:
4899
+ - Deleting ItemList also deletes Keys tags.
4900
+
4822
4901
  Notes:
4823
4902
 
4824
4903
  1) B<Many tag values may be assigned in a single command>. If two
@@ -4915,7 +4994,9 @@ prevent shell redirection, and there is no C<=> sign as when assigning new
4915
4994
  values. Source and/or destination tags may be prefixed by a group name
4916
4995
  and/or suffixed by C<#>. Wildcards are allowed in both the source and
4917
4996
  destination tag names. A destination group and/or tag name of C<All> or
4918
- C<*> writes to the same family 1 group and/or tag name as the source. If no
4997
+ C<*> writes to the same family 1 group and/or tag name as the source (but
4998
+ the family may be specified by adding a leading number to the group name,
4999
+ eg. C<0All> writes to the same family 0 group as the source). If no
4919
5000
  destination group is specified, the information is written to the preferred
4920
5001
  group. Whitespace around the C<E<gt>> or C<E<lt>> is ignored. As a
4921
5002
  convenience, C<-tagsFromFile @> is assumed for any redirected tags which are
@@ -4973,16 +5054,14 @@ for list-type tags and conditional replacements because each copy operation
4973
5054
  on a tag overrides any previous operations. While this avoids duplicate
4974
5055
  list items when copying groups of tags from a file containing redundant
4975
5056
  information, it also prevents values of different tags from being copied
4976
- into the same list when this is the intent. So a B<-addTagsFromFile> option
4977
- is provided which allows copying of multiple tags into the same list. eg)
5057
+ into the same list when this is the intent. To accumulate values
5058
+ from different operations into the same list, add a C<+> after the initial
5059
+ C<-> of the argument. For example:
4978
5060
 
4979
- exiftool -addtagsfromfile @ '-subject<make' '-subject<model' ...
5061
+ exiftool -tagsfromfile @ '-subject<make' '-+subject<model' ...
4980
5062
 
4981
- Similarly, B<-addTagsFromFile> must be used when conditionally replacing a
4982
- tag to prevent overriding earlier conditions.
4983
-
4984
- Other than these differences, the B<-tagsFromFile> and B<-addTagsFromFile>
4985
- options are equivalent.
5063
+ Similarly, C<-+DSTTAG> must be used when conditionally replacing a tag to
5064
+ prevent overriding earlier conditions.
4986
5065
 
4987
5066
  6) The B<-a> option (allow duplicate tags) is always in effect when copying
4988
5067
  tags from I<SRCFILE>, but the highest priority tag is always copied last so
@@ -5249,12 +5328,12 @@ escaped. The inverse conversion is applied when writing tags.
5249
5328
 
5250
5329
  =item B<-f> (B<-forcePrint>)
5251
5330
 
5252
- Force printing of tags even if their values are not found. This option only
5253
- applies when specific tags are requested on the command line (ie. not with
5254
- wildcards or by C<-all>). With this option, a dash (C<->) is printed for
5255
- the value of any missing tag, but the dash may be changed via the API
5256
- MissingTagValue option. May also be used to add a 'flags' attribute to the
5257
- B<-listx> output, or to allow tags to be deleted when writing with the
5331
+ Force printing of tags even if they don't exist. This option applies to
5332
+ tags specified on the command line, or with the B<-p>, B<-if> or
5333
+ B<-tagsFromFile> options. When B<-f> is used, the value of any missing tag
5334
+ is set to a dash (C<->) by default, but this may be configured via the API
5335
+ MissingTagValue option. B<-f> is also used to add a 'flags' attribute to
5336
+ the B<-listx> output, or to allow tags to be deleted when writing with the
5258
5337
  B<-csv>=I<CSVFILE> feature.
5259
5338
 
5260
5339
  =item B<-g>[I<NUM>][:I<NUM>...] (B<-groupHeadings>)
@@ -5262,15 +5341,15 @@ B<-csv>=I<CSVFILE> feature.
5262
5341
  Organize output by tag group. I<NUM> specifies a group family number, and
5263
5342
  may be 0 (general location), 1 (specific location), 2 (category), 3
5264
5343
  (document number), 4 (instance number), 5 (metadata path), 6 (EXIF/TIFF
5265
- format) or 7 (tag ID). B<-g0> is assumed if a family number is not
5266
- specified. May be combined with other options to add group names to the
5267
- output. Multiple families may be specified by separating them with colons.
5268
- By default the resulting group name is simplified by removing any leading
5269
- C<Main:> and collapsing adjacent identical group names, but this can be
5270
- avoided by placing a colon before the first family number (eg. B<-g:3:1>).
5271
- Use the B<-listg> option to list group names for a specified family. The
5272
- API SavePath and SaveFormat options are automatically enabled if the
5273
- respective family 5 or 6 group names are requested. See the
5344
+ format), 7 (tag ID) or 8 (file number). B<-g0> is assumed if a family
5345
+ number is not specified. May be combined with other options to add group
5346
+ names to the output. Multiple families may be specified by separating them
5347
+ with colons. By default the resulting group name is simplified by removing
5348
+ any leading C<Main:> and collapsing adjacent identical group names, but this
5349
+ can be avoided by placing a colon before the first family number (eg.
5350
+ B<-g:3:1>). Use the B<-listg> option to list group names for a specified
5351
+ family. The API SavePath and SaveFormat options are automatically enabled
5352
+ if the respective family 5 or 6 group names are requested. See the
5274
5353
  L<API GetGroup documentation|Image::ExifTool/GetGroup> for more information.
5275
5354
 
5276
5355
  =item B<-G>[I<NUM>][:I<NUM>...] (B<-groupNames>)
@@ -5449,8 +5528,9 @@ which case the string is loaded from the contents of the file. Tag names in
5449
5528
  the format file or string begin with a C<$> symbol and may contain leading
5450
5529
  group names and/or a trailing C<#> (to disable print conversion). Case is
5451
5530
  not significant. Braces C<{}> may be used around the tag name to separate
5452
- it from subsequent text. Use C<$$> to represent a C<$> symbol, and C<$/>
5453
- for a newline.
5531
+ it from subsequent text (and must be used if subsequent text begins with an
5532
+ alphanumeric character, hyphen, underline, colon or number sign). Use C<$$>
5533
+ to represent a C<$> symbol, and C<$/> for a newline.
5454
5534
 
5455
5535
  Multiple B<-p> options may be used, each contributing a line (or more) of
5456
5536
  text to the output. Lines beginning with C<#[HEAD]> and C<#[TAIL]> are
@@ -5477,7 +5557,7 @@ with this command:
5477
5557
 
5478
5558
  produces output like this:
5479
5559
 
5480
- -- Generated by ExifTool 12.56 --
5560
+ -- Generated by ExifTool 12.62 --
5481
5561
  File: a.jpg - 2003:10:31 15:44:19
5482
5562
  (f/5.6, 1/60s, ISO 100)
5483
5563
  File: b.jpg - 2006:05:23 11:57:38
@@ -6110,7 +6190,7 @@ If a password is required but not given, a warning is issued and the
6110
6190
  document is not processed. This option is ignored if a password is not
6111
6191
  required.
6112
6192
 
6113
- =item B<-progress>[:[I<TITLE>]]
6193
+ =item B<-progress>[NUM][:[I<TITLE>]]
6114
6194
 
6115
6195
  Show the progress when processing files. Without a colon, the B<-progress>
6116
6196
  option adds a progress count in brackets after the name of each processed
@@ -6118,17 +6198,19 @@ file, giving the current file number and the total number of files to be
6118
6198
  processed. Implies the B<-v0> option, causing the names of processed files
6119
6199
  to also be printed when writing. When combined with the B<-if> option, the
6120
6200
  total count includes all files before the condition is applied, but files
6121
- that fail the condition will not have their names printed.
6201
+ that fail the condition will not have their names printed. If NUM is
6202
+ specified, the progress is shown every NUM input files.
6122
6203
 
6123
6204
  If followed by a colon (ie. B<-progress:>), the console window title is set
6124
6205
  according to the specified I<TITLE> string. If no I<TITLE> is given, a
6125
6206
  default I<TITLE> string of "ExifTool %p%%" is assumed. In the string, %f
6126
6207
  represents the file name, %p is the progress as a percent, %r is the
6127
- progress as a ratio, %##b is a progress bar of width "##" (20 characters if
6128
- "##" is omitted), and %% is a % character. May be combined with the normal
6129
- B<-progress> option to also show the progress count in console messages.
6130
- (Note: For this feature to function correctly on Mac/Linux, stderr must go
6131
- to the console.)
6208
+ progress as a ratio, %##b is a progress bar of width "##" (where "##" is an
6209
+ integer specifying the bar width in characters, or 20 characters by default
6210
+ if "##" is omitted), and %% is a % character. May be combined with the
6211
+ normal B<-progress> option to also show the progress count in console
6212
+ messages. (Note: For this feature to function correctly on Mac/Linux, stderr
6213
+ must go to the console.)
6132
6214
 
6133
6215
  =item B<-q> (B<-quiet>)
6134
6216
 
@@ -6366,12 +6448,12 @@ I<SHIFT> string. For example:
6366
6448
 
6367
6449
  Add features from specified plug-in I<MODULE>. Currently, the MWG module is
6368
6450
  the only plug-in module distributed with exiftool. This module adds
6369
- read/write support for tags as recommended by the Metadata Working Group.
6370
- As a convenience, C<-use MWG> is assumed if the C<MWG> group is specified
6371
- for any tag on the command line. See the L<MWG Tags
6372
- documentation|Image::ExifTool::TagNames/MWG Tags> for more details. Note
6373
- that this option is not reversible, and remains in effect until the
6374
- application terminates, even across the B<-execute> option.
6451
+ read/write support for tags as recommended by the Metadata Working Group. As
6452
+ a convenience, C<-use MWG> is assumed if the group name prefix starts with
6453
+ C<MWG:> exactly for any requested tag. See the
6454
+ L<MWG Tags documentation|Image::ExifTool::TagNames/MWG Tags> for more
6455
+ details. Note that this option is not reversible, and remains in effect
6456
+ until the application terminates, even across the B<-execute> option.
6375
6457
 
6376
6458
  =back
6377
6459
 
@@ -6457,10 +6539,11 @@ exit status of the command (see L</EXIT STATUS>).
6457
6539
 
6458
6540
  Save the names of files giving errors (I<NUM> missing or 1), files that were
6459
6541
  unchanged (I<NUM> is 2), files that fail the B<-if> condition (I<NUM> is 4),
6460
- or any combination thereof by summing I<NUM> (eg. B<-efile3> is the same
6461
- has having both B<-efile> and B<-efile2> options with the same I<ERRFILE>).
6462
- By default, file names are appended to any existing I<ERRFILE>, but
6463
- I<ERRFILE> is overwritten if an exclamation point is added to the option
6542
+ files that were updated (I<NUM> is 8), files that were created (I<NUM> is
6543
+ 16), or any combination thereof by summing I<NUM> (eg. B<-efile3> is the
6544
+ same has having both B<-efile> and B<-efile2> options with the same
6545
+ I<ERRFILE>). By default, file names are appended to any existing I<ERRFILE>,
6546
+ but I<ERRFILE> is overwritten if an exclamation point is added to the option
6464
6547
  (eg. B<-efile!>). Saves the name of the file specified by the B<-srcfile>
6465
6548
  option if applicable.
6466
6549
 
@@ -6475,6 +6558,25 @@ line. I<NUM> is an optional number that is echoed in the "{ready}" message
6475
6558
  when using the B<-stay_open> feature. If a I<NUM> is specified, the B<-q>
6476
6559
  option no longer suppresses the output "{readyNUM}" message.
6477
6560
 
6561
+ =item B<-file>I<NUM> I<ALTFILE>
6562
+
6563
+ Read tags from an alternate source file. Among other things, this allows
6564
+ tags from different files to be compared and combined using the B<-if> and
6565
+ B<-p> options. Tags from alternate files are accessed via the corresponding
6566
+ family 8 group name (eg. C<File1:TAG> for the B<-file1> option, C<File2:TAG>
6567
+ for B<-file2>, etc). I<ALTFILE> may contain filename formatting codes like
6568
+ the B<-w> option (%d, %f, etc), and/or tag names with a leading C<$> symbol
6569
+ to access tags from the source file in the same way as the B<-p> option (so
6570
+ any other dollar symbol in the file name must be doubled, eg.
6571
+ C<money$$.jpg>). For example, assuming that the OriginalFileName tag has
6572
+ been set in the edited file, a command to copy Rights from the original file
6573
+ could look like this:
6574
+
6575
+ exiftool -file1 '$originalfilename' '-rights<file1:rights' edited.jpg
6576
+
6577
+ Composite tags may access tags from alternate files using the appropriate
6578
+ (case-sensitive) family 8 group name.
6579
+
6478
6580
  =item B<-list_dir>
6479
6581
 
6480
6582
  List directories themselves instead of their contents. This option