exiftool_vendored 11.99.0 → 12.11.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +201 -2
  3. data/bin/MANIFEST +8 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +43 -42
  7. data/bin/exiftool +172 -99
  8. data/bin/lib/Image/ExifTool.pm +170 -117
  9. data/bin/lib/Image/ExifTool.pod +132 -97
  10. data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  11. data/bin/lib/Image/ExifTool/APE.pm +2 -2
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +21 -10
  13. data/bin/lib/Image/ExifTool/Canon.pm +202 -13
  14. data/bin/lib/Image/ExifTool/CanonCustom.pm +82 -16
  15. data/bin/lib/Image/ExifTool/DPX.pm +56 -2
  16. data/bin/lib/Image/ExifTool/DarwinCore.pm +22 -3
  17. data/bin/lib/Image/ExifTool/EXE.pm +8 -5
  18. data/bin/lib/Image/ExifTool/Exif.pm +15 -6
  19. data/bin/lib/Image/ExifTool/Font.pm +9 -2
  20. data/bin/lib/Image/ExifTool/GIF.pm +6 -1
  21. data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
  22. data/bin/lib/Image/ExifTool/Geotag.pm +2 -2
  23. data/bin/lib/Image/ExifTool/GoPro.pm +48 -22
  24. data/bin/lib/Image/ExifTool/H264.pm +1 -1
  25. data/bin/lib/Image/ExifTool/ID3.pm +86 -12
  26. data/bin/lib/Image/ExifTool/IPTC.pm +1 -0
  27. data/bin/lib/Image/ExifTool/Import.pm +12 -9
  28. data/bin/lib/Image/ExifTool/JSON.pm +27 -4
  29. data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
  30. data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  31. data/bin/lib/Image/ExifTool/M2TS.pm +1 -1
  32. data/bin/lib/Image/ExifTool/MPF.pm +2 -2
  33. data/bin/lib/Image/ExifTool/MacOS.pm +154 -38
  34. data/bin/lib/Image/ExifTool/Matroska.pm +3 -1
  35. data/bin/lib/Image/ExifTool/Minolta.pm +7 -2
  36. data/bin/lib/Image/ExifTool/Nikon.pm +143 -17
  37. data/bin/lib/Image/ExifTool/Olympus.pm +40 -17
  38. data/bin/lib/Image/ExifTool/PNG.pm +14 -3
  39. data/bin/lib/Image/ExifTool/PPM.pm +5 -5
  40. data/bin/lib/Image/ExifTool/Panasonic.pm +148 -14
  41. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +34 -0
  42. data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
  43. data/bin/lib/Image/ExifTool/Pentax.pm +11 -3
  44. data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
  45. data/bin/lib/Image/ExifTool/QuickTime.pm +240 -37
  46. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +419 -60
  47. data/bin/lib/Image/ExifTool/README +25 -21
  48. data/bin/lib/Image/ExifTool/RSRC.pm +17 -11
  49. data/bin/lib/Image/ExifTool/Radiance.pm +7 -2
  50. data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
  51. data/bin/lib/Image/ExifTool/Shift.pl +1 -0
  52. data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
  53. data/bin/lib/Image/ExifTool/Sony.pm +423 -39
  54. data/bin/lib/Image/ExifTool/Stim.pm +2 -2
  55. data/bin/lib/Image/ExifTool/TagLookup.pm +5798 -5675
  56. data/bin/lib/Image/ExifTool/TagNames.pod +575 -100
  57. data/bin/lib/Image/ExifTool/Validate.pm +4 -4
  58. data/bin/lib/Image/ExifTool/WriteExif.pl +1 -0
  59. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +30 -21
  60. data/bin/lib/Image/ExifTool/Writer.pl +49 -24
  61. data/bin/lib/Image/ExifTool/XMP.pm +99 -17
  62. data/bin/lib/Image/ExifTool/XMP2.pl +1 -0
  63. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  64. data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
  65. data/bin/perl-Image-ExifTool.spec +42 -41
  66. data/lib/exiftool_vendored/version.rb +1 -1
  67. metadata +9 -8
@@ -14,16 +14,33 @@ use vars qw($VERSION);
14
14
  use Image::ExifTool qw(:DataAccess :Utils);
15
15
  use Image::ExifTool::Import;
16
16
 
17
- $VERSION = '1.01';
17
+ $VERSION = '1.02';
18
18
 
19
19
  sub ProcessTag($$$$%);
20
20
 
21
21
  %Image::ExifTool::JSON::Main = (
22
22
  GROUPS => { 0 => 'JSON', 1 => 'JSON', 2 => 'Other' },
23
+ VARS => { NO_ID => 1 },
23
24
  NOTES => q{
24
- No JSON tags have been pre-defined, but ExifTool will read any existing
25
- tags from basic JSON-formatted files.
25
+ Other than a few tags in the table below, JSON tags have not been
26
+ pre-defined. However, ExifTool will read any existing tags from basic
27
+ JSON-formatted files.
26
28
  },
29
+ # ON1 settings tags
30
+ ON1_SettingsData => {
31
+ RawConv => q{
32
+ require Image::ExifTool::XMP;
33
+ $val = Image::ExifTool::XMP::DecodeBase64($val);
34
+ },
35
+ SubDirectory => { TagTable => 'Image::ExifTool::PLIST::Main' },
36
+ },
37
+ ON1_SettingsMetadataCreated => { Groups => { 2 => 'Time' } },
38
+ ON1_SettingsMetadataModified => { Groups => { 2 => 'Time' } },
39
+ ON1_SettingsMetadataName => { },
40
+ ON1_SettingsMetadataPluginID => { },
41
+ ON1_SettingsMetadataTimestamp => { Groups => { 2 => 'Time' } },
42
+ ON1_SettingsMetadataUsage => { },
43
+ ON1_SettingsMetadataVisibleToUser=>{ },
27
44
  );
28
45
 
29
46
  #------------------------------------------------------------------------------
