exiftool_vendored 12.14.0 → 12.18.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

@@ -19,7 +19,7 @@ use Image::ExifTool qw(:DataAccess);
19
19
  use Image::ExifTool::Canon;
20
20
  use Image::ExifTool::Exif;
21
21
 
22
- $VERSION = '1.57';
22
+ $VERSION = '1.58';
23
23
 
24
24
  sub ProcessCanonCustom($$$);
25
25
  sub ProcessCanonCustom2($$$);
@@ -2098,6 +2098,24 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
2098
2098
  '$val=~/(\d+)/ ? $1 : 0',
2099
2099
  '$val=~/(\d+)/ ? $1 : 0',
2100
2100
  ],
2101
+ },{ # (1DXmkIII firmware 1.3)
2102
+ Name => 'ContinuousShootingSpeed',
2103
+ Condition => '$count == 5',
2104
+ Count => 5,
2105
+ PrintConv => [
2106
+ '"Hi $val"',
2107
+ '"Cont $val"',
2108
+ '"Lo $val"',
2109
+ '"Soft $val"',
2110
+ '"Soft LS $val"',
2111
+ ],
2112
+ PrintConvInv => [
2113
+ '$val=~/(\d+)/ ? $1 : 0',
2114
+ '$val=~/(\d+)/ ? $1 : 0',
2115
+ '$val=~/(\d+)/ ? $1 : 0',
2116
+ '$val=~/(\d+)/ ? $1 : 0',
2117
+ '$val=~/(\d+)/ ? $1 : 0',
2118
+ ],
2101
2119
  },{ # others
2102
2120
  Name => 'ContinuousShootingSpeed',
2103
2121
  Count => 3,
@@ -15,7 +15,7 @@ use Image::ExifTool::Exif;
15
15
  use Image::ExifTool::XMP;
16
16
  use Image::ExifTool::GPS;
17
17
 
18
- $VERSION = '1.02';
18
+ $VERSION = '1.03';
19
19
 
20
20
  my %convFloat2 = (
21
21
  PrintConv => 'sprintf("%+.2f", $val)',
@@ -44,6 +44,32 @@ my %convFloat2 = (
44
44
  0x0b => { Name => 'CameraRoll', Writable => 'float', %convFloat2 },
45
45
  );
46
46
 
47
+ # thermal parameters in APP4 of DJI ZH20T images (ref forum11401)
48
+ %Image::ExifTool::DJI::ThermalParams = (
49
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
50
+ GROUPS => { 0 => 'APP4', 2 => 'Image' },
51
+ NOTES => 'Thermal parameters extracted from APP4 of DJI RJPEG files from the ZH20T.',
52
+ # 0x00 - 0xaa551206 - temperature header magic number
53
+ 0x24 => { Name => 'K1', Format => 'float' },
54
+ 0x28 => { Name => 'K2', Format => 'float' },
55
+ 0x2c => { Name => 'K3', Format => 'float' },
56
+ 0x30 => { Name => 'K4', Format => 'float' },
57
+ 0x34 => { Name => 'KF', Format => 'float' },
58
+ 0x38 => { Name => 'B1', Format => 'float' },
59
+ 0x3c => { Name => 'B2', Format => 'float' },
60
+ 0x44 => { Name => 'ObjectDistance', Format => 'int16u' },
61
+ 0x46 => { Name => 'RelativeHumidity', Format => 'int16u' },
62
+ 0x48 => { Name => 'Emissivity', Format => 'int16u' },
63
+ 0x4a => { Name => 'Reflection', Format => 'int16u', },
64
+ 0x4c => { Name => 'AmbientTemperature', Format => 'int16u' }, # (aka D1)
65
+ 0x50 => { Name => 'D2', Format => 'int32s' },
66
+ 0x54 => { Name => 'KJ', Format => 'int16u' },
67
+ 0x56 => { Name => 'DB', Format => 'int16u' },
68
+ 0x58 => { Name => 'KK', Format => 'int16u' },
69
+ # 0x500 - 0x55aa1206 - device header magic number
70
+ # (nothing yet decoded from device header)
71
+ );
72
+
47
73
  %Image::ExifTool::DJI::XMP = (
48
74
  %Image::ExifTool::XMP::xmpTableDefaults,
49
75
  GROUPS => { 0 => 'XMP', 1 => 'XMP-drone-dji', 2 => 'Location' },
@@ -15,7 +15,7 @@ use strict;
15
15
  use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
 
18
- $VERSION = '1.04';
18
+ $VERSION = '1.05';
19
19
 
20
20
  # DPX tags
21
21
  %Image::ExifTool::DPX::Main = (
@@ -158,11 +158,11 @@ $VERSION = '1.04';
158
158
  1588=> { Name => 'InputDeviceSerialNumber', Format => 'string[32]' },
159
159
  # 1620=> { Name => 'AspectRatio', Format => 'int32u' },
160
160
  1724 => { Name => 'OriginalFrameRate',Format => 'float' },
161
- 1728 => { Name => 'ShutterAngle', Format => 'float', RawConv => '$val =~ /\d/ ? $val : undef' }, #2
161
+ 1728 => { Name => 'ShutterAngle', Format => 'float', RawConv => '($val =~ /\d/ and $val !~ /nan/i) ? $val : undef' }, #2
162
162
  1732 => { Name => 'FrameID', Format => 'string[32]' },
163
163
  1764 => { Name => 'SlateInformation', Format => 'string[100]' },
164
164
  1920 => { Name => 'TimeCode', Format => 'int32u' }, #2
165
- 1940 => { Name => 'FrameRate', Format => 'float', RawConv => '$val =~ /\d/ ? $val : undef' }, #2
165
+ 1940 => { Name => 'FrameRate', Format => 'float', RawConv => '($val =~ /\d/ and $val !~ /nan/i) ? $val : undef' }, #2
166
166
  1972 => { Name => 'Reserved5', Format => 'string[76]', Unknown => 1 },
167
167
  2048 => { Name => 'UserID', Format => 'string[32]' },
168
168
  );
@@ -56,7 +56,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
56
56
  use Image::ExifTool qw(:DataAccess :Utils);
57
57
  use Image::ExifTool::MakerNotes;
58
58
 
59
- $VERSION = '4.31';
59
+ $VERSION = '4.32';
60
60
 
61
61
  sub ProcessExif($$$);
62
62
  sub WriteExif($$$);
@@ -2560,6 +2560,7 @@ my %opcodeInfo = (
2560
2560
  5 => 'Color sequential area',
2561
2561
  7 => 'Trilinear',
2562
2562
  8 => 'Color sequential linear',
2563
+ # 15 - used by DJI XT2
2563
2564
  },
2564
2565
  },
2565
2566
  0xa300 => {
@@ -4728,8 +4729,8 @@ my %subSecConv = (
4728
4729
  },
4729
4730
  LensID => {
4730
4731
  Groups => { 2 => 'Camera' },
4732
+ Require => 'LensType',
4731
4733
  Desire => {
4732
- 0 => 'LensType',
4733
4734
  1 => 'FocalLength',
4734
4735
  2 => 'MaxAperture',
4735
4736
  3 => 'MaxApertureValue',
@@ -4748,25 +4749,16 @@ my %subSecConv = (
4748
4749
  Applies only to LensType values with a lookup table. May be configured
4749
4750
  by adding user-defined lenses
4750
4751
  },
4751
- # this LensID is only valid if the LensType has a PrintConv,
4752
- # or LensType or LensModel are the model name
4752
+ # this LensID is only valid if the LensType has a PrintConv or is a model name
4753
4753
  RawConv => q{
4754
4754
  my $printConv = $$self{TAG_INFO}{LensType}{PrintConv};
4755
- return $val if ref $printConv eq 'HASH' or
4756
- (ref $printConv eq 'ARRAY' and ref $$printConv[0] eq 'HASH') or
4757
- (defined $val[0] and $val[0] =~ /(mm|\d\/F)/) or
4758
- (defined $val[6] and $val[6] =~ /(mm|\d\/F)/);
4755
+ return $val if ref $printConv eq 'HASH' or (ref $printConv eq 'ARRAY' and
4756
+ ref $$printConv[0] eq 'HASH') or $val[0] =~ /(mm|\d\/F)/;
4759
4757
  return undef;
4760
4758
  },
4761
- ValueConv => '$val[0] || $val[6]',
4759
+ ValueConv => '$val',
4762
4760
  PrintConv => q{
4763
4761
  my $pcv;
4764
- # use LensModel ([6]) if LensType ([0]) is not populated
4765
- # (iPhone populates LensModel but not LensType)
4766
- if (not defined $val[0] and defined $val[6]) {
4767
- $val[0] = $val[6];
4768
- $prt[0] = $prt[6];
4769
- }
4770
4762
  # use LensType2 instead of LensType if available and valid (Sony E-mount lenses)
4771
4763
  # (0x8000 or greater; 0 for several older/3rd-party E-mount lenses)
4772
4764
  if (defined $val[9] and ($val[9] & 0x8000 or $val[9] == 0)) {
@@ -4794,6 +4786,30 @@ my %subSecConv = (
4794
4786
  return $lens;
4795
4787
  },
4796
4788
  },
4789
+ 'LensID-2' => {
4790
+ Name => 'LensID',
4791
+ Groups => { 2 => 'Camera' },
4792
+ Desire => {
4793
+ 0 => 'LensModel',
4794
+ 1 => 'Lens',
4795
+ 2 => 'XMP-aux:LensID',
4796
+ 3 => 'Make',
4797
+ },
4798
+ Inhibit => {
4799
+ 4 => 'Composite:LensID',
4800
+ },
4801
+ RawConv => q{
4802
+ return undef if defined $val[2] and defined $val[3];
4803
+ return $val if defined $val[0] and $val[0] =~ /(mm|\d\/F)/;
4804
+ return $val if defined $val[1] and $val[1] =~ /(mm|\d\/F)/;
4805
+ return undef;
4806
+ },
4807
+ ValueConv => q{
4808
+ return $val[0] if defined $val[0] and $val[0] =~ /(mm|\d\/F)/;
4809
+ return $val[1];
4810
+ },
4811
+ PrintConv => '$_=$val; s/(\d)\/F/$1mm F/; s/mmF/mm F/; s/(\d) mm/${1}mm/; s/ - /-/; $_',
4812
+ },
4797
4813
  );
4798
4814
 
4799
4815
  # table for unknown IFD entries
@@ -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.78';
34
+ $VERSION = '1.79';
35
35
 
36
36
  sub ProcessFujiDir($$$);
37
37
  sub ProcessFaceRec($$$);
@@ -623,6 +623,7 @@ my %faceCategories = (
623
623
  0x700 => 'Eterna', #12
624
624
  0x800 => 'Classic Negative', #forum10536
625
625
  0x900 => 'Bleach Bypass', #forum10890
626
+ 0xa00 => 'Nostalgic Neg', #forum12085
626
627
  },
627
628
  },
628
629
  0x1402 => { #2
@@ -12,7 +12,7 @@ use strict;
12
12
  use vars qw($VERSION);
13
13
  use Image::ExifTool::Exif;
14
14
 
15
- $VERSION = '1.51';
15
+ $VERSION = '1.52';
16
16
 
17
17
  my %coordConv = (
18
18
  ValueConv => 'Image::ExifTool::GPS::ToDegrees($val)',
@@ -50,8 +50,8 @@ my %coordConv = (
50
50
  OTHER => sub {
51
51
  my ($val, $inv) = @_;
52
52
  return undef unless $inv;
53
- return uc $1 if $val =~ /\b([NS])$/i;
54
- return $1 eq '-' ? 'S' : 'N' if $val =~ /^([-+]?)\d+(\.\d*)?$/;
53
+ return uc $1 if $val =~ /\b([NS])\b/i;
54
+ return $1 eq '-' ? 'S' : 'N' if $val =~ /([-+]?)\d+/;
55
55
  return undef;
56
56
  },
57
57
  N => 'North',
@@ -78,8 +78,8 @@ my %coordConv = (
78
78
  OTHER => sub {
79
79
  my ($val, $inv) = @_;
80
80
  return undef unless $inv;
81
- return uc $1 if $val =~ /\b([EW])$/i;
82
- return $1 eq '-' ? 'W' : 'E' if $val =~ /^([-+]?)\d+(\.\d*)?$/;
81
+ return uc $1 if $val =~ /\b([EW])\b/i;
82
+ return $1 eq '-' ? 'W' : 'E' if $val =~ /([-+]?)\d+/;
83
83
  return undef;
84
84
  },
85
85
  E => 'East',
@@ -89,7 +89,7 @@ my $parsePictureTiming; # flag to enable parsing of picture timing information (
89
89
  Notes => 'hours:minutes:seconds:frames',
90
90
  ValueConv => 'sprintf("%.2x:%.2x:%.2x:%.2x",reverse unpack("C*",$val))',
91
91
  },
92
- # 0x14 - TitleBinaryGroup
92
+ # 0x14 - TitleBinaryGroup - val: 0x00000000,0x14200130
93
93
  # 0x15 - TitleCassetteNo (ref 7)
94
94
  # 0x16-0x17 - TitleSoftID (ref 7)
95
95
  # (0x18,0x19 listed as TitleTextHeader/TitleText by ref 7)
@@ -134,8 +134,8 @@ my $parsePictureTiming; # flag to enable parsing of picture timing information (
134
134
  Name => 'Camera2',
135
135
  SubDirectory => { TagTable => 'Image::ExifTool::H264::Camera2' },
136
136
  },
137
- # 0x73 Lens - val: 0x75ffffd3,0x0effffd3,0x59ffffd3,0x79ffffd3,0xffffffd3...
138
- # 0x74 Gain
137
+ # 0x73 Lens - val: 0x04ffffd3,0x0effffd3,0x15ffffd3,0x41ffffd3,0x52ffffd3,0x59ffffd3,0x65ffffd3,0x71ffffd3,0x75ffffd3,0x79ffffd3,0x7fffffd3,0xffffffd3...
138
+ # 0x74 Gain - val: 0xb8ffff0f
139
139
  # 0x75 Pedestal
140
140
  # 0x76 Gamma
141
141
  # 0x77 Detail
@@ -376,34 +376,49 @@ my $parsePictureTiming; # flag to enable parsing of picture timing information (
376
376
  Notes => 'combined with tag 0xc8',
377
377
  },
378
378
  # 0xc9-0xcf - GPSOption
379
+ # 0xc9 - val: 0x001d0203
380
+ 0xca => { #PH (Sony DSC-HX7V)
381
+ Name => 'GPSDateStamp',
382
+ Format => 'string',
383
+ Groups => { 1 => 'GPS', 2 => 'Time' },
384
+ Combine => 2, # the next 2 tags contain the rest of the string
385
+ Notes => 'combined with tags 0xcb and 0xcc',
386
+ ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
387
+ },
379
388
  0xe0 => {
380
389
  Name => 'MakeModel',
381
390
  SubDirectory => { TagTable => 'Image::ExifTool::H264::MakeModel' },
382
391
  },
383
392
  # 0xe1-0xef - MakerOption
384
393
  # 0xe1 - val: 0x01000670,0x01000678,0x06ffffff,0x01ffffff,0x01000020,0x01000400...
385
- # 0xe2-0xe8 - val: 0x00000000 in many samples
386
394
  0xe1 => { #6
387
395
  Name => 'RecInfo',
388
396
  Condition => '$$self{Make} eq "Canon"',
389
397
  Notes => 'Canon only',
390
398
  SubDirectory => { TagTable => 'Image::ExifTool::H264::RecInfo' },
391
399
  },
400
+ # 0xe2-0xe8 - val: 0x00000000 in many samples
401
+ # 0xe2 - val: 0x00000000,0x01000000,0x01010000,0x8080900c,0x8080a074
402
+ # 0xe3 - val: 0x00801f89,0x00801f8b,0x00c01f89,0xc9c01f80
392
403
  0xe4 => { #PH
393
404
  Name => 'Model',
394
405
  Condition => '$$self{Make} eq "Sony"', # (possibly also Canon models?)
395
406
  Description => 'Camera Model Name',
396
- Notes => 'Sony cameras only, combined with tags 0xe5 and 0xe6',
407
+ Notes => 'Sony only, combined with tags 0xe5 and 0xe6',
397
408
  Format => 'string',
398
409
  Combine => 2, # (not sure about 0xe6, but include it just in case)
399
410
  RawConv => '$val eq "" ? undef : $val',
400
411
  },
412
+ # 0xeb - val: 0x008a0a00,0x0a300000,0x508a0a00,0x52880a00,0x528a0a00
413
+ # 0xec - val: 0x0b700000
414
+ # 0xed - val: 0x0ce0f819
401
415
  0xee => { #6 (HFS200)
402
416
  Name => 'FrameInfo',
403
417
  Condition => '$$self{Make} eq "Canon"',
404
418
  Notes => 'Canon only',
405
419
  SubDirectory => { TagTable => 'Image::ExifTool::H264::FrameInfo' },
406
420
  },
421
+ # 0xef - val: 0x01c00000,0x0e00000c
407
422
  );
408
423
 
409
424
  # ConsumerCamera1 information (ref PH)
@@ -16,7 +16,7 @@ $VERSION = '1.30';
16
16
  sub ProcessOcad($$$);
17
17
  sub ProcessJPEG_HDR($$$);
18
18
 
19
- # (this main JPEG table is for documentation purposes only)
19
+ # (most of the tags in this table are for documentation purposes only)
20
20
  %Image::ExifTool::JPEG::Main = (
21
21
  NOTES => q{
22
22
  This table lists information extracted by ExifTool from JPEG images. See
@@ -96,6 +96,12 @@ sub ProcessJPEG_HDR($$$);
96
96
  Name => 'Stim',
97
97
  Condition => '$$valPt =~ /^Stim\0/',
98
98
  SubDirectory => { TagTable => 'Image::ExifTool::Stim::Main' },
99
+ }, {
100
+ Name => 'ThermalData', # (written by DJI FLIR models)
101
+ Condition => '$$self{Make} eq "DJI"',
102
+ Notes => 'DJI raw thermal data',
103
+ Groups => { 0 => 'APP3', 1 => 'DJI', 2 => 'Image' },
104
+ Binary => 1,
99
105
  }, {
100
106
  Name => 'PreviewImage', # (written by HP R837 and Samsung S1060)
101
107
  Condition => '$$valPt =~ /^\xff\xd8\xff\xdb/',
@@ -109,6 +115,10 @@ sub ProcessJPEG_HDR($$$);
109
115
  Name => 'FPXR', # (non-standard location written by some HP models)
110
116
  Condition => '$$valPt =~ /^FPXR\0/',
111
117
  SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::Main' },
118
+ }, {
119
+ Name => 'ThermalParams', # (written by DJI FLIR models)
120
+ Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^\xaa\x55\x12\x06/',
121
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::ThermalParams' },
112
122
  }, {
113
123
  Name => 'PreviewImage', # (eg. Samsung S1060)
114
124
  Notes => 'continued from APP3',
@@ -121,6 +131,12 @@ sub ProcessJPEG_HDR($$$);
121
131
  Name => 'SamsungUniqueID',
122
132
  Condition => '$$valPt =~ /ssuniqueid\0/',
123
133
  SubDirectory => { TagTable => 'Image::ExifTool::Samsung::APP5' },
134
+ }, {
135
+ Name => 'ThermalCalibration', # (written by DJI FLIR models)
136
+ Condition => '$$self{Make} eq "DJI"',
137
+ Notes => 'DJI thermal calibration data',
138
+ Groups => { 0 => 'APP5', 1 => 'DJI', 2 => 'Image' },
139
+ Binary => 1,
124
140
  }, {
125
141
  Name => 'PreviewImage', # (eg. BenQ DC E1050)
126
142
  Notes => 'continued from APP4',
@@ -142,6 +158,12 @@ sub ProcessJPEG_HDR($$$);
142
158
  Condition => '$$valPt =~ /^GoPro\0/',
143
159
  SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
144
160
  # also seen Motorola APP6 "MMIMETA\0", with sub-types: AL3A,ALED,MMI0,MOTD,QC3A
161
+ }, {
162
+ Name => 'DJI_DTAT', # (written by ZH20T)
163
+ Condition => '$$valPt =~ /^DTAT\0\0.\{/s',
164
+ Groups => { 0 => 'APP6', 1 => 'DJI' },
165
+ Notes => 'DJI Thermal Analysis Tool record',
166
+ ValueConv => 'substr($val,7)',
145
167
  }],
146
168
  APP7 => [{
147
169
  Name => 'Pentax',
@@ -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.90';
65
+ $VERSION = '3.93';
66
66
 
67
67
  sub LensIDConv($$$);
68
68
  sub ProcessNikonAVI($$$);
@@ -886,33 +886,33 @@ my %afPoints39 = (
886
886
  # AF point indices for models with 105 focus points, eg. D6 (ref 28)
887
887
  # - 7 rows (A-G) with 15 columns (1-15), center is D8
888
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',
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
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',
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
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',
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
916
  );
917
917
 
918
918
  # AF point indices for models with 135 focus points, eg. 1J1 (ref PH)
@@ -1097,7 +1097,12 @@ my %binaryDataAttrs = (
1097
1097
  0x0004 => { Name => 'Quality', Writable => 'string' },
1098
1098
  0x0005 => { Name => 'WhiteBalance', Writable => 'string' },
1099
1099
  0x0006 => { Name => 'Sharpness', Writable => 'string' },
1100
- 0x0007 => { Name => 'FocusMode', Writable => 'string' },
1100
+ 0x0007 => {
1101
+ Name => 'FocusMode',
1102
+ DataMember => 'FocusMode',
1103
+ Writable => 'string',
1104
+ RawConv => '$$self{FocusMode} = $val',
1105
+ },
1101
1106
  # FlashSetting (better named FlashSyncMode, ref 28) values:
1102
1107
  # "Normal", "Slow", "Rear Slow", "RED-EYE", "RED-EYE SLOW"
1103
1108
  0x0008 => { Name => 'FlashSetting', Writable => 'string' },
@@ -1424,12 +1429,27 @@ my %binaryDataAttrs = (
1424
1429
  Count => 4,
1425
1430
  # (may need to divide by 4 for some images, eg. D3300/D5300, 12 bit - ref IB)
1426
1431
  },
1432
+ 0x003e => { #28
1433
+ Name => 'ImageSizeRAW',
1434
+ PrintConv => {
1435
+ 1 => 'Large',
1436
+ 2 => 'Medium',
1437
+ 3 => 'Small',
1438
+ },
1439
+ },
1427
1440
  0x0045 => { #IB
1428
1441
  Name => 'CropArea',
1429
1442
  Notes => 'left, top, width, height',
1430
1443
  Writable => 'int16u',
1431
1444
  Count => 4,
1432
1445
  },
1446
+ 0x004e => { #28
1447
+ Name => 'NikonSettings',
1448
+ Writable => 'undef',
1449
+ Permanent => 0,
1450
+ Flags => [ 'Binary', 'Protected' ],
1451
+ SubDirectory => { TagTable => 'Image::ExifTool::NikonSettings::Main' },
1452
+ },
1433
1453
  0x004f => { #IB (D850)
1434
1454
  Name => 'ColorTemperatureAuto',
1435
1455
  Writable => 'int16u',
@@ -1500,6 +1520,7 @@ my %binaryDataAttrs = (
1500
1520
  7 => 'Fired, External', #14
1501
1521
  8 => 'Fired, Commander Mode',
1502
1522
  9 => 'Fired, TTL Mode',
1523
+ 18 => 'LED Light', #G.F. (movie LED light)
1503
1524
  },
1504
1525
  },
1505
1526
  0x0088 => [
@@ -1828,9 +1849,9 @@ my %binaryDataAttrs = (
1828
1849
  Condition => '$$valPt =~ /^0246/',
1829
1850
  Name => 'ShotInfoD6',
1830
1851
  SubDirectory => {
1831
- TagTable => 'Image::ExifTool::Nikon::ShotInfo',
1852
+ TagTable => 'Image::ExifTool::Nikon::ShotInfoD6',
1832
1853
  DecryptStart => 4,
1833
- DecryptLen => 0xa4, # only decrypt the version info & offset fields for now
1854
+ DecryptLen => 0xc21a + 12,
1834
1855
  ByteOrder => 'LittleEndian',
1835
1856
  },
1836
1857
  },
@@ -1844,6 +1865,16 @@ my %binaryDataAttrs = (
1844
1865
  ByteOrder => 'BigEndian',
1845
1866
  },
1846
1867
  },
1868
+ { # (Z6_2 firmware version 1.00 and Z7_2 firmware versions 1.00 & 1.01, ref 28)
1869
+ Condition => '$$valPt =~ /^0800/ or $$valPt =~ /^0803/',
1870
+ Name => 'ShotInfoZ7_2',
1871
+ SubDirectory => {
1872
+ TagTable => 'Image::ExifTool::Nikon::ShotInfoZ7_2',
1873
+ DecryptStart => 4,
1874
+ DecryptLen => 0xce32 + 12,
1875
+ ByteOrder => 'LittleEndian',
1876
+ },
1877
+ },
1847
1878
  { # D7100=0227, Z6/Z7=0800
1848
1879
  Condition => '$$valPt =~ /^0[28]/',
1849
1880
  Name => 'ShotInfo02xx',
@@ -2218,6 +2249,11 @@ my %binaryDataAttrs = (
2218
2249
  Name => 'FlashInfo0107', # (0107 for D4S/D750/D810/D5500/D7200, 0108 for D5/D500/D3400)
2219
2250
  Condition => '$$valPt =~ /^010[78]/',
2220
2251
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0107' },
2252
+ },
2253
+ {
2254
+ Name => 'FlashInfo0300', # (Z7_2)
2255
+ Condition => '$$valPt =~ /^0300/',
2256
+ SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0300' },
2221
2257
  },
2222
2258
  {
2223
2259
  Name => 'FlashInfoUnknown',
@@ -3381,13 +3417,13 @@ my %binaryDataAttrs = (
3381
3417
  130 => 'Subject Tracking (41 points)', #PH (NC)
3382
3418
  131 => 'Face Priority (41 points)', #PH (NC)
3383
3419
  192 => 'Pinpoint', #PH (Z7)
3384
- 193 => 'Single', #PH (Z7) (AF-S?)
3420
+ 193 => 'Single', #PH (Z7)
3385
3421
  194 => 'Dynamic', #PH (Z7)
3386
3422
  195 => 'Wide (S)', #PH (Z7)
3387
3423
  196 => 'Wide (L)', #PH (Z7)
3388
3424
  197 => 'Auto', #PH (Z7)
3389
- 198 => 'Auto (198)', #PH (Z7) (focus lock with AF-C maybe?)
3390
- 199 => 'Auto (focus lock)', #PH (Z7, AF-S)
3425
+ 198 => 'Auto (People)', #28 (Z7) #if no faces are detected, will record as 'Auto'. Camera setting recorded in AFAreaMode field in the MakerNotes area
3426
+ 199 => 'Auto (Animal)', #28 (Z7) #if no animals are detected, will record as 'Auto'. Camera setting recorded in AFAreaMode field in the MakerNotes area
3391
3427
  200 => 'Normal-area AF', #28 (D6)
3392
3428
  201 => 'Wide-area AF', #28 (D6)
3393
3429
  202 => 'Face-priority AF', #28 (D6)
@@ -3682,7 +3718,7 @@ my %binaryDataAttrs = (
3682
3718
  ],
3683
3719
  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
3684
3720
  Name => 'AFPointsUsed',
3685
- Condition => '$$self{AFInfo2Version} eq "0301" and $$self{PhaseDetectAF} == 9',
3721
+ Condition => '$$self{AFInfo2Version} eq "0301" and $$self{PhaseDetectAF} == 9',
3686
3722
  Notes => q{
3687
3723
  models with 105-point AF -- 7 rows (A-G) and 15 columns (1-15). Center
3688
3724
  point is D8
@@ -3771,6 +3807,14 @@ my %binaryDataAttrs = (
3771
3807
  },
3772
3808
  Format => 'int16u',
3773
3809
  },
3810
+ 0x2f => { #28 (Z7) Still photography range 1-17 for the 493 point Z7 (arranged in a 29x17 grid. Center at x=16, y=10).
3811
+ Name => 'AFFocusPointXPosition',
3812
+ Condition => q{
3813
+ $$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
3814
+ $$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} =~ /^0301/
3815
+ },
3816
+ PrintConv => sub { my ($val) = @_; PrintAFPointsLeftRight($val, 29 ); },
3817
+ },
3774
3818
  0x30 => [
3775
3819
  { #PH (Z7)
3776
3820
  Name => 'AFAreaYPosition',
@@ -3790,6 +3834,14 @@ my %binaryDataAttrs = (
3790
3834
  PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints153); },
3791
3835
  },
3792
3836
  ],
3837
+ 0x31 => { #28 (Z7)
3838
+ Name => 'AFFocusPointYPosition',
3839
+ Condition => q{
3840
+ $$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
3841
+ $$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} =~ /^0301/
3842
+ },
3843
+ PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 17 ); },
3844
+ },
3793
3845
  0x32 => { #PH (Z7)
3794
3846
  Name => 'AFAreaWidth',
3795
3847
  Condition => '$$self{AFInfo2Version} =~ /^03/',
@@ -6394,6 +6446,77 @@ my %nikonFocalConversions = (
6394
6446
  },
6395
6447
  # note: DecryptLen currently set to OtherOffset + 0x2ea5 - 0x2c90
6396
6448
  );
6449
+
6450
+ # shot information for the D6 firmware 1.00 (encrypted) - ref 28
6451
+ %Image::ExifTool::Nikon::ShotInfoD6 = (
6452
+ PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6453
+ WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6454
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6455
+ VARS => { ID_LABEL => 'Index' },
6456
+ DATAMEMBER => [ 0x9c, 0xc219 ],
6457
+ WRITABLE => 1,
6458
+ FIRST_ENTRY => 0,
6459
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6460
+ NOTES => 'These tags are extracted from encrypted data in images from the D6.',
6461
+ 0x00 => {
6462
+ Name => 'ShotInfoVersion',
6463
+ Format => 'string[4]',
6464
+ Writable => 0,
6465
+ },
6466
+ 0x24 => {
6467
+ Name => 'NumberOffsets', # (number of entries in offset table. offsets are from start of ShotInfo data)
6468
+ DataMember => 'NumberOffsets',
6469
+ Format => 'int32u',
6470
+ Writable => 0,
6471
+ Hidden => 1,
6472
+ },
6473
+ 0x9c => {
6474
+ Name => 'OrientationOffset',
6475
+ DataMember => 'OrientationOffset',
6476
+ Format => 'int32u',
6477
+ Writable => 0,
6478
+ Hidden => 1,
6479
+ RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
6480
+ },
6481
+ ### 0xc21a - OrientationInfo start (D6 firmware 1.00)
6482
+ 0xc219 => {
6483
+ Name => 'Hook1',
6484
+ Hidden => 1,
6485
+ RawConv => 'undef',
6486
+ # account for variable location of OrientationInfo data
6487
+ Hook => '$varSize = $$self{OrientationOffset} - 0xc21a',
6488
+ },
6489
+
6490
+ 0xc21a => {
6491
+ Name => 'RollAngle',
6492
+ Format => 'fixed32u',
6493
+ Notes => 'converted to degrees of clockwise camera roll',
6494
+ ValueConv => '$val <= 180 ? $val : $val - 360',
6495
+ ValueConvInv => '$val >= 0 ? $val : $val + 360',
6496
+ PrintConv => 'sprintf("%.1f", $val)',
6497
+ PrintConvInv => '$val',
6498
+ },
6499
+ 0xc21e => {
6500
+ Name => 'PitchAngle',
6501
+ Format => 'fixed32u',
6502
+ Notes => 'converted to degrees of upward camera tilt',
6503
+ ValueConv => '$val <= 180 ? $val : $val - 360',
6504
+ ValueConvInv => '$val >= 0 ? $val : $val + 360',
6505
+ PrintConv => 'sprintf("%.1f", $val)',
6506
+ PrintConvInv => '$val',
6507
+ },
6508
+ 0xc222 => {
6509
+ Name => 'YawAngle',
6510
+ Format => 'fixed32u',
6511
+ Notes => 'the camera yaw angle when shooting in portrait orientation',
6512
+ ValueConv => '$val <= 180 ? $val : $val - 360',
6513
+ ValueConvInv => '$val >= 0 ? $val : $val + 360',
6514
+ PrintConv => 'sprintf("%.1f", $val)',
6515
+ PrintConvInv => '$val',
6516
+ },
6517
+ # note: DecryptLen currently set to 0xc21a + 12
6518
+ );
6519
+
6397
6520
  # shot information for the D610 firmware 1.00 (encrypted) - ref PH
6398
6521
  %Image::ExifTool::Nikon::ShotInfoD610 = (
6399
6522
  PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
@@ -7211,6 +7334,98 @@ my %nikonFocalConversions = (
7211
7334
  # note: DecryptLen currently set to 0x3697
7212
7335
  );
7213
7336
 
7337
+ # shot information for the Z7_2 firmware 1.00 (encrypted) - ref 28
7338
+ %Image::ExifTool::Nikon::ShotInfoZ7_2 = (
7339
+ PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7340
+ WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7341
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7342
+ VARS => { ID_LABEL => 'Index' },
7343
+ DATAMEMBER => [ 0x04, 0x0e, 0x18, 0x98, 0xce31 ],
7344
+ WRITABLE => 1,
7345
+ FIRST_ENTRY => 0,
7346
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7347
+ NOTES => 'These tags are extracted from encrypted data in images from the Z7_2.',
7348
+ 0x00 => {
7349
+ Name => 'ShotInfoVersion',
7350
+ Format => 'string[4]',
7351
+ Writable => 0,
7352
+ },
7353
+ 0x04 => {
7354
+ Name => 'FirmwareVersion',
7355
+ DataMember => 'FirmwareVersion',
7356
+ Format => 'string[8]',
7357
+ Writable => 0,
7358
+ RawConv => '$$self{FirmwareVersion} = $val',
7359
+ },
7360
+ 0x0E => {
7361
+ Name => 'FirmwareVersion2',
7362
+ Format => 'string[8]',
7363
+ Writable => 0,
7364
+ RawConv => '$$self{FirmwareVersion2} = $val',
7365
+ Hidden => 1,
7366
+ },
7367
+ 0x18 => {
7368
+ Name => 'FirmwareVersion3',
7369
+ Format => 'string[8]',
7370
+ Writable => 0,
7371
+ RawConv => '$$self{FirmwareVersion3} = $val',
7372
+ Hidden => 1,
7373
+ },
7374
+ 0x24 => {
7375
+ Name => 'NumberOffsets', #number of entries in offset table. offsets are from start of ShotInfo data.
7376
+ DataMember => 'NumberOffsets',
7377
+ Format => 'int32u',
7378
+ Writable => 0,
7379
+ Hidden => 1,
7380
+ },
7381
+ 0x98 => {
7382
+ Name => 'OrientationOffset',
7383
+ DataMember => 'OrientationOffset',
7384
+ Format => 'int32u',
7385
+ Writable => 0,
7386
+ Hidden => 1,
7387
+ RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
7388
+ },
7389
+
7390
+ ### 0xce32 - OrientationInfo start (Z7_2 firmware 1.00)
7391
+ 0xce31 => {
7392
+ Name => 'Hook1',
7393
+ Hidden => 1,
7394
+ RawConv => 'undef',
7395
+ # account for variable location of OrientationInfo data
7396
+ Hook => '$varSize = $$self{OrientationOffset} - 0xce32',
7397
+ },
7398
+
7399
+ 0xce32 => {
7400
+ Name => 'RollAngle',
7401
+ Format => 'fixed32u',
7402
+ Notes => 'converted to degrees of clockwise camera roll',
7403
+ ValueConv => '$val <= 180 ? $val : $val - 360',
7404
+ ValueConvInv => '$val >= 0 ? $val : $val + 360',
7405
+ PrintConv => 'sprintf("%.1f", $val)',
7406
+ PrintConvInv => '$val',
7407
+ },
7408
+ 0xce36 => {
7409
+ Name => 'PitchAngle',
7410
+ Format => 'fixed32u',
7411
+ Notes => 'converted to degrees of upward camera tilt',
7412
+ ValueConv => '$val <= 180 ? $val : $val - 360',
7413
+ ValueConvInv => '$val >= 0 ? $val : $val + 360',
7414
+ PrintConv => 'sprintf("%.1f", $val)',
7415
+ PrintConvInv => '$val',
7416
+ },
7417
+ 0xce3a => {
7418
+ Name => 'YawAngle',
7419
+ Format => 'fixed32u',
7420
+ Notes => 'the camera yaw angle when shooting in portrait orientation',
7421
+ ValueConv => '$val <= 180 ? $val : $val - 360',
7422
+ ValueConvInv => '$val >= 0 ? $val : $val + 360',
7423
+ PrintConv => 'sprintf("%.1f", $val)',
7424
+ PrintConvInv => '$val',
7425
+ },
7426
+ #note: DecryptLen currently set to 0xce32 + 12
7427
+ );
7428
+
7214
7429
  # Flash information (ref JD)
7215
7430
  %Image::ExifTool::Nikon::FlashInfo0100 = (
7216
7431
  %binaryDataAttrs,
@@ -8105,6 +8320,42 @@ my %nikonFocalConversions = (
8105
8320
  ],
8106
8321
  );
8107
8322
 
8323
+ # Flash information for the Z7_2 (ref 28)
8324
+ # (likey similar to FlashInfo010 and FlashInfo0108 with addition of support for radio controlled units such as the SB-5000?
8325
+ %Image::ExifTool::Nikon::FlashInfo0300 = (
8326
+ %binaryDataAttrs,
8327
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8328
+ 0 => {
8329
+ Name => 'FlashInfoVersion',
8330
+ Format => 'string[4]',
8331
+ Writable => 0,
8332
+ },
8333
+ 4 => {
8334
+ Name => 'FlashSource',
8335
+ PrintConv => {
8336
+ 0 => 'None',
8337
+ 1 => 'External',
8338
+ 2 => 'Internal',
8339
+ },
8340
+ },
8341
+ 6 => {
8342
+ Format => 'int8u[2]',
8343
+ Name => 'ExternalFlashFirmware',
8344
+ SeparateTable => 'FlashFirmware',
8345
+ PrintConv => \%flashFirmware,
8346
+ },
8347
+ 27 => {
8348
+ Name => 'FlashCompensation',
8349
+ # this is the compensation from the camera (0x0012) for "Built-in" FlashType, or
8350
+ # the compensation from the external unit (0x0017) for "Optional" FlashType - PH
8351
+ Format => 'int8s',
8352
+ Priority => 0,
8353
+ ValueConv => '-$val/6',
8354
+ ValueConvInv => '-6 * $val',
8355
+ PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
8356
+ PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
8357
+ },
8358
+ );
8108
8359
  # Unknown Flash information
8109
8360
  %Image::ExifTool::Nikon::FlashInfoUnknown = (
8110
8361
  %binaryDataAttrs,
@@ -8933,6 +9184,7 @@ my %nikonFocalConversions = (
8933
9184
  7 => 'Fired, External', #14
8934
9185
  8 => 'Fired, Commander Mode',
8935
9186
  9 => 'Fired, TTL Mode',
9187
+ 18 => 'LED Light', #G.F. (movie LED light)
8936
9188
  },
8937
9189
  },
8938
9190
  0x2000098 => [
@@ -9262,6 +9514,32 @@ sub PrintAFPointsGridInv($$$)
9262
9514
  return join(" ", unpack("H2"x$size, pack('C*', @dat)));
9263
9515
  }
9264
9516
 
9517
+ #------------------------------------------------------------------------------
9518
+ # Print conversion for relative Left/Right AF points (ref 28)
9519
+ # Inputs: 0) column, 1) number of columns
9520
+ # Returns: AF point data as a string (e.g. '2L' or 'C' or '3R')
9521
+ sub PrintAFPointsLeftRight($$)
9522
+ {
9523
+ my ($col, $ncol) = @_;
9524
+ my $center = 1 + ($ncol + 1)/2;
9525
+ return 'C' if $col == $center;
9526
+ return sprintf('%d', $center - $col) . 'L of Center' if $col < $center;
9527
+ return sprintf('%d', $col - $center) . 'R of Center' if $col > $center;
9528
+ }
9529
+
9530
+ #------------------------------------------------------------------------------
9531
+ # Print conversion for relative Up/Down AF points (ref 28)
9532
+ # Inputs: 0) column, 1) number of columns
9533
+ # Returns: AF point data as a string (e.g. '2U' or 'C' or '3D')
9534
+ sub PrintAFPointsUpDown($$)
9535
+ {
9536
+ my ($row, $nrow) = @_;
9537
+ my $center = 1 + ($nrow + 1)/2;
9538
+ return 'C' if $row == $center;
9539
+ return sprintf('%d', $center - $row) . 'U from Center' if $row < $center;
9540
+ return sprintf('%d', $row - $center) . 'D from Center' if $row > $center;
9541
+ }
9542
+
9265
9543
  #------------------------------------------------------------------------------
9266
9544
  # Print PictureControl value
9267
9545
  # Inputs: 0) value (with 0x80 subtracted),
@@ -9667,12 +9945,10 @@ sub PrescanExif($$$)
9667
9945
  $dataLen = length $data;
9668
9946
  $dirStart = 0;
9669
9947
  }
9670
- # loop through necessary IFD entries
9671
- my ($lastTag) = sort { $b <=> $a } keys %$tagHash; # (reverse sort)
9948
+ # loop through Nikon MakerNote IFD entries
9672
9949
  for ($index=0; $index<$numEntries; ++$index) {
9673
9950
  my $entry = $dirStart + 2 + 12 * $index;
9674
9951
  my $tagID = Get16u($dataPt, $entry);
9675
- last if $tagID > $lastTag; # (assuming tags are in order)
9676
9952
  next unless exists $$tagHash{$tagID}; # only extract required tags
9677
9953
  my $format = Get16u($dataPt, $entry+2);
9678
9954
  next if $format < 1 or $format > 13;