exiftool-vendored.pl 12.62.0 → 12.65.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 (54) hide show
  1. package/bin/Changes +76 -1
  2. package/bin/MANIFEST +4 -0
  3. package/bin/META.json +5 -3
  4. package/bin/META.yml +5 -3
  5. package/bin/Makefile.PL +7 -1
  6. package/bin/README +50 -46
  7. package/bin/config_files/guano.config +161 -0
  8. package/bin/exiftool +108 -75
  9. package/bin/lib/Image/ExifTool/7Z.pm +793 -0
  10. package/bin/lib/Image/ExifTool/Apple.pm +14 -7
  11. package/bin/lib/Image/ExifTool/BigTIFF.pm +8 -1
  12. package/bin/lib/Image/ExifTool/Canon.pm +4 -1
  13. package/bin/lib/Image/ExifTool/CanonRaw.pm +4 -4
  14. package/bin/lib/Image/ExifTool/CanonVRD.pm +4 -1
  15. package/bin/lib/Image/ExifTool/Exif.pm +31 -14
  16. package/bin/lib/Image/ExifTool/FlashPix.pm +8 -2
  17. package/bin/lib/Image/ExifTool/FujiFilm.pm +3 -3
  18. package/bin/lib/Image/ExifTool/GPS.pm +5 -2
  19. package/bin/lib/Image/ExifTool/Geotag.pm +4 -1
  20. package/bin/lib/Image/ExifTool/Jpeg2000.pm +226 -28
  21. package/bin/lib/Image/ExifTool/Lang/fr.pm +1467 -202
  22. package/bin/lib/Image/ExifTool/MPF.pm +2 -1
  23. package/bin/lib/Image/ExifTool/Matroska.pm +16 -1
  24. package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
  25. package/bin/lib/Image/ExifTool/Nikon.pm +939 -31
  26. package/bin/lib/Image/ExifTool/NikonCustom.pm +874 -63
  27. package/bin/lib/Image/ExifTool/PDF.pm +23 -5
  28. package/bin/lib/Image/ExifTool/PLIST.pm +8 -1
  29. package/bin/lib/Image/ExifTool/PNG.pm +6 -6
  30. package/bin/lib/Image/ExifTool/PhaseOne.pm +5 -5
  31. package/bin/lib/Image/ExifTool/QuickTime.pm +91 -30
  32. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +20 -19
  33. package/bin/lib/Image/ExifTool/README +2 -2
  34. package/bin/lib/Image/ExifTool/RIFF.pm +11 -9
  35. package/bin/lib/Image/ExifTool/Samsung.pm +227 -227
  36. package/bin/lib/Image/ExifTool/Shortcuts.pm +2 -1
  37. package/bin/lib/Image/ExifTool/SigmaRaw.pm +4 -4
  38. package/bin/lib/Image/ExifTool/Sony.pm +229 -30
  39. package/bin/lib/Image/ExifTool/TagLookup.pm +4757 -4633
  40. package/bin/lib/Image/ExifTool/TagNames.pod +706 -18
  41. package/bin/lib/Image/ExifTool/Validate.pm +17 -1
  42. package/bin/lib/Image/ExifTool/WriteExif.pl +9 -7
  43. package/bin/lib/Image/ExifTool/WriteQuickTime.pl +21 -9
  44. package/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
  45. package/bin/lib/Image/ExifTool/Writer.pl +35 -12
  46. package/bin/lib/Image/ExifTool/XMP.pm +14 -2
  47. package/bin/lib/Image/ExifTool/XMP2.pl +32 -0
  48. package/bin/lib/Image/ExifTool/XMPStruct.pl +96 -28
  49. package/bin/lib/Image/ExifTool/ZIP.pm +5 -5
  50. package/bin/lib/Image/ExifTool.pm +176 -128
  51. package/bin/lib/Image/ExifTool.pod +109 -53
  52. package/bin/perl-Image-ExifTool.spec +44 -44
  53. package/bin/pp_build_exe.args +7 -4
  54. package/package.json +3 -3
package/bin/exiftool CHANGED
@@ -11,12 +11,13 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '12.62';
14
+ my $version = '12.65';
15
15
 