@@ -33,12 +50,18 @@ sub FoundTag($$$$%)
33
50
  {
34
51
  my ($et, $tagTablePtr, $tag, $val, %flags) = @_;
35
52
 
53
+ # special case to reformat ON1 tag names
54
+ if ($tag =~ s/^settings\w{8}-\w{4}-\w{4}-\w{4}-\w{12}(Data|Metadata.+)$/ON1_Settings$1/) {
55
+ $et->OverrideFileType('ONP','application/on1') if $$et{FILE_TYPE} eq 'JSON';
56
+ }
57
+
36
58
  # avoid conflict with special table entries
37
59
  $tag .= '!' if $Image::ExifTool::specialTags{$tag};
38
60
 
39
61
  AddTagToTable($tagTablePtr, $tag, {
40
62
  Name => Image::ExifTool::MakeTagName($tag),
41
63
  %flags,
64
+ Temporary => 1,
42
65
  }) unless $$tagTablePtr{$tag};
43
66
 
44
67
  $et->HandleTag($tagTablePtr, $tag, $val);
@@ -94,7 +117,7 @@ sub ProcessJSON($$)
94
117
 
95
118
  # remove any old tag definitions in case they change flags
96
119
  foreach $key (TagTableKeys($tagTablePtr)) {
97
- delete $$tagTablePtr{$key};
120
+ delete $$tagTablePtr{$key} if $$tagTablePtr{$key}{Temporary};
98
121
  }
99
122
 
100
123
  # extract tags from JSON database
@@ -11,7 +11,7 @@ package Image::ExifTool::Lang::de;
11
11
  use strict;
12
12
  use vars qw($VERSION);
13
13
 
14
- $VERSION = '1.35';
14
+ $VERSION = '1.36';
15
15
 
16
16
  %Image::ExifTool::Lang::de::Translate = (
17
17
  'AEAperture' => 'AE-Blende',
@@ -993,7 +993,9 @@ $VERSION = '1.35';
993
993
  },
994
994
  },
