exiftool-vendored.exe 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 (60) hide show
  1. package/bin/exiftool_files/Changes +115 -5
  2. package/bin/exiftool_files/LICENSE +674 -0
  3. package/bin/exiftool_files/README +45 -44
  4. package/bin/exiftool_files/config_files/example.config +1 -0
  5. package/bin/exiftool_files/config_files/rotate_regions.config +1 -1
  6. package/bin/exiftool_files/exiftool.pl +262 -160
  7. package/bin/exiftool_files/lib/Image/ExifTool/AIFF.pm +2 -2
  8. package/bin/exiftool_files/lib/Image/ExifTool/APE.pm +2 -2
  9. package/bin/exiftool_files/lib/Image/ExifTool/BMP.pm +0 -1
  10. package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +23 -19
  11. package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +26 -6
  12. package/bin/exiftool_files/lib/Image/ExifTool/CanonRaw.pm +5 -1
  13. package/bin/exiftool_files/lib/Image/ExifTool/DJI.pm +28 -2
  14. package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +77 -19
  15. package/bin/exiftool_files/lib/Image/ExifTool/FlashPix.pm +33 -10
  16. package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +7 -3
  17. package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +7 -2
  18. package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +30 -7
  19. package/bin/exiftool_files/lib/Image/ExifTool/JPEG.pm +14 -2
  20. package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +36 -11
  21. package/bin/exiftool_files/lib/Image/ExifTool/LIF.pm +10 -2
  22. package/bin/exiftool_files/lib/Image/ExifTool/LNK.pm +5 -4
  23. package/bin/exiftool_files/lib/Image/ExifTool/MIE.pm +3 -3
  24. package/bin/exiftool_files/lib/Image/ExifTool/MPEG.pm +2 -2
  25. package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +3 -2
  26. package/bin/exiftool_files/lib/Image/ExifTool/Minolta.pm +6 -7
  27. package/bin/exiftool_files/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
  28. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +1005 -909
  29. package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +2 -2
  30. package/bin/exiftool_files/lib/Image/ExifTool/NikonSettings.pm +1 -1
  31. package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +88 -6
  32. package/bin/exiftool_files/lib/Image/ExifTool/PDF.pm +17 -8
  33. package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +10 -2
  34. package/bin/exiftool_files/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
  35. package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +8 -5
  36. package/bin/exiftool_files/lib/Image/ExifTool/PhaseOne.pm +14 -1
  37. package/bin/exiftool_files/lib/Image/ExifTool/Photoshop.pm +38 -7
  38. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +48 -14
  39. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +91 -27
  40. package/bin/exiftool_files/lib/Image/ExifTool/README +19 -2
  41. package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +34 -13
  42. package/bin/exiftool_files/lib/Image/ExifTool/Rawzor.pm +2 -2
  43. package/bin/exiftool_files/lib/Image/ExifTool/Ricoh.pm +2 -1
  44. package/bin/exiftool_files/lib/Image/ExifTool/Sigma.pm +5 -4
  45. package/bin/exiftool_files/lib/Image/ExifTool/SigmaRaw.pm +9 -3
  46. package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +39 -10
  47. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4687 -4628
  48. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +338 -117
  49. package/bin/exiftool_files/lib/Image/ExifTool/Validate.pm +5 -5
  50. package/bin/exiftool_files/lib/Image/ExifTool/WPG.pm +296 -0
  51. package/bin/exiftool_files/lib/Image/ExifTool/WriteExif.pl +42 -0
  52. package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +7 -8
  53. package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +1 -1
  54. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +162 -40
  55. package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +35 -8
  56. package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +2 -1
  57. package/bin/exiftool_files/lib/Image/ExifTool/ZIP.pm +159 -41
  58. package/bin/exiftool_files/lib/Image/ExifTool.pm +286 -65
  59. package/bin/exiftool_files/lib/Image/ExifTool.pod +95 -51
  60. package/package.json +2 -2
@@ -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
  my $exePath;
@@ -69,6 +69,7 @@ sub AcceptFile($);
69
69
  sub SlurpFile($$);
70
70
  sub FilterArgfileLine($);
71
71
  sub ReadStayOpen($);
72
+ sub Progress($$);
72
73
  sub PrintTagList($@);
73
74
  sub PrintErrors($$$);
74
75
  sub Help();
@@ -95,6 +96,7 @@ my @newValues; # list of new tag values to set
95
96
  my @requestTags; # tags to request (for -p or -if option arguments)
96
97
  my @srcFmt; # source file name format strings
97
98
  my @tags; # list of tags to extract
99
+ my %altFile; # alternate files to extract information (keyed by lower-case family 8 group)
98
100
  my %appended; # list of files appended to
99
101
  my %countLink; # count hard and symbolic links made
100
102
  my %created; # list of files we created
@@ -107,6 +109,7 @@ my %outComma; # flag that output text file needs a comma
107
109
  my %outTrailer; # trailer for output text file
108
110
  my %preserveTime; # preserved timestamps for files
109
111
  my %printFmt; # the contents of the print format file
112
+ my %seqFileDir; # file sequence number in each directory
110
113
  my %setTags; # hash of list references for tags to set from files
111
114
  my %setTagsList; # list of other tag lists for multiple -tagsFromFile from the same file
112
115
  my %usedFileName; # lookup for file names we already used in TestName feature
@@ -175,7 +178,9 @@ my $pause; # pause before returning
175
178
  my $preserveTime; # flag to preserve times of updated files (2=preserve FileCreateDate only)
176
179
  my $progress; # flag to calculate total files to process (0=calculate but don't display)
177
180
  my $progressCount; # count of files processed
181
+ my $progressIncr; # increment for progress counter
178
182
  my $progressMax; # total number of files to process
183
+ my $progressNext; # next progress count to output
179
184
  my $progStr; # progress message string
180
185
  my $quiet; # flag to disable printing of informational messages / warnings
181
186
  my $rafStdin; # File::RandomAccess for stdin (if necessary to rewind)
@@ -186,7 +191,7 @@ my $saveCount; # count the number of times we will/did call SaveNewValues()
186
191
  my $scanWritable; # flag to process only writable file types
187
192
  my $sectHeader; # current section header for -p option
188
193
  my $sectTrailer; # section trailer for -p option
189
- my $seqFileBase; # sequential file number at start of directory
194
+ my $seqFileDir; # sequential file number used for %-C
190
195
  my $seqFileNum; # sequential file number used for %C
191
196
  my $setCharset; # character set setting ('default' if not set and -csv -b used)
192
197
  my $showGroup; # number of group to show (may be zero or '')
@@ -204,6 +209,7 @@ my $validFile; # flag indicating we processed a valid file
204
209
  my $verbose; # verbose setting
205
210
  my $vout; # verbose output file reference (\*STDOUT or \*STDERR)
206
211
  my $windowTitle; # title for console window
212
+ my %wroteHEAD; # list of output txt files to which we wrote HEAD
207
213
  my $xml; # flag for XML-formatted output
208
214
 
209
215
  # flag to keep the input -@ argfile open:
