exiftool_vendored 12.76.1 → 12.81.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +105 -4
  3. data/bin/MANIFEST +29 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +4 -3
  7. data/bin/config_files/acdsee.config +37 -57
  8. data/bin/config_files/example.config +16 -2
  9. data/bin/exiftool +102 -31
  10. data/bin/lib/Image/ExifTool/Canon.pm +12 -9
  11. data/bin/lib/Image/ExifTool/CanonVRD.pm +8 -2
  12. data/bin/lib/Image/ExifTool/Exif.pm +52 -4
  13. data/bin/lib/Image/ExifTool/FujiFilm.pm +14 -5
  14. data/bin/lib/Image/ExifTool/GPS.pm +5 -3
  15. data/bin/lib/Image/ExifTool/GeoLang/cs.pm +978 -0
  16. data/bin/lib/Image/ExifTool/GeoLang/de.pm +1975 -0
  17. data/bin/lib/Image/ExifTool/GeoLang/en_ca.pm +44 -0
  18. data/bin/lib/Image/ExifTool/GeoLang/en_gb.pm +124 -0
  19. data/bin/lib/Image/ExifTool/GeoLang/es.pm +2921 -0
  20. data/bin/lib/Image/ExifTool/GeoLang/fi.pm +1116 -0
  21. data/bin/lib/Image/ExifTool/GeoLang/fr.pm +3171 -0
  22. data/bin/lib/Image/ExifTool/GeoLang/it.pm +2750 -0
  23. data/bin/lib/Image/ExifTool/GeoLang/ja.pm +10256 -0
  24. data/bin/lib/Image/ExifTool/GeoLang/ko.pm +4499 -0
  25. data/bin/lib/Image/ExifTool/GeoLang/nl.pm +1270 -0
  26. data/bin/lib/Image/ExifTool/GeoLang/pl.pm +3019 -0
  27. data/bin/lib/Image/ExifTool/GeoLang/ru.pm +18220 -0
  28. data/bin/lib/Image/ExifTool/GeoLang/sk.pm +441 -0
  29. data/bin/lib/Image/ExifTool/GeoLang/sv.pm +714 -0
  30. data/bin/lib/Image/ExifTool/GeoLang/tr.pm +452 -0
  31. data/bin/lib/Image/ExifTool/GeoLang/zh_cn.pm +2225 -0
  32. data/bin/lib/Image/ExifTool/GeoLang/zh_tw.pm +72 -0
  33. data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
  34. data/bin/lib/Image/ExifTool/Geolocation.pm +935 -0
  35. data/bin/lib/Image/ExifTool/Geotag.pm +14 -2
  36. data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -1
  37. data/bin/lib/Image/ExifTool/Import.pm +5 -2
  38. data/bin/lib/Image/ExifTool/JSON.pm +15 -10
  39. data/bin/lib/Image/ExifTool/M2TS.pm +32 -4
  40. data/bin/lib/Image/ExifTool/MWG.pm +1 -0
  41. data/bin/lib/Image/ExifTool/MacOS.pm +19 -4
  42. data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -2
  43. data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
  44. data/bin/lib/Image/ExifTool/Nikon.pm +331 -23
  45. data/bin/lib/Image/ExifTool/NikonCustom.pm +55 -1
  46. data/bin/lib/Image/ExifTool/Ogg.pm +3 -2
  47. data/bin/lib/Image/ExifTool/Olympus.pm +4 -1
  48. data/bin/lib/Image/ExifTool/OpenEXR.pm +37 -19
  49. data/bin/lib/Image/ExifTool/PDF.pm +5 -5
  50. data/bin/lib/Image/ExifTool/PNG.pm +3 -3
  51. data/bin/lib/Image/ExifTool/Pentax.pm +1 -1
  52. data/bin/lib/Image/ExifTool/QuickTime.pm +195 -12
  53. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +253 -237
  54. data/bin/lib/Image/ExifTool/README +6 -5
  55. data/bin/lib/Image/ExifTool/Sony.pm +1 -1
  56. data/bin/lib/Image/ExifTool/TagLookup.pm +4871 -4752
  57. data/bin/lib/Image/ExifTool/TagNames.pod +722 -383
  58. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +43 -9
  59. data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  60. data/bin/lib/Image/ExifTool/Writer.pl +65 -8
  61. data/bin/lib/Image/ExifTool/XMP.pm +18 -2
  62. data/bin/lib/Image/ExifTool/XMP2.pl +64 -0
  63. data/bin/lib/Image/ExifTool.pm +265 -49
  64. data/bin/lib/Image/ExifTool.pod +63 -25
  65. data/bin/perl-Image-ExifTool.spec +2 -2
  66. data/lib/exiftool_vendored/version.rb +1 -1
  67. metadata +22 -2
data/bin/exiftool CHANGED
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '12.76';
14
+ my $version = '12.81';
15
15
 
16
16
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
17
17
  my $exePath;
@@ -166,6 +166,7 @@ my $filtered; # flag indicating file was filtered by name
166
166
  my $filterFlag; # file filter flag (0x01=deny extensions, 0x02=allow extensions, 0x04=add ext)
167
167
  my $fixLen; # flag to fix description lengths when writing alternate languages