995
995
  'AdvancedSceneMode' => {
996
+ Description => 'Erweiteter Szenenmodus',
996
997
  PrintConv => {
998
+ 'Off' => 'Aus',
997
999
  'Creative Macro' => 'Makro kreativ',
998
1000
  'Flower' => 'Blumen',
999
1001
  'HDR B&W' => 'HDR Schwarz-Weiß',
@@ -1302,7 +1302,7 @@ $VERSION = '1.16';
1302
1302
  'ExifImageHeight' => 'Alto Imagen',
1303
1303
  'ExifImageWidth' => 'Ancho Imagen',
1304
1304
  'ExifOffset' => 'Puntero Exif IFD',
1305
- 'ExifToolVersion' => 'Versión Exiftool',
1305
+ 'ExifToolVersion' => 'Versión ExifTool',
1306
1306
  'ExifVersion' => 'Versión Exif',
1307
1307
  'ExpandFilm' => 'Película Expandida',
1308
1308
  'ExpandFilterLens' => 'Filtro Objetivo Expandida',
@@ -262,7 +262,7 @@ sub ParseAC3Descriptor($$)
262
262
 
263
263
  #------------------------------------------------------------------------------
264
264
  # Parse PID stream data
265
- # Inputs: 0) Exiftool ref, 1) PID number, 2) PID type, 3) PID name, 4) data ref
265
+ # Inputs: 0) ExifTool ref, 1) PID number, 2) PID type, 3) PID name, 4) data ref
266
266
  # Returns: 0=stream parsed OK,
267
267
  # 1=stream parsed but we want to parse more of these,
268
268
  # -1=can't parse yet because we don't know the type
@@ -28,8 +28,8 @@ sub ProcessMPImageList($$$);
28
28
  from this segment is stored as a JPEG trailer. The MPF tags are not
29
29
  writable, however the MPF segment may be deleted as a group (with "MPF:All")
30
30
  but then the JPEG trailer should also be deleted (with "Trailer:All"). See
31
- L<http://www.cipa.jp/std/documents/e/DC-007_E.pdf> for the official
32
- specification.
31
+ L<https://web.archive.org/web/20190713230858/http://www.cipa.jp/std/documents/e/DC-007_E.pdf>
32
+ for the official specification.
33
33
  },
34
34
  0xb000 => 'MPFVersion',
35
35
  0xb001 => 'NumberOfImages',
@@ -4,6 +4,7 @@
4
4
  # Description: Read/write MacOS system tags
5
5
  #
6
6
  # Revisions: 2017/03/01 - P. Harvey Created
7
+ # 2020/10/13 - PH Added ability to read MacOS "._" files
7
8
  #------------------------------------------------------------------------------
8
9
 
9
10
  package Image::ExifTool::MacOS;
@@ -11,15 +12,38 @@ use strict;
11
12
  use vars qw($VERSION);
12
13
  use Image::ExifTool qw(:DataAccess :Utils);
13
14
 
14
- $VERSION = '1.09';
15
+ $VERSION = '1.11';
15
16
 
16
17
  sub MDItemLocalTime($);
18
+ sub ProcessATTR($$$);
17
19
 
18
20
  my %mdDateInfo = (
19
21
  ValueConv => \&MDItemLocalTime,
20
22
  PrintConv => '$self->ConvertDateTime($val)',
21
23
  );
22
24
 
25
+ # Information decoded from Mac OS sidecar files
26
+ %Image::ExifTool::MacOS::Main = (
27
+ GROUPS => { 0 => 'File', 1 => 'MacOS' },
28
+ NOTES => q{
29
+ Note that on some filesystems, MacOS creates sidecar files with names that
30
+ begin with "._". ExifTool will read these files if specified, and extract
31
+ the information listed in the following table without the need for extra
32
+ options, but these files are not writable directly.
33
+ },
34
+ 2 => {
35
+ Name => 'RSRC',
36
+ SubDirectory => { TagTable => 'Image::ExifTool::RSRC::Main' },
37
+ },
38
+ 9 => {
39
+ Name => 'ATTR',
40
+ SubDirectory => {
41
+ TagTable => 'Image::ExifTool::MacOS::XAttr',
42
+ ProcessProc => \&ProcessATTR,
43
+ },
44
+ },
45
+ );
46
+
23
47
  # "mdls" tags (ref PH)
24
48
  %Image::ExifTool::MacOS::MDItem = (
25
49
  WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
@@ -221,6 +245,8 @@ my %mdDateInfo = (
221
245
  XAttr tags are extracted using the "xattr" utility. They are extracted if
222
246
  any "XAttr*" tag or the MacOS group is specifically requested, or by setting
223
247
  the L<XAttrTags|../ExifTool.html#XAttrTags> API option to 1 or the L<RequestAll|../ExifTool.html#RequestAll> API option to 2 or higher.
248
+ And they extracted by default from MacOS "._" files when reading
249
+ these files directly.
224
250
  },
225
251
  'com.apple.FinderInfo' => {
226
252
  Name => 'XAttrFinderInfo',
@@ -325,7 +351,7 @@ sub MDItemLocalTime($)
325
351
 
326
352
  #------------------------------------------------------------------------------
327
353
  # Set MacOS MDItem and XAttr tags from new tag values
328
- # Inputs: 0) Exiftool ref, 1) file name, 2) list of tags to set
354
+ # Inputs: 0) ExifTool ref, 1) file name, 2) list of tags to set
329
355
  # Returns: 1=something was set OK, 0=didn't try, -1=error (and warning set)
330
356
  # Notes: There may be errors even if 1 is returned
331
357
  sub SetMacOSTags($$$)
@@ -486,8 +512,50 @@ sub ExtractMDItemTags($$)
486
512
  $$et{INDENT} =~ s/\| $//;
487
513
  }
488
514
 
515
+
516
+ #------------------------------------------------------------------------------
517
+ # Read MacOS XAttr value
518
+ # Inputs: 0) ExifTool object ref, 1) file name
519
+ sub ReadXAttrValue($$$$)
520
+ {
521
+ my ($et, $tagTablePtr, $tag, $val) = @_;
522
+ # add to our table if necessary
523
+ unless ($$tagTablePtr{$tag}) {
524
+ my $name;
525
+ # generate tag name from attribute name
526
+ if ($tag =~ /^com\.apple\.(.*)$/) {
527
+ ($name = $1) =~ s/^metadata:_?k//;
528
+ $name =~ s/^metadata:(com_)?//;
529
+ } else {
530
+ $name = $tag;
531
+ }
532
+ $name =~ s/[.:_]([a-z])/\U$1/g;
533
+ $name = 'XAttr' . ucfirst $name;
534
+ my %tagInfo = ( Name => $name );
535
+ $tagInfo{Groups} = { 2 => 'Time' } if $tag=~/Date$/;
536
+ $et->VPrint(0, " [adding $tag]\n");
537
+ AddTagToTable($tagTablePtr, $tag, \%tagInfo);
538
+ }
539
+ if ($val =~ /^bplist0/) {
540
+ my %dirInfo = ( DataPt => \$val );
541
+ require Image::ExifTool::PLIST;
542
+ if (Image::ExifTool::PLIST::ProcessBinaryPLIST($et, \%dirInfo, $tagTablePtr)) {
543
+ return undef if ref $dirInfo{Value} eq 'HASH';
544
+ $val = $dirInfo{Value}
545
+ } else {
546
+ $et->Warn("Error decoding $$tagTablePtr{$tag}{Name}");
547
+ return undef;
548
+ }
549
+ }
550
+ if (not ref $val and ($val =~ /\0/ or length($val) > 200) or $tag eq 'XAttrMDLabel') {
551
+ my $buff = $val;
552
+ $val = \$buff;
553
+ }
554
+ return $val;
555
+ }
556
+
489
557
  #------------------------------------------------------------------------------
490
- # Extract MacOS extended attribute tags
558
+ # Read MacOS extended attribute tags using 'xattr' utility
491
559
  # Inputs: 0) ExifTool object ref, 1) file name
492
560
  sub ExtractXAttrTags($$)
493
561
  {
@@ -517,39 +585,8 @@ sub ExtractXAttrTags($$)
517
585
  $val .= pack('H*', $_);
518
586
  next;
519
587
  } elsif ($tag and defined $val) {
520
- # add to our table if necessary
521
- unless ($$tagTablePtr{$tag}) {
522
- my $name;
523
- # generate tag name from attribute name
524
- if ($tag =~ /^com\.apple\.(.*)$/) {
525
- ($name = $1) =~ s/^metadata:_?k//;
526
- $name =~ s/^metadata:(com_)?//;
527
- } else {
528
- $name = $tag;
529
- }
530
- $name =~ s/[.:_]([a-z])/\U$1/g;
531
- $name = 'XAttr' . ucfirst $name;
532
- my %tagInfo = ( Name => $name );
533
- $tagInfo{Groups} = { 2 => 'Time' } if $tag=~/Date$/;
534
- $et->VPrint(0, " [adding $tag]\n");
535
- AddTagToTable($tagTablePtr, $tag, \%tagInfo);
536
- }
537
- if ($val =~ /^bplist0/) {
538
- my %dirInfo = ( DataPt => \$val );
539
- require Image::ExifTool::PLIST;
540
- if (Image::ExifTool::PLIST::ProcessBinaryPLIST($et, \%dirInfo, $tagTablePtr)) {
541
- next if ref $dirInfo{Value} eq 'HASH';
542
- $val = $dirInfo{Value}
543
- } else {
544
- $et->Warn("Error decoding $$tagTablePtr{$tag}{Name}");
545
- next;
546
- }
547
- }
548
- if (not ref $val and ($val =~ /\0/ or length($val) > 200) or $tag eq 'XAttrMDLabel') {
549
- my $buff = $val;
550
- $val = \$buff;
551
- }
552
- $et->HandleTag($tagTablePtr, $tag, $val);
588
+ $val = ReadXAttrValue($et, $tagTablePtr, $tag, $val);
589
+ $et->HandleTag($tagTablePtr, $tag, $val) if defined $val;
553
590
  undef $tag;
554
591
  undef $val;
555
592
  }
@@ -584,6 +621,84 @@ sub GetFileCreateDate($$)
584
621
  delete $$et{SET_GROUP1};
585
622
  }
586
623
 
624
+ #------------------------------------------------------------------------------
625
+ # Read ATTR metadata from "._" file
626
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
627
+ # Return: 1 on success
628
+ # (ref https://www.swiftforensics.com/2018/11/the-dot-underscore-file-format.html)
629
+ sub ProcessATTR($$$)
630
+ {
631
+ my ($et, $dirInfo, $tagTablePtr) = @_;
632
+ my $dataPt = $$dirInfo{DataPt};
633
+ my $dataPos = $$dirInfo{DataPos};
634
+ my $dataLen = length $$dataPt;
635
+
636
+ $dataLen >= 58 and $$dataPt =~ /^.{34}ATTR/s or $et->Warn('Invalid ATTR header'), return 0;
637
+ my $entries = Get32u($dataPt, 66);
638
+ $et->VerboseDir('ATTR', $entries);
639
+ # (Note: The RAF is not in $dirInfo because it would break RSRC reading --
640
+ # the RSCR block uses relative offsets, while the ATTR block uses absolute! grrr!)
641
+ my $raf = $$et{RAF};
642
+ my $pos = 70; # first entry is after ATTR header
643
+ my $i;
644
+ for ($i=0; $i<$entries; ++$i) {
645
+ $pos + 12 > $dataLen and $et->Warn('Truncated ATTR entry'), last;
646
+ my $off = Get32u($dataPt, $pos);
647
+ my $len = Get32u($dataPt, $pos + 4);
648
+ my $n = Get8u($dataPt, $pos + 10); # number of characters in tag name
649
+ $pos + 11 + $n > $dataLen and $et->Warn('Truncated ATTR name'), last;
650
+ $off -= $dataPos; # convert to relative offset (grrr!)
651
+ $off < 0 or $off > $dataLen and $et->Warn('Invalid ATTR offset'), last;
652
+ my $tag = substr($$dataPt, $pos + 11, $n);
653
+ $tag =~ s/\0+$//; # remove null terminator
654
+ # remove random ID after kMDLabel in tag ID
655
+ $tag =~ s/^com.apple.metadata:kMDLabel_.*/com.apple.metadata:kMDLabel/s;
656
+ $off + $len > $dataLen and $et->Warn('Truncated ATTR value'), last;
657
+ my $val = ReadXAttrValue($et, $tagTablePtr, $tag, substr($$dataPt, $off, $len));
658
+ $et->HandleTag($tagTablePtr, $tag, $val,
659
+ DataPt => $dataPt,
660
+ DataPos => $dataPos,
661
+ Start => $off,
662
+ Size => $len,
663
+ ) if defined $val;
664
+ $pos += (11 + $n + 3) & -4; # step to next entry (on even 4-byte boundary)
665
+ }
666
+ return 1;
667
+ }
668
+
669
+ #------------------------------------------------------------------------------
670
+ # Read information from a MacOS "._" sidecar file
671
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref
672
+ # Returns: 1 on success, 0 if this wasn't a valid "._" file
673
+ # (ref https://www.swiftforensics.com/2018/11/the-dot-underscore-file-format.html)
674
+ sub ProcessMacOS($$)
675
+ {
676
+ my ($et, $dirInfo) = @_;
677
+ my $raf = $$dirInfo{RAF};
678
+ my ($hdr, $buff, $i);
679
+
680
+ return 0 unless $raf->Read($hdr, 26) == 26 and $hdr =~ /^\0\x05\x16\x07\0(.)\0\0Mac OS X /s;
681
+ my $ver = ord $1;
682
+ # (extension may be anything, so just echo back the incoming file extension if it exists)
683
+ $et->SetFileType(undef, undef, $$et{FILE_EXT});
684
+ $ver == 2 or $et->Warn("Unsupported file version $ver"), return 1;
685
+ SetByteOrder('MM');
686
+ my $tagTablePtr = GetTagTable('Image::ExifTool::MacOS::Main');
687
+ my $entries = Get16u(\$hdr, 0x18);
688
+ $et->VerboseDir('MacOS', $entries);
689
+ $raf->Read($hdr, $entries * 12) == $entries * 12 or $et->Warn('Truncated header'), return 1;
690
+ for ($i=0; $i<$entries; ++$i) {
691
+ my $pos = $i * 12;
692
+ my $tag = Get32u(\$hdr, $pos);
693
+ my $off = Get32u(\$hdr, $pos + 4);
694
+ my $len = Get32u(\$hdr, $pos + 8);
695
+ $len > 100000000 and $et->Warn('Record size too large'), last;
696
+ $raf->Seek($off,0) and $raf->Read($buff,$len) == $len or $et->Warn('Truncated record'), last;
697
+ $et->HandleTag($tagTablePtr, $tag, undef, DataPt => \$buff, DataPos => $off, Index => $i);
698
+ }
699
+ return 1;
700
+ }
701
+
587
702
  1; # end
588
703
 
589
704
  __END__
@@ -600,8 +715,9 @@ This module is used by Image::ExifTool
600
715
 
601
716
  This module contains definitions required by Image::ExifTool to extract
602
717
  MDItem* and XAttr* tags on MacOS systems using the "mdls" and "xattr"
603
- utilities respectively. Writable tags use "xattr", "setfile" or "osascript"
604
- for writing.
718
+ utilities respectively. It also reads metadata directly from the MacOS "_."
719
+ sidecar files that are used on some filesystems to store file attributes.
720
+ Writable tags use "xattr", "setfile" or "osascript" for writing.
605
721
 
606
722
  =head1 AUTHOR
607
723
 
@@ -14,7 +14,7 @@ use strict;
14
14
  use vars qw($VERSION);
15
15
  use Image::ExifTool qw(:DataAccess :Utils);
16
16
 
17
- $VERSION = '1.09';
17
+ $VERSION = '1.10';
18
18
 
19
19
  my %noYes = ( 0 => 'No', 1 => 'Yes' );
20
20
 
@@ -221,6 +221,8 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
221
221
  },