16
16
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
17
+ my $exePath;
17
18
  BEGIN {
18
19
  # (undocumented -xpath option added in 11.91, must come before other options)
19
- my $exePath = @ARGV && lc($ARGV[0]) eq '-xpath' && shift() ? $^X : $0;
20
+ $exePath = @ARGV && lc($ARGV[0]) eq '-xpath' && shift() ? $^X : $0;
20
21
  # get exe directory
21
22
  my $exeDir = ($exePath =~ /(.*)[\\\/]/) ? $1 : '.';
22
23
  my $incDir = ($0 =~ /(.*)[\\\/]/) ? "$1/lib" : './lib';
@@ -297,8 +298,11 @@ my @recommends = qw(
297
298
  POSIX::strptime
298
299
  Time::Local
299
300
  Unicode::LineBreak
301
+ Compress::Raw::Lzma
300
302
  IO::Compress::RawDeflate
301
303
  IO::Uncompress::RawInflate
304
+ IO::Compress::Brotli
305
+ IO::Uncompress::Brotli
302
306
  Win32::API
303
307
  Win32::FindFile
304
308
  Win32API::File
@@ -722,6 +726,13 @@ for (;;) {
722
726
  print "ExifTool version $version$str$Image::ExifTool::RELEASE\n";
723
727
  printf "Perl version %s%s\n", $], (defined ${^UNICODE} ? " (-C${^UNICODE})" : '');
724
728
  print "Platform: $^O\n";
729
+ if ($verbose > 8) {
730
+ print "Current Dir: " . Cwd::getcwd() . "\n" if (eval { require Cwd });
731
+ print "Script Name: $0\n";
732
+ print "Exe Name: $^X\n";
733
+ print "Exe Dir: $Image::ExifTool::exeDir\n";
734
+ print "Exe Path: $exePath\n";
735
+ }
725
736
  print "Optional libraries:\n";
726
737
  foreach (@recommends) {
727
738
  next if /^Win32/ and $^O ne 'MSWin32';
@@ -803,11 +814,17 @@ for (;;) {
803
814
  /^(-?)(a|duplicates)$/i and $mt->Options(Duplicates => ($1 ? 0 : 1)), next;
804
815
  if ($a eq 'api') {
805
816
  my $opt = shift;
806
- defined $opt or Error("Expected OPT[=VAL] argument for -api option\n"), $badCmd=1, next;
807
- my $val = ($opt =~ s/=(.*)//s) ? $1 : 1;
808
- # empty string means an undefined value unless ^= is used
809
- $val = undef unless $opt =~ s/\^$// or length $val;
810
- $mt->Options($opt => $val);
817
+ if (defined $opt and length $opt) {
818
+ my $val = ($opt =~ s/=(.*)//s) ? $1 : 1;
819
+ # empty string means an undefined value unless ^= is used
820
+ $val = undef unless $opt =~ s/\^$// or length $val;
821
+ $mt->Options($opt => $val);
822
+ } else {
823
+ print "Available API Options:\n";
824
+ my $availableOptions = Image::ExifTool::AvailableOptions();
825
+ printf(" %-17s - %s\n", $$_[0], $$_[2]) foreach @$availableOptions;
826
+ $helped = 1;
827
+ }
811
828
  next;
812
829
  }
813
830
  /^arg(s|format)$/i and $argFormat = 1, next;
@@ -1465,6 +1482,10 @@ if ($csv and $csv eq 'CSV' and not $isWriting) {
1465
1482
  $binaryOutput = 0;
1466
1483
  $setCharset = 'default' unless defined $setCharset;
1467
1484
  }
1485
+ if (%printFmt) {
1486
+ Warn "The -csv option has no effect when -p is used\n";
1487
+ undef $csv;
1488
+ }
1468
1489
  require Image::ExifTool::XMP if $setCharset;
1469
1490
  }
1470
1491
 
@@ -2363,7 +2384,7 @@ TAG: foreach $tag (@foundTags) {
2363
2384
  next unless defined $val;
2364
2385
  if ($structOpt and ref $val) {
2365
2386
  # serialize structure if necessary
2366
- $val = Image::ExifTool::XMP::SerializeStruct($val) unless $xml or $json;
2387
+ $val = Image::ExifTool::XMP::SerializeStruct($et, $val) unless $xml or $json;
2367
2388
  } elsif (ref $val eq 'ARRAY') {
2368
2389
  if (defined $listItem) {
2369
2390
  # take only the specified item
@@ -2512,7 +2533,7 @@ TAG: foreach $tag (@foundTags) {
2512
2533
  my $tok = "$group:$tagName";
2513
2534
  if ($outFormat > 0) {
2514
2535
  if ($structOpt and ref $val) {
2515
- $val = Image::ExifTool::XMP::SerializeStruct($val);
2536
+ $val = Image::ExifTool::XMP::SerializeStruct($et, $val);
2516
2537
  }
2517
2538
  if ($escapeHTML) {
2518
2539
  $val =~ tr/\0-\x08\x0b\x0c\x0e-\x1f/./;
@@ -2859,7 +2880,7 @@ sub SetImageInfo($$$)
2859
2880
  }
2860
2881
  unless ($isStdout) {
2861
2882
  $outfile = NextUnusedFilename($outfile);
2862
- if ($et->Exists($outfile) and not $doSetFileName) {
2883
+ if ($et->Exists($outfile, 1) and not $doSetFileName) {
2863
2884
  Warn "Error: '${outfile}' already exists - $infile\n";
2864
2885
  EFile($infile);
2865
2886
  ++$countBadWr;
@@ -2990,7 +3011,7 @@ sub SetImageInfo($$$)
2990
3011
  $outfile = Image::ExifTool::GetNewFileName(defined $outfile ? $outfile : $file, $newDir);
2991
3012
  }
2992
3013
  $outfile = NextUnusedFilename($outfile, $infile);
2993
- if ($et->Exists($outfile)) {
3014
+ if ($et->Exists($outfile, 1)) {
2994
3015
  if ($infile eq $outfile) {
2995
3016
  undef $outfile; # not changing the file name after all
2996
3017
  # (allow for case-insensitive filesystems)
@@ -4070,6 +4091,8 @@ sub SuggestedExtension($$$)
4070
4091
  $ext = 'dr4';
4071
4092
  } elsif ($$valPt =~ /^(.{10}|.{522})(\x11\x01|\x00\x11)/s) {
4072
4093
  $ext = 'pict';
4094
+ } elsif ($$valPt =~ /^\xff\x0a|\0\0\0\x0cJXL \x0d\x0a......ftypjxl/s) {
4095
+ $ext = 'jxl';
4073
4096
  } else {
4074
4097
  $ext = 'dat';
4075
4098
  }
@@ -4216,7 +4239,7 @@ sub NextUnusedFilename($;$)
4216
4239
  }
4217
4240
  $filename .= substr($fmt, $pos); # add rest of file name
4218
4241
  # return now with filename unless file exists
4219
- return $filename unless ($mt->Exists($filename) and not defined $usedFileName{$filename}) or $usedFileName{$filename};
4242
+ return $filename unless ($mt->Exists($filename, 1) and not defined $usedFileName{$filename}) or $usedFileName{$filename};
4220
4243
  if (defined $okfile) {
4221
4244
  return $filename if $filename eq $okfile;
4222
4245
  my ($fn, $ok) = (AbsPath($filename), AbsPath($okfile));
@@ -4296,7 +4319,7 @@ sub OpenOutputFile($;@)
4296
4319
  $outfile .= $textOut;
4297
4320
  }
4298
4321
  my $mode = '>';
4299
- if ($mt->Exists($outfile)) {
4322
+ if ($mt->Exists($outfile, 1)) {
4300
4323
  unless ($textOverwrite) {
4301
4324
  Warn "Output file $outfile already exists for $file\n";
4302
4325
  return ();
@@ -4605,49 +4628,49 @@ supported by ExifTool (r = read, w = write, c = create):
4605
4628
 
4606
4629
  File Types
4607
4630
  ------------+-------------+-------------+-------------+------------
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 |
4631
+ 360 r/w | DPX r | ITC r | NUMBERS r | RAW r/w
4632
+ 3FR r | DR4 r/w/c | J2C r | O r | RIFF r
4633
+ 3G2 r/w | DSS r | JNG r/w | ODP r | RSRC r
4634
+ 3GP r/w | DV r | JP2 r/w | ODS r | RTF r
4635
+ 7Z r | DVB r/w | JPEG r/w | ODT r | RW2 r/w
4636
+ A r | DVR-MS r | JSON r | OFR r | RWL r/w
4637
+ AA r | DYLIB r | JXL r | OGG r | RWZ r
4638
+ AAE r | EIP r | K25 r | OGV r | RM r
4639
+ AAX r/w | EPS r/w | KDC r | ONP r | SEQ r
4640
+ ACR r | EPUB r | KEY r | OPUS r | SKETCH r
4641
+ AFM r | ERF r/w | LA r | ORF r/w | SO r
4642
+ AI r/w | EXE r | LFP r | ORI r/w | SR2 r/w
4643
+ AIFF r | EXIF r/w/c | LIF r | OTF r | SRF r
4644
+ APE r | EXR r | LNK r | PAC r | SRW r/w
4645
+ ARQ r/w | EXV r/w/c | LRV r/w | PAGES r | SVG r
4646
+ ARW r/w | F4A/V r/w | M2TS r | PBM r/w | SWF r
4647
+ ASF r | FFF r/w | M4A/V r/w | PCD r | THM r/w
4648
+ AVI r | FITS r | MACOS r | PCX r | TIFF r/w
4649
+ AVIF r/w | FLA r | MAX r | PDB r | TORRENT r
4650
+ AZW r | FLAC r | MEF r/w | PDF r/w | TTC r
4651
+ BMP r | FLIF r/w | MIE r/w/c | PEF r/w | TTF r
4652
+ BPG r | FLV r | MIFF r | PFA r | TXT r
4653
+ BTF r | FPF r | MKA r | PFB r | VCF r
4654
+ CHM r | FPX r | MKS r | PFM r | VNT r
4655
+ COS r | GIF r/w | MKV r | PGF r | VRD r/w/c
4656
+ CR2 r/w | GLV r/w | MNG r/w | PGM r/w | VSD r
4657
+ CR3 r/w | GPR r/w | MOBI r | PLIST r | WAV r
4658
+ CRM r/w | GZ r | MODD r | PICT r | WDP r/w
4659
+ CRW r/w | HDP r/w | MOI r | PMP r | WEBP r/w
4660
+ CS1 r/w | HDR r | MOS r/w | PNG r/w | WEBM r
4661
+ CSV r | HEIC r/w | MOV r/w | PPM r/w | WMA r
4662
+ CUR r | HEIF r/w | MP3 r | PPT r | WMV r
4663
+ CZI r | HTML r | MP4 r/w | PPTX r | WPG r
4664
+ DCM r | ICC r/w/c | MPC r | PS r/w | WTV r
4665
+ DCP r/w | ICO r | MPG r | PSB r/w | WV r
4666
+ DCR r | ICS r | MPO r/w | PSD r/w | X3F r/w
4667
+ DFONT r | IDML r | MQV r/w | PSP r | XCF r
4668
+ DIVX r | IIQ r/w | MRC r | QTIF r/w | XLS r
4669
+ DJVU r | IND r/w | MRW r/w | R3D r | XLSX r
4670
+ DLL r | INSP r/w | MXF r | RA r | XMP r/w/c
4671
+ DNG r/w | INSV r | NEF r/w | RAF r/w | ZIP r
4672
+ DOC r | INX r | NKSC r/w | RAM r |
4673
+ DOCX r | ISO r | NRW r/w | RAR r |
4651
4674
 
4652
4675
  Meta Information
4653
4676
  ----------------------+----------------------+---------------------
@@ -4860,8 +4883,8 @@ for more details). C<+=> may also be used to increment numerical values (or
4860
4883
  decrement if I<VALUE> is negative), and C<-=> may be used to conditionally
4861
4884
  delete or replace a tag (see L</WRITING EXAMPLES> for examples). C<^=> is
4862
4885
  used to write an empty string instead of deleting the tag when no I<VALUE>
4863
- is given, but otherwise it is equivalent to C<=>, but note that the caret
4864
- must be quoted on the Windows command line.
4886
+ is given, but otherwise it is equivalent to C<=>. (Note that the caret must
4887
+ be quoted on the Windows command line.)
4865
4888
 
4866
4889
  I<TAG> may contain one or more leading family 0, 1, 2 or 7 group names,
4867
4890
  prefixed by optional family numbers, and separated colons. If no group name
@@ -4927,7 +4950,9 @@ while C<-all:all=> deletes entire blocks.
4927
4950
  5) The "APP" group names ("APP0" through "APP15") are used to delete JPEG
4928
4951
  application segments which are not associated with another deletable group.
4929
4952
  For example, specifying C<-APP14:All=> will NOT delete the APP14 "Adobe"
4930
- segment because this is accomplished with C<-Adobe:All>.
4953
+ segment because this is accomplished with C<-Adobe:All>. But note that
4954
+ these unnamed APP segments may not be excluded with C<--APPxx:all>) when
4955
+ deleting all information.
4931
4956
 
4932
4957
  6) When shifting a value, the shift is applied to the original value of the
4933
4958
  tag, overriding any other values previously assigned to the tag on the same
@@ -5557,7 +5582,7 @@ with this command:
5557
5582
 
5558
5583
  produces output like this:
5559
5584
 
5560
- -- Generated by ExifTool 12.62 --
5585
+ -- Generated by ExifTool 12.65 --
5561
5586
  File: a.jpg - 2003:10:31 15:44:19
5562
5587
  (f/5.6, 1/60s, ISO 100)
5563
5588
  File: b.jpg - 2006:05:23 11:57:38
@@ -6080,13 +6105,10 @@ newline and C<$$> represents a single C<$> symbol. So Perl variables, if
6080
6105
  used, require a double C<$>, and regular expressions ending in C<$/> must
6081
6106
  use C<$$/> instead.
6082
6107
 
6083
- 4) The condition may only test tags from the file being processed. To
6084
- process one file based on tags from another, two steps are required. For
6085
- example, to process XMP sidecar files in directory C<DIR> based on tags from
6086
- the associated NEF:
6087
-
6088
- exiftool -if EXPR -p '$directory/$filename' -ext nef DIR > nef.txt
6089
- exiftool -@ nef.txt -srcfile %d%f.xmp ...
6108
+ 4) The condition accesses only tags from the file being processed unless the
6109
+ B<-fileNUM> option is used to read an alternate file and the corresponding
6110
+ family 8 group name is specified for the tag. See the B<-fileNUM> option
6111
+ details for more information.
6090
6112
 
6091
6113
  5) The B<-a> option has no effect on the evaluation of the expression, and
6092
6114
  the values of duplicate tags are accessible only by specifying a group name
@@ -6270,10 +6292,12 @@ for EXIF this is the individual IFD (the family 1 group).
6270
6292
  When reading, causes information to be extracted from .gz and .bz2
6271
6293
  compressed images (only one image per archive; requires gzip and bzip2 to be
6272
6294
  available). When writing, causes compressed information to be written if
6273
- supported by the metadata format (eg. compressed textual metadata in PNG),
6274
- disables the recommended padding in embedded XMP (saving 2424 bytes when
6275
- writing XMP in a file), and writes XMP in shorthand format -- the equivalent
6276
- of setting the API Compress=1 and Compact="NoPadding,Shorthand".
6295
+ supported by the metadata format (eg. PNG supports compressed textual
6296
+ metadata, JXL supports compressed EXIF and XML, and MIE supports any
6297
+ compressed metadata), disables the recommended padding in embedded XMP
6298
+ (saving 2424 bytes when writing XMP in a file), and writes XMP in shorthand
6299
+ format -- the equivalent of setting the API Compress=1 and
6300
+ Compact="NoPadding,Shorthand".
6277
6301
 
6278
6302
  =back
6279
6303
 
@@ -6498,13 +6522,14 @@ load exiftool for each invocation.
6498
6522
 
6499
6523
  =over 5
6500
6524
 
6501
- =item B<-api> I<OPT[[^]=[VAL]]>
6525
+ =item B<-api> [I<OPT[[^]=[VAL]]>]
6502
6526
 
6503
6527
  Set ExifTool API option. I<OPT> is an API option name. The option value is
6504
6528
  set to 1 if I<=VAL> is omitted. If I<VAL> is omitted, the option value is
6505
- set to undef if C<=> is used, or an empty string with C<^=>. See
6506
- L<Image::ExifTool Options|Image::ExifTool/Options> for a list of available
6507
- API options. This overrides API options set via the config file.
6529
+ set to undef if C<=> is used, or an empty string with C<^=>. If I<OPT> is
6530
+ not specified a list of available options is returned. See
6531
+ L<Image::ExifTool Options|Image::ExifTool/Options> for option details. This
6532
+ overrides API options set via the config file.
6508
6533
 
6509
6534
  =item B<-common_args>
6510
6535
 
@@ -6758,6 +6783,14 @@ rewritten unnecessarily:
6758
6783
 
6759
6784
  Note that function names are case sensitive.
6760
6785
 
6786
+ ExifTool 12.64 adds an API NoDups option which makes the NoDups helper
6787
+ function largely redundant, with all the functionality except the ability to
6788
+ avoid rewriting the file if there are no duplicates, but with the advantage
6789
+ the duplicates may be removed when accumulating list items from multiple
6790
+ sources. An equivalent to the above commands using this feature would be:
6791
+
6792
+ exiftool -tagsfromfile @ -keywords -api nodups a.jpg
6793
+
6761
6794
  =head1 WINDOWS UNICODE FILE NAMES
6762
6795
 
6763
6796
  In Windows, command-line arguments are specified using the current code page