168
168
  my $forcePrint; # string to use for missing tag values (undef to not print them)
169
+ my $geoOnly; # flag to extract Geolocation tags only
169
170
  my $helped; # flag to avoid printing help if no tags specified
170
171
  my $html; # flag for html-formatted output (2=html dump)
171
172
  my $interrupted; # flag set if CTRL-C is pressed during a critical process
@@ -490,6 +491,7 @@ undef $fileHeader;
490
491
  undef $filtered;
491
492
  undef $fixLen;
492
493
  undef $forcePrint;
494
+ undef $geoOnly;
493
495
  undef $ignoreHidden;
494
496
  undef $joinLists;
495
497
  undef $langOpt;
@@ -587,6 +589,11 @@ if (not $preserveTime and $^O eq 'MSWin32') {
587
589
  $preserveTime = 2 if eval { require Win32::API } and eval { require Win32API::File };
588
590
  }
589
591
 
592
+ # add user-defined command-line arguments
593
+ if (@Image::ExifTool::UserDefined::Arguments) {
594
+ unshift @ARGV, @Image::ExifTool::UserDefined::Arguments;
595
+ }
596
+
590
597
  # parse command-line options in 2 passes...
591
598
  # pass 1: set all of our ExifTool options
592
599
  # pass 2: print all of our help and informational output (-list, -ver, etc)
@@ -663,7 +670,7 @@ for (;;) {
663
670
  next;
664
671
  }
665
672
  my $a = lc $_;