222
222
  0x2e => {
223
223
  Name => 'TrackEntry',
224
+ # reset TrackType member at the start of each track
225
+ Condition => 'delete $$self{TrackType}; 1',
224
226
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
225
227
  },
226
228
  0x57 => { Name => 'TrackNumber', Format => 'unsigned' },
@@ -49,7 +49,7 @@ use vars qw($VERSION %minoltaLensTypes %minoltaTeleconverters %minoltaColorMode
49
49
  use Image::ExifTool qw(:DataAccess :Utils);
50
50
  use Image::ExifTool::Exif;
51
51
 
52
- $VERSION = '2.83';
52
+ $VERSION = '2.87';
53
53
 
54
54
  # Full list of product codes for Sony-compatible Minolta lenses
55
55
  # (ref http://www.kb.sony.com/selfservice/documentLink.do?externalId=C1000570)
@@ -602,13 +602,18 @@ $VERSION = '2.83';
602
602
  15 => 'Light', #JR (NC)
603
603
  16 => 'Autumn Leaves', #JR (NC)
604
604
  17 => 'Sepia', #JR
605
+ 18 => 'FL', #JR (7SM3)
606
+ 19 => 'Vivid 2', #JR (7SM3)
607
+ 20 => 'IN', #JR (7SM3)
608
+ 21 => 'SH', #JR (7SM3)
605
609
  100 => 'Neutral', #JD
606
610
  101 => 'Clear', #JD
607
611
  102 => 'Deep', #JD
608
612
  103 => 'Light', #JD
609
613
  104 => 'Night View', #JD
610
614
  105 => 'Autumn Leaves', #JD
611
- 0xffffffff => 'n/a', #PH
615
+ 255 => 'Off', #JR (new for ILCE-7SM3, July 2020)
616
+ 0xffffffff => 'n/a', #PH
612
617
  );