@@ -244,17 +250,15 @@ my %optArgs = (
244
250
  '-csvdelim' => 1,
245
251
  '-d' => 1, '-dateformat' => 1,
246
252
  '-D' => 0, # necessary to avoid matching lower-case equivalent
247
- '-echo' => 1, '-echo1' => 1, '-echo2' => 1, '-echo3' => 1, '-echo4' => 1,
248
- '-efile' => 1, '-efile1' => 1, '-efile2' => 1, '-efile3' => 1, '-efile4' => 1,
249
- '-efile!' => 1, '-efile1!' => 1, '-efile2!' => 1, '-efile3!' => 1, '-efile4!' => 1,
253
+ '-echo' => 1, '-echo#' => 1,
254
+ '-efile' => 1, '-efile#' => 1, '-efile!' => 1, '-efile#!' => 1,
250
255
  '-ext' => 1, '--ext' => 1, '-ext+' => 1, '--ext+' => 1,
251
256
  '-extension' => 1, '--extension' => 1, '-extension+' => 1, '--extension+' => 1,
252
- '-fileorder' => 1, '-fileorder0' => 1, '-fileorder1' => 1, '-fileorder2' => 1,
253
- '-fileorder3' => 1, '-fileorder4' => 1, '-fileorder5' => 1,
257
+ '-fileorder' => 1, '-fileorder#' => 1,
254
258
  '-geotag' => 1,
255
259
  '-globaltimeshift' => 1,
256
260
  '-i' => 1, '-ignore' => 1,
257
- '-if' => 1, '-if0' => 1, '-if1' => 1, '-if2' => 1, '-if3' => 1, '-if4' => 1, '-if5' => 1,
261
+ '-if' => 1, '-if#' => 1,
258
262
  '-lang' => 0, # (optional arg; cannot begin with "-")
259
263
  '-listitem' => 1,
260
264
  '-o' => 1, '-out' => 1,
@@ -375,13 +379,14 @@ if ($exePath =~ /\(([^\\\/]+)\)(.exe|.pl)?$/i) {
375
379
 
376
380
  # isolate arguments common to all commands
377
381
  if (grep /^-common_args$/i, @ARGV) {
378
- my (@newArgs, $common);
382
+ my (@newArgs, $common, $end);
379
383
  foreach (@ARGV) {
380
- if (/^-common_args$/i) {
384
+ if (/^-common_args$/i and not $end) {
381
385
  $common = 1;
382
386
  } elsif ($common) {
383
387
  push @commonArgs, $_;
384
388
  } else {
389
+ $end = 1 if $_ eq '--';
385
390
  push @newArgs, $_;
386
391
  }
387
392
  }
@@ -462,6 +467,7 @@ undef %outComma;
462
467
  undef %outTrailer;
463
468
  undef %printFmt;
464
469
  undef %preserveTime;
470
+ undef %seqFileDir;
465
471
  undef %setTags;
466
472
  undef %setTagsList;
467
473
  undef %usedFileName;
@@ -503,7 +509,9 @@ undef $outOpt;
503
509
  undef $preserveTime;
504
510
  undef $progress;
505
511
  undef $progressCount;
512
+ undef $progressIncr;
506
513
  undef $progressMax;
514
+ undef $progressNext;
507
515
  undef $recurse;
508
516
  undef $scanWritable;
509
517
  undef $sectHeader;
@@ -546,7 +554,7 @@ $quiet = 0;
546
554
  $rtnVal = 0;
547
555
  $saveCount = 0;
548
556
  $sectTrailer = '';
549
- $seqFileBase = 0;
557
+ $seqFileDir = 0;
550
558
  $seqFileNum = 0;
551
559
  $tabFormat = 0;
552
560
  $vout = \*STDOUT;
@@ -843,7 +851,7 @@ for (;;) {
843
851
  $mt->Options(Charset => $charset);
844
852
  }
845
853
  if ($evalWarning) {
846
- warn $evalWarning;
854
+ Warn $evalWarning;
847
855
  } else {
848
856
  $setCharset = $mt->Options('Charset');
849
857
  }
@@ -929,12 +937,14 @@ for (;;) {
929
937
  $mt->Options(Duplicates => 1);
930
938
  next;
931
939
  }
932
- if (/^efile(\d)?(!)?$/i) {
940
+ if (/^efile(\d+)?(!)?$/i) {
933
941
  my $arg = shift;
934
942
  defined $arg or Error("Expecting file name for -$_ option\n"), $badCmd=1, next;
935
- $efile[0] = $arg if not $1 or $1 & 0x01;
936
- $efile[1] = $arg if $1 and $1 & 0x02;
937
- $efile[2] = $arg if $1 and $1 & 0x04;
943
+ $efile[0] = $arg if not $1 or $1 & 0x01;# error
944
+ $efile[1] = $arg if $1 and $1 & 0x02; # unchanged
945
+ $efile[2] = $arg if $1 and $1 & 0x04; # failed -if condition
946
+ $efile[3] = $arg if $1 and $1 & 0x08; # updated
947
+ $efile[4] = $arg if $1 and $1 & 0x016; # created
938
948
  unlink $arg if $2;
939
949
  next;
940
950
  }
@@ -960,6 +970,10 @@ for (;;) {
960
970
  $mt->Options(FastScan => (length $1 ? $1 : 1));
961
971
  next;
962
972
  }
973
+ if (/^(file\d+)$/i) {
974
+ $altFile{lc $1} = shift or Error("Expecting file name for -file option\n"), $badCmd=1, next;
975
+ next;
976
+ }
963
977
  if (/^fileorder(\d*)$/i) {
964
978
  push @fileOrder, shift if @ARGV;
965
979
  my $num = $1 || 0;
@@ -1133,9 +1147,11 @@ for (;;) {
1133
1147
  }
1134
1148
  (/^P$/ or $a eq 'preserve') and $preserveTime = 1, next;
1135
1149
  /^password$/i and $mt->Options(Password => shift), next;
1136
- if (/^progress(:.*)?$/i) {
1137
- if ($1) {
1138
- $windowTitle = substr $1, 1;
1150
+ if (/^progress(\d*)(:.*)?$/i) {
1151
+ $progressIncr = $1 || 1;
1152
+ $progressNext = 0; # start showing progress at the first file
1153
+ if ($2) {
1154
+ $windowTitle = substr $2, 1;
1139
1155
  $windowTitle = 'ExifTool %p%%' unless length $windowTitle;
1140
1156
  $windowTitle =~ /%\d*[bpr]/ and $progress = 0 unless defined $progress;
1141
1157
  } else {
@@ -1253,7 +1269,8 @@ for (;;) {
1253
1269
  next;
1254
1270
  }
1255
1271
  if (/^(w|textout|tagout)([!+]*)$/i) {
1256
- $textOut = shift || Warn("Expecting output extension for -$_ option\n");
1272
+ # (note: all logic ignores $textOut of 0 or '')
1273
+ $textOut = shift || Warn("Expecting argument for -$_ option\n");
1257
1274
  my ($t1, $t2) = ($1, $2);
1258
1275
  $textOverwrite = 0;
1259
1276
  $textOverwrite += 1 if $t2 =~ /!/; # overwrite
@@ -1337,7 +1354,7 @@ for (;;) {
1337
1354
  AddSetTagsFile($setTagsFile = '@') if not $setTagsFile and /(<|>)/;
1338
1355
  if ($setTagsFile) {
1339
1356
  push @{$setTags{$setTagsFile}}, $_;
1340
- if (/>/) {
1357
+ if ($1 eq '>') {
1341
1358
  $useMWG = 1 if /^(.*>\s*)?mwg:/si;
1342
1359
  if (/\b(filename|directory|testname)#?$/i) {
1343
1360
  $doSetFileName = 1;
@@ -1709,7 +1726,7 @@ if (defined $showGroup and not (@tags and $allGroup) and ($sortOpt or not define
1709
1726
  $mt->Options(Sort => "Group$showGroup");
1710
1727
  }
1711
1728
 
1712
- if (defined $textOut) {
1729
+ if ($textOut) {
1713
1730
  CleanFilename($textOut); # make all forward slashes
1714
1731
  # add '.' before output extension if necessary
1715
1732
  $textOut = ".$textOut" unless $textOut =~ /[.%]/ or defined $tagOut;
@@ -1719,7 +1736,8 @@ if (defined $textOut) {
1719
1736
  if ($outOpt) {
1720
1737
  my $type = GetFileType($outOpt);
1721
1738
  if ($type) {
1722
- unless (CanWrite($type)) {
1739
+ # (must test original file name because we can write .webp but not other RIFF types)
1740
+ unless (CanWrite($outOpt)) {
1723
1741
  Warn "Can't write $type files\n";
1724
1742
  $rtnVal = 1;
1725
1743
  next;
@@ -1930,25 +1948,34 @@ Exit $rtnValApp; # all done
1930
1948
  sub GetImageInfo($$)
1931
1949
  {
1932
1950
  my ($et, $orig) = @_;
1933
- my (@foundTags, $info, $file, $ind);
1951
+ my (@foundTags, $info, $file, $ind, $g8);
1934
1952
 
1935
1953
  # set window title for this file if necessary
1936
1954
  if (defined $windowTitle) {
1937
- my $prog = $progressMax ? "$progressCount/$progressMax" : '0/0';
1938
- my $title = $windowTitle;
1939
- my ($num, $denom) = split '/', $prog;
1940
- my $frac = $num / ($denom || 1);
1941
- my $n = $title =~ s/%(\d+)b/%b/ ? $1 : 20; # length of bar
1942
- my $bar = int($frac * $n + 0.5);
1943
- my %lkup = (
1944
- b => ('I' x $bar) . ('.' x ($n - $bar)), # (undocumented)
1945
- f => $orig,
1946
- p => int(100 * $frac + 0.5),
1947
- r => $prog,
1948
- '%'=> '%',
1949
- );
1950
- $title =~ s/%([%bfpr])/$lkup{$1}/eg;
1951
- SetWindowTitle($title);
1955
+ if ($progressCount >= $progressNext) {
1956
+ my $prog = $progressMax ? "$progressCount/$progressMax" : '0/0';
1957
+ my $title = $windowTitle;
1958
+ my ($num, $denom) = split '/', $prog;
1959
+ my $frac = $num / ($denom || 1);
1960
+ my $n = $title =~ s/%(\d+)b/%b/ ? $1 : 20; # length of bar
1961
+ my $bar = int($frac * $n + 0.5);
1962
+ my %lkup = (
1963
+ b => ('I' x $bar) . ('.' x ($n - $bar)),
1964
+ f => $orig,
1965
+ p => int(100 * $frac + 0.5),
1966
+ r => $prog,
1967
+ '%'=> '%',
1968
+ );
1969
+ $title =~ s/%([%bfpr])/$lkup{$1}/eg;
1970
+ SetWindowTitle($title);
1971
+ if (defined $progressMax) {
1972
+ undef $progressNext;
1973
+ } else {
1974
+ $progressNext += $progressIncr;
1975
+ }
1976
+ }
1977
+ # ($progressMax is not defined for "-progress:%f")
1978
+ ++$progressCount unless defined $progressMax;
1952
1979
  }
1953
1980
  unless (length $orig or $outOpt) {
1954
1981
  Warn qq(Error: Zero-length file name - ""\n);
@@ -1972,6 +1999,15 @@ sub GetImageInfo($$)
1972
1999
  } else {
1973
2000
  $file = $orig;
1974
2001
  }
2002
+ # set alternate file names
2003
+ foreach $g8 (sort keys %altFile) {
2004
+ my $altName = $orig;
2005
+ # must double any '$' symbols in the original file name because
2006
+ # they are used for tag names in a -fileNUM argument
2007
+ $altName =~ s/\$/\$\$/g;
2008
+ $altName = FilenameSPrintf($altFile{$g8}, $altName);
2009
+ $et->SetAlternateFile($g8, $altName);
2010
+ }
1975
2011
 
1976
2012
  my $pipe = $file;
1977
2013
  if ($doUnzip) {
@@ -2042,7 +2078,7 @@ sub GetImageInfo($$)
2042
2078
  undef @foundTags if $fastCondition; # ignore if we didn't get all tags
2043
2079
  }
2044
2080
  unless ($result) {
2045
- $verbose and print $vout "-------- $file (failed condition)$progStr\n";
2081
+ Progress($vout, "-------- $file (failed condition)") if $verbose;
2046
2082
  EFile($file, 2);
2047
2083
  ++$countFailed;
2048
2084
  return;
@@ -2052,7 +2088,7 @@ sub GetImageInfo($$)
2052
2088
  undef $info if $verbose or defined $fastCondition;
2053
2089
  }
2054
2090
  if (defined $deleteOrig) {
2055
- print $vout "======== $file$progStr\n" if defined $verbose;
2091
+ Progress($vout, "======== $file") if defined $verbose;
2056
2092
  ++$count;
2057
2093
  my $original = "${file}_original";
2058
2094
  $et->Exists($original) or return;
@@ -2061,6 +2097,7 @@ sub GetImageInfo($$)
2061
2097
  push @delFiles, $original;
2062
2098
  } elsif ($et->Rename($original, $file)) {
2063
2099
  $verbose and print $vout "Restored from $original\n";
2100
+ EFile($file, 3);
2064
2101
  ++$countGoodWr;
2065
2102
  } else {
2066
2103
  Warn "Error renaming $original\n";
@@ -2070,6 +2107,8 @@ sub GetImageInfo($$)
2070
2107
  return;
2071
2108
  }
2072
2109
  ++$seqFileNum; # increment our file counter
2110
+ my ($dir) = Image::ExifTool::SplitFileName($orig);
2111
+ $seqFileDir = $seqFileDir{$dir} = ($seqFileDir{$dir} || 0) + 1;
2073
2112
 
2074
2113
  my $lineCount = 0;
2075
2114
  my ($fp, $outfile, $append);
@@ -2082,12 +2121,12 @@ sub GetImageInfo($$)
2082
2121
  }
2083
2122
 
2084
2123
  if ($isWriting) {
2085
- print $vout "======== $file$progStr\n" if defined $verbose;
2124
+ Progress($vout, "======== $file") if defined $verbose;
2086
2125
  SetImageInfo($et, $file, $orig);
2087
2126
  $info = $et->GetInfo('Warning', 'Error');
2088
2127
  PrintErrors($et, $info, $file);
2089
2128
  # close output text file if necessary
2090
- if ($outfile) {
2129
+ if (defined $outfile) {
2091
2130
  undef $tmpText;
2092
2131
  close($fp);
2093
2132
  $et->Options(TextOut => $vout);
@@ -2106,7 +2145,7 @@ sub GetImageInfo($$)
2106
2145
  unless ($file eq '-' or $et->Exists($file)) {
2107
2146
  Warn "Error: File not found - $file\n";
2108
2147
  FileNotFound($file);
2109
- $outfile and close($fp), undef($tmpText), $et->Unlink($outfile);
2148
+ defined $outfile and close($fp), undef($tmpText), $et->Unlink($outfile);
2110
2149
  EFile($file);
2111
2150
  ++$countBad;
2112
2151
  return;
@@ -2123,7 +2162,7 @@ sub GetImageInfo($$)
2123
2162
  }
2124
2163
  }
2125
2164
  $o = \*STDERR if $progress and not $o;
2126
- $o and print $o "======== $file$progStr\n";
2165
+ Progress($o, "======== $file") if $o;
2127
2166
  if ($info) {
2128
2167
  # get the information we wanted
2129
2168
  if (@tags and not %printFmt) {
@@ -2145,7 +2184,7 @@ sub GetImageInfo($$)
2145
2184
  }
2146
2185
  # all done now if we already wrote output text file (eg. verbose option)
2147
2186
  if ($fp) {
2148
- if ($outfile) {
2187
+ if (defined $outfile) {
2149
2188
  $et->Options(TextOut => \*STDOUT);
2150
2189
  undef $tmpText;
2151
2190
  if ($info->{Error}) {
@@ -2174,7 +2213,7 @@ sub GetImageInfo($$)
2174
2213
  }
2175
2214
 
2176
2215
  # open output file (or stdout if no output file) if not done already
2177
- unless ($outfile or $tagOut) {
2216
+ unless (defined $outfile or $tagOut) {
2178
2217
  ($fp, $outfile, $append) = OpenOutputFile($orig);
2179
2218
  $fp or EFile($file), ++$countBad, return;
2180
2219
  $tmpText = $outfile unless $append;
@@ -2199,6 +2238,10 @@ sub GetImageInfo($$)
2199
2238
  my $skipBody;
2200
2239
  foreach $type (qw(HEAD SECT IF BODY ENDS TAIL)) {
2201
2240
  my $prf = $printFmt{$type} or next;
2241
+ if ($type eq 'HEAD' and defined $outfile) {
2242
+ next if $wroteHEAD{$outfile};
2243
+ $wroteHEAD{$outfile} = 1;
2244
+ }
2202
2245
  next if $type eq 'BODY' and $skipBody;
2203
2246
  if ($lastDoc) {
2204
2247
  if ($doc) {
@@ -2236,7 +2279,7 @@ sub GetImageInfo($$)
2236
2279
  }
2237
2280
  }
2238
2281
  }
2239
- delete $printFmt{HEAD} unless $outfile; # print header only once per output file
2282
+ delete $printFmt{HEAD} unless defined $outfile; # print header only once per output file
2240
2283
  my $errs = $et->GetInfo('Warning', 'Error');
2241
2284
  PrintErrors($et, $errs, $file) and EFile($file);
2242
2285
  } elsif (not $disableOutput) {
@@ -2392,7 +2435,7 @@ TAG: foreach $tag (@foundTags) {
2392
2435
  next TAG;
2393
2436
  }
2394
2437
  my @groups = $et->GetGroup($tag);
2395
- $outfile and close($fp), undef($tmpText); # (shouldn't happen)
2438
+ defined $outfile and close($fp), undef($tmpText); # (shouldn't happen)
2396
2439
  my $org = $et->GetValue('OriginalRawFileName') || $et->GetValue('OriginalFileName');
2397
2440
  ($fp, $outfile, $append) = OpenOutputFile($orig, $tagName, \@groups, $ext, $org);
2398
2441
  $fp or ++$countBad, next TAG;
@@ -2505,6 +2548,7 @@ TAG: foreach $tag (@foundTags) {
2505
2548
  $xtra .= " et:table='${table}'";
2506
2549
  $xtra .= " et:index='${index}'" if defined $index;
2507
2550
  }
2551
+ # Note: New $xtra attributes must be added to %ignoreEtProp in XMP.pm!
2508
2552
  my $lastVal = $val;
2509
2553
  for ($valNum=0; $valNum<2; ++$valNum) {
2510
2554
  $val = FormatXML($val, $ind, $group);
@@ -2698,7 +2742,7 @@ TAG: foreach $tag (@foundTags) {
2698
2742
  }
2699
2743
  }
2700
2744
  }
2701
- if ($outfile) {
2745
+ if (defined $outfile) {
2702
2746
  if ($textOverwrite & 0x02) {
2703
2747
  # save state of this file if we may be appending
2704
2748
  $outComma{$outfile} = $comma;
@@ -3014,6 +3058,7 @@ sub SetImageInfo($$$)
3014
3058
  $r3 = $et->SetSystemTags($file);
3015
3059
  }
3016
3060
  if ($r0 > 0 or $r1 > 0 or $r2 > 0 or $r3 > 0) {
3061
+ EFile($infile, 3);
3017
3062
  ++$countGoodWr;
3018
3063
  } elsif ($r0 < 0 or $r1 < 0 or $r2 < 0 or $r3 < 0) {
3019
3064
  EFile($infile);
@@ -3128,6 +3173,7 @@ sub SetImageInfo($$$)
3128
3173
  $preserveTime{$file} = [ $aTime, $mTime, $cTime ];
3129
3174
  }
3130
3175
  }
3176
+ EFile($infile, 3);
3131
3177
  ++$countGoodWr;
3132
3178
  } else {
3133
3179
  close(NEW_FILE);
@@ -3143,6 +3189,7 @@ sub SetImageInfo($$$)
3143
3189
  # simply rename temporary file to replace original
3144
3190
  # (if we didn't already rename it to add "_original")
3145
3191
  } elsif ($et->Rename($tmpFile, $dstFile)) {
3192
+ EFile($infile, 3);
3146
3193
  ++$countGoodWr;
3147
3194
  } else {
3148
3195
  my $newFile = $tmpFile;
@@ -3160,21 +3207,26 @@ sub SetImageInfo($$$)
3160
3207
  # (don't delete tmp file now because it is all we have left)
3161
3208
  ++$countBadWr;
3162
3209
  } else {
3210
+ EFile($infile, 3);
3163
3211
  ++$countGoodWr;
3164
3212
  }
3165
3213
  }
3166
3214
  } elsif ($overwriteOrig) {
3167
3215
  # erase original file
3216
+ EFile($infile, 3);
3168
3217
  $et->Unlink($file) or Warn "Error erasing original $file\n";
3169
3218
  ++$countGoodWr;
3170
3219
  } else {
3220
+ EFile($infile, 4);
3171
3221
  ++$countGoodCr;
3172
3222
  }
3173
3223
  } else {
3174
3224
  # this file was created from scratch, not edited
3225
+ EFile($infile, 4);
3175
3226
  ++$countGoodCr;
3176
3227
  }
3177
3228
  } else {
3229
+ EFile($infile, 3);
3178
3230
  ++$countGoodWr;
3179
3231
  }
3180
3232
  } elsif ($success) {
@@ -3659,8 +3711,19 @@ sub ProcessFiles($;$)
3659
3711
  foreach $file (@files) {
3660
3712
  $et->Options(CharsetFileName => 'UTF8') if $utf8FileName{$file};
3661
3713
  if (defined $progressMax) {
3714
+ unless (defined $progressNext) {
3715
+ $progressNext = $progressCount + $progressIncr;
3716
+ $progressNext -= $progressNext % $progressIncr; # (show even multiples)
3717
+ $progressNext = $progressMax if $progressNext > $progressMax;
3718
+ }
3662
3719
  ++$progressCount;
3663
- $progStr = " [$progressCount/$progressMax]" if $progress;
3720
+ if ($progress) {
3721
+ if ($progressCount >= $progressNext) {
3722
+ $progStr = " [$progressCount/$progressMax]";
3723
+ } else {
3724
+ undef $progStr; # don't update progress yet
3725
+ }
3726
+ }
3664
3727
  }
3665
3728
  if ($et->IsDirectory($file) and not $listDir) {
3666
3729
  $multiFile = $validFile = 1;
@@ -3668,7 +3731,7 @@ sub ProcessFiles($;$)
3668
3731
  } elsif ($filterFlag and not AcceptFile($file)) {
3669
3732
  if ($et->Exists($file)) {
3670
3733
  $filtered = 1;
3671
- $verbose and print $vout "-------- $file (wrong extension)$progStr\n";
3734
+ Progress($vout, "-------- $file (wrong extension)") if $verbose;
3672
3735
  } else {
3673
3736
  Warn "Error: File not found - $file\n";
3674
3737
  FileNotFound($file);
@@ -3716,8 +3779,6 @@ sub ScanDir($$;$)
3716
3779
  $utf8Name = 1;
3717
3780
  }
3718
3781
  return if $ignore{$dir};
3719
- my $oldBase = $seqFileBase;
3720
- $seqFileBase = $seqFileNum;
3721
3782
  # use Win32::FindFile on Windows if available
3722
3783
  # (ReadDir will croak if there is a wildcard, so check for this)
3723
3784
  if ($^O eq 'MSWin32' and $dir !~ /[*?]/) {
@@ -3749,7 +3810,6 @@ sub ScanDir($$;$)
3749
3810
  # use standard perl library routines to read directory
3750
3811
  unless (opendir(DIR_HANDLE, $dir)) {
3751
3812
  Warn("Error opening directory $dir\n");
3752
- $seqFileBase = $oldBase + ($seqFileNum - $seqFileBase);
3753
3813
  return;
3754
3814
  }
3755
3815
  @fileList = readdir(DIR_HANDLE);
@@ -3829,8 +3889,6 @@ sub ScanDir($$;$)
3829
3889
  }
3830
3890
  ++$countDir;
3831
3891
  $et->Options(CharsetFileName => $enc); # restore original setting
3832
- # update sequential file base for parent directory
3833
- $seqFileBase = $oldBase + ($seqFileNum - $seqFileBase);
3834
3892
  }
3835
3893
 
3836
3894
  #------------------------------------------------------------------------------
@@ -4126,16 +4184,15 @@ sub NextUnusedFilename($;$)
4126
4184
  return $fmt unless $fmt =~ /%[-+]?\d*\.?\d*[lun]?[cC]/;
4127
4185
  my %sep = ( '-' => '-', '+' => '_' );
4128
4186
  my ($copy, $alpha) = (0, 'a');
4129
- my $seq = $seqFileNum - 1;
4130
4187
  for (;;) {
4131
4188
  my ($filename, $pos) = ('', 0);
4132
4189
  while ($fmt =~ /(%([-+]?)(\d*)(\.?)(\d*)([lun]?)([cC]))/g) {
4133
4190
  $filename .= substr($fmt, $pos, pos($fmt) - $pos - length($1));
4134
4191
  $pos = pos($fmt);
4135
4192
  my ($sign, $wid, $dec, $wid2, $mod, $tok) = ($2, $3 || 0, $4, $5 || 0, $6, $7);
4136
- my $diff;
4193
+ my $seq;
4137
4194
  if ($tok eq 'C') {
4138
- $diff = $wid - ($sign eq '-' ? $seqFileBase : 0);
4195
+ $seq = $wid + ($sign eq '-' ? $seqFileDir : $seqFileNum) - 1;
4139
4196
  $wid = $wid2;
4140
4197
  } else {
4141
4198
  next unless $dec or $copy;
@@ -4144,13 +4201,13 @@ sub NextUnusedFilename($;$)
4144
4201
  $filename .= $sep{$sign} if $sign;
4145
4202
  }
4146
4203
  if ($mod and $mod ne 'n') {
4147
- my $a = $tok eq 'C' ? Num2Alpha($diff + $seq) : $alpha;
4204
+ my $a = $tok eq 'C' ? Num2Alpha($seq) : $alpha;
4148
4205
  my $str = ($wid and $wid > length $a) ? 'a' x ($wid - length($a)) : '';
4149
4206
  $str .= $a;
4150
4207
  $str = uc $str if $mod eq 'u';
4151
4208
  $filename .= $str;
4152
4209
  } else {
4153
- my $c = $tok eq 'C' ? ($diff + $seq) : $copy;
4210
+ my $c = $tok eq 'C' ? $seq : $copy;
4154
4211
  my $num = $c + ($mod ? 1 : 0);
4155
4212
  $filename .= $wid ? sprintf("%.${wid}d",$num) : $num;
4156
4213
  }
@@ -4165,7 +4222,6 @@ sub NextUnusedFilename($;$)
4165
4222
  }
4166
4223
  ++$copy;
4167
4224
  ++$alpha;
4168
- ++$seq;
4169
4225
  }
4170
4226
  }
4171
4227
 
@@ -4371,9 +4427,13 @@ sub ReadStayOpen($)
4371
4427
  undef $optArgs;
4372
4428
  next unless $lastOpt eq '-stay_open' or $lastOpt eq '-@';
4373
4429
  } else {
4374
- $optArgs = $optArgs{$arg};
4375
4430
  $lastOpt = lc $arg;
4376
- $optArgs = $optArgs{$lastOpt} unless defined $optArgs;
4431
+ $optArgs = $optArgs{$arg};
4432
+ unless (defined $optArgs) {
4433
+ $optArgs = $optArgs{$lastOpt};
4434
+ # handle options with trailing numbers
4435
+ $optArgs = $optArgs{"$1#$2"} if not defined $optArgs and $lastOpt =~ /^(.*?)\d+(!?)$/;
4436
+ }
4377
4437
  next unless $lastOpt =~ /^-execute\d*$/;
4378
4438
  }
4379
4439
  $processArgs = 1;
@@ -4403,7 +4463,7 @@ sub ReadStayOpen($)
4403
4463
 
4404
4464
  #------------------------------------------------------------------------------
4405
4465
  # Add new entry to -efile output file
4406
- # Inputs: 0) file name, 1) -efile option number (0=error, 1=same, 2=failed)
4466
+ # Inputs: 0) file name, 1) -efile option number (0=error, 1=same, 2=failed, 3=updated, 4=created)
4407
4467
  sub EFile($$)
4408
4468
  {
4409
4469
  my $entry = shift;
@@ -4424,6 +4484,18 @@ sub EFile($$)
4424
4484
  }
4425
4485
  }
4426
4486
 
4487
+ #------------------------------------------------------------------------------
4488
+ # Print progress message if it is time for it
4489
+ # Inputs: 0) file ref, 1) message
4490
+ sub Progress($$)
4491
+ {
4492
+ my ($file, $msg) = @_;
4493
+ if (defined $progStr) {
4494
+ print $file $msg, $progStr, "\n";
4495
+ undef $progressNext if defined $progressMax;
4496
+ }
4497
+ }
4498
+
4427
4499
  #------------------------------------------------------------------------------
4428
4500
  # Print list of tags
4429
4501
  # Inputs: 0) message, 1-N) list of tag names
@@ -4542,48 +4614,49 @@ DESCRIPTION
4542
4614
 
4543
4615
  File Types
4544
4616
  ------------+-------------+-------------+-------------+------------
4545
- 360 r/w | DPX r | ITC r | NRW r/w | RAM r
4546
- 3FR r | DR4 r/w/c | J2C r | NUMBERS r | RAR r
4547
- 3G2 r/w | DSS r | JNG r/w | O r | RAW r/w
4548
- 3GP r/w | DV r | JP2 r/w | ODP r | RIFF r
4549
- A r | DVB r/w | JPEG r/w | ODS r | RSRC r
4550
- AA r | DVR-MS r | JSON r | ODT r | RTF r
4551
- AAE r | DYLIB r | JXL r | OFR r | RW2 r/w
4552
- AAX r/w | EIP r | K25 r | OGG r | RWL r/w
4553
- ACR r | EPS r/w | KDC r | OGV r | RWZ r
4554
- AFM r | EPUB r | KEY r | ONP r | RM r
4555
- AI r/w | ERF r/w | LA r | OPUS r | SEQ r
4556
- AIFF r | EXE r | LFP r | ORF r/w | SKETCH r
4557
- APE r | EXIF r/w/c | LIF r | ORI r/w | SO r
4558
- ARQ r/w | EXR r | LNK r | OTF r | SR2 r/w
4559
- ARW r/w | EXV r/w/c | LRV r/w | PAC r | SRF r
4560
- ASF r | F4A/V r/w | M2TS r | PAGES r | SRW r/w
4561
- AVI r | FFF r/w | M4A/V r/w | PBM r/w | SVG r
4562
- AVIF r/w | FITS r | MACOS r | PCD r | SWF r
4563
- AZW r | FLA r | MAX r | PCX r | THM r/w
4564
- BMP r | FLAC r | MEF r/w | PDB r | TIFF r/w
4565
- BPG r | FLIF r/w | MIE r/w/c | PDF r/w | TORRENT r
4566
- BTF r | FLV r | MIFF r | PEF r/w | TTC r
4567
- CHM r | FPF r | MKA r | PFA r | TTF r
4568
- COS r | FPX r | MKS r | PFB r | TXT r
4569
- CR2 r/w | GIF r/w | MKV r | PFM r | VCF r
4570
- CR3 r/w | GPR r/w | MNG r/w | PGF r | VNT r
4571
- CRM r/w | GZ r | MOBI r | PGM r/w | VRD r/w/c
4572
- CRW r/w | HDP r/w | MODD r | PLIST r | VSD r
4573
- CS1 r/w | HDR r | MOI r | PICT r | WAV r
4574
- CSV r | HEIC r/w | MOS r/w | PMP r | WDP r/w
4575
- CUR r | HEIF r/w | MOV r/w | PNG r/w | WEBP r/w
4576
- CZI r | HTML r | MP3 r | PPM r/w | WEBM r
4577
- DCM r | ICC r/w/c | MP4 r/w | PPT r | WMA r
4578
- DCP r/w | ICO r | MPC r | PPTX r | WMV r
4579
- DCR r | ICS r | MPG r | PS r/w | WTV r
4580
- DFONT r | IDML r | MPO r/w | PSB r/w | WV r
4581
- DIVX r | IIQ r/w | MQV r/w | PSD r/w | X3F r/w
4582
- DJVU r | IND r/w | MRC r | PSP r | XCF r
4583
- DLL r | INSP r/w | MRW r/w | QTIF r/w | XLS r
4584
- DNG r/w | INSV r | MXF r | R3D r | XLSX r
4585
- DOC r | INX r | NEF r/w | RA r | XMP r/w/c
4586
- DOCX r | ISO r | NKSC r/w | RAF r/w | ZIP r
4617
+ 360 r/w | DR4 r/w/c | JNG r/w | ODP r | RSRC r
4618
+ 3FR r | DSS r | JP2 r/w | ODS r | RTF r
4619
+ 3G2 r/w | DV r | JPEG r/w | ODT r | RW2 r/w
4620
+ 3GP r/w | DVB r/w | JSON r | OFR r | RWL r/w
4621
+ A r | DVR-MS r | JXL r | OGG r | RWZ r
4622
+ AA r | DYLIB r | K25 r | OGV r | RM r
4623
+ AAE r | EIP r | KDC r | ONP r | SEQ r
4624
+ AAX r/w | EPS r/w | KEY r | OPUS r | SKETCH r
4625
+ ACR r | EPUB r | LA r | ORF r/w | SO r
4626
+ AFM r | ERF r/w | LFP r | ORI r/w | SR2 r/w
4627
+ AI r/w | EXE r | LIF r | OTF r | SRF r
4628
+ AIFF r | EXIF r/w/c | LNK r | PAC r | SRW r/w
4629
+ APE r | EXR r | LRV r/w | PAGES r | SVG r
4630
+ ARQ r/w | EXV r/w/c | M2TS r | PBM r/w | SWF r
4631
+ ARW r/w | F4A/V r/w | M4A/V r/w | PCD r | THM r/w
4632
+ ASF r | FFF r/w | MACOS r | PCX r | TIFF r/w
4633
+ AVI r | FITS r | MAX r | PDB r | TORRENT r
4634
+ AVIF r/w | FLA r | MEF r/w | PDF r/w | TTC r
4635
+ AZW r | FLAC r | MIE r/w/c | PEF r/w | TTF r
4636
+ BMP r | FLIF r/w | MIFF r | PFA r | TXT r
4637
+ BPG r | FLV r | MKA r | PFB r | VCF r
4638
+ BTF r | FPF r | MKS r | PFM r | VNT r
4639
+ CHM r | FPX r | MKV r | PGF r | VRD r/w/c
4640
+ COS r | GIF r/w | MNG r/w | PGM r/w | VSD r
4641
+ CR2 r/w | GPR r/w | MOBI r | PLIST r | WAV r
4642
+ CR3 r/w | GZ r | MODD r | PICT r | WDP r/w
4643
+ CRM r/w | HDP r/w | MOI r | PMP r | WEBP r/w
4644
+ CRW r/w | HDR r | MOS r/w | PNG r/w | WEBM r
4645
+ CS1 r/w | HEIC r/w | MOV r/w | PPM r/w | WMA r
4646
+ CSV r | HEIF r/w | MP3 r | PPT r | WMV r
4647
+ CUR r | HTML r | MP4 r/w | PPTX r | WPG r
4648
+ CZI r | ICC r/w/c | MPC r | PS r/w | WTV r
4649
+ DCM r | ICO r | MPG r | PSB r/w | WV r
4650
+ DCP r/w | ICS r | MPO r/w | PSD r/w | X3F r/w
4651
+ DCR r | IDML r | MQV r/w | PSP r | XCF r
4652
+ DFONT r | IIQ r/w | MRC r | QTIF r/w | XLS r
4653
+ DIVX r | IND r/w | MRW r/w | R3D r | XLSX r
4654
+ DJVU r | INSP r/w | MXF r | RA r | XMP r/w/c
4655
+ DLL r | INSV r | NEF r/w | RAF r/w | ZIP r
4656
+ DNG r/w | INX r | NKSC r/w | RAM r |
4657
+ DOC r | ISO r | NRW r/w | RAR r |
4658
+ DOCX r | ITC r | NUMBERS r | RAW r/w |
4659
+ DPX r | J2C r | O r | RIFF r |
4587
4660
 
4588
4661
  Meta Information
4589
4662
  ----------------------+----------------------+---------------------
@@ -4620,7 +4693,7 @@ OPTIONS
4620
4693
  -TAG or --TAG Extract or exclude specified tag
4621
4694
  -TAG[+-^]=[VALUE] Write new value for tag
4622
4695
  -TAG[+-]<=DATFILE Write tag value from contents of file
4623
- -TAG[+-]<SRCTAG Copy tag value (see -tagsFromFile)
4696
+ -[+]TAG[+-]<SRCTAG Copy tag value (see -tagsFromFile)
4624
4697
 
4625
4698
  -tagsFromFile SRCFILE Copy tag values from file
4626
4699
  -x TAG (-exclude) Exclude specified tag
@@ -4680,7 +4753,7 @@ OPTIONS
4680
4753
  -overwrite_original_in_place Overwrite original by copying tmp file
4681
4754
  -P (-preserve) Preserve file modification date/time
4682
4755
  -password PASSWD Password for processing protected files
4683
- -progress[:[TITLE]] Show file progress count
4756
+ -progress[NUM][:[TITLE]] Show file progress count
4684
4757
  -q (-quiet) Quiet processing
4685
4758
  -r[.] (-recurse) Recursively process subdirectories
4686
4759
  -scanForXMP Brute force XMP scan
@@ -4716,6 +4789,7 @@ OPTIONS
4716
4789
  -echo[NUM] TEXT Echo text to stdout or stderr
4717
4790
  -efile[NUM][!] ERRFILE Save names of files with errors
4718
4791
  -execute[NUM] Execute multiple commands on one line
4792
+ -fileNUM ALTFILE Load tags from alternate file
4719
4793
  -list_dir List directories, not their contents
4720
4794
  -srcfile FMT Process a different source file
4721
4795
  -stay_open FLAG Keep reading -@ argfile even after EOF
@@ -4731,8 +4805,10 @@ OPTIONS
4731
4805
  A tag name may include leading group names separated by colons (eg.
4732
4806
  "-EXIF:CreateDate", or "-Doc1:XMP:Creator"), and each group name
4733
4807
  may be prefixed by a digit to specify family number (eg.
4734
- "-1IPTC:City"). Use the -listg option to list available group names
4735
- by family.
4808
+ "-1IPTC:City"). (Note that the API SavePath and SaveFormat options
4809
+ must be used for the family 5 and 6 groups respectively to be
4810
+ available.) Use the -listg option to list available group names by
4811
+ family.
4736
4812
 
4737
4813
  A special tag name of "All" may be used to indicate all meta
4738
4814
  information (ie. -All). This is particularly useful when a group
@@ -4829,6 +4905,9 @@ OPTIONS
4829
4905
  - Deleting EXIF only removes ExifIFD which also deletes
4830
4906
  InteropIFD and MakerNotes.
4831
4907
 
4908
+ MOV/MP4 Video:
4909
+ - Deleting ItemList also deletes Keys tags.
4910
+
4832
4911
  Notes:
4833
4912
 
4834
4913
  1) Many tag values may be assigned in a single command. If two
@@ -4932,7 +5011,9 @@ OPTIONS
4932
5011
  may be prefixed by a group name and/or suffixed by "#". Wildcards
4933
5012
  are allowed in both the source and destination tag names. A
4934
5013
  destination group and/or tag name of "All" or "*" writes to the
4935
- same family 1 group and/or tag name as the source. If no
5014
+ same family 1 group and/or tag name as the source (but the family
5015
+ may be specified by adding a leading number to the group name, eg.
5016
+ "0All" writes to the same family 0 group as the source). If no
4936
5017
  destination group is specified, the information is written to the
4937
5018
  preferred group. Whitespace around the ">" or "<" is ignored. As a
4938
5019
  convenience, "-tagsFromFile @" is assumed for any redirected tags
@@ -4993,17 +5074,14 @@ OPTIONS
4993
5074
  operations. While this avoids duplicate list items when copying
4994
5075
  groups of tags from a file containing redundant information, it
4995
5076
  also prevents values of different tags from being copied into the
4996
- same list when this is the intent. So a -addTagsFromFile option is
4997
- provided which allows copying of multiple tags into the same list.
4998
- eg)
4999
-
5000
- exiftool -addtagsfromfile @ "-subject<make" "-subject<model" ...
5077
+ same list when this is the intent. To accumulate values from
5078
+ different operations into the same list, add a "+" after the
5079
+ initial "-" of the argument. For example:
5001
5080
 
5002
- Similarly, -addTagsFromFile must be used when conditionally
5003
- replacing a tag to prevent overriding earlier conditions.
5081
+ exiftool -tagsfromfile @ '-subject<make' '-+subject<model' ...
5004
5082
 
5005
- Other than these differences, the -tagsFromFile and
5006
- -addTagsFromFile options are equivalent.
5083
+ Similarly, "-+DSTTAG" must be used when conditionally replacing a
5084
+ tag to prevent overriding earlier conditions.
5007
5085
 
5008
5086
  6) The -a option (allow duplicate tags) is always in effect when
5009
5087
  copying tags from *SRCFILE*, but the highest priority tag is always
@@ -5270,29 +5348,29 @@ OPTIONS
5270
5348
  are escaped. The inverse conversion is applied when writing tags.
5271
5349
 
5272
5350
  -f (-forcePrint)
5273
- Force printing of tags even if their values are not found. This
5274
- option only applies when specific tags are requested on the command
5275
- line (ie. not with wildcards or by "-all"). With this option, a
5276
- dash ("-") is printed for the value of any missing tag, but the
5277
- dash may be changed via the API MissingTagValue option. May also be
5278
- used to add a 'flags' attribute to the -listx output, or to allow
5279
- tags to be deleted when writing with the -csv=*CSVFILE* feature.
5351
+ Force printing of tags even if they don't exist. This option
5352
+ applies to tags specified on the command line, or with the -p, -if
5353
+ or -tagsFromFile options. When -f is used, the value of any missing
5354
+ tag is set to a dash ("-") by default, but this may be configured
5355
+ via the API MissingTagValue option. -f is also used to add a
5356
+ 'flags' attribute to the -listx output, or to allow tags to be
5357
+ deleted when writing with the -csv=*CSVFILE* feature.
5280
5358
 
5281
5359
  -g[*NUM*][:*NUM*...] (-groupHeadings)
5282
5360
  Organize output by tag group. *NUM* specifies a group family
5283
5361
  number, and may be 0 (general location), 1 (specific location), 2
5284
5362
  (category), 3 (document number), 4 (instance number), 5 (metadata
5285
- path), 6 (EXIF/TIFF format) or 7 (tag ID). -g0 is assumed if a
5286
- family number is not specified. May be combined with other options
5287
- to add group names to the output. Multiple families may be
5288
- specified by separating them with colons. By default the resulting
5289
- group name is simplified by removing any leading "Main:" and
5290
- collapsing adjacent identical group names, but this can be avoided
5291
- by placing a colon before the first family number (eg. -g:3:1). Use
5292
- the -listg option to list group names for a specified family. The
5293
- API SavePath and SaveFormat options are automatically enabled if
5294
- the respective family 5 or 6 group names are requested. See the API
5295
- GetGroup documentation for more information.
5363
+ path), 6 (EXIF/TIFF format), 7 (tag ID) or 8 (file number). -g0 is
5364
+ assumed if a family number is not specified. May be combined with
5365
+ other options to add group names to the output. Multiple families
5366
+ may be specified by separating them with colons. By default the
5367
+ resulting group name is simplified by removing any leading "Main:"
5368
+ and collapsing adjacent identical group names, but this can be
5369
+ avoided by placing a colon before the first family number (eg.
5370
+ -g:3:1). Use the -listg option to list group names for a specified
5371
+ family. The API SavePath and SaveFormat options are automatically
5372
+ enabled if the respective family 5 or 6 group names are requested.
5373
+ See the API GetGroup documentation for more information.
5296
5374
 
5297
5375
  -G[*NUM*][:*NUM*...] (-groupNames)
5298
5376
  Same as -g but print group name for each tag. -G0 is assumed if
@@ -5472,8 +5550,10 @@ OPTIONS
5472
5550
  file. Tag names in the format file or string begin with a "$"
5473
5551
  symbol and may contain leading group names and/or a trailing "#"
5474
5552
  (to disable print conversion). Case is not significant. Braces "{}"
5475
- may be used around the tag name to separate it from subsequent
5476
- text. Use $$ to represent a "$" symbol, and $/ for a newline.
5553
+ may be used around the tag name to separate it from subsequent text
5554
+ (and must be used if subsequent text begins with an alphanumeric
5555
+ character, hyphen, underline, colon or number sign). Use $$ to
5556
+ represent a "$" symbol, and $/ for a newline.
5477
5557
 
5478
5558
  Multiple -p options may be used, each contributing a line (or more)
5479
5559
  of text to the output. Lines beginning with "#[HEAD]" and "#[TAIL]"
@@ -5501,7 +5581,7 @@ OPTIONS
5501
5581
 
5502
5582
  produces output like this:
5503
5583
 
5504
- -- Generated by ExifTool 12.56 --
5584
+ -- Generated by ExifTool 12.62 --
5505
5585
  File: a.jpg - 2003:10:31 15:44:19
5506
5586
  (f/5.6, 1/60s, ISO 100)
5507
5587
  File: b.jpg - 2006:05:23 11:57:38
@@ -6144,7 +6224,7 @@ OPTIONS
6144
6224
  issued and the document is not processed. This option is ignored if
6145
6225
  a password is not required.
6146
6226
 
6147
- -progress[:[*TITLE*]]
6227
+ -progress[NUM][:[*TITLE*]]
6148
6228
  Show the progress when processing files. Without a colon, the
6149
6229
  -progress option adds a progress count in brackets after the name
6150
6230
  of each processed file, giving the current file number and the
@@ -6152,18 +6232,20 @@ OPTIONS
6152
6232
  causing the names of processed files to also be printed when
6153
6233
  writing. When combined with the -if option, the total count
6154
6234
  includes all files before the condition is applied, but files that
6155
- fail the condition will not have their names printed.
6235
+ fail the condition will not have their names printed. If NUM is
6236
+ specified, the progress is shown every NUM input files.
6156
6237
 
6157
6238
  If followed by a colon (ie. -progress:), the console window title
6158
6239
  is set according to the specified *TITLE* string. If no *TITLE* is
6159
6240
  given, a default *TITLE* string of "ExifTool %p%%" is assumed. In
6160
6241
  the string, %f represents the file name, %p is the progress as a
6161
6242
  percent, %r is the progress as a ratio, %##b is a progress bar of
6162
- width "##" (20 characters if "##" is omitted), and %% is a %
6163
- character. May be combined with the normal -progress option to also
6164
- show the progress count in console messages. (Note: For this
6165
- feature to function correctly on Mac/Linux, stderr must go to the
6166
- console.)
6243
+ width "##" (where "##" is an integer specifying the bar width in
6244
+ characters, or 20 characters by default if "##" is omitted), and %%
6245
+ is a % character. May be combined with the normal -progress option
6246
+ to also show the progress count in console messages. (Note: For
6247
+ this feature to function correctly on Mac/Linux, stderr must go to
6248
+ the console.)
6167
6249
 
6168
6250
  -q (-quiet)
6169
6251
  Quiet processing. One -q suppresses normal informational messages,
@@ -6387,10 +6469,10 @@ OPTIONS
6387
6469
  module is the only plug-in module distributed with exiftool. This
6388
6470
  module adds read/write support for tags as recommended by the
6389
6471
  Metadata Working Group. As a convenience, "-use MWG" is assumed if
6390
- the "MWG" group is specified for any tag on the command line. See
6391
- the MWG Tags documentation for more details. Note that this option
6392
- is not reversible, and remains in effect until the application
6393
- terminates, even across the -execute option.
6472
+ the group name prefix starts with "MWG:" exactly for any requested
6473
+ tag. See the MWG Tags documentation for more details. Note that
6474
+ this option is not reversible, and remains in effect until the
6475
+ application terminates, even across the -execute option.
6394
6476
 
6395
6477
  Utilities
6396
6478
  -restore_original
@@ -6462,12 +6544,13 @@ OPTIONS
6462
6544
  -efile[*NUM*][!] *ERRFILE*
6463
6545
  Save the names of files giving errors (*NUM* missing or 1), files
6464
6546
  that were unchanged (*NUM* is 2), files that fail the -if condition
6465
- (*NUM* is 4), or any combination thereof by summing *NUM* (eg.
6466
- -efile3 is the same has having both -efile and -efile2 options with
6467
- the same *ERRFILE*). By default, file names are appended to any
6468
- existing *ERRFILE*, but *ERRFILE* is overwritten if an exclamation
6469
- point is added to the option (eg. -efile!). Saves the name of the
6470
- file specified by the -srcfile option if applicable.
6547
+ (*NUM* is 4), files that were updated (*NUM* is 8), files that were
6548
+ created (*NUM* is 16), or any combination thereof by summing *NUM*
6549
+ (eg. -efile3 is the same has having both -efile and -efile2 options
6550
+ with the same *ERRFILE*). By default, file names are appended to
6551
+ any existing *ERRFILE*, but *ERRFILE* is overwritten if an
6552
+ exclamation point is added to the option (eg. -efile!). Saves the
6553
+ name of the file specified by the -srcfile option if applicable.
6471
6554
 
6472
6555
  -execute[*NUM*]
6473
6556
  Execute command for all arguments up to this point on the command
@@ -6480,6 +6563,25 @@ OPTIONS
6480
6563
  feature. If a *NUM* is specified, the -q option no longer
6481
6564
  suppresses the output "{readyNUM}" message.
6482
6565
 
6566
+ -file*NUM* *ALTFILE*
6567
+ Read tags from an alternate source file. Among other things, this
6568
+ allows tags from different files to be compared and combined using
6569
+ the -if and -p options. Tags from alternate files are accessed via
6570
+ the corresponding family 8 group name (eg. "File1:TAG" for the
6571
+ -file1 option, "File2:TAG" for -file2, etc). *ALTFILE* may contain
6572
+ filename formatting codes like the -w option (%d, %f, etc), and/or
6573
+ tag names with a leading "$" symbol to access tags from the source
6574
+ file in the same way as the -p option (so any other dollar symbol
6575
+ in the file name must be doubled, eg. "money$$.jpg"). For example,
6576
+ assuming that the OriginalFileName tag has been set in the edited
6577
+ file, a command to copy Rights from the original file could look
6578
+ like this:
6579
+
6580
+ exiftool -file1 "$originalfilename" "-rights<file1:rights" edited.jpg
6581
+
6582
+ Composite tags may access tags from alternate files using the
6583
+ appropriate (case-sensitive) family 8 group name.
6584
+
6483
6585
  -list_dir
6484
6586
  List directories themselves instead of their contents. This option
6485
6587
  effectively causes directories to be treated as normal files when