666
- if (/^list([wfrdx]|wf|g(\d*))?$/i) {
673
+ if (/^list([wfrdx]|wf|g(\d*)|geo)?$/i) {
667
674
  $pass or push @nextPass, "-$_";
668
675
  my $type = lc($1 || '');
669
676
  if (not $type or $type eq 'w' or $type eq 'x') {
@@ -712,6 +719,28 @@ for (;;) {
712
719
  PrintTagList('Recognized file extensions', GetFileType(undef, 0));
713
720
  } elsif ($type eq 'd') {
714
721
  PrintTagList('Deletable groups', GetDeleteGroups());
722
+ } elsif ($type eq 'geo') {
723
+ require Image::ExifTool::Geolocation;
724
+ my ($i, $entry);
725
+ print "Geolocation database:\n" unless $quiet;
726
+ my $isAlt = $mt->Options('GeolocAltNames') ? ',AltNames' : '';
727
+ $isAlt = '' if $isAlt and not Image::ExifTool::Geolocation::ReadAltNames();
728
+ print "City,Region,Subregion,CountryCode,Country,TimeZone,FeatureCode,Population,Latitude,Longitude$isAlt\n";
729
+ Image::ExifTool::Geolocation::SortDatabase('City') if $sortOpt;
730
+ my $minPop = $mt->Options('GeolocMinPop');
731
+ my $feature = $mt->Options('GeolocFeature') || '';
732
+ my $neg = $feature =~ s/^-//;
733
+ my %fcodes = map { lc($_) => 1 } split /\s*,\s*/, $feature;
734
+ my @isUTF8 = (0,1,2,4); # items that need converting from UTF8
735
+ push @isUTF8, 10 if $isAlt;
736
+ for ($i=0; ; ++$i) {
737
+ my @entry = Image::ExifTool::Geolocation::GetEntry($i,$langOpt,1) or last;
738
+ push @entry, Image::ExifTool::Geolocation::GetAltNames($i,1) if $isAlt;
739
+ next if $minPop and $entry[7] < $minPop;
740
+ next if %fcodes and $neg ? $fcodes{lc $entry[6]} : not $fcodes{lc $entry[6]};
741
+ $_ = defined $_ ? $mt->Decode($_, 'UTF8') : '' foreach @entry[@isUTF8];
742
+ print join(',', @entry), "\n";
743
+ }
715
744
  } else { # 'g(\d*)'
716
745
  # list all groups in specified family
717
746
  my $family = $2 || 0;
@@ -1102,7 +1131,7 @@ for (;;) {
1102
1131
  } else {
1103
1132
  $pass or push(@nextPass, '-lang'), next;
1104
1133
  }
1105
- my $langs = "Available languages:\n";
1134
+ my $langs = $quiet ? '' : "Available languages:\n";
1106
1135
  $langs .= " $_ - $Image::ExifTool::langName{$_}\n" foreach @Image::ExifTool::langs;
1107
1136
  $langs =~ tr/_/-/; # display dashes instead of underlines in language codes
1108
1137
  $langs = Image::ExifTool::HTML::EscapeHTML($langs) if $escapeHTML;
@@ -1341,11 +1370,11 @@ for (;;) {
1341
1370
  $useMWG = 1;
1342
1371
  } elsif (/^([-\w]+:)*(filename|directory|testname)\b/i) {
1343
1372
  $doSetFileName = 1;
1344
- } elsif (/^([-\w]+:)*(geotag|geotime|geosync)\b/i) {
1373
+ } elsif (/^([-\w]+:)*(geotag|geotime|geosync|geolocate)\b/i) {
1345
1374
  if (lc $2 eq 'geotime') {
1346
1375
  $addGeotime = '';
1347
1376
  } else {
1348
- # add geotag/geosync commands first
1377
+ # add geotag/geosync/geolocate commands first
1349
1378
  unshift @newValues, pop @newValues;
1350
1379
  if (lc $2 eq 'geotag' and (not defined $addGeotime or $addGeotime) and length $val) {
1351
1380
  $addGeotime = ($1 || '') . 'Geotime<DateTimeOriginal#';
@@ -1414,8 +1443,15 @@ if ($useMWG and not defined $mt->Options('CharsetEXIF')) {
1414
1443
  $mt->Options(CharsetEXIF => 'UTF8');
1415
1444
  }
1416
1445
 
1446
+ # allow geolocation without input file if set to a position
1447
+ if (not @files and not $outOpt and not @newValues) {
1448
+ my $loc = $mt->Options('Geolocation');
1449
+ # use undocumented feature to input JSON file directly from command line
1450
+ $loc and $loc ne '1' and push(@files, qq(\@JSON:{})), $geoOnly = 1;
1451
+ }
1452
+
1417
1453
  # print help
1418
- unless ((@tags and not $outOpt) or @files or @newValues) {
1454
+ unless ((@tags and not $outOpt) or @files or @newValues or $geoOnly) {
1419
1455
  if ($doGlob and $doGlob == 2) {
1420
1456
  Warn "No matching files\n";
1421
1457
  $rtnVal = 1;
@@ -2113,6 +2149,11 @@ sub GetImageInfo($$)
2113
2149
  # can't make use of $info if verbose because we must reprocess
2114
2150
  # the file anyway to generate the verbose output
2115
2151
  undef $info if $verbose or defined $fastCondition;
2152
+ } elsif ($file =~ s/^(\@JSON:)(.*)/$1/) {
2153
+ # read JSON file from command line
2154
+ my $dat = $2;
2155
+ $info = $et->ImageInfo(\$dat, \@foundTags);
2156
+ if ($geoOnly) { /^Geolocation/ or delete $$info{$_} foreach keys %$info; $file = ' ' }
2116
2157
  }
2117
2158
  if (defined $deleteOrig) {
2118
2159
  Progress($vout, "======== $file") if defined $verbose;
@@ -2169,7 +2210,7 @@ sub GetImageInfo($$)
2169
2210
  }
2170
2211
 
2171
2212
  # extract information from this file
2172
- unless ($file eq '-' or $et->Exists($file)) {
2213
+ unless ($file eq '-' or $et->Exists($file) or $info) {
2173
2214
  Warn "Error: File not found - $file\n";
2174
2215
  FileNotFound($file);
2175
2216
  defined $outfile and close($fp), undef($tmpText), $et->Unlink($outfile);
@@ -2354,7 +2395,7 @@ sub GetImageInfo($$)
2354
2395
  # set delimiters for JSON or PHP output
2355
2396
  ($bra, $ket, $sep) = $json == 1 ? ('{','}',':') : ('Array(',')',' =>');
2356
2397
  print $fp ",\n" if $comma;
2357
- print $fp qq($bra\n "SourceFile"$sep ), EscapeJSON(MyConvertFileName($et,$file));
2398
+ print $fp qq($bra\n "SourceFile"$sep ), EscapeJSON(MyConvertFileName($et,$file),1);
2358
2399
  $comma = 1;
2359
2400
  $ind = (defined $showGroup and not $allGroup) ? ' ' : ' ';
2360
2401
  } elsif ($csv) {
@@ -3372,7 +3413,22 @@ sub FormatXML($$$)
3372
3413
  my @keys = $$val{_ordered_keys_} ? @{$$val{_ordered_keys_}} : sort keys %$val;
3373
3414
  foreach (@keys) {
3374
3415
  # (some variable-namespace XML structure fields may have a different group)
3375
- my $tok = /:/ ? $_ : ($grp . ':' . $_);
3416
+ my ($ns, $tg) = ($grp, $_);
3417
+ if (/^(.*?):(.*)/) {
3418
+ if ($grp eq 'JSON') {
3419
+ $tg =~ tr/:/_/; # colons in JSON structure elements are not namespaces
3420
+ } else {
3421
+ ($ns, $tg) = ($1, $2);
3422
+ }
3423
+ }
3424
+ # validate XML attribute name
3425
+ my $name;
3426
+ foreach $name ($ns, $tg) {
3427
+ # make sure name is valid for XML
3428
+ $name =~ tr/-_A-Za-z0-9.//dc;
3429
+ $name = '_' . $name if $name !~ /^[_A-Za-z]/;
3430
+ }
3431
+ my $tok = $ns . ':' . $tg;
3376
3432
  $val2 .= "\n$ind <$tok" . FormatXML($$val{$_}, "$ind ", $grp) . "</$tok>";
3377
3433
  }
3378
3434
  $val = "$val2\n$ind";
@@ -3515,7 +3571,7 @@ sub PrintCSV()
3515
3571
  }
3516
3572
 
3517
3573
  #------------------------------------------------------------------------------
3518
- # Add tag groups from structure fields to a list
3574
+ # Add tag groups from structure fields to a list for xmlns
3519
3575
  # Inputs: 0) tag value, 1) parent group, 2) group hash ref, 3) group list ref
3520
3576
  sub AddGroups($$$$)
3521
3577
  {
@@ -3523,7 +3579,7 @@ sub AddGroups($$$$)
3523
3579
  my ($key, $val2);
3524
3580
  if (ref $val eq 'HASH') {
3525
3581
  foreach $key (sort keys %$val) {
3526
- if ($key =~ /(.*?):/ and not $$groupHash{$1}) {
3582
+ if ($key =~ /^(.*?):/ and not $$groupHash{$1} and $grp ne 'JSON') {
3527
3583
  $$groupHash{$1} = $grp;
3528
3584
  push @$groupList, $1;
3529
3585
  }
@@ -4614,7 +4670,7 @@ B<exiftool> [I<OPTIONS>] B<-tagsFromFile> I<SRCFILE>
4614
4670
  =head2 Other
4615
4671
 
4616
4672
  B<exiftool> [ B<-ver> |
4617
- B<-list>[B<w>|B<f>|B<r>|B<wf>|B<g>[I<NUM>]|B<d>|B<x>] ]
4673
+ B<-list>[B<w>|B<f>|B<r>|B<wf>|B<g>[I<NUM>]|B<d>|B<x>|B<geo>] ]
4618
4674
 
4619
4675
  For specific examples, see the L<EXAMPLES|/READING EXAMPLES> sections below.
4620
4676
 
@@ -4655,7 +4711,7 @@ supported by ExifTool (r = read, w = write, c = create):
4655
4711
  3GP r/w | DSS r | JP2 r/w | ODT r | RWL r/w
4656
4712
  7Z r | DV r | JPEG r/w | OFR r | RWZ r
4657
4713
  A r | DVB r/w | JSON r | OGG r | RM r
4658
- AA r | DVR-MS r | JXL r | OGV r | SEQ r
4714
+ AA r | DVR-MS r | JXL r/w | OGV r | SEQ r
4659
4715
  AAC r | DYLIB r | K25 r | ONP r | SKETCH r
4660
4716
  AAE r | EIP r | KDC r | OPUS r | SO r
4661
4717
  AAX r/w | EPS r/w | KEY r | ORF r/w | SR2 r/w
@@ -4824,7 +4880,7 @@ L<Advanced options|/Advanced options>
4824
4880
  -common_args Define common arguments
4825
4881
  -config CFGFILE Specify configuration file name
4826
4882
  -echo[NUM] TEXT Echo text to stdout or stderr
4827
- -efile[NUM][!] ERRFILE Save names of files with errors
4883
+ -efile[NUM][!] TXTFILE Save names of files with errors
4828
4884
  -execute[NUM] Execute multiple commands on one line
4829
4885
  -fileNUM ALTFILE Load tags from alternate file
4830
4886
  -list_dir List directories, not their contents
@@ -5216,8 +5272,9 @@ Notes:
5216
5272
  when copying tags using the B<-tagsFromFile> option.
5217
5273
 
5218
5274
  2) If the hemisphere is known, a reference direction (N, S, E or W) is
5219
- appended to each printed coordinate, but adding a C<+> to the format
5220
- specifier (eg. C<%+.6f>) prints a signed coordinate instead.
5275
+ appended to each printed coordinate, but adding a C<+> or C<-> to the format
5276
+ specifier (eg. C<%+.6f> or C<%-.6f>) prints a signed coordinate instead.
5277
+ (C<+> adds a leading "+" for positive coordinates, but C<-> does not.)
5221
5278
 
5222
5279
  3) This print formatting may be disabled with the B<-n> option to extract
5223
5280
  coordinates as signed decimal degrees.
@@ -5605,7 +5662,7 @@ with this command:
5605
5662
 
5606
5663
  produces output like this:
5607
5664
 
5608
- -- Generated by ExifTool 12.76 --
5665
+ -- Generated by ExifTool 12.81 --
5609
5666
  File: a.jpg - 2003:10:31 15:44:19
5610
5667
  (f/5.6, 1/60s, ISO 100)
5611
5668
  File: b.jpg - 2006:05:23 11:57:38
@@ -6367,22 +6424,25 @@ prevent the command window from closing when run as a Windows drag and drop
6367
6424
  application.
6368
6425
 
6369
6426
  =item B<-list>, B<-listw>, B<-listf>, B<-listr>, B<-listwf>,
6370
- B<-listg>[I<NUM>], B<-listd>, B<-listx>
6427
+ B<-listg>[I<NUM>], B<-listd>, B<-listx>, B<-listgeo>
6371
6428
 
6372
6429
  Print a list of all valid tag names (B<-list>), all writable tag names
6373
6430
  (B<-listw>), all supported file extensions (B<-listf>), all recognized file
6374
6431
  extensions (B<-listr>), all writable file extensions (B<-listwf>), all tag
6375
6432
  groups [in a specified family] (B<-listg>[I<NUM>]), all deletable tag groups
6376
- (B<-listd>), or an XML database of tag details including language
6377
- translations (B<-listx>). The B<-list>, B<-listw> and B<-listx> options may
6378
- be followed by an additional argument of the form C<-GROUP:All> to list only
6379
- tags in a specific group, where C<GROUP> is one or more family 0-2 group
6380
- names (excepting EXIF IFD groups) separated by colons. With B<-listg>,
6381
- I<NUM> may be given to specify the group family, otherwise family 0 is
6382
- assumed. The B<-l> option may be combined with B<-listf>, B<-listr> or
6383
- B<-listwf> to add file descriptions to the list. The B<-lang> option may be
6384
- combined with B<-listx> to output descriptions in a single language. Here
6385
- are some examples:
6433
+ (B<-listd>), an XML database of tag details including language translations
6434
+ (B<-listx>), or the Geolocation database (B<-listgeo>). The B<-list>,
6435
+ B<-listw> and B<-listx> options may be followed by an additional argument of
6436
+ the form C<-GROUP:All> to list only tags in a specific group, where C<GROUP>
6437
+ is one or more family 0-2 group names (excepting EXIF IFD groups) separated
6438
+ by colons. With B<-listg>, I<NUM> may be given to specify the group family,
6439
+ otherwise family 0 is assumed. The B<-l> option may be combined with
6440
+ B<-listf>, B<-listr> or B<-listwf> to add file descriptions to the list.
6441
+ The B<-lang> option may be combined with B<-listx> to output descriptions in
6442
+ a single language, and the B<-sort> and/or B<-lang> options may be combined
6443
+ with B<-listgeo>. Also, the API GeolocMinPop, GeolocFeature and
6444
+ GeolocAltNames options apply to the B<-listgeo> output. Here are some
6445
+ examples:
6386
6446
 
6387
6447
  -list # list all tag names
6388
6448
  -list -EXIF:All # list all EXIF tags
@@ -6395,6 +6455,7 @@ are some examples:
6395
6455
  -listd # list all deletable groups
6396
6456
  -listx -EXIF:All # list database of EXIF tags in XML format
6397
6457
  -listx -XMP:All -s # list short XML database of XMP tags
6458
+ -listgeo -lang de # list geolocation database in German
6398
6459
 
6399
6460
  When combined with B<-listx>, the B<-s> option shortens the output by
6400
6461
  omitting the descriptions and values (as in the last example above), and
@@ -6483,6 +6544,10 @@ examples. Also see "geotag.html" in the full ExifTool distribution and the
6483
6544
  L<Image::ExifTool Options|Image::ExifTool/Options> for more details and for
6484
6545
  information about geotag configuration options.
6485
6546
 
6547
+ The API Geolocation option may be set to the value "geotag" to also write
6548
+ the name, province/state and country of the nearest city while geotagging.
6549
+ See L<https://exiftool.org/geolocation.html> for details.
6550
+
6486
6551
  =item B<-globalTimeShift> I<SHIFT>
6487
6552
 
6488
6553
  Shift all formatted date/time values by the specified amount when reading.
@@ -6596,15 +6661,15 @@ respectively) after processing is complete. For B<-echo3> and B<-echo4>,
6596
6661
  "${status}" may be used in the I<TEXT> string to represent the numerical
6597
6662
  exit status of the command (see L</EXIT STATUS>).
6598
6663
 
6599
- =item B<-efile>[I<NUM>][!] I<ERRFILE>
6664
+ =item B<-efile>[I<NUM>][!] I<TXTFILE>
6600
6665
 
6601
6666
  Save the names of files giving errors (I<NUM> missing or 1), files that were
6602
6667
  unchanged (I<NUM> is 2), files that fail the B<-if> condition (I<NUM> is 4),
6603
6668
  files that were updated (I<NUM> is 8), files that were created (I<NUM> is
6604
6669
  16), or any combination thereof by summing I<NUM> (eg. B<-efile3> is the
6605
6670
  same has having both B<-efile> and B<-efile2> options with the same
6606
- I<ERRFILE>). By default, file names are appended to any existing I<ERRFILE>,
6607
- but I<ERRFILE> is overwritten if an exclamation point is added to the option
6671
+ I<TXTFILE>). By default, file names are appended to any existing I<TXTFILE>,
6672
+ but I<TXTFILE> is overwritten if an exclamation point is added to the option
6608
6673
  (eg. B<-efile!>). Saves the name of the file specified by the B<-srcfile>
6609
6674
  option if applicable.
6610
6675
 
@@ -7380,6 +7445,12 @@ Geotag an image (C<a.jpg>) from position information in a GPS track log
7380
7445
  DateTimeOriginal is used for geotagging. Local system time is assumed
7381
7446
  unless DateTimeOriginal contains a timezone.
7382
7447
 
7448
+ =item exiftool -geotag track.log -geolocate=geotag a.jpg
7449
+
7450
+ Geotag an image and also write geolocation information of the nearest city
7451
+ (city name, state/province and country). Read here for more details about
7452
+ the Geolocation feature: L<https://exiftool.org/geolocation.html#Write>
7453
+
7383
7454
  =item exiftool -geotag t.log -geotime='2009:04:02 13:41:12-05:00' a.jpg
7384
7455
 
7385
7456
  Geotag an image with the GPS position for a specific time.
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.73';
91
+ $VERSION = '4.74';
92
92
 
93
93
  # Note: Removed 'USM' from 'L' lenses since it is redundant - PH
94
94
  # (or is it? Ref 32 shows 5 non-USM L-type lenses)
@@ -203,7 +203,8 @@ $VERSION = '4.73';
203
203
  52 => 'Canon EF-S 18-55mm f/3.5-5.6 IS II', #PH
204
204
  53 => 'Canon EF-S 18-55mm f/3.5-5.6 III', #Jon Charnas
205
205
  54 => 'Canon EF-S 55-250mm f/4-5.6 IS II', #47
206
- 60 => 'Irix 11mm f/4', #50
206
+ 60 => 'Irix 11mm f/4 or 15mm f/2.4', #50
207
+ 60.1 => 'Irix 15mm f/2.4', #forum15655
207
208
  63 => 'Irix 30mm F1.4 Dragonfly', #IB
208
209
  80 => 'Canon TS-E 50mm f/2.8L Macro', #42
209
210
  81 => 'Canon TS-E 90mm f/2.8L Macro', #42
@@ -4731,6 +4732,7 @@ my %ciMaxFocal = (
4731
4732
  NOTES => 'CameraInfo tags for the PowerShot G5 X Mark II.',
4732
4733
  0x0293 => {
4733
4734
  Name => 'ShutterCount',
4735
+ Condition => '$$self{FileType} eq "JPEG"',
4734
4736
  Format => 'int32u',
4735
4737
  Notes => 'includes electronic + mechanical shutter',
4736
4738
  # - advances by 1 for each photo file, regardless of mechanical or electronic shutter
@@ -4738,26 +4740,27 @@ my %ciMaxFocal = (
4738
4740
  # - advances for time lapse video files
4739
4741
  # - creating a new directory or resetting the counter from the menu doesn't affect this shutter count
4740
4742
  },
4743
+ 0x0a95 => {
4744
+ Name => 'ShutterCount',
4745
+ Condition => '$$self{FileType} eq "CR3"',
4746
+ Format => 'int32u',
4747
+ Notes => 'includes electronic + mechanical shutter',
4748
+ },
4741
4749
  0x0b21 => {
4742
4750
  Name => 'DirectoryIndex',
4751
+ Condition => '$$self{FileType} eq "JPEG"',
4743
4752
  Groups => { 2 => 'Image' },
4744
4753
  Format => 'int32u',
4745
4754
  },
4746
4755
  0x0b2d => {
4747
4756
  Name => 'FileIndex',
4757
+ Condition => '$$self{FileType} eq "JPEG"',
4748
4758
  Format => 'int32u',
4749
4759
  Groups => { 2 => 'Image' },
4750
4760
  Format => 'int32u',
4751
4761
  ValueConv => '$val + 1',
4752
4762
  ValueConvInv => '$val - 1',
4753
4763
  },
4754
- #0x0b39 => {
4755
- # Name => 'DirectoryIndex',
4756
- # Groups => { 2 => 'Image' },
4757
- # Format => 'int32u',
4758
- # ValueConv => '$val - 1',
4759
- # ValueConvInv => '$val + 1',
4760
- #},
4761
4764
  );
4762
4765
 
4763
4766
  # Canon camera information for 70D (MakerNotes tag 0x0d) (ref PH)
@@ -23,7 +23,7 @@ use vars qw($VERSION);
23
23
  use Image::ExifTool qw(:DataAccess :Utils);
24
24
  use Image::ExifTool::Canon;
25
25
 
26
- $VERSION = '1.37';
26
+ $VERSION = '1.39';
27
27
 
28
28
  sub ProcessCanonVRD($$;$);
29
29
  sub WriteCanonVRD($$;$);
@@ -51,6 +51,7 @@ my %vrdFormat = (
51
51
  8 => 'int32u',
52
52
  9 => 'int32s',
53
53
  13 => 'double',
54
+ 24 => 'int32s', # (rectangle coordinates)
54
55
  33 => 'int32u', # (array)
55
56
  38 => 'double', # (array)
56
57
  # 254 => 'undef', ?
@@ -1226,6 +1227,11 @@ my $blankFooter = "CANON OPTIONAL DATA\0" . ("\0" x 42) . "\xff\xd9";
1226
1227
  # 0x20a08 - (unknown picture style settings)
1227
1228
  # 0x20a09 - Custom picture style settings
1228
1229
  # 0x20a20 - Fine Detail picture style settings
1230
+ 0x20b10 => 'DPRAWMicroadjustBackFront', #forum15660
1231
+ 0x20b12 => 'DPRAWMicroadjustStrength', #forum15660
1232
+ 0x20b20 => 'DPRAWBokehShift', #forum15660
1233
+ 0x20b21 => 'DPRAWBokehShiftArea', #PH
1234
+ 0x20b30 => 'DPRAWGhostingReductionArea', #forum15660
1229
1235
  0x30101 => {
1230
1236
  Name => 'CropAspectRatio',
1231
1237
  PrintConv => {
@@ -1752,7 +1758,7 @@ sub ProcessDR4($$;$)
1752
1758
  } else {
1753
1759
  # load DR4 file into memory
1754
1760
  my $buff;
1755
- $raf->Read($buff, 8) == 8 and $buff eq "IIII\x04\0\x04\0" or return 0;
1761
+ $raf->Read($buff, 8) == 8 and $buff =~ /^IIII[\x04|\x05]\0\x04\0/ or return 0;
1756
1762
  $et->SetFileType();
1757
1763
  $raf->Seek(0, 2) or return $err = 1;
1758
1764
  $dirLen = $raf->Tell();
@@ -57,7 +57,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
57
57
  use Image::ExifTool qw(:DataAccess :Utils);
58
58
  use Image::ExifTool::MakerNotes;
59
59
 
60
- $VERSION = '4.50';
60
+ $VERSION = '4.51';
61
61
 
62
62
  sub ProcessExif($$$);
63
63
  sub WriteExif($$$);
@@ -593,6 +593,14 @@ my %opcodeInfo = (
593
593
  OffsetPair => 0x117, # point to associated byte counts
594
594
  DataTag => 'OtherImage',
595
595
  },
596
+ {
597
+ Condition => '$$self{Compression} and $$self{Compression} eq "52546"', # DNG 1.7 Jpeg XL
598
+ Name => 'PreviewJXLStart',
599
+ IsOffset => 1,
600
+ IsImageData => 1,
601
+ OffsetPair => 0x117, # point to associated byte counts
602
+ DataTag => 'PreviewJXL',
603
+ },
596
604
  {
597
605
  # (APP1 IFD2 is for Leica JPEG preview)
598
606
  Condition => q[
@@ -687,6 +695,12 @@ my %opcodeInfo = (
687
695
  OffsetPair => 0x111, # point to associated offset
688
696
  DataTag => 'OtherImage',
689
697
  },
698
+ {
699
+ Condition => '$$self{Compression} and $$self{Compression} eq "52546"', # DNG 1.7 Jpeg XL
700
+ Name => 'PreviewJXLLength',
701
+ OffsetPair => 0x111, # point to associated offset
702
+ DataTag => 'PreviewJXL',
703
+ },
690
704
  {
691
705
  # (APP1 IFD2 is for Leica JPEG preview)
692
706
  Condition => q[
@@ -2421,7 +2435,7 @@ my %opcodeInfo = (
2421
2435
  Count => -1, # 2, 3 or 4 values
2422
2436
  },
2423
2437
  0x9215 => 'ExposureIndex', #12
2424
- 0x9216 => 'TIFF-EPStandardID', #12
2438
+ 0x9216 => { Name => 'TIFF-EPStandardID', PrintConv => '$val =~ tr/ /./; $val' }, #12
2425
2439
  0x9217 => { #12
2426
2440
  Name => 'SensingMethod',
2427
2441
  Groups => { 2 => 'Camera' },
@@ -2711,7 +2725,7 @@ my %opcodeInfo = (
2711
2725
  Count => 2,
2712
2726
  },
2713
2727
  0xa215 => { Name => 'ExposureIndex', Writable => 'rational64u' },
2714
- 0xa216 => 'TIFF-EPStandardID',
2728
+ 0xa216 => { Name => 'TIFF-EPStandardID', PrintConv => '$val =~ tr/ /./; $val' },
2715
2729
  0xa217 => {
2716
2730
  Name => 'SensingMethod',
2717
2731
  Groups => { 2 => 'Camera' },
@@ -4971,6 +4985,39 @@ my %subSecConv = (
4971
4985
  Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"OtherImage");
4972
4986
  },
4973
4987
  },
4988
+ PreviewJXL => {
4989
+ Groups => { 0 => 'EXIF', 1 => 'SubIFD', 2 => 'Preview' },
4990
+ Require => {
4991
+ 0 => 'PreviewJXLStart',
4992
+ 1 => 'PreviewJXLLength',
4993
+ },
4994
+ Desire => {
4995
+ 2 => 'PreviewJXLStart (1)',
4996
+ 3 => 'PreviewJXLLength (1)',
4997
+ },
4998
+ # retrieve all other JXL images
4999
+ RawConv => q{
5000
+ if ($val[2] and $val[3]) {
5001
+ my $i = 1;
5002
+ for (;;) {
5003
+ my %val = ( 0 => $$val{2}, 1 => $$val{3} );
5004
+ $self->FoundTag($tagInfo, \%val);
5005
+ ++$i;
5006
+ $$val{2} = "$$val{0} ($i)";
5007
+ last unless defined $$self{VALUE}{$$val{2}};
5008
+ $$val{3} = "$$val{1} ($i)";
5009
+ last unless defined $$self{VALUE}{$$val{3}};
5010
+ }
5011
+ }
5012
+ @grps = $self->GetGroup($$val{0});
5013
+ my $image = $self->ExtractBinary($val[0], $val[1], 'PreviewJXL');
5014
+ unless ($image =~ /^(Binary data|\xff\x0a|\0\0\0\x0cJXL \x0d\x0a......ftypjxl )/s) {
5015
+ $self->Warn("$tag is not a valid JXL image",1);
5016
+ return undef;
5017
+ }
5018
+ return \$image;
5019
+ },
5020
+ },
4974
5021
  PreviewImageSize => {
4975
5022
  Require => {
4976
5023
  0 => 'PreviewImageWidth',
@@ -5096,7 +5143,8 @@ my %subSecConv = (
5096
5143
  GPSLongitudeRef => '(defined $val and $val =~ / (-?)/) ? ($1 ? "W" : "E") : undef',
5097
5144
  },
5098
5145
  PrintConvInv => q{
5099
- return undef unless $val =~ /(.*? ?[NS]?), ?(.*? ?[EW]?)$/;
5146
+ return undef unless $val =~ /(.*? ?[NS]?), ?(.*? ?[EW]?)$/ or
5147
+ $val =~ /^\s*(-?\d+(?:\.\d+)?)\s*(-?\d+(?:\.\d+)?)\s*$/;
5100
5148
  my ($lat, $lon) = ($1, $2);
5101
5149
  require Image::ExifTool::GPS;
5102
5150
  $lat = Image::ExifTool::GPS::ToDegrees($lat, 1, "lat");
@@ -31,7 +31,7 @@ use vars qw($VERSION);
31
31
  use Image::ExifTool qw(:DataAccess :Utils);
32
32
  use Image::ExifTool::Exif;
33
33
 
34
- $VERSION = '1.92';
34
+ $VERSION = '1.93';
35
35
 
36
36
  sub ProcessFujiDir($$$);
37
37
  sub ProcessFaceRec($$$);
@@ -528,6 +528,7 @@ my %faceCategories = (
528
528
  1 => 'Full-frame on GFX', #IB
529
529
  2 => 'Sports Finder Mode', # (mechanical shutter)
530
530
  4 => 'Electronic Shutter 1.25x Crop', # (continuous high)
531
+ 8 => 'Digital Tele-Conv', #forum15784
531
532
  },
532
533
  },
533
534
  0x104e => { #forum10800 (X-Pro3)
@@ -549,6 +550,9 @@ my %faceCategories = (
549
550
  3 => 'Electronic Front Curtain', #10
550
551
  },
551
552
  },
553
+ 0x1051 => { Name => 'Cropped', Writable => 'int8u', PrintConv => { 0 => 'No', 1 => 'Yes' } }, #forum15784
554
+ 0x1052 => { Name => 'CropTopLeft', Writable => 'int32u' }, #forum15784
555
+ 0x1053 => { Name => 'CropSize', Writable => 'int32u' }, #forum15784
552
556
  # 0x1100 - This may not work well for newer cameras (ref forum12682)
553
557
  0x1100 => [{
554
558
  Name => 'AutoBracketing',
@@ -1030,14 +1034,19 @@ my %faceCategories = (
1030
1034
  },
1031
1035
  0.5 => {
1032
1036
  Name => 'AFAreaZoneSize',
1033
- Mask => 0xf0000,
1037
+ Mask => 0xff0000,
1034
1038
  PrintConv => {
1035
1039
  0 => 'n/a',
1036
1040
  OTHER => sub {
1037
1041
  my ($val, $inv) = @_;
1038
- return "$val x $val" unless $inv;
1039
- $val =~ s/ ?x.*//;
1040
- return $val;
1042
+ my ($w, $h);
1043
+ if ($inv) {
1044
+ my ($w, $h) = $val =~ /(\d+)/g;
1045
+ return 0 unless $w and $h;
1046
+ return((($h << 5) & 0xf0) | ($w & 0x0f));
1047
+ }
1048
+ ($w, $h) = ($val & 0x0f, $val >> 5);
1049
+ return "$w x $h";
1041
1050
  },
1042
1051
  },
1043
1052
  },
@@ -12,7 +12,7 @@ use strict;
12
12
  use vars qw($VERSION);
13
13
  use Image::ExifTool::Exif;
14
14
 
15
- $VERSION = '1.55';
15
+ $VERSION = '1.56';
16
16
 
17
17
  my %coordConv = (
18
18
  ValueConv => 'Image::ExifTool::GPS::ToDegrees($val)',
@@ -491,7 +491,7 @@ sub PrintTimeStamp($)
491
491
  sub ToDMS($$;$$)
492
492
  {
493
493
  my ($et, $val, $doPrintConv, $ref) = @_;
494
- my ($fmt, @fmt, $num, $sign, $rtnVal, $neg);
494
+ my ($fmt, @fmt, $num, $sign, $minus, $rtnVal, $neg);
495
495
 
496
496
  unless (length $val) {
497
497
  # don't convert an empty value
@@ -503,8 +503,10 @@ sub ToDMS($$;$$)
503
503
  $val = -$val;
504
504
  $ref = {N => 'S', E => 'W'}->{$ref};
505
505
  $sign = '-';
506
+ $minus = '-';
506
507
  } else {
507
508
  $sign = '+';
509
+ $minus = '';
508
510
  }
509
511
  $ref = " $ref" unless $doPrintConv and $doPrintConv eq '2';
510
512
  } else {
@@ -522,7 +524,7 @@ sub ToDMS($$;$$)
522
524
  $fmt = q{%d deg %d' %.2f"} . $ref;
523
525
  } elsif ($ref) {
524
526
  # use signed value instead of reference direction if specified
525
- $fmt =~ s/%\+/$sign%/g or $fmt .= $ref;
527
+ $fmt =~ s/%\+/$sign%/g or $fmt =~ s/%-/$minus%/g or $fmt .= $ref;
526
528
  } else {
527
529
  $fmt =~ s/%\+/%/g; # don't know sign, so don't print it
528
530
  }