613
618
 
614
619
  %minoltaSceneMode = (
@@ -62,7 +62,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
62
62
  use Image::ExifTool::Exif;
63
63
  use Image::ExifTool::GPS;
64
64
 
65
- $VERSION = '3.83';
65
+ $VERSION = '3.89';
66
66
 
67
67
  sub LensIDConv($$$);
68
68
  sub ProcessNikonAVI($$$);
@@ -349,6 +349,7 @@ sub GetAFPointGrid($$;$);
349
349
  'FE 47 00 00 24 24 4B 06' => 'Sigma 4.5mm F2.8 EX DC HSM Circular Fisheye', #JD
350
350
  '26 48 11 11 30 30 1C 02' => 'Sigma 8mm F4 EX Circular Fisheye',
351
351
  '79 40 11 11 2C 2C 1C 06' => 'Sigma 8mm F3.5 EX Circular Fisheye', #JD
352
+ 'DB 40 11 11 2C 2C 1C 06' => 'Sigma 8mm F3.5 EX DG Circular Fisheye', #30
352
353
  'DC 48 19 19 24 24 4B 06' => 'Sigma 10mm F2.8 EX DC HSM Fisheye',
353
354
  'C2 4C 24 24 14 14 4B 06' => 'Sigma 14mm F1.8 DG HSM | A', #IB
354
355
  '48 48 24 24 24 24 4B 02' => 'Sigma 14mm F2.8 EX Aspherical HSM',
@@ -449,6 +450,7 @@ sub GetAFPointGrid($$;$);
449
450
  # '92 3E 2D 88 2C 40 4B 0E' (22mm)
450
451
  # '92 40 2D 88 2C 40 4B 0E' (18mm)
451
452
  '26 48 31 49 24 24 1C 02' => 'Sigma 20-40mm F2.8',
453
+ '7B 48 37 44 18 18 4B 06' => 'Sigma 24-35mm F2.0 DG HSM | A', #30
452
454
  '02 3A 37 50 31 3D 02 00' => 'Sigma 24-50mm F4-5.6 UC',
453
455
  '26 48 37 56 24 24 1C 02' => 'Sigma 24-60mm F2.8 EX DG',
454
456
  'B6 48 37 56 24 24 1C 02' => 'Sigma 24-60mm F2.8 EX DG',
@@ -513,6 +515,7 @@ sub GetAFPointGrid($$;$);
513
515
  'CE 34 76 A0 38 40 4B 0E' => 'Sigma 150-500mm F5-6.3 DG OS APO HSM', #JD
514
516
  '81 34 76 A6 38 40 4B 0E' => 'Sigma 150-600mm F5-6.3 DG OS HSM | S', #Jaap Voets
515
517
  '82 34 76 A6 38 40 4B 0E' => 'Sigma 150-600mm F5-6.3 DG OS HSM | C',
518
+ 'C4 4C 73 73 14 14 4B 46' => 'Sigma 135mm F1.8 DG HSM | A', #forum3833
516
519
  '26 40 7B A0 34 40 1C 02' => 'Sigma APO 170-500mm F5-6.3 Aspherical RF',
517
520
  'A7 49 80 A0 24 24 4B 06' => 'Sigma APO 200-500mm F2.8 EX DG',
518
521
  '48 3C 8E B0 3C 3C 4B 02' => 'Sigma APO 300-800mm F5.6 EX DG HSM',
@@ -579,6 +582,7 @@ sub GetAFPointGrid($$;$);
579
582
  '4D 41 3C 8E 2B 40 62 02' => 'Tamron AF 28-300mm f/3.5-6.3 XR Di LD Aspherical (IF) (A061)',
580
583
  '4D 41 3C 8E 2C 40 62 02' => 'Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical (IF) (185D)',
581
584
  'F9 40 3C 8E 2C 40 40 0E' => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical (IF) Macro (A20)',
585
+ 'C9 3C 44 76 25 31 DF 4E' => 'Tamron 35-150mm f/2.8-4 Di VC OSD (A043)', #30
582
586
  '00 47 53 80 30 3C 00 06' => 'Tamron AF 55-200mm f/4-5.6 Di II LD (A15)',
583
587
  'F7 53 5C 80 24 24 84 06' => 'Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)',
584
588
  'FE 53 5C 80 24 24 84 06' => 'Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)',
@@ -711,6 +715,7 @@ sub GetAFPointGrid($$;$);
711
715
  '00 48 80 80 30 30 00 00' => 'Nikkor 200mm f/4 AiS',
712
716
  '00 40 11 11 2C 2C 00 00' => 'Samyang 8mm f/3.5 Fish-Eye',
713
717
  '00 58 64 64 20 20 00 00' => 'Soligor C/D Macro MC 90mm f/2.5',
718
+ '4A 58 30 30 14 0C 4D 02' => 'Rokinon 20mm f/1.8 ED AS UMC', #30
714
719
  );
715
720
 
716
721
  # text encoding used in LocationInfo (ref PH)
@@ -878,6 +883,38 @@ my %afPoints39 = (
878
883
  10 => 'E3', 20 => 'B9', 30 => 'D4',
879
884
  );
880
885
 
886
+ # AF point indices for models with 105 focus points, eg. D6 (ref 28)
887
+ # - 7 rows (A-G) with 15 columns (1-15), center is D8
888
+ my %afPoints105 = (
889
+ 1 => 'D8', 28 => 'G7', 55 => 'F13', 82 => 'E4',
890
+ 2 => 'C8', 29 => 'D6', 56 => 'G13', 83 => 'F4',
891
+ 3 => 'B8', 30 => 'C6', 57 => 'D14', 84 => 'G4',
892
+ 4 => 'A8', 31 => 'B6', 58 => 'C14', 85 => 'D3',
893
+ 5 => 'E8', 32 => 'A6', 59 => 'B14', 86 => 'C3',
894
+ 6 => 'F8', 33 => 'E6', 60 => 'A14', 87 => 'B3',
895
+ 7 => 'G8', 34 => 'F6', 61 => 'E14', 88 => 'A3',
896
+ 8 => 'D9', 35 => 'G6', 62 => 'F14', 89 => 'E3',
897
+ 9 => 'C9', 36 => 'D11', 63 => 'G14', 90 => 'F3',
898
+ 10 => 'B9', 37 => 'C11', 64 => 'D15', 91 => 'G3',
899
+ 11 => 'A9', 38 => 'B11', 65 => 'C15', 92 => 'D2',
900
+ 12 => 'E9', 39 => 'A11', 66 => 'B15', 93 => 'C2',
901
+ 13 => 'F9', 40 => 'E11', 67 => 'A15', 94 => 'B2',
902
+ 14 => 'G9', 41 => 'F11', 68 => 'E15', 95 => 'A2',
903
+ 15 => 'D10', 42 => 'G11', 69 => 'F15', 96 => 'E2',
904
+ 16 => 'C10', 43 => 'D12', 70 => 'G15', 97 => 'F2',
905
+ 17 => 'B10', 44 => 'C12', 71 => 'D5', 98 => 'G2',
906
+ 18 => 'A10', 45 => 'B12', 72 => 'C5', 99 => 'D1',
907
+ 19 => 'E10', 46 => 'A12', 73 => 'B5', 100 => 'C1',
908
+ 20 => 'F10', 47 => 'E12', 74 => 'A5', 101 => 'B1',
909
+ 21 => 'G10', 48 => 'F12', 75 => 'E5', 102 => 'A1',
910
+ 22 => 'D7', 49 => 'G12', 76 => 'F5', 103 => 'E1',
911
+ 23 => 'C7', 50 => 'D13', 77 => 'G5', 104 => 'F1',
912
+ 24 => 'B7', 51 => 'C13', 78 => 'D4', 105 => 'G1',
913
+ 25 => 'A7', 52 => 'B13', 79 => 'C4',
914
+ 26 => 'E7', 53 => 'A13', 80 => 'B4',
915
+ 27 => 'F7', 54 => 'E13', 81 => 'A4',
916
+ );
917
+
881
918
  # AF point indices for models with 135 focus points, eg. 1J1 (ref PH)
882
919
  # - 9 rows (A-I) with 15 columns (1-15), center is E8
883
920
  # - odd columns, columns 2 and 14, and the remaining corner points are
@@ -1540,7 +1577,7 @@ my %binaryDataAttrs = (
1540
1577
  0x008c => {
1541
1578
  Name => 'ContrastCurve', #JD
1542
1579
  Writable => 'undef',
1543
- Flags => [ 'Binary', 'Protected' ],
1580
+ Flags => [ 'Binary', 'Protected', 'Drop' ], # (drop because not found in Nikon JPEG's)
1544
1581
  },
1545
1582
  # ColorHue: MODE1/MODE1a=sRGB, MODE2=Adobe RGB, MODE3a=more saturated sRGB
1546
1583
  # --> should really be called ColorSpace or ColorMode, but that would conflict with other tags
@@ -1785,6 +1822,16 @@ my %binaryDataAttrs = (
1785
1822
  ByteOrder => 'LittleEndian',
1786
1823
  },
1787
1824
  },
1825
+ { # (D6 firmware version 1.00, ref 28)
1826
+ Condition => '$$valPt =~ /^0246/',
1827
+ Name => 'ShotInfoD6',
1828
+ SubDirectory => {
1829
+ TagTable => 'Image::ExifTool::Nikon::ShotInfo',
1830
+ DecryptStart => 4,
1831
+ DecryptLen => 0xa4, # only decrypt the version info & offset fields for now
1832
+ ByteOrder => 'LittleEndian',
1833
+ },
1834
+ },
1788
1835
  { # (D610 firmware version 1.00)
1789
1836
  Condition => '$$valPt =~ /^0232/',
1790
1837
  Name => 'ShotInfoD610',
@@ -1834,6 +1881,7 @@ my %binaryDataAttrs = (
1834
1881
  7 => 'Unpacked 12 bits', #IB (padded to 16)
1835
1882
  8 => 'Small', #IB
1836
1883
  9 => 'Packed 12 bits', #IB (2 pixels in 3 bytes)
1884
+ 10 => 'Packed 14 bits', #28 (4 pixels in 7 bytes, eg. D6 uncompressed 14 bit)
1837
1885
  },
1838
1886
  },
1839
1887
  0x0094 => { Name => 'SaturationAdj', Writable => 'int16s' },
@@ -2035,7 +2083,7 @@ my %binaryDataAttrs = (
2035
2083
  },
2036
2084
  },
2037
2085
  {
2038
- Condition => '$$valPt =~ /^0800/', # Z6/Z7
2086
+ Condition => '$$valPt =~ /^080[01]/', # Z6/Z7
2039
2087
  Name => 'LensData0800',
2040
2088
  SubDirectory => {
2041
2089
  TagTable => 'Image::ExifTool::Nikon::LensData0800',
@@ -3300,6 +3348,7 @@ my %binaryDataAttrs = (
3300
3348
  15 => 'Dynamic Area (72 points)', #PH
3301
3349
  16 => 'Group Area (HL)', #28
3302
3350
  17 => 'Group Area (VL)', #28
3351
+ 18 => 'Dynamic Area (49 points)', #28
3303
3352
  128 => 'Single', #PH (1J1,1J2,1J3,1J4,1S1,1S2,1V2,1V3)
3304
3353
  129 => 'Auto (41 points)', #PH (1J1,1J2,1J3,1J4,1S1,1S2,1V1,1V2,1V3,AW1)
3305
3354
  130 => 'Subject Tracking (41 points)', #PH (1J1,1J4,1J3)
@@ -3337,6 +3386,10 @@ my %binaryDataAttrs = (
3337
3386
  197 => 'Auto', #PH (Z7)
3338
3387
  198 => 'Auto (198)', #PH (Z7) (focus lock with AF-C maybe?)
3339
3388
  199 => 'Auto (focus lock)', #PH (Z7, AF-S)
3389
+ 200 => 'Normal-area AF', #28 (D6)
3390
+ 201 => 'Wide-area AF', #28 (D6)
3391
+ 202 => 'Face-priority AF', #28 (D6)
3392
+ 203 => 'Subject-tracking AF', #28 (D6)
3340
3393
  },
3341
3394
  },
3342
3395
  ],
@@ -3355,12 +3408,14 @@ my %binaryDataAttrs = (
3355
3408
  6 => 'On (105-point)', #PH (1J4/1V3[128/130])
3356
3409
  7 => 'On (153-point)', #PH (D5/D500/D850)
3357
3410
  8 => 'On (81-point)', #38
3411
+ 9 => 'On (105-point)', #28 (D6)
3358
3412
  },
3359
3413
  },
3360
3414
  7 => [
3361
3415
  { #PH/JD
3362
3416
  Name => 'PrimaryAFPoint',
3363
- Condition => '$$self{PhaseDetectAF} < 2',
3417
+ # PrimaryAFPoint may only be valid for PhaseDetect - certainly true on the D6, possibly other bodies? (ref 28)
3418
+ Condition => '$$self{PhaseDetectAF} < 2 and $$self{AFInfo2Version} ne "0301"',
3364
3419
  Notes => q{
3365
3420
  models with 51-point AF -- 5 rows (A-E) and 11 columns (1-11): D3, D3S, D3X,
3366
3421
  D4, D4S, D300, D300S, D700, D800, D800e and D810
@@ -3495,7 +3550,7 @@ my %binaryDataAttrs = (
3495
3550
  8 => [
3496
3551
  { #JD/PH
3497
3552
  Name => 'AFPointsUsed',
3498
- Condition => '$$self{PhaseDetectAF} < 2',
3553
+ Condition => '$$self{PhaseDetectAF} < 2 and $$self{AFInfo2Version} ne "0301"',
3499
3554
  Notes => q{
3500
3555
  models with 51-point AF -- 5 rows: A1-9, B1-11, C1-11, D1-11, E1-9. Center
3501
3556
  point is C6
@@ -3614,6 +3669,8 @@ my %binaryDataAttrs = (
3614
3669
  },
3615
3670
  { #PH
3616
3671
  Name => 'AFPointsUsed',
3672
+ # version 301 uses a separate field at offset 0x0a for this tag (ref 28)
3673
+ Condition => '$$self{AFInfo2Version} ne "0301"',
3617
3674
  Format => 'undef[7]',
3618
3675
  ValueConv => 'join(" ", unpack("H2"x7, $val))',
3619
3676
  ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
@@ -3621,6 +3678,19 @@ my %binaryDataAttrs = (
3621
3678
  PrintConvInv => '$val=~s/Unknown \\((.*)\\)/$1/; $val',
3622
3679
  },
3623
3680
  ],
3681
+ 0x0a => { #28 (D6) in any of the 3 Group modes on the D6, the points specify the outer boundaries of the focus point area; otherwise the tag value is consistent with other Nikon bodies
3682
+ Name => 'AFPointsUsed',
3683
+ Condition => '$$self{AFInfo2Version} eq "0301" and $$self{PhaseDetectAF} == 9',
3684
+ Notes => q{
3685
+ models with 105-point AF -- 7 rows (A-G) and 15 columns (1-15). Center
3686
+ point is D8
3687
+ },
3688
+ Format => 'undef[14]',
3689
+ ValueConv => 'join(" ", unpack("H2"x14, $val))',
3690
+ ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
3691
+ PrintConv => sub { PrintAFPoints(shift, \%afPoints105); },
3692
+ PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints105); },
3693
+ },
3624
3694
  0x10 => { #PH (D90 and D5000)
3625
3695
  Name => 'AFImageWidth',
3626
3696
  Condition => '$$self{AFInfo2Version} eq "0100"',
@@ -3663,11 +3733,21 @@ my %binaryDataAttrs = (
3663
3733
  Format => 'int16u',
3664
3734
  RawConv => '$val ? $val : undef',
3665
3735
  },
3666
- 0x1c => { #PH
3667
- Name => 'ContrastDetectAFInFocus',
3668
- Condition => '$$self{AFInfo2Version} eq "0100"',
3669
- PrintConv => { 0 => 'No', 1 => 'Yes' },
3670
- },
3736
+ 0x1c => [
3737
+ { #PH
3738
+ Name => 'ContrastDetectAFInFocus',
3739
+ Condition => '$$self{AFInfo2Version} eq "0100"',
3740
+ PrintConv => { 0 => 'No', 1 => 'Yes' },
3741
+ },{ #PH (D500, see forum11190)
3742
+ Name => 'AFPointsSelected',
3743
+ Condition => '$$self{AFInfo2Version} eq "0101" and $$self{PhaseDetectAF} == 7',
3744
+ Format => 'undef[20]',
3745
+ ValueConv => 'join(" ", unpack("H2"x20, $val))',
3746
+ ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
3747
+ PrintConv => sub { PrintAFPoints(shift, \%afPoints153); },
3748
+ PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints153); },
3749
+ },
3750
+ ],
3671
3751
  # 0x1d - always zero (with or without live view)
3672
3752
  0x2a => { #PH (Z7)
3673
3753
  Name => 'AFImageWidth',
@@ -3683,14 +3763,31 @@ my %binaryDataAttrs = (
3683
3763
  },
3684
3764
  0x2e => { #PH (Z7)
3685
3765
  Name => 'AFAreaXPosition',
3686
- Condition => '$$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/',
3687
- Format => 'int16u',
3688
- },
3689
- 0x30 => { #PH (Z7)
3690
- Name => 'AFAreaYPosition',
3691
- Condition => '$$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/',
3766
+ Condition => q{
3767
+ $$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
3768
+ $$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} =~ /^0301/
3769
+ },
3692
3770
  Format => 'int16u',
3693
3771
  },
3772
+ 0x30 => [
3773
+ { #PH (Z7)
3774
+ Name => 'AFAreaYPosition',
3775
+ Condition => q{
3776
+ $$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
3777
+ $$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} =~ /^0301/
3778
+ },
3779
+ Format => 'int16u',
3780
+ },{ #PH (D500, see forum11190)
3781
+ Name => 'AFPointsInFocus',
3782
+ Condition => '$$self{AFInfo2Version} eq "0101" and $$self{PhaseDetectAF} == 7',
3783
+ Notes => 'AF points in focus at the time time image was captured',
3784
+ Format => 'undef[20]',
3785
+ ValueConv => 'join(" ", unpack("H2"x20, $val))',
3786
+ ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
3787
+ PrintConv => sub { PrintAFPoints(shift, \%afPoints153); },
3788
+ PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints153); },
3789
+ },
3790
+ ],
3694
3791
  0x32 => { #PH (Z7)
3695
3792
  Name => 'AFAreaWidth',
3696
3793
  Condition => '$$self{AFInfo2Version} =~ /^03/',
@@ -3703,6 +3800,19 @@ my %binaryDataAttrs = (
3703
3800
  Format => 'int16u',
3704
3801
  RawConv => '$val ? $val : undef',
3705
3802
  },
3803
+ 0x38 => { #28
3804
+ Name => 'PrimaryAFPoint',
3805
+ Condition => '$$self{PhaseDetectAF} == 9 and $$self{AFInfo2Version} =~ /^03/',
3806
+ Notes => q{
3807
+ Nikon models with 105-point AF -- 7 rows (A-G) and 15 columns (1-15): D6
3808
+ },
3809
+ PrintConvColumns => 5,
3810
+ PrintConv => {
3811
+ 0 => '(none)',
3812
+ %afPoints105,
3813
+ 1 => 'D8 (Center)',
3814
+ },
3815
+ },
3706
3816
  0x44 => [
3707
3817
  {
3708
3818
  Name => 'PrimaryAFPoint',
@@ -3802,6 +3912,7 @@ my %binaryDataAttrs = (
3802
3912
  # (don't know what the difference between 1 and 2 is)
3803
3913
  1 => 'On (1)',
3804
3914
  2 => 'On (2)',
3915
+ 3 => 'On (Zoom)', #28
3805
3916
  },
3806
3917
  },
3807
3918
  1 => {
@@ -3811,6 +3922,7 @@ my %binaryDataAttrs = (
3811
3922
  PrintConvInv => '$val eq "n/a" ? 255 : $val',
3812
3923
  },
3813
3924
  2 => {
3925
+ # when AFFineTune = 3 (indicating a zoom lens), this Tag stores the tuning adjustment for the wide end of the zoom range (ref 28)
3814
3926
  Name => 'AFFineTuneAdj',
3815
3927
  Priority => 0, # so other value takes priority if it exists
3816
3928
  Notes => 'may only be valid for saved lenses',
@@ -3818,6 +3930,14 @@ my %binaryDataAttrs = (
3818
3930
  PrintConv => '$val > 0 ? "+$val" : $val',
3819
3931
  PrintConvInv => '$val',
3820
3932
  },
3933
+ 3 => {
3934
+ Name => 'AFFineTuneAdjTele',
3935
+ # should probably insert a Condition that restricts this to AFFineTune = 3 (ref 28)
3936
+ Notes => 'only valid for zoom lenses (ie, AFTune=3)',
3937
+ Format => 'int8s',
3938
+ PrintConv => '$val > 0 ? "+$val" : $val',
3939
+ PrintConvInv => '$val',
3940
+ },
3821
3941
  );
3822
3942
 
3823
3943
  # Nikon NEF processing information (ref forum6281)
@@ -4538,6 +4658,12 @@ my %nikonFocalConversions = (
4538
4658
  13 => 'Nikkor Z 24-70mm f/2.8 S',
4539
4659
  14 => 'Nikkor Z 85mm f/1.8 S',
4540
4660
  15 => 'Nikkor Z 24mm f/1.8 S', #IB
4661
+ 16 => 'Nikkor Z 70-200mm f/2.8 VR S', #IB
4662
+ 17 => 'Nikkor Z 20mm f/1.8 S', #IB
4663
+ 18 => 'Nikkor Z 24-200mm f/4-6.3 VR', #IB
4664
+ 21 => 'Nikkor Z 50mm f/1.2 S', #IB
4665
+ 22 => 'Nikkor Z 24-50mm f/4-6.3', #IB
4666
+ 23 => 'Nikkor Z 14-24mm f/2.8 S', #IB
4541
4667
  },
4542
4668
  },
4543
4669
  0x36 => {
@@ -8873,7 +8999,7 @@ my %nikonFocalConversions = (
8873
8999
  },
8874
9000
  },
8875
9001
  {
8876
- Condition => '$$valPt =~ /^0800/', # Z6/Z7
9002
+ Condition => '$$valPt =~ /^080[01]/', # Z6/Z7
8877
9003
  Name => 'LensData0800',
8878
9004
  SubDirectory => {
8879
9005
  TagTable => 'Image::ExifTool::Nikon::LensData0800',