Nikon.pm (Image-ExifTool-12.57) | : | Nikon.pm (Image-ExifTool-12.58) | ||
---|---|---|---|---|
skipping to change at line 67 | skipping to change at line 67 | |||
package Image::ExifTool::Nikon; | package Image::ExifTool::Nikon; | |||
use strict; | use strict; | |||
use vars qw($VERSION %nikonLensIDs %nikonTextEncoding); | use vars qw($VERSION %nikonLensIDs %nikonTextEncoding); | |||
use Image::ExifTool qw(:DataAccess :Utils); | use Image::ExifTool qw(:DataAccess :Utils); | |||
use Image::ExifTool::Exif; | use Image::ExifTool::Exif; | |||
use Image::ExifTool::GPS; | use Image::ExifTool::GPS; | |||
use Image::ExifTool::XMP; | use Image::ExifTool::XMP; | |||
$VERSION = '4.19'; | $VERSION = '4.20'; | |||
sub LensIDConv($$$); | sub LensIDConv($$$); | |||
sub ProcessNikonAVI($$$); | sub ProcessNikonAVI($$$); | |||
sub ProcessNikonMOV($$$); | sub ProcessNikonMOV($$$); | |||
sub ProcessNikonEncrypted($$$); | sub ProcessNikonEncrypted($$$); | |||
sub FormatString($); | sub FormatString($); | |||
sub ProcessNikonCaptureEditVersions($$$); | sub ProcessNikonCaptureEditVersions($$$); | |||
sub PrintAFPoints($$); | sub PrintAFPoints($$); | |||
sub PrintAFPointsInv($$); | sub PrintAFPointsInv($$); | |||
sub PrintAFPointsGrid($$); | sub PrintAFPointsGrid($$); | |||
sub PrintAFPointsGridInv($$$); | sub PrintAFPointsGridInv($$$); | |||
sub GetAFPointGrid($$;$); | sub GetAFPointGrid($$;$); | |||
# nikon lens ID numbers (ref 8/11) | # nikon lens ID numbers (ref 8/11) | |||
%nikonLensIDs = ( | %nikonLensIDs = ( | |||
Notes => q{ | Notes => q{ | |||
The Nikon LensID is constructed as a Composite tag from the raw hex valu es | The Nikon LensID is constructed as a Composite tag from the raw hex valu es | |||
of 8 other tags: LensIDNumber, LensFStops, MinFocalLength, MaxFocalLengt h, | of 8 other tags: LensIDNumber, LensFStops, MinFocalLength, MaxFocalLengt h, | |||
MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, i n | MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, i n | |||
that order. Multiple lenses with the same LensID are differentiated by | that order. The user-defined "Lenses" list may be used to specify the l | |||
decimal values in the list below. The user-defined "Lenses" list may be | ens | |||
used to specify the lens for ExifTool to choose in these cases (see the | for ExifTool to choose in these cases (see the | |||
L<sample config file|../config.html> for details). | L<sample config file|../config.html> for details). | |||
}, | }, | |||
OTHER => \&LensIDConv, | OTHER => \&LensIDConv, | |||
# Note: Sync this list with Robert's Perl version at | # Note: Sync this list with Robert's Perl version at | |||
# http://www.rottmerhusen.com/objektives/lensid/files/exif/fmountlens.p.txt | # http://www.rottmerhusen.com/objektives/lensid/files/exif/fmountlens.p.txt | |||
# (hex digits must be uppercase in keys below) | # (hex digits must be uppercase in keys below) | |||
'01 58 50 50 14 14 02 00' => 'AF Nikkor 50mm f/1.8', | '01 58 50 50 14 14 02 00' => 'AF Nikkor 50mm f/1.8', | |||
'01 58 50 50 14 14 05 00' => 'AF Nikkor 50mm f/1.8', | '01 58 50 50 14 14 05 00' => 'AF Nikkor 50mm f/1.8', | |||
'02 42 44 5C 2A 34 02 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5', | '02 42 44 5C 2A 34 02 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5', | |||
'02 42 44 5C 2A 34 08 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5', | '02 42 44 5C 2A 34 08 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5', | |||
skipping to change at line 884 | skipping to change at line 883 | |||
my %bracketProgramZ9 = ( | my %bracketProgramZ9 = ( | |||
0 => 'Disabled', | 0 => 'Disabled', | |||
2 => '2F', | 2 => '2F', | |||
3 => '3F', | 3 => '3F', | |||
4 => '4F', | 4 => '4F', | |||
5 => '5F', | 5 => '5F', | |||
7 => '7F', | 7 => '7F', | |||
9 => '9F', | 9 => '9F', | |||
); | ); | |||
my %dynamicAfAreaModesZ9 = ( | ||||
0 => 'Small', | ||||
1 => 'Medium', | ||||
2 => 'Large', | ||||
); | ||||
my %flashControlModeZ7 = ( | my %flashControlModeZ7 = ( | |||
0 => 'TTL', | 0 => 'TTL', | |||
1 => 'Auto External Flash', | 1 => 'Auto External Flash', | |||
2 => 'GN (distance priority)', | 2 => 'GN (distance priority)', | |||
3 => 'Manual', | 3 => 'Manual', | |||
4 => 'Repeating Flash', | 4 => 'Repeating Flash', | |||
); | ); | |||
my %flashRemoteControlZ7 = ( | my %flashRemoteControlZ7 = ( | |||
0 => 'Group', | 0 => 'Group', | |||
skipping to change at line 2069 | skipping to change at line 2074 | |||
# LightSource shows 3 values COLORED SPEEDLIGHT NATURAL. | # LightSource shows 3 values COLORED SPEEDLIGHT NATURAL. | |||
# (SPEEDLIGHT when flash goes. Have no idea about difference between other t wo.) | # (SPEEDLIGHT when flash goes. Have no idea about difference between other t wo.) | |||
0x0090 => { Name => 'LightSource', Writable => 'string' }, #2 | 0x0090 => { Name => 'LightSource', Writable => 'string' }, #2 | |||
0x0091 => [ #18 | 0x0091 => [ #18 | |||
{ #PH | { #PH | |||
Condition => '$$valPt =~ /^0209/', | Condition => '$$valPt =~ /^0209/', | |||
Name => 'ShotInfoD40', | Name => 'ShotInfoD40', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD40', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD40', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 748, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ | { | |||
Condition => '$$valPt =~ /^0208/', | Condition => '$$valPt =~ /^0208/', | |||
Name => 'ShotInfoD80', | Name => 'ShotInfoD80', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD80', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD80', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 765, | ||||
# (Capture NX can change the makernote byte order, but this stay s big-endian) | # (Capture NX can change the makernote byte order, but this stay s big-endian) | |||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH (D90, firmware 1.00) | { #PH (D90, firmware 1.00) | |||
Condition => '$$valPt =~ /^0213/', | Condition => '$$valPt =~ /^0213/', | |||
Name => 'ShotInfoD90', | Name => 'ShotInfoD90', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD90', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD90', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x398, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH (D3, firmware 0.37 and 1.00) | { #PH (D3, firmware 0.37 and 1.00) | |||
Condition => '$$valPt =~ /^0210/ and $count == 5399', | Condition => '$$valPt =~ /^0210/ and $count == 5399', | |||
Name => 'ShotInfoD3a', | Name => 'ShotInfoD3a', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD3a', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD3a', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x318, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH (D3, firmware 1.10, 2.00 and 2.01 [count 5408], and 2.02 [count 54 12]) | { #PH (D3, firmware 1.10, 2.00 and 2.01 [count 5408], and 2.02 [count 54 12]) | |||
Condition => '$$valPt =~ /^0210/ and ($count == 5408 or $count == 54 12)', | Condition => '$$valPt =~ /^0210/ and ($count == 5408 or $count == 54 12)', | |||
Name => 'ShotInfoD3b', | Name => 'ShotInfoD3b', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD3b', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD3b', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x321, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH (D3X, firmware 1.00) | { #PH (D3X, firmware 1.00) | |||
Condition => '$$valPt =~ /^0214/ and $count == 5409', | Condition => '$$valPt =~ /^0214/ and $count == 5409', | |||
Name => 'ShotInfoD3X', | Name => 'ShotInfoD3X', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD3X', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD3X', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x323, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH (D3S, firmware 0.16 and 1.00) | { #PH (D3S, firmware 0.16 and 1.00) | |||
Condition => '$$valPt =~ /^0218/ and ($count == 5356 or $count == 53 88)', | Condition => '$$valPt =~ /^0218/ and ($count == 5356 or $count == 53 88)', | |||
Name => 'ShotInfoD3S', | Name => 'ShotInfoD3S', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD3S', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD3S', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x2e9, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #JD (D300, firmware 0.25 and 1.00) | { #JD (D300, firmware 0.25 and 1.00) | |||
# D3 and D300 use the same version number, but the length is differe nt | # D3 and D300 use the same version number, but the length is differe nt | |||
Condition => '$$valPt =~ /^0210/ and $count == 5291', | Condition => '$$valPt =~ /^0210/ and $count == 5291', | |||
Name => 'ShotInfoD300a', | Name => 'ShotInfoD300a', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD300a', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD300a', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 813, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH (D300, firmware version 1.10) | { #PH (D300, firmware version 1.10) | |||
# yet again the same ShotInfoVersion for different data | # yet again the same ShotInfoVersion for different data | |||
Condition => '$$valPt =~ /^0210/ and $count == 5303', | Condition => '$$valPt =~ /^0210/ and $count == 5303', | |||
Name => 'ShotInfoD300b', | Name => 'ShotInfoD300b', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD300b', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD300b', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 825, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH (D300S, firmware version 1.00) | { #PH (D300S, firmware version 1.00) | |||
# yet again the same ShotInfoVersion for different data | # yet again the same ShotInfoVersion for different data | |||
Condition => '$$valPt =~ /^0216/ and $count == 5311', | Condition => '$$valPt =~ /^0216/ and $count == 5311', | |||
Name => 'ShotInfoD300S', | Name => 'ShotInfoD300S', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD300S', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD300S', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 827, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
# 0225 - D600 | # 0225 - D600 | |||
{ #29 (D700 firmware version 1.02f) | { #29 (D700 firmware version 1.02f) | |||
Condition => '$$valPt =~ /^0212/ and $count == 5312', | Condition => '$$valPt =~ /^0212/ and $count == 5312', | |||
Name => 'ShotInfoD700', | Name => 'ShotInfoD700', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD700', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD700', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x358, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #28 (D780 firmware version 1.00) | ||||
Condition => '$$valPt =~ /^0245/', | ||||
Name => 'ShotInfoD780', | ||||
SubDirectory => { | ||||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD780', | ||||
DecryptStart => 4, | ||||
ByteOrder => 'LittleEndian', | ||||
}, | ||||
}, | ||||
{ #28 (D7500 firmware version 1.00h) | ||||
Condition => '$$valPt =~ /^0242/', | ||||
Name => 'ShotInfoD7500', | ||||
SubDirectory => { | ||||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD7500', | ||||
DecryptStart => 4, | ||||
ByteOrder => 'LittleEndian', | ||||
}, | ||||
}, | ||||
{ #PH (D800 firmware 1.01a) | { #PH (D800 firmware 1.01a) | |||
Condition => '$$valPt =~ /^0222/', | Condition => '$$valPt =~ /^0222/', | |||
Name => 'ShotInfoD800', | Name => 'ShotInfoD800', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD800', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD800', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x720, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #28 (D810 firmware 1.01) | { #28 (D810 firmware 1.01) | |||
Condition => '$$valPt =~ /^0233/', | Condition => '$$valPt =~ /^0233/', | |||
Name => 'ShotInfoD810', | Name => 'ShotInfoD810', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD810', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD810', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
ByteOrder => 'LittleEndian', | ByteOrder => 'LittleEndian', | |||
skipping to change at line 2215 | skipping to change at line 2226 | |||
}, | }, | |||
# 0217 - D3000 | # 0217 - D3000 | |||
# 0219 - D3100 | # 0219 - D3100 | |||
# 0224 - D3200 | # 0224 - D3200 | |||
{ #PH | { #PH | |||
Condition => '$$valPt =~ /^0215/ and $count == 6745', | Condition => '$$valPt =~ /^0215/ and $count == 6745', | |||
Name => 'ShotInfoD5000', | Name => 'ShotInfoD5000', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD5000', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD5000', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x39a, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH | { #PH | |||
Condition => '$$valPt =~ /^0221/ and $count == 8902', | Condition => '$$valPt =~ /^0221/ and $count == 8902', | |||
Name => 'ShotInfoD5100', | Name => 'ShotInfoD5100', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD5100', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD5100', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x430, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #PH | { #PH | |||
Condition => '$$valPt =~ /^0226/ and $count == 11587', | Condition => '$$valPt =~ /^0226/ and $count == 11587', | |||
Name => 'ShotInfoD5200', | Name => 'ShotInfoD5200', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD5200', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD5200', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0xd00, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ #29 (D7000 firmware version 1.01b) | { #29 (D7000 firmware version 1.01b) | |||
Condition => '$$valPt =~ /^0220/', | Condition => '$$valPt =~ /^0220/', | |||
Name => 'ShotInfoD7000', | Name => 'ShotInfoD7000', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD7000', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD7000', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x448, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ # (D4 firmware version 1.00g) | { # (D4 firmware version 1.00g) | |||
Condition => '$$valPt =~ /^0223/', | Condition => '$$valPt =~ /^0223/', | |||
Name => 'ShotInfoD4', | Name => 'ShotInfoD4', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD4', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD4', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x789, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ # (D4S firmware version 1.00d and 1.01a) | { # (D4S firmware version 1.00d and 1.01a) | |||
Condition => '$$valPt =~ /^0231/', | Condition => '$$valPt =~ /^0231/', | |||
Name => 'ShotInfoD4S', | Name => 'ShotInfoD4S', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD4S', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD4S', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x3697, | ||||
ByteOrder => 'LittleEndian', | ByteOrder => 'LittleEndian', | |||
}, | }, | |||
}, | }, | |||
{ #28 (D500 firmware version 1.00 and D5 firmware version 1.10a) | { #28 (D500 firmware version 1.00 and D5 firmware version 1.10a) | |||
Condition => '$$valPt =~ /^023[89]/', | Condition => '$$valPt =~ /^023[89]/', | |||
Name => 'ShotInfoD500', | Name => 'ShotInfoD500', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD500', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD500', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
ByteOrder => 'LittleEndian', | ByteOrder => 'LittleEndian', | |||
skipping to change at line 2293 | skipping to change at line 2298 | |||
DecryptStart => 4, | DecryptStart => 4, | |||
ByteOrder => 'LittleEndian', | ByteOrder => 'LittleEndian', | |||
}, | }, | |||
}, | }, | |||
{ # (D610 firmware version 1.00) | { # (D610 firmware version 1.00) | |||
Condition => '$$valPt =~ /^0232/', | Condition => '$$valPt =~ /^0232/', | |||
Name => 'ShotInfoD610', | Name => 'ShotInfoD610', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoD610', | TagTable => 'Image::ExifTool::Nikon::ShotInfoD610', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x7ff, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ # (Z6_2 firmware version 1.00 and Z7II firmware versions 1.00 & 1.01, ref 28) | { # (Z6_2 firmware version 1.00 and Z7II firmware versions 1.00 & 1.01, ref 28) | |||
# 0800=Z6/Z7 0801=Z50 0802=Z5 0803=Z6II/Z7II 0804=Zfc | # 0800=Z6/Z7 0801=Z50 0802=Z5 0803=Z6II/Z7II 0804=Zfc | |||
Condition => '$$valPt =~ /^080[01234]/', | Condition => '$$valPt =~ /^080[01234]/', | |||
Name => 'ShotInfoZ7II', | Name => 'ShotInfoZ7II', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfoZ7II', | TagTable => 'Image::ExifTool::Nikon::ShotInfoZ7II', | |||
DecryptStart => 4, | DecryptStart => 4, | |||
skipping to change at line 2324 | skipping to change at line 2328 | |||
}, | }, | |||
}, | }, | |||
{ # D7100=0227 | { # D7100=0227 | |||
Condition => '$$valPt =~ /^0[28]/', | Condition => '$$valPt =~ /^0[28]/', | |||
Name => 'ShotInfo02xx', | Name => 'ShotInfo02xx', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfo', | TagTable => 'Image::ExifTool::Nikon::ShotInfo', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, | WriteProc => \&ProcessNikonEncrypted, | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 0x251, | ||||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
}, | }, | |||
{ | { | |||
Name => 'ShotInfoUnknown', | Name => 'ShotInfoUnknown', | |||
Writable => 0, | Writable => 0, | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ShotInfo', | TagTable => 'Image::ExifTool::Nikon::ShotInfo', | |||
ByteOrder => 'BigEndian', | ByteOrder => 'BigEndian', | |||
}, | }, | |||
skipping to change at line 2391 | skipping to change at line 2394 | |||
}, | }, | |||
}, | }, | |||
{ | { | |||
Condition => '$$valPt =~ /^0205/', # (D50) | Condition => '$$valPt =~ /^0205/', # (D50) | |||
Name => 'ColorBalance0205', | Name => 'ColorBalance0205', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ColorBalance2', | TagTable => 'Image::ExifTool::Nikon::ColorBalance2', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, | WriteProc => \&ProcessNikonEncrypted, | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 22, # 284 bytes encrypted, but don't need to decry | DirOffset => 14, # (start of directory relative to DecryptStart) | |||
pt it all | ||||
DirOffset => 14, | ||||
}, | }, | |||
}, | }, | |||
{ # (D3/D3X/D300/D700=0209,D300S=0212,D3S=0214) | { # (D3/D3X/D300/D700=0209,D300S=0212,D3S=0214) | |||
Condition => '$$valPt =~ /^02(09|12|14)/', | Condition => '$$valPt =~ /^02(09|12|14)/', | |||
Name => 'ColorBalance0209', | Name => 'ColorBalance0209', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ColorBalance4', | TagTable => 'Image::ExifTool::Nikon::ColorBalance4', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, | WriteProc => \&ProcessNikonEncrypted, | |||
DecryptStart => 284, | DecryptStart => 284, | |||
DecryptLen => 18, # 324 bytes encrypted, but don't need to decry pt it all | ||||
DirOffset => 10, | DirOffset => 10, | |||
}, | }, | |||
}, | }, | |||
{ # (D2X/D2Xs=0204,D2Hs=0206,D200=0207,D40/D40X/D80=0208,D60=0210) | { # (D2X/D2Xs=0204,D2Hs=0206,D200=0207,D40/D40X/D80=0208,D60=0210) | |||
Condition => '$$valPt =~ /^02(\d{2})/ and $1 < 11', | Condition => '$$valPt =~ /^02(\d{2})/ and $1 < 11', | |||
Name => 'ColorBalance02', | Name => 'ColorBalance02', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ColorBalance2', | TagTable => 'Image::ExifTool::Nikon::ColorBalance2', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, | WriteProc => \&ProcessNikonEncrypted, | |||
DecryptStart => 284, | DecryptStart => 284, | |||
DecryptLen => 14, # don't need to decrypt it all | ||||
DirOffset => 6, | DirOffset => 6, | |||
}, | }, | |||
}, | }, | |||
{ | { | |||
Condition => '$$valPt =~ /^0211/', # (D90/D5000) | Condition => '$$valPt =~ /^0211/', # (D90/D5000) | |||
Name => 'ColorBalance0211', | Name => 'ColorBalance0211', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ColorBalance4', | TagTable => 'Image::ExifTool::Nikon::ColorBalance4', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, | WriteProc => \&ProcessNikonEncrypted, | |||
DecryptStart => 284, | DecryptStart => 284, | |||
DecryptLen => 24, # don't need to decrypt it all | ||||
DirOffset => 16, | DirOffset => 16, | |||
}, | }, | |||
}, | }, | |||
{ | { | |||
Condition => '$$valPt =~ /^0213/', # (D3000) | Condition => '$$valPt =~ /^0213/', # (D3000) | |||
Name => 'ColorBalance0213', | Name => 'ColorBalance0213', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ColorBalance2', | TagTable => 'Image::ExifTool::Nikon::ColorBalance2', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, | WriteProc => \&ProcessNikonEncrypted, | |||
DecryptStart => 284, | DecryptStart => 284, | |||
DecryptLen => 18, # don't need to decrypt it all | ||||
DirOffset => 10, | DirOffset => 10, | |||
}, | }, | |||
}, | }, | |||
{ # (D3100=0215,D7000/D5100=0216,D4/D600/D800/D800E/D3200=0217) | { # (D3100=0215,D7000/D5100=0216,D4/D600/D800/D800E/D3200=0217) | |||
Condition => '$$valPt =~ /^021[567]/', | Condition => '$$valPt =~ /^021[567]/', | |||
Name => 'ColorBalance0215', | Name => 'ColorBalance0215', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ColorBalance4', | TagTable => 'Image::ExifTool::Nikon::ColorBalance4', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, | WriteProc => \&ProcessNikonEncrypted, | |||
DecryptStart => 284, | DecryptStart => 284, | |||
DecryptLen => 12, # don't need to decrypt it all | ||||
DirOffset => 4, | DirOffset => 4, | |||
}, | }, | |||
}, | }, | |||
{ # (D5200/D7100=0218, D5300=0219, D610/Df=0220, D3300=0221, CoolpixA= 0601) | { # (D5200/D7100=0218, D5300=0219, D610/Df=0220, D3300=0221, CoolpixA= 0601) | |||
Name => 'ColorBalanceUnknown02', | Name => 'ColorBalanceUnknown02', | |||
Condition => '$$valPt =~ /^0[26]/', | Condition => '$$valPt =~ /^0[26]/', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown', | TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt th is if serial number changed) | WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt th is if serial number changed) | |||
DecryptStart => 284, | DecryptStart => 284, | |||
DecryptLen => 10, # (arbitrary) | ||||
}, | }, | |||
}, | }, | |||
{ # (1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403, Z6/Z7=0800) | { # (1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403, Z6/Z7=0800) | |||
Name => 'ColorBalanceUnknown04', | Name => 'ColorBalanceUnknown04', | |||
Condition => '$$valPt =~ /^0[48]/', | Condition => '$$valPt =~ /^0[48]/', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown', | TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown', | |||
ProcessProc => \&ProcessNikonEncrypted, | ProcessProc => \&ProcessNikonEncrypted, | |||
WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt th is if serial number changed) | WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt th is if serial number changed) | |||
DecryptStart => 4, | DecryptStart => 4, | |||
DecryptLen => 10, # (arbitrary) | ||||
}, | }, | |||
}, | }, | |||
{ | { | |||
# (CoolpixP7700/P7800=0500, CoolpixP330/P520=0502) | # (CoolpixP7700/P7800=0500, CoolpixP330/P520=0502) | |||
Name => 'ColorBalanceUnknown', | Name => 'ColorBalanceUnknown', | |||
SubDirectory => { TagTable => 'Image::ExifTool::Nikon::ColorBalanceU nknown' }, | SubDirectory => { TagTable => 'Image::ExifTool::Nikon::ColorBalanceU nknown' }, | |||
}, | }, | |||
], | ], | |||
0x0098 => [ | 0x0098 => [ | |||
{ #8 | { #8 | |||
skipping to change at line 5269 | skipping to change at line 5264 | |||
%nikonApertureConversions, | %nikonApertureConversions, | |||
}, | }, | |||
# | # | |||
# ---- new LensData tags used by Nikkor Z cameras (ref PH/28). ---- | # ---- new LensData tags used by Nikkor Z cameras (ref PH/28). ---- | |||
# (some fields are strictly for Z-series lenses, others apply to legacy F-mount as well, ref 28) | # (some fields are strictly for Z-series lenses, others apply to legacy F-mount as well, ref 28) | |||
# | # | |||
0x2f => { # look forward to see if new lens data exists... | 0x2f => { # look forward to see if new lens data exists... | |||
Name => 'NewLensData', | Name => 'NewLensData', | |||
Format => 'undef[17]', | Format => 'undef[17]', | |||
RawConv => '$$self{NewLensData} = 1 unless $val =~ /^.\0+$/s; undef', | RawConv => '$$self{NewLensData} = 1 unless $val =~ /^.\0+$/s; undef', | |||
Hidden => 1, | #Hidden => 1, | |||
}, | }, | |||
0x30 => { #PH | 0x30 => { #PH | |||
Name => 'LensID', | Name => 'LensID', | |||
Condition => '$$self{NewLensData}', | Condition => '$$self{NewLensData}', | |||
Notes => 'tags from here onward used for Nikkor Z lenses only', | Notes => 'tags from here onward used for Nikkor Z lenses only', | |||
Format => 'int16u', | Format => 'int16u', | |||
PrintConv => { | PrintConv => { | |||
1 => 'Nikkor Z 24-70mm f/4 S', | 1 => 'Nikkor Z 24-70mm f/4 S', | |||
2 => 'Nikkor Z 14-30mm f/4 S', | 2 => 'Nikkor Z 14-30mm f/4 S', | |||
4 => 'Nikkor Z 35mm f/1.8 S', | 4 => 'Nikkor Z 35mm f/1.8 S', | |||
skipping to change at line 5314 | skipping to change at line 5309 | |||
37 => 'Nikkor Z 600mm f/4 TC VR S', #28 | 37 => 'Nikkor Z 600mm f/4 TC VR S', #28 | |||
39 => 'Nikkor Z 17-28mm f/2.8', #IB | 39 => 'Nikkor Z 17-28mm f/2.8', #IB | |||
32768 => 'Nikkor Z 400mm f/2.8 TC VR S TC-1.4x', #28 | 32768 => 'Nikkor Z 400mm f/2.8 TC VR S TC-1.4x', #28 | |||
32769 => 'Nikkor Z 600mm f/4 TC VR S TC-1.4x', #28 | 32769 => 'Nikkor Z 600mm f/4 TC VR S TC-1.4x', #28 | |||
}, | }, | |||
}, | }, | |||
0x35 => { #28 | 0x35 => { #28 | |||
Name => 'LensMountType', | Name => 'LensMountType', | |||
RawConv => '$$self{LensMountType} = $val', # 0=> DSLR lens via FTZ st yle adapter; 1=> Native Z lens; | RawConv => '$$self{LensMountType} = $val', # 0=> DSLR lens via FTZ st yle adapter; 1=> Native Z lens; | |||
Format => 'int8u', | Format => 'int8u', | |||
Unknown => 1, | #Unknown => 1, | |||
PrintConv => { | PrintConv => { | |||
0 => 'F-mount Lens', | 0 => 'F-mount Lens', | |||
1 => 'Z-mount Lens', | 1 => 'Z-mount Lens', | |||
}, | }, | |||
}, | }, | |||
0x36 => { #PH | 0x36 => { #PH | |||
Name => 'MaxAperture', | Name => 'MaxAperture', | |||
Condition => '$$self{NewLensData}', | Condition => '$$self{NewLensData}', | |||
Format => 'int16u', | Format => 'int16u', | |||
Priority => 0, | Priority => 0, | |||
skipping to change at line 5377 | skipping to change at line 5372 | |||
Name => 'LensDriveEnd', # byte contains: 1 at CFD/MOD; 2 at Infinity ; 0 otherwise | Name => 'LensDriveEnd', # byte contains: 1 at CFD/MOD; 2 at Infinity ; 0 otherwise | |||
Condition => '$$self{NewLensData} and $$self{LensMountType} and $$self{L ensMountType} == 1', | Condition => '$$self{NewLensData} and $$self{LensMountType} and $$self{L ensMountType} == 1', | |||
Format => 'int8u', | Format => 'int8u', | |||
RawConv => 'unless (defined $$self{FocusDistanceRangeWidth} and not $$se lf{FocusDistanceRangeWidth}) { if ($val == 0 ) {$$self{LensDriveEnd} = "No"} els e { $$self{LensDriveEnd} = "CFD"}; } else{ $$self{LensDriveEnd} = "Inf"}', | RawConv => 'unless (defined $$self{FocusDistanceRangeWidth} and not $$se lf{FocusDistanceRangeWidth}) { if ($val == 0 ) {$$self{LensDriveEnd} = "No"} els e { $$self{LensDriveEnd} = "CFD"}; } else{ $$self{LensDriveEnd} = "Inf"}', | |||
Unknown => 1, | Unknown => 1, | |||
}, | }, | |||
0x5a => { #28 | 0x5a => { #28 | |||
Name => 'LensPositionAbsolute', # <=0 at infinity. Typical value at CFD might be 58000. Only valid for Z-mount lenses. | Name => 'LensPositionAbsolute', # <=0 at infinity. Typical value at CFD might be 58000. Only valid for Z-mount lenses. | |||
Condition => '$$self{NewLensData} and $$self{LensMountType} and $$self{L ensMountType} == 1', | Condition => '$$self{NewLensData} and $$self{LensMountType} and $$self{L ensMountType} == 1', | |||
Format => 'int32s', | Format => 'int32s', | |||
Unknown => 1, | #Unknown => 1, | |||
}, | }, | |||
); | ); | |||
# Unknown Nikon lens data (note: data may need decrypting after byte 4) | # Unknown Nikon lens data (note: data may need decrypting after byte 4) | |||
%Image::ExifTool::Nikon::LensDataUnknown = ( | %Image::ExifTool::Nikon::LensDataUnknown = ( | |||
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, | |||
FIRST_ENTRY => 0, | FIRST_ENTRY => 0, | |||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | |||
0x00 => { | 0x00 => { | |||
Name => 'LensDataVersion', | Name => 'LensDataVersion', | |||
skipping to change at line 5500 | skipping to change at line 5495 | |||
0x0f => 'On', | 0x0f => 'On', | |||
}, | }, | |||
}, | }, | |||
0x24d => { #PH | 0x24d => { #PH | |||
Name => 'ShutterCount', | Name => 'ShutterCount', | |||
Condition => '$$self{ShotInfoVersion} eq "0211"', | Condition => '$$self{ShotInfoVersion} eq "0211"', | |||
Notes => 'D60', | Notes => 'D60', | |||
Format => 'int32u', | Format => 'int32u', | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x251 | ||||
# 0x55c - int16u[2400] TiffMeteringImage2: 60x40 image (ShotInfoVersion 0800 , ref JR) | # 0x55c - int16u[2400] TiffMeteringImage2: 60x40 image (ShotInfoVersion 0800 , ref JR) | |||
# 0x181c - int16u[1200] TiffMeteringImage?: 60x20 image for some NEF's (Shot InfoVersion 0800, ref JR) | # 0x181c - int16u[1200] TiffMeteringImage?: 60x20 image for some NEF's (Shot InfoVersion 0800, ref JR) | |||
# 0x217c - int16u[2400] TiffMeteringImage3: 60x40 image (ShotInfoVersion 080 0, ref JR) | # 0x217c - int16u[2400] TiffMeteringImage3: 60x40 image (ShotInfoVersion 080 0, ref JR) | |||
# 0x3d9c - int16u[2400] TiffMeteringImage4: 60x40 image (ShotInfoVersion 080 0, ref JR) | # 0x3d9c - int16u[2400] TiffMeteringImage4: 60x40 image (ShotInfoVersion 080 0, ref JR) | |||
# 0x59c0 - TiffMeteringImageWidth (ShotInfoVersion 0800, ref JR) | # 0x59c0 - TiffMeteringImageWidth (ShotInfoVersion 0800, ref JR) | |||
# 0x59c2 - TiffMeteringImageHeight (ShotInfoVersion 0800, ref JR) | # 0x59c2 - TiffMeteringImageHeight (ShotInfoVersion 0800, ref JR) | |||
# 0x59c4 - int16u[1800] TiffMeteringImage5: 30x20 RGB image (ShotInfoVersion 0800, ref JR) | # 0x59c4 - int16u[1800] TiffMeteringImage5: 30x20 RGB image (ShotInfoVersion 0800, ref JR) | |||
); | ); | |||
# shot information for D40 and D40X (encrypted) - ref PH | # shot information for D40 and D40X (encrypted) - ref PH | |||
skipping to change at line 5544 | skipping to change at line 5537 | |||
Mask => 0x08, | Mask => 0x08, | |||
PrintConv => { 0 => 'Off', 1 => 'On' }, | PrintConv => { 0 => 'Off', 1 => 'On' }, | |||
}, | }, | |||
729 => { #JD | 729 => { #JD | |||
Name => 'CustomSettingsD40', | Name => 'CustomSettingsD40', | |||
Format => 'undef[12]', | Format => 'undef[12]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD40', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD40', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 748 | ||||
); | ); | |||
# shot information for D80 (encrypted) - ref JD | # shot information for D80 (encrypted) - ref JD | |||
%Image::ExifTool::Nikon::ShotInfoD80 = ( | %Image::ExifTool::Nikon::ShotInfoD80 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 748 ], | IS_SUBDIR => [ 748 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 5624 | skipping to change at line 5616 | |||
6 => 'NEF (RAW) + JPEG Basic', | 6 => 'NEF (RAW) + JPEG Basic', | |||
}, | }, | |||
}, | }, | |||
748 => { #JD | 748 => { #JD | |||
Name => 'CustomSettingsD80', | Name => 'CustomSettingsD80', | |||
Format => 'undef[17]', | Format => 'undef[17]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD80', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD80', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 765 | ||||
); | ); | |||
# shot information for D90 (encrypted) - ref PH | # shot information for D90 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD90 = ( | %Image::ExifTool::Nikon::ShotInfoD90 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0x374 ], | IS_SUBDIR => [ 0x374 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 5670 | skipping to change at line 5661 | |||
Format => 'int32u', | Format => 'int32u', | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
0x374 => { | 0x374 => { | |||
Name => 'CustomSettingsD90', | Name => 'CustomSettingsD90', | |||
Format => 'undef[36]', | Format => 'undef[36]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD90', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD90', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x398 | ||||
); | ); | |||
# shot information for the D3 firmware 0.37 and 1.00 (encrypted) - ref PH | # shot information for the D3 firmware 0.37 and 1.00 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD3a = ( | %Image::ExifTool::Nikon::ShotInfoD3a = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0x301 ], | IS_SUBDIR => [ 0x301 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 5734 | skipping to change at line 5724 | |||
7 => 'JPEG Basic', | 7 => 'JPEG Basic', | |||
}, | }, | |||
}, | }, | |||
0x301 => { #(NC) | 0x301 => { #(NC) | |||
Name => 'CustomSettingsD3', | Name => 'CustomSettingsD3', | |||
Format => 'undef[24]', | Format => 'undef[24]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x318 | ||||
); | ); | |||
# shot information for the D3 firmware 1.10, 2.00 and 2.01 (encrypted) - ref PH | # shot information for the D3 firmware 1.10, 2.00 and 2.01 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD3b = ( | %Image::ExifTool::Nikon::ShotInfoD3b = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0x30a ], | IS_SUBDIR => [ 0x30a ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 5829 | skipping to change at line 5818 | |||
# for the SB-800 and SB-900: | # for the SB-800 and SB-900: | |||
# $val < 140 ? 2**(0.08372*$val-12.352) : $val | # $val < 140 ? 2**(0.08372*$val-12.352) : $val | |||
}, | }, | |||
0x30a => { # tested with firmware 2.00 | 0x30a => { # tested with firmware 2.00 | |||
Name => 'CustomSettingsD3', | Name => 'CustomSettingsD3', | |||
Format => 'undef[24]', | Format => 'undef[24]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x321 | ||||
); | ); | |||
# shot information for the D3X firmware 1.00 (encrypted) - ref PH | # shot information for the D3X firmware 1.00 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD3X = ( | %Image::ExifTool::Nikon::ShotInfoD3X = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0x30b ], | IS_SUBDIR => [ 0x30b ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 5875 | skipping to change at line 5863 | |||
Format => 'int32u', | Format => 'int32u', | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
0x30b => { #(NC) | 0x30b => { #(NC) | |||
Name => 'CustomSettingsD3X', | Name => 'CustomSettingsD3X', | |||
Format => 'undef[24]', | Format => 'undef[24]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x323 | ||||
); | ); | |||
# shot information for the D3S firmware 0.16 and 1.00 (encrypted) - ref PH | # shot information for the D3S firmware 0.16 and 1.00 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD3S = ( | %Image::ExifTool::Nikon::ShotInfoD3S = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0x2ce ], | IS_SUBDIR => [ 0x2ce ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 5930 | skipping to change at line 5917 | |||
Format => 'int32u', | Format => 'int32u', | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
0x2ce => { #(NC) | 0x2ce => { #(NC) | |||
Name => 'CustomSettingsD3S', | Name => 'CustomSettingsD3S', | |||
Format => 'undef[27]', | Format => 'undef[27]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x2e9 | ||||
); | ); | |||
# shot information for the D300 firmware 1.00 (encrypted) - ref JD | # shot information for the D300 firmware 1.00 (encrypted) - ref JD | |||
%Image::ExifTool::Nikon::ShotInfoD300a = ( | %Image::ExifTool::Nikon::ShotInfoD300a = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 790 ], | IS_SUBDIR => [ 790 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 6023 | skipping to change at line 6009 | |||
0x40c2 => '-20', | 0x40c2 => '-20', | |||
}, | }, | |||
}, | }, | |||
790 => { | 790 => { | |||
Name => 'CustomSettingsD300', | Name => 'CustomSettingsD300', | |||
Format => 'undef[24]', | Format => 'undef[24]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 813 | ||||
); | ); | |||
# shot information for the D300 firmware 1.10 (encrypted) - ref PH | # shot information for the D300 firmware 1.10 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD300b = ( | %Image::ExifTool::Nikon::ShotInfoD300b = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
DATAMEMBER => [ 4 ], | DATAMEMBER => [ 4 ], | |||
IS_SUBDIR => [ 802 ], | IS_SUBDIR => [ 802 ], | |||
skipping to change at line 6174 | skipping to change at line 6159 | |||
0x90c2 => '-20', | 0x90c2 => '-20', | |||
}, | }, | |||
}], | }], | |||
802 => { | 802 => { | |||
Name => 'CustomSettingsD300', | Name => 'CustomSettingsD300', | |||
Format => 'undef[24]', | Format => 'undef[24]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 825 | ||||
); | ); | |||
# shot information for the D300S firmware 1.00 (encrypted) - ref PH | # shot information for the D300S firmware 1.00 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD300S = ( | %Image::ExifTool::Nikon::ShotInfoD300S = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 804 ], | IS_SUBDIR => [ 804 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 6220 | skipping to change at line 6204 | |||
Format => 'int32u', | Format => 'int32u', | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
804 => { #(NC) | 804 => { #(NC) | |||
Name => 'CustomSettingsD300S', | Name => 'CustomSettingsD300S', | |||
Format => 'undef[24]', | Format => 'undef[24]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD3', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 827 | ||||
); | ); | |||
# shot information for the D700 firmware 1.02f (encrypted) - ref 29 | # shot information for the D700 firmware 1.02f (encrypted) - ref 29 | |||
%Image::ExifTool::Nikon::ShotInfoD700 = ( | %Image::ExifTool::Nikon::ShotInfoD700 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 804 ], | IS_SUBDIR => [ 804 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 6266 | skipping to change at line 6249 | |||
Format => 'int32u', | Format => 'int32u', | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
804 => { # 0x324 (NC) | 804 => { # 0x324 (NC) | |||
Name => 'CustomSettingsD700', | Name => 'CustomSettingsD700', | |||
Format => 'undef[48]', | Format => 'undef[48]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD700', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD700', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 852 | ); | |||
# shot information for the D780 - ref #28 | ||||
%Image::ExifTool::Nikon::ShotInfoD780 = ( | ||||
PROCESS_PROC => \&ProcessNikonEncrypted, | ||||
WRITE_PROC => \&ProcessNikonEncrypted, | ||||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | ||||
VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 }, | ||||
DATAMEMBER => [ 0x04 ], | ||||
IS_SUBDIR => [ 0x9c ], | ||||
WRITABLE => 1, | ||||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | ||||
NOTES => 'These tags are extracted from encrypted data in images from the D7 | ||||
80.', | ||||
0x00 => { | ||||
Name => 'ShotInfoVersion', | ||||
Format => 'string[4]', | ||||
Writable => 0, | ||||
}, | ||||
0x04 => { | ||||
Name => 'FirmwareVersion', | ||||
DataMember => 'FirmwareVersion', | ||||
Format => 'string[5]', | ||||
Writable => 0, | ||||
RawConv => '$$self{FirmwareVersion} = $val', | ||||
}, | ||||
0x9c => { | ||||
Name => 'OrientOffset', | ||||
Format => 'int32u', | ||||
SubDirectory => { | ||||
TagTable => 'Image::ExifTool::Nikon::OrientationInfo', | ||||
Start => '$val', | ||||
}, | ||||
}, | ||||
); | ); | |||
# shot information for the D5000 firmware 1.00 (encrypted) - ref PH | # shot information for the D5000 firmware 1.00 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD5000 = ( | %Image::ExifTool::Nikon::ShotInfoD5000 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0x378 ], | IS_SUBDIR => [ 0x378 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 6312 | skipping to change at line 6327 | |||
Format => 'int32u', | Format => 'int32u', | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
0x378 => { | 0x378 => { | |||
Name => 'CustomSettingsD5000', | Name => 'CustomSettingsD5000', | |||
Format => 'undef[34]', | Format => 'undef[34]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD5000', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD5000', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x39a | ||||
); | ); | |||
# shot information for the D5100 firmware 1.00f (encrypted) - ref PH | # shot information for the D5100 firmware 1.00f (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD5100 = ( | %Image::ExifTool::Nikon::ShotInfoD5100 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0x407 ], | IS_SUBDIR => [ 0x407 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 6347 | skipping to change at line 6361 | |||
Format => 'int32u', | Format => 'int32u', | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
0x407 => { | 0x407 => { | |||
Name => 'CustomSettingsD5100', | Name => 'CustomSettingsD5100', | |||
Format => 'undef[34]', | Format => 'undef[34]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD5100', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD5100', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x430 | ||||
); | ); | |||
# shot information for the D5200 firmware 1.00 (encrypted) - ref PH | # shot information for the D5200 firmware 1.00 (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD5200 = ( | %Image::ExifTool::Nikon::ShotInfoD5200 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0xcd5 ], | IS_SUBDIR => [ 0xcd5 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 6385 | skipping to change at line 6398 | |||
Priority => 0, | Priority => 0, | |||
}, | }, | |||
# 0xcd2 - 12=VR Off, 15=VR On | # 0xcd2 - 12=VR Off, 15=VR On | |||
0xcd5 => { | 0xcd5 => { | |||
Name => 'CustomSettingsD5200', | Name => 'CustomSettingsD5200', | |||
Format => 'undef[34]', | Format => 'undef[34]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD5200', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD5200', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0xd00 | ||||
); | ); | |||
# shot information for the D7000 firmware 1.01d (encrypted) - ref 29 | # shot information for the D7000 firmware 1.01d (encrypted) - ref 29 | |||
%Image::ExifTool::Nikon::ShotInfoD7000 = ( | %Image::ExifTool::Nikon::ShotInfoD7000 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 1028 ], | IS_SUBDIR => [ 1028 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 6433 | skipping to change at line 6445 | |||
}, | }, | |||
0x404 => { # 1028 (NC) | 0x404 => { # 1028 (NC) | |||
Name => 'CustomSettingsD7000', | Name => 'CustomSettingsD7000', | |||
Format => 'undef[48]', | Format => 'undef[48]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD7000', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD7000', | |||
}, | }, | |||
}, | }, | |||
); | ); | |||
# shot information for the D7500 - ref #28 | ||||
%Image::ExifTool::Nikon::ShotInfoD7500 = ( | ||||
PROCESS_PROC => \&ProcessNikonEncrypted, | ||||
WRITE_PROC => \&ProcessNikonEncrypted, | ||||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | ||||
VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c }, | ||||
DATAMEMBER => [ 0x04 ], | ||||
IS_SUBDIR => [ 0xa0 ], | ||||
WRITABLE => 1, | ||||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | ||||
NOTES => 'These tags are extracted from encrypted data in images from the D7 | ||||
500.', | ||||
0x00 => { | ||||
Name => 'ShotInfoVersion', | ||||
Format => 'string[4]', | ||||
Writable => 0, | ||||
}, | ||||
0x04 => { | ||||
Name => 'FirmwareVersion', | ||||
DataMember => 'FirmwareVersion', | ||||
Format => 'string[5]', | ||||
Writable => 0, | ||||
RawConv => '$$self{FirmwareVersion} = $val', | ||||
}, | ||||
0xa0 => { | ||||
Name => 'OrientOffset', | ||||
Format => 'int32u', | ||||
SubDirectory => { | ||||
TagTable => 'Image::ExifTool::Nikon::OrientationInfo', | ||||
Start => '$val', | ||||
}, | ||||
}, | ||||
); | ||||
# shot information for the D800 firmware 1.01a (encrypted) - ref PH | # shot information for the D800 firmware 1.01a (encrypted) - ref PH | |||
%Image::ExifTool::Nikon::ShotInfoD800 = ( | %Image::ExifTool::Nikon::ShotInfoD800 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
IS_SUBDIR => [ 0x6ec ], | IS_SUBDIR => [ 0x6ec ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
FIRST_ENTRY => 0, | FIRST_ENTRY => 0, | |||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | |||
skipping to change at line 6551 | skipping to change at line 6596 | |||
Name => 'ShutterCount', | Name => 'ShutterCount', | |||
Format => 'int32u', | Format => 'int32u', | |||
}, | }, | |||
0x6ec => { | 0x6ec => { | |||
Name => 'CustomSettingsD800', | Name => 'CustomSettingsD800', | |||
Format => 'undef[48]', | Format => 'undef[48]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD800', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD800', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x720 | ||||
); | ); | |||
# shot information for the D5 firmware 1.10a and D500 firmware 1.01 (encrypted) - ref 28 | # shot information for the D5 firmware 1.10a and D500 firmware 1.01 (encrypted) - ref 28 | |||
%Image::ExifTool::Nikon::ShotInfoD500 = ( | %Image::ExifTool::Nikon::ShotInfoD500 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c }, | VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c }, | |||
DATAMEMBER => [ 0x04 ], | DATAMEMBER => [ 0x04 ], | |||
IS_SUBDIR => [ 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8 ], | IS_SUBDIR => [ 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8 ], | |||
skipping to change at line 7011 | skipping to change at line 7055 | |||
Condition => '$$self{Model} =~ /\bD500\b/', # (didn't seem to work for D 5, but I need more samples) | Condition => '$$self{Model} =~ /\bD500\b/', # (didn't seem to work for D 5, but I need more samples) | |||
Notes => 'D500 only', | Notes => 'D500 only', | |||
Mask => 0x03, | Mask => 0x03, | |||
PrintConv => { | PrintConv => { | |||
0 => 'Matrix', | 0 => 'Matrix', | |||
1 => 'Center', | 1 => 'Center', | |||
2 => 'Spot', | 2 => 'Spot', | |||
3 => 'Highlight' | 3 => 'Highlight' | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to OtherOffset + 0x2ea5 - 0x2c90 | ||||
); | ); | |||
# shot information for the D6 firmware 1.00 (encrypted) - ref 28 | # shot information for the D6 firmware 1.00 (encrypted) - ref 28 | |||
%Image::ExifTool::Nikon::ShotInfoD6 = ( | %Image::ExifTool::Nikon::ShotInfoD6 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 }, | VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 }, | |||
IS_SUBDIR => [ 0x30, 0x9c, 0xa4 ], | IS_SUBDIR => [ 0x30, 0x9c, 0xa4 ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
skipping to change at line 7246 | skipping to change at line 7289 | |||
Format => 'string[5]', | Format => 'string[5]', | |||
Writable => 0, | Writable => 0, | |||
}, | }, | |||
0x07cf => { | 0x07cf => { | |||
Name => 'CustomSettingsD610', | Name => 'CustomSettingsD610', | |||
Format => 'undef[48]', | Format => 'undef[48]', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::NikonCustom::SettingsD610', | TagTable => 'Image::ExifTool::NikonCustom::SettingsD610', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x7ff | ||||
); | ); | |||
# shot information for the D810 firmware 1.00(PH)/1.01 (encrypted) - ref 28 | # shot information for the D810 firmware 1.00(PH)/1.01 (encrypted) - ref 28 | |||
%Image::ExifTool::Nikon::ShotInfoD810 = ( | %Image::ExifTool::Nikon::ShotInfoD810 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c }, | VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c }, | |||
DATAMEMBER => [ 0x04 ], | DATAMEMBER => [ 0x04 ], | |||
IS_SUBDIR => [ 0x10, 0x24, 0x38, 0x40, 0x84 ], | IS_SUBDIR => [ 0x10, 0x24, 0x38, 0x40, 0x84 ], | |||
skipping to change at line 7680 | skipping to change at line 7722 | |||
Name => 'FirmwareVersion', | Name => 'FirmwareVersion', | |||
Format => 'string[5]', | Format => 'string[5]', | |||
Writable => 0, | Writable => 0, | |||
}, | }, | |||
0x0751 => { #PH (NC) | 0x0751 => { #PH (NC) | |||
Name => 'CustomSettingsD4', | Name => 'CustomSettingsD4', | |||
# (seems to work for 1.00g and 1.02b) | # (seems to work for 1.00g and 1.02b) | |||
Format => 'undef[56]', | Format => 'undef[56]', | |||
SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsD4' }, | SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsD4' }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x789 | ||||
); | ); | |||
# shot information for the D4S firmware 1.01a (ref 28, encrypted) | # shot information for the D4S firmware 1.01a (ref 28, encrypted) | |||
%Image::ExifTool::Nikon::ShotInfoD4S = ( | %Image::ExifTool::Nikon::ShotInfoD4S = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index' }, | VARS => { ID_LABEL => 'Index' }, | |||
DATAMEMBER => [ 4 ], | DATAMEMBER => [ 4 ], | |||
IS_SUBDIR => [ 0x189d, 0x193d, 0x350b ], | IS_SUBDIR => [ 0x189d, 0x193d, 0x350b ], | |||
skipping to change at line 7972 | skipping to change at line 8013 | |||
0x3693 => { | 0x3693 => { | |||
Name => 'Rotation', | Name => 'Rotation', | |||
Mask => 0x30, | Mask => 0x30, | |||
PrintConv => { | PrintConv => { | |||
0 => 'Horizontal', | 0 => 'Horizontal', | |||
1 => 'Rotate 270 CW', | 1 => 'Rotate 270 CW', | |||
2 => 'Rotate 90 CW', | 2 => 'Rotate 90 CW', | |||
3 => 'Rotate 180', | 3 => 'Rotate 180', | |||
}, | }, | |||
}, | }, | |||
# note: DecryptLen currently set to 0x3697 | ||||
); | ); | |||
# shot information for the Z7II firmware 1.00 (encrypted) - ref 28 | # shot information for the Z7II firmware 1.00 (encrypted) - ref 28 | |||
%Image::ExifTool::Nikon::ShotInfoZ7II = ( | %Image::ExifTool::Nikon::ShotInfoZ7II = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 }, | VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 }, | |||
DATAMEMBER => [ 0x04 ], | DATAMEMBER => [ 0x04 ], | |||
IS_SUBDIR => [ 0x30, 0x38, 0x98, 0xa0 ], | IS_SUBDIR => [ 0x30, 0x38, 0x98, 0xa0 ], | |||
skipping to change at line 8117 | skipping to change at line 8157 | |||
}, | }, | |||
); | ); | |||
# shot information for the Z9 firmware 1.00 (encrypted) - ref 28 | # shot information for the Z9 firmware 1.00 (encrypted) - ref 28 | |||
%Image::ExifTool::Nikon::ShotInfoZ9 = ( | %Image::ExifTool::Nikon::ShotInfoZ9 = ( | |||
PROCESS_PROC => \&ProcessNikonEncrypted, | PROCESS_PROC => \&ProcessNikonEncrypted, | |||
WRITE_PROC => \&ProcessNikonEncrypted, | WRITE_PROC => \&ProcessNikonEncrypted, | |||
CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | CHECK_PROC => \&Image::ExifTool::CheckBinaryData, | |||
VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 }, | VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 }, | |||
DATAMEMBER => [ 0x04 ], | DATAMEMBER => [ 0x04 ], | |||
IS_SUBDIR => [ 0x30, 0x84, 0x8c ], | IS_SUBDIR => [ 0x30, 0x58, 0x84, 0x8c ], | |||
WRITABLE => 1, | WRITABLE => 1, | |||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | |||
NOTES => 'These tags are extracted from encrypted data in images from the Z9 .', | NOTES => 'These tags are extracted from encrypted data in images from the Z9 .', | |||
0x00 => { | 0x00 => { | |||
Name => 'ShotInfoVersion', | Name => 'ShotInfoVersion', | |||
Format => 'string[4]', | Format => 'string[4]', | |||
Writable => 0, | Writable => 0, | |||
}, | }, | |||
0x04 => { | 0x04 => { | |||
Name => 'FirmwareVersion', | Name => 'FirmwareVersion', | |||
skipping to change at line 8160 | skipping to change at line 8200 | |||
}, | }, | |||
# subdirectories, referenced by offsets (not processed if offset is zero) | # subdirectories, referenced by offsets (not processed if offset is zero) | |||
0x30 => { | 0x30 => { | |||
Name => 'SequenceOffset', | Name => 'SequenceOffset', | |||
Format => 'int32u', | Format => 'int32u', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::SeqInfoZ9', | TagTable => 'Image::ExifTool::Nikon::SeqInfoZ9', | |||
Start => '$val', | Start => '$val', | |||
}, | }, | |||
}, | }, | |||
0x58 => { | ||||
Name => 'Offset13', #offset13 - length x'8f80 (Z9 firmware 3.01 NEF), | ||||
using currently for a few foucs related tags. Might be premature to give the of | ||||
fset a more meaningful name at this point. | ||||
Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} ge "03 | ||||
.01"', | ||||
Format => 'int32u', | ||||
SubDirectory => { | ||||
TagTable => 'Image::ExifTool::Nikon::Offset13InfoZ9', | ||||
Start => '$val', | ||||
}, | ||||
}, | ||||
0x84 => { | 0x84 => { | |||
Name => 'OrientOffset', | Name => 'OrientOffset', | |||
Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #no t valid for C30/C60/C120 | Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #no t valid for C30/C60/C120 | |||
Format => 'int32u', | Format => 'int32u', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::OrientationInfo', | TagTable => 'Image::ExifTool::Nikon::OrientationInfo', | |||
Start => '$val', | Start => '$val', | |||
}, | }, | |||
}, | }, | |||
0x8c => { | 0x8c => { | |||
Name => 'MenuOffset', | Name => 'MenuOffset', | |||
Format => 'int32u', | Format => 'int32u', | |||
SubDirectory => { | SubDirectory => { | |||
TagTable => 'Image::ExifTool::Nikon::MenuInfoZ9', | TagTable => 'Image::ExifTool::Nikon::MenuInfoZ9', | |||
Start => '$val', | Start => '$val', | |||
}, | }, | |||
}, | }, | |||
); | ); | |||
# ref 28 | ||||
%Image::ExifTool::Nikon::SeqInfoZ9 = ( | %Image::ExifTool::Nikon::SeqInfoZ9 = ( | |||
%binaryDataAttrs, | %binaryDataAttrs, | |||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | |||
DATAMEMBER => [ 0x20, 0x28, 0x2a ], | DATAMEMBER => [ 0x20, 0x28, 0x2a ], | |||
0x0020 => { | 0x0020 => { | |||
Name => 'FocusShiftShooting', | Name => 'FocusShiftShooting', | |||
Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #no t valid for C30/C60/C120 | Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #no t valid for C30/C60/C120 | |||
RawConv => '$$self{FocusShiftShooting} = $val', | RawConv => '$$self{FocusShiftShooting} = $val', | |||
PrintConv => q{ | PrintConv => q{ | |||
return 'Off' if $val == 0 ; | return 'Off' if $val == 0 ; | |||
skipping to change at line 8215 | skipping to change at line 8265 | |||
}, | }, | |||
0x002a => { | 0x002a => { | |||
Name => 'IntervalFrame', | Name => 'IntervalFrame', | |||
RawConv => '$$self{IntervalFrame} = $val', | RawConv => '$$self{IntervalFrame} = $val', | |||
Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$se lf{FocusShiftShooting} > 0', #not valid for C30/C60/C120 | Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$se lf{FocusShiftShooting} > 0', #not valid for C30/C60/C120 | |||
Format => 'int16u', | Format => 'int16u', | |||
Hidden => 1, | Hidden => 1, | |||
}, | }, | |||
); | ); | |||
# ref 28 | ||||
%Image::ExifTool::Nikon::Offset13InfoZ9 = ( | ||||
%binaryDataAttrs, | ||||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | ||||
DATAMEMBER => [ 0x0bea, 0x0beb ], | ||||
0x0be8 => { | ||||
Name => 'AFAreaInitialXPosition', #stored as a representation of | ||||
the horizontal position of the center of the portion of the focus box positioned | ||||
top left when in Wide Area (L/S/C1/C2) focus modes (before subject detection po | ||||
tentially refines focus) | ||||
Condition => '$$self{ShutterMode} ne 96 and $$self{AFAreaMode} < 2 ', | ||||
#not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19 | ||||
Format => 'int8s', | ||||
PrintConv => q{ | ||||
#in FX mode and Single-point, the 29 horizontal focus points are spa | ||||
ced 259 pixels apart starting at pixel 502 and ending at 7754. Spacing is the s | ||||
ame for Wide(L/C1/C2) with different start points. | ||||
#in FX mode and Dynamic(L), the 27 horizontal focus points are space | ||||
d 259 pixels apart starting at pixel 761 and ending at 7495 | ||||
#in FX mode and Dynamic(M), the 29 horizontal focus points are space | ||||
d 259 pixels apart starting at pixel 502 and ending at 7754 | ||||
#in DX mode and Single-point, the 19 horizontal focus points are spa | ||||
ced 388 pixels apart starting at pixel 636 and ending at 7620. [These correspon | ||||
d to FX positions and match the corresponding values in AFAreaMode tag AFAreaXPo | ||||
sition]. | ||||
#in DX mode and Wide(S), the 17 horizontal focus points are spaced 3 | ||||
93 pixels apart starting at pixel 591 and ending at 7272. | ||||
#in DX mode and Dynamic(L), the 17 horizontal focus points are space | ||||
d 388 pixels apart starting at pixel 1024 and ending at 7232 | ||||
#in DX mode and Dynamic(M), the 19 horizontal focus points are space | ||||
d 388 pixels apart starting at pixel 636 and ending at 7620 | ||||
my $areaMode = $$self{VALUE}{PhotoShootingMenuBankImageArea}; | ||||
my $afAreaMode = $$self{VALUE}{AFAreaMode}; | ||||
my $dynamicAFAreaSize = $$self{VALUE}{DynamicAFAreaSize}; | ||||
my $FX = 0; | ||||
my $DX = 1; | ||||
my $Single = 1; | ||||
my $Dynamic = 2; | ||||
my $WideS = 3; | ||||
my $WideL = 4; | ||||
my $ThreeD = 5; | ||||
my $Auto = 6; | ||||
my $WideC1 = 12; | ||||
my $DynamicS = 0; | ||||
my $DynamicM = 1; | ||||
my $DynamicL = 2; | ||||
my $start = 502; | ||||
#FX - all flavors | ||||
$start = 636 if $areaMode == $DX and ($afAreaMode == $Dynamic or $af | ||||
AreaMode == $WideL or $afAreaMode == $ThreeD or $afAreaMode == $Auto or $afArea | ||||
Mode >= $WideC1); #DX Wide(L/C1/C2) + Dynamic (L/M/S) + 3D + Auto | ||||
$start = 591 if $areaMode == $DX and $afAreaMode == $WideS ; | ||||
#DX Wide(S) | ||||
my $increment = 259; | ||||
#FX - all flavors | ||||
$increment = 388 if $areaMode == $DX and ($afAreaMode == $Dynamic or | ||||
$afAreaMode == $WideL or $afAreaMode == $ThreeD or $afAreaMode == $Auto or $af | ||||
AreaMode >= $WideC1); #DX Wide(L/C1/C2) + Dynamic (L/M/S) + 3D + Auto | ||||
$increment = 393 if $areaMode == $DX and $afAreaMode == $WideS ; | ||||
#DX Wide(S) | ||||
my $divisor = 4; | ||||
$divisor = 6 if $areaMode == $DX ; | ||||
my $offsetVal = 0; | ||||
$offsetVal = 12 if $areaMode == $FX and $afAreaMode == $Dynamic ; | ||||
#FX Dynamic (L/M) - force positive values so perl rounding to | ||||
ward zero isn't an issue | ||||
$offsetVal = 18 if $areaMode == $DX and $afAreaMode == $Dynamic ; | ||||
#DX Dynamic (L/M) | ||||
my $offsetSum = -1; | ||||
$offsetSum = -4 if $afAreaMode == $Dynamic ; # Dyn | ||||
amic (L/M) | ||||
my $ncol = $$self{AFAreaInitialWidth}; | ||||
$ncol = int($ncol * 2 / 3) if $areaMode == $DX ; #DX | ||||
#some sample mappings: | ||||
#FX Wide(S/L/C1/C2) [6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 49, | ||||
53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117] to 502 | ||||
, 761, 1020, 1279, 1538, 1797, 2056, 2315, 2574, 2833, 3092, 3351, 3610, 3869, 4 | ||||
128, 4387, 4646, 4905, 5164, 5423, 5682, 5941, 6200, 6459, 6718, 6977, 7236, 749 | ||||
5, 7754] | ||||
#DX Wide(L/C1/C2) map for Wide(L)/C1/C2 [6, 12, 18, 24, 30, 36, 42, | ||||
48, 54, 60, 67, 73, 79, 85, 91, 97, 103, 109, 115] to [636, 1024, 1412, 1800, 21 | ||||
88, 2576, 2964, 3352, 3740, 4128, 4516, 4904, 5292, 5680, 6068, 6456, 6844, 7232 | ||||
, 7620] | ||||
#DX Wide(S) for Wide(S) [6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 67, | ||||
73, 79, 85, 91, 97, 103] to [984, 1377, 1770, 2163, 2556, 2949, 3342, 3735, 4128 | ||||
, 4521, 4914, 5307, 5700, 6093, 6486, 6879, 7272] | ||||
#FX Dynamic (L) map [-9, -5, -1, 2, 6, 10, 14, 18, 22, 26, 30, 34, 3 | ||||
8, 42, 46, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93] to [761, 1020, 1279, | ||||
1538, 1797, 2056, 2315, 2574, 2833, 3092, 3351, 3610, 3869, 4128, 4387, 4646, 49 | ||||
05, 5164, 5423, 5682, 5941, 6200, 6459, 6718, 6977, 7236, 7495] | ||||
return $start + $increment * (int(($val + $offsetVal) / $divisor) + | ||||
int($ncol / 2) + $offsetSum) ; #do not use simple int() becuase it rounds negat | ||||
ive fractions toward zero resulting in duplicate values - instead use the 10xdiv | ||||
isor to force positive values | ||||
}, | ||||
}, | ||||
0x0be9 => { | ||||
Name =>'AFAreaInitialYPosition', #stored as a representation of the v | ||||
ertical position of the center of the portion of the focus box positioned top le | ||||
ft when in Wide Area (L/S/C1/C2) focus modes (before subject detection potential | ||||
ly refines focus) | ||||
Condition => '$$self{ShutterMode} ne 96 and $$self{AFAreaMode} < 2', | ||||
#not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19 | ||||
Format => 'int8s', | ||||
PrintConv => q{ | ||||
#in FX mode and Single-point, the 17 vertical focus points are space | ||||
d 291 pixels apart starting at pixel 424 and ending at 5080. Spacing is the sam | ||||
e for Wide(L/C1/C2) | ||||
#in FX mode and Dynamic(L), the 15 vertical focus points are spaced | ||||
291 pixels apart starting at pixel 715 and ending at 4789 | ||||
#in FX mode and Dynamic(M), the 17 vertical l focus points are space | ||||
d 291 pixels apart starting at pixel 424 and ending at 5080 | ||||
#in DX mode and Single-point, the 11 vertical focus points are space | ||||
d 436 pixels apart starting at pixel 572 and ending at 4932. [These correspond | ||||
to FX positions and match the corresponding values in AFAreaMode tag AFAreaYPosi | ||||
tion]. | ||||
#in DX Mode and Wide(S) the 9 vertical focus points are spaced 442 p | ||||
ixels apart starting at pixel 542 and ending at 4520 | ||||
#in DX mode and Dynamic(L), the 9 vertical focus points are spaced 4 | ||||
36 pixels apart starting at pixel 1008 and ending at 4496 | ||||
my $areaMode = $$self{VALUE}{PhotoShootingMenuBankImageArea}; | ||||
my $afAreaMode = $$self{VALUE}{AFAreaMode}; | ||||
my $dynamicAFAreaSize = $$self{VALUE}{DynamicAFAreaSize}; | ||||
my $FX = 0; | ||||
my $DX = 1; | ||||
my $Single = 1; | ||||
my $Dynamic = 2; | ||||
my $WideS = 3; | ||||
my $WideL = 4; | ||||
my $ThreeD = 5; | ||||
my $Auto = 6; | ||||
my $WideC1 = 12; | ||||
my $DynamicS = 0; | ||||
my $DynamicM = 1; | ||||
my $DynamicL = 2; | ||||
my $start = 424; | ||||
#FX - all flavors | ||||
$start = 572 if $areaMode == $DX and ($afAreaMode == $Dynamic or $af | ||||
AreaMode == $WideL or $afAreaMode == $ThreeD or $afAreaMode == $Auto or $afAreaM | ||||
ode >= $WideC1); #DX Wide(L/C1/C2) + Dynamic(L/M/S) + 3D + Auto | ||||
$start = 542 if $areaMode == $DX and $afAreaMode == 3 ; | ||||
#DX Wide(S) | ||||
my $increment = 291; | ||||
#FX - all flavors | ||||
$increment = 436 if $areaMode == $DX and ($afAreaMode == $Dynamic or | ||||
$afAreaMode == $WideL or $afAreaMode == $ThreeD or $afAreaMode == $Auto or $afA | ||||
reaMode >= $WideC1); #DX Wide(L/C1/C2) + Dynamic (L/M/S) +3D + Auto | ||||
$increment = 442 if $areaMode == $DX and $afAreaMode == 3 ; | ||||
#DX Wide(S) | ||||
my $divisor = 7; | ||||
$divisor = 10 if $areaMode == $DX ; | ||||
#DX | ||||
my $offsetVal = -1; | ||||
$offsetVal = 39 if $afAreaMode == $Dynamic and ( $dynamicAFAreaSize | ||||
== $DynamicL ) ; #Dynamic (L) - force positive values so perl rounding tow | ||||
ard zero isn't an issue | ||||
$offsetVal = 40 if $afAreaMode == $Dynamic and $dynamicAFAreaSize == | ||||
$DynamicM ; #Dynamic (M) | ||||
$offsetVal = 40 if $areaMode == $FX and (($afAreaMode == $Dynamic an | ||||
d $dynamicAFAreaSize == $DynamicS) or $afAreaMode == $ThreeD) ; #FX Dynamic | ||||
(S) or 3D | ||||
$offsetVal = 38 if $areaMode == $DX and ($afAreaMode == $Dynamic and | ||||
$dynamicAFAreaSize == $DynamicS ) ; #DX Dynamic (S)or 3D | ||||
my $offsetSum = 0; | ||||
$offsetSum = -6 if $areaMode == $FX and ($afAreaMode == $Dynamic or | ||||
$afAreaMode == $ThreeD); #FX Dynamic (L/M/S) or 3D | ||||
$offsetSum = -4 if $areaMode == $DX and ($afAreaMode == $Dynamic or | ||||
$afAreaMode == $ThreeD ); #DX Dynamic (L/M/S) or 3D | ||||
my $nrow = $$self{AFAreaInitialHeight}; | ||||
$nrow = int($nrow * 2 / 3) if $areaMode == $DX; | ||||
#DX | ||||
#some sample mappings: | ||||
#FX Wide(S/L/C1/C2) map [7, 13, 20, 27, 33, 40, 47, 53, 60, 67, 74, | ||||
80, 87, 94, 100, 107, 114] to [424, 715, 1006, 1297, 1588, 1879, 2170, 2461, 275 | ||||
2, 3043, 3334, 3625, 3916, 4207, 4498, 4789, 5080] | ||||
#DX Wide(L/C1/C2) map [7, 17, 28, 38, 48, 58, 69, 79, 89, 100, 110] | ||||
to [572, 1008, 1444, 1880, 2316, 2752, 3188, 3624, 4060, 4496, 4932] | ||||
#DX Wide(S) map for Wide(S) [7, 17, 28, 38, 48, 58, 69, 79, 89] to | ||||
[984, 1426, 1868, 2310, 2752, 3194, 3636, 4078, 4520] | ||||
#FX Dynamic (L) map [-19, -13, -6, 0, 7, 13, 20, 27, 33, 40, 47, 53, | ||||
60, 67, 74] to [715, 1006, 1297, 1588, 1879, 2170, 2461, 2752, 3043, 3334, 3625 | ||||
, 3916, 4207, 4498, 4789] | ||||
return $start + $increment * (int(($val + $offsetVal) / $divisor) + | ||||
int($nrow / 2) + $offsetSum) ;; | ||||
}, | ||||
}, | ||||
0x0bea => { | ||||
Name => 'AFAreaInitialWidth', | ||||
Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120 | ||||
ValueConv => '$$self{VALUE}{PhotoShootingMenuBankImageArea} eq 0 ? $val | ||||
: int($val * 2 / 3)', #DX mode requires scaling down TODO: add support ImageA | ||||
reas 1:1 and 16:9 | ||||
RawConv => '$$self{AFAreaInitialWidth} = 1 + int ($val / 4)', #conver | ||||
t from [3, 11, 19, 35, 51, 75] to [1, 3, 5, 9 13, 19] to match camera options fo | ||||
r C1/C2 focus modes .. input/output of 11/3 is for Wide(S) | ||||
}, | ||||
0x0beb => { | ||||
Name => 'AFAreaInitialHeight', | ||||
Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120 | ||||
ValueConv => '$$self{VALUE}{PhotoShootingMenuBankImageArea} eq 0 ? $val | ||||
: int($val * 2 / 3)', #DX mode requires scaling down TODO: add support ImageA | ||||
reas 1:1 and 16:9 | ||||
RawConv => '$$self{AFAreaInitialHeight} = 1 + int ($val / 7) ', #conv | ||||
ert from [6, 20, 33, 46, 73] to [1, 3, 5, 7, 11] to match camera options for C1/ | ||||
C2 focus modes .. input/output of 33/5 is for Wide(L) | ||||
}, | ||||
); | ||||
%Image::ExifTool::Nikon::MenuInfoZ9 = ( | %Image::ExifTool::Nikon::MenuInfoZ9 = ( | |||
%binaryDataAttrs, | %binaryDataAttrs, | |||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | |||
IS_SUBDIR => [ 0x10 ], | IS_SUBDIR => [ 0x10 ], | |||
# 0x00 - int32u size of this directory | # 0x00 - int32u size of this directory | |||
0x10 => [ | 0x10 => [ | |||
{ | { | |||
Name => 'MenuSettingsOffsetZ9', | Name => 'MenuSettingsOffsetZ9', | |||
Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} lt "03.00"', | Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} lt "03.00"', | |||
Format => 'int32u', | Format => 'int32u', | |||
skipping to change at line 8512 | skipping to change at line 8707 | |||
RawConv => '$$self{HDMIOutputNLog} = $val', | RawConv => '$$self{HDMIOutputNLog} = $val', | |||
Unknown => 1, | Unknown => 1, | |||
PrintConv => \%offOn, | PrintConv => \%offOn, | |||
}, | }, | |||
#859 => HDMIViewAssist | #859 => HDMIViewAssist | |||
); | ); | |||
%Image::ExifTool::Nikon::MenuSettingsZ9 = ( | %Image::ExifTool::Nikon::MenuSettingsZ9 = ( | |||
%binaryDataAttrs, | %binaryDataAttrs, | |||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | |||
DATAMEMBER => [ 140, 188, 192, 232, 424, 534 ], | DATAMEMBER => [ 140, 188, 192, 232, 424, 534, 576 ], | |||
IS_SUBDIR => [ 799 ], | IS_SUBDIR => [ 799 ], | |||
NOTES => 'These tags are used by the Z9.', | NOTES => 'These tags are used by the Z9.', | |||
#90 ISO | #90 ISO | |||
140 => { | 140 => { | |||
Name => 'MultipleExposureMode', | Name => 'MultipleExposureMode', | |||
RawConv => '$$self{MultipleExposureMode} = $val', | RawConv => '$$self{MultipleExposureMode} = $val', | |||
PrintConv => \%multipleExposureModeZ9, | PrintConv => \%multipleExposureModeZ9, | |||
}, | }, | |||
142 => {Name => 'MultiExposureShots', Condition => '$$self{MultipleExposureM ode} != 0' }, #range 2-9 | 142 => {Name => 'MultiExposureShots', Condition => '$$self{MultipleExposureM ode} != 0' }, #range 2-9 | |||
188 => { | 188 => { | |||
skipping to change at line 8652 | skipping to change at line 8847 | |||
538 => { | 538 => { | |||
Name => 'BracketIncrement', | Name => 'BracketIncrement', | |||
Condition => '$$self{BracketSet} < 3', | Condition => '$$self{BracketSet} < 3', | |||
Notes => 'AE and/or Flash Bracketing', | Notes => 'AE and/or Flash Bracketing', | |||
PrintConv => \%bracketIncrementZ9, | PrintConv => \%bracketIncrementZ9, | |||
}, | }, | |||
#544 BracketProgram for ADL | #544 BracketProgram for ADL | |||
556 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFuncti onZ9 }, | 556 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFuncti onZ9 }, | |||
572 => { Name => 'DXCropAlert', PrintConv => \%offOn }, | 572 => { Name => 'DXCropAlert', PrintConv => \%offOn }, | |||
574 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 }, | 574 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 }, | |||
576 => { | ||||
Name => 'DynamicAFAreaSize', | ||||
Condition => '$$self{AFAraMode} = 2', | ||||
RawConv => '$$self{DynamicAFAreaSize} = $val', | ||||
PrintConv => \%dynamicAfAreaModesZ9, | ||||
}, | ||||
604 => { | 604 => { | |||
Name => 'MovieImageArea', | Name => 'MovieImageArea', | |||
Unknown => 1, | Unknown => 1, | |||
Mask => 0x01, # without the mask 4 => 'FX', 5 => DX. only the 2nd Z-seri es field encountered with a mask | Mask => 0x01, # without the mask 4 => 'FX', 5 => DX. only the 2nd Z-seri es field encountered with a mask | |||
PrintConv => \%imageAreaZ9b, | PrintConv => \%imageAreaZ9b, | |||
}, | }, | |||
614 => { Name => 'MovieType', PrintConv => \%movieTypeZ9, Unknown => 1 }, | 614 => { Name => 'MovieType', PrintConv => \%movieTypeZ9, Unknown => 1 }, | |||
616 => { | 616 => { | |||
Name => 'MovieISOAutoHiLimit', | Name => 'MovieISOAutoHiLimit', | |||
Format => 'int16u', | Format => 'int16u', | |||
skipping to change at line 8717 | skipping to change at line 8918 | |||
1573 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release ', 1 => 'Enable Release' }, Unknown => 1 }, | 1573 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release ', 1 => 'Enable Release' }, Unknown => 1 }, | |||
1608 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 } , | 1608 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 } , | |||
1632 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 } , | 1632 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 } , | |||
1636 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 } , | 1636 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 } , | |||
1645 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 }, | 1645 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 }, | |||
); | ); | |||
%Image::ExifTool::Nikon::MenuSettingsZ9v3 = ( | %Image::ExifTool::Nikon::MenuSettingsZ9v3 = ( | |||
%binaryDataAttrs, | %binaryDataAttrs, | |||
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, | |||
DATAMEMBER => [ 154, 204, 208, 248, 444, 554 ], | DATAMEMBER => [ 154, 204, 208, 248, 444, 554, 596 ], | |||
IS_SUBDIR => [ 847 ], | IS_SUBDIR => [ 847 ], | |||
NOTES => 'These tags are used by the Z9 firmware 3.00.', | NOTES => 'These tags are used by the Z9 firmware 3.00.', | |||
72 => { | 72 => { | |||
Name => 'HighFrameRate', #CH and C30/C60/C120 but not CL | Name => 'HighFrameRate', #CH and C30/C60/C120 but not CL | |||
PrintConv => \%highFrameRateZ9, | PrintConv => \%highFrameRateZ9, | |||
}, | }, | |||
154 => { | 154 => { | |||
Name => 'MultipleExposureMode', | Name => 'MultipleExposureMode', | |||
RawConv => '$$self{MultipleExposureMode} = $val', | RawConv => '$$self{MultipleExposureMode} = $val', | |||
PrintConv => \%multipleExposureModeZ9, | PrintConv => \%multipleExposureModeZ9, | |||
skipping to change at line 8846 | skipping to change at line 9047 | |||
}, | }, | |||
558 => { | 558 => { | |||
Name => 'BracketIncrement', | Name => 'BracketIncrement', | |||
Condition => '$$self{BracketSet} < 3', | Condition => '$$self{BracketSet} < 3', | |||
Notes => 'AE and/or Flash Bracketing', | Notes => 'AE and/or Flash Bracketing', | |||
PrintConv => \%bracketIncrementZ9, | PrintConv => \%bracketIncrementZ9, | |||
}, | }, | |||
576 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFuncti onZ9 }, | 576 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFuncti onZ9 }, | |||
592 => { Name => 'DXCropAlert', PrintConv => \%offOn }, | 592 => { Name => 'DXCropAlert', PrintConv => \%offOn }, | |||
594 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 }, | 594 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 }, | |||
596 => { | ||||
Name => 'DynamicAFAreaSize', | ||||
Condition => '$$self{AFAraMode} = 2', | ||||
RawConv => '$$self{DynamicAFAreaSize} = $val', | ||||
PrintConv => \%dynamicAfAreaModesZ9, | ||||
}, | ||||
636 => { Name => 'HighFrequencyFlickerReductionShooting', PrintConv => \%off On, Unknown => 1 }, # new with firmware 3.0 | 636 => { Name => 'HighFrequencyFlickerReductionShooting', PrintConv => \%off On, Unknown => 1 }, # new with firmware 3.0 | |||
646 => { | 646 => { | |||
Name => 'MovieImageArea', | Name => 'MovieImageArea', | |||
Unknown => 1, | Unknown => 1, | |||
Mask => 0x01, # without the mask 4 => 'FX' 5 => DX only the 2nd Z-ser ies field encountered with a mask. | Mask => 0x01, # without the mask 4 => 'FX' 5 => DX only the 2nd Z-ser ies field encountered with a mask. | |||
PrintConv => \%imageAreaZ9b, | PrintConv => \%imageAreaZ9b, | |||
}, | }, | |||
656 => { Name => 'MovieType', PrintConv => \%movieTypeZ9, Unknown => 1 }, | 656 => { Name => 'MovieType', PrintConv => \%movieTypeZ9, Unknown => 1 }, | |||
658 => { | 658 => { | |||
Name => 'MovieISOAutoHiLimit', | Name => 'MovieISOAutoHiLimit', | |||
skipping to change at line 11224 | skipping to change at line 11431 | |||
2 => 'MinFocalLength', | 2 => 'MinFocalLength', | |||
3 => 'MaxFocalLength', | 3 => 'MaxFocalLength', | |||
4 => 'MaxApertureAtMinFocal', | 4 => 'MaxApertureAtMinFocal', | |||
5 => 'MaxApertureAtMaxFocal', | 5 => 'MaxApertureAtMaxFocal', | |||
6 => 'MCUVersion', | 6 => 'MCUVersion', | |||
7 => 'Nikon:LensType', | 7 => 'Nikon:LensType', | |||
}, | }, | |||
# construct lens ID string as per ref 11 | # construct lens ID string as per ref 11 | |||
ValueConv => 'sprintf("%.2X"." %.2X"x7, @raw)', | ValueConv => 'sprintf("%.2X"." %.2X"x7, @raw)', | |||
PrintConv => \%nikonLensIDs, | PrintConv => \%nikonLensIDs, | |||
PrintInt => 1, | ||||
}, | }, | |||
AutoFocus => { | AutoFocus => { | |||
Require => { | Require => { | |||
0 => 'Nikon:PhaseDetectAF', | 0 => 'Nikon:PhaseDetectAF', | |||
1 => 'Nikon:ContrastDetectAF', | 1 => 'Nikon:ContrastDetectAF', | |||
}, | }, | |||
ValueConv => '($val[0] or $val[1]) ? 1 : 0', | ValueConv => '($val[0] or $val[1]) ? 1 : 0', | |||
PrintConv => \%offOn, | PrintConv => \%offOn, | |||
}, | }, | |||
); | ); | |||
skipping to change at line 11731 | skipping to change at line 11939 | |||
$$et{NikonSerialKey} = SerialKey($et, $needTags{0x110a431}); | $$et{NikonSerialKey} = SerialKey($et, $needTags{0x110a431}); | |||
$$et{NikonCountKey} = $needTags{0x20000a7}; | $$et{NikonCountKey} = $needTags{0x20000a7}; | |||
} | } | |||
$pos += $size; # is this padded to an even offset???? | $pos += $size; # is this padded to an even offset???? | |||
} | } | |||
} | } | |||
return 1; | return 1; | |||
} | } | |||
#------------------------------------------------------------------------------ | #------------------------------------------------------------------------------ | |||
# Get offset of end-of-data for a tag | ||||
# Inputs: 0) tag table ref, 1) tag ID, 2) true to not calculate end for a SubDir | ||||
ectory | ||||
# Returns: offset of tag value end, undef if it can't be determined | ||||
sub GetTagEnd($$;$) | ||||
{ | ||||
my ($tagTablePtr, $tagID, $ignoreSubdir) = @_; | ||||
my $tagInfo = $$tagTablePtr{$tagID}; | ||||
$tagInfo = $$tagInfo[0] if ref $tagInfo eq 'ARRAY'; | ||||
# (can't pre-determine position of offset-based subdirectories) | ||||
return undef if $ignoreSubdir and $$tagInfo{SubDirectory}; | ||||
my $fmt = $$tagInfo{Format} || $$tagTablePtr{FORMAT} || 'int8u'; | ||||
my $nm = $fmt =~ s/\[(\d+)\]$// ? $1 : 1; | ||||
my $sz = Image::ExifTool::FormatSize($fmt) or return undef; | ||||
return int($tagID) + $sz * $nm; | ||||
} | ||||
#------------------------------------------------------------------------------ | ||||
# Initialize SubDirectory KnownStart/KnownEnd limits of known tags (used in decr | ||||
yption) | ||||
# Inputs: 0) tagInfo ref containing this SubDirectory, 2) tag table ref for encr | ||||
ypted subdir | ||||
# Notes: KnownStart/KnownEnd are relative to the SubDirectory Start. If KnownSt | ||||
art/KnownEnd | ||||
# aren't set then the entire data is decrypted, so all of this effort is | ||||
just for speed. | ||||
sub InitEncryptedSubdir($$) | ||||
{ | ||||
my ($tagInfo, $tagTablePtr) = @_; | ||||
# | ||||
# for encrypted NIKON_OFFSETS tables we loop through all SubDirectory tags in th | ||||
is table | ||||
# and set the KnownEnd for each of these according to the last tag in the child | ||||
tables | ||||
# | ||||
my $vars = $$tagTablePtr{VARS}; | ||||
$vars or $vars = $$tagTablePtr{VARS} = { }; | ||||
if ($$vars{NIKON_OFFSETS} and not $$vars{NIKON_INITIALIZED}) { | ||||
$$vars{NIKON_INITIALIZED} = 1; | ||||
my $tagID; | ||||
foreach $tagID (TagTableKeys($tagTablePtr)) { | ||||
my $tagInfo = $$tagTablePtr{$tagID}; | ||||
next unless ref $tagInfo eq 'HASH'; | ||||
my $subdir = $$tagInfo{SubDirectory} or next; | ||||
my $tbl = GetTagTable($$subdir{TagTable}); | ||||
my ($last) = sort { $b <=> $a } TagTableKeys($tbl); # (reverse sort) | ||||
$$subdir{KnownEnd} = GetTagEnd($tbl, $last, 1); | ||||
} | ||||
} | ||||
# | ||||
# for other encrypted Nikon tables we set the KnownStart/KnownEnd entries in the | ||||
# SubDirectory of the parent tag | ||||
# | ||||
unless ($$tagInfo{NikonInitialized}) { | ||||
$$tagInfo{NikonInitialized} = 1; | ||||
my $subdir = $$tagInfo{SubDirectory}; | ||||
my $start = $$subdir{DecryptStart} || 0; | ||||
my $off = $$subdir{DirOffset}; | ||||
my @tagIDs = sort { $a <=> $b } TagTableKeys($tagTablePtr); | ||||
if (defined $off) { | ||||
$off += $start; # (DirOffset, if specified, is relative to DecryptSt | ||||
art) | ||||
} else { | ||||
# ignore tags that come before the start of encryption | ||||
shift @tagIDs while @tagIDs and $tagIDs[0] < $start; | ||||
$off = 0; | ||||
} | ||||
if (@tagIDs) { | ||||
my ($first, $last) = @tagIDs[0,-1]; | ||||
my $lastInfo = $$tagTablePtr{$last}; | ||||
$lastInfo = $$lastInfo[0] if ref $lastInfo eq 'ARRAY'; | ||||
$$subdir{KnownStart} = int($first) + $off if $first + $off > $start; | ||||
$$subdir{KnownEnd} = GetTagEnd($tagTablePtr, $last); | ||||
if (defined $$subdir{KnownEnd}) { | ||||
$$subdir{KnownEnd} += $off; | ||||
} else { | ||||
warn "Internal error setting KnownEnd for $$tagTablePtr{SHORT_NA | ||||
ME}\n"; | ||||
} | ||||
} else { | ||||
$$subdir{KnownStart} = $$subdir{KnownEnd} = $start; | ||||
} | ||||
} | ||||
} | ||||
#------------------------------------------------------------------------------ | ||||
# Prepare to process NIKON_OFFSETS directory and decrypt necessary data | # Prepare to process NIKON_OFFSETS directory and decrypt necessary data | |||
# Inputs: 0) ExifTool ref, 1) data ref, 2) tag table ref, 3) decrypt start, | # Inputs: 0) ExifTool ref, 1) data ref, 2) tag table ref, 3) decrypt start, | |||
# 4) serial key, 5) count key, 6) decrypt mode (0=piecewise, | # 4) decrypt mode (0=piecewise, 1=continuous to end of last known sectio | |||
# 1=continuous to end of last known section, 2=all) | n, 2=all) | |||
# Returns: end of decrypted data (or undef for piecewise decryption) | # Returns: end of decrypted data (or undef for piecewise decryption) | |||
sub PrepareNikonOffsets($$$$$$$) | sub PrepareNikonOffsets($$$$$) | |||
{ | { | |||
my ($et, $dataPt, $tagTablePtr, $start, $serial, $count, $decryptMode) = @_; | my ($et, $dataPt, $tagTablePtr, $start, $decryptMode) = @_; | |||
my $offset = $$tagTablePtr{VARS}{NIKON_OFFSETS}; | my $offset = $$tagTablePtr{VARS}{NIKON_OFFSETS}; | |||
my $unknown = $et->Options('Unknown'); | ||||
my $dataLen = length $$dataPt; | my $dataLen = length $$dataPt; | |||
return undef if $offset + 4 > $dataLen or $offset < $start; | return undef if $offset + 4 > $dataLen or $offset < $start; | |||
my $dpos = $offset + 4; # decrypt the first 4 bytes | my $serial = $$et{NikonSerialKey}; | |||
my $count = $$et{NikonCountKey}; | ||||
my $dpos = $offset + 4; # decrypt up to NumberOffsets | ||||
$$dataPt = Decrypt($dataPt, $start, $dpos - $start, $serial, $count); | $$dataPt = Decrypt($dataPt, $start, $dpos - $start, $serial, $count); | |||
my $numOffsets = Get32u($dataPt, $offset); | my $numOffsets = Get32u($dataPt, $offset); | |||
my $more = $numOffsets * 4; | my $more = $numOffsets * 4; # more bytes to decrypt entire offsets table | |||
return undef if $offset + 4 + $more > $dataLen; | return undef if $offset + 4 + $more > $dataLen; | |||
$$dataPt = Decrypt($dataPt, $dpos, $more); | $$dataPt = Decrypt($dataPt, $dpos, $more); | |||
$dpos += $more; | $dpos += $more; | |||
my $doneAlready = $$tagTablePtr{VARS}{NIKON_OFFSETS_DONE}; | my $unknown = $et->Options('Unknown'); | |||
$$tagTablePtr{VARS}{NIKON_OFFSETS_DONE} = 1; | my ($i, @offInfo, $end); | |||
my ($i, @offInfo); | # extract non-zero offsets and create unknown subdirectories if Unknown > 1 | |||
for ($i=0; $i<$numOffsets; ++$i) { | for ($i=0; $i<$numOffsets; ++$i) { | |||
my $pos = $offset + 4 + 4 * $i; | my $pos = $offset + 4 + 4 * $i; | |||
my $off = Get32u($dataPt, $pos) or next; | my $off = Get32u($dataPt, $pos) or next; | |||
my $tagInfo = $$tagTablePtr{$pos}; | my $tagInfo = $$tagTablePtr{$pos}; | |||
my $known = 0; | ||||
if ($tagInfo) { | if ($tagInfo) { | |||
if (not $doneAlready and ref $tagInfo eq 'HASH' and | $known = 1 if ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown}; | |||
not $$tagInfo{Unknown} and $$tagInfo{SubDirectory}) | ||||
{ | ||||
# determine length of subdirectory up to end of last known tag | ||||
my $subdir = $$tagInfo{SubDirectory}; | ||||
my $tbl = GetTagTable($$subdir{TagTable}); | ||||
my ($last) = sort { $b <=> $a } TagTableKeys($tbl); | ||||
my $lastInfo = $$tbl{$last}; | ||||
$lastInfo = $$lastInfo[0] if ref $lastInfo eq 'ARRAY'; | ||||
# (can't pre-determine known length of offset-based subdirectori | ||||
es) | ||||
unless ($$lastInfo{SubDirectory}) { | ||||
my $fmt = $$lastInfo{Format} || $$tbl{FORMAT} || 'int8u'; | ||||
my $nm = $fmt =~ s/\[(\d+)\]$// ? $1 : 1; | ||||
my $sz = Image::ExifTool::FormatSize($fmt); | ||||
$$subdir{KnownLen} = int($last) + $sz * $nm if $sz; | ||||
} | ||||
} | ||||
} elsif ($unknown > 1) { | } elsif ($unknown > 1) { | |||
# create new table for unknown information | # create new table for unknown information | |||
my $tbl = sprintf('Image::ExifTool::Nikon::UnknownInfo%.2x', $pos); | my $tbl = sprintf('Image::ExifTool::Nikon::UnknownInfo%.2x', $pos); | |||
no strict 'refs'; | no strict 'refs'; | |||
unless (%$tbl) { | unless (%$tbl) { | |||
%$tbl = ( %binaryDataAttrs, GROUPS => { 0=>'MakerNotes', 2=>'Unk nown' } ); | %$tbl = ( %binaryDataAttrs, GROUPS => { 0=>'MakerNotes', 2=>'Unk nown' } ); | |||
GetTagTable($tbl); | GetTagTable($tbl); | |||
} | } | |||
# add unknown entry in offset table for this subdirectory | # add unknown entry in offset table for this subdirectory | |||
$tagInfo = AddTagToTable($tagTablePtr, $pos, { | $tagInfo = AddTagToTable($tagTablePtr, $pos, { | |||
Name => sprintf('UnknownOffset%.2x', $pos), | Name => sprintf('UnknownOffset%.2x', $pos), | |||
Format => 'int32u', | Format => 'int32u', | |||
SubDirectory => { TagTable => $tbl }, | SubDirectory => { TagTable => $tbl }, | |||
Unknown => 2, | Unknown => 2, | |||
}); | }); | |||
} | } | |||
if ($off) { | push @offInfo, [ $pos, $off, $known ]; # save parameters for non-zero o | |||
my $known = ($tagInfo and (ref $tagInfo ne 'HASH' or not $$tagInfo{U | ffsets | |||
nknown})) ? 1 : 0; | ||||
push @offInfo, [ $pos, $off, $known ]; | ||||
} | ||||
} | } | |||
my $end; | ||||
# sort offsets in ascending order, and use the differences to calculate | # sort offsets in ascending order, and use the differences to calculate | |||
# directory lengths and update the SubDirectory DirLen's accordingly | # directory lengths and update the SubDirectory DirLen's accordingly | |||
my @sorted = sort { $$a[1] <=> $$b[1] or $$a[0] <=> $$b[0] } @offInfo; | my @sorted = sort { $$a[1] <=> $$b[1] or $$a[0] <=> $$b[0] } @offInfo; | |||
push @sorted, [ 0, length($$dataPt), 0 ]; | push @sorted, [ 0, length($$dataPt), 0 ]; | |||
for ($i=0; $i<@sorted-1; ++$i) { | for ($i=0; $i<@sorted-1; ++$i) { | |||
my $pos = $sorted[$i][0]; | my $pos = $sorted[$i][0]; | |||
my $len = $sorted[$i+1][1] - $sorted[$i][1]; | my $len = $sorted[$i+1][1] - $sorted[$i][1]; | |||
# set DirLen in SubDirectory entry | # set DirLen in SubDirectory entry | |||
my $tagInfo = $$tagTablePtr{$pos}; | my $tagInfo = $$tagTablePtr{$pos}; | |||
my $subdir; | my $subdir; | |||
if (ref $tagInfo eq 'HASH' and defined($subdir=$$tagInfo{SubDirectory})) | $$subdir{DirLen} = $len if ref $tagInfo eq 'HASH' and defined($subdir=$$ | |||
{ | tagInfo{SubDirectory}); | |||
$$tagInfo{SubDirectory}{DirLen} = $len; | ||||
} | ||||
if ($decryptMode) { | if ($decryptMode) { | |||
# keep track of end of last known directory | # keep track of end of last known directory | |||
$end = $sorted[$i+1][1] if $sorted[$i][2]; | $end = $sorted[$i+1][1] if $sorted[$i][2]; | |||
} elsif ($tagInfo and (ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown}) ) { | } elsif ($tagInfo and (ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown}) ) { | |||
# decrypt data piecewise as necessary | # decrypt data piecewise as necessary | |||
my $n = $len; | my $n = $len; | |||
if ($subdir and $$subdir{KnownLen}) { | if ($subdir and $$subdir{KnownEnd}) { | |||
$n = $$subdir{KnownLen}; | $n = $$subdir{KnownEnd}; | |||
if ($n > $len) { | if ($n > $len) { | |||
$et->Warn("Data too short for $$tagInfo{Name}",1); | $et->Warn("Data too short for $$tagInfo{Name}",1); | |||
$n = $len; | $n = $len; | |||
} | } | |||
} | } | |||
$$dataPt = Decrypt($dataPt, $sorted[$i][1], $n); | $$dataPt = Decrypt($dataPt, $sorted[$i][1], $n); | |||
} | } | |||
} | } | |||
if ($decryptMode) { | if ($decryptMode) { | |||
# decrypt the remaining required data | # decrypt the remaining required data | |||
skipping to change at line 11865 | skipping to change at line 12129 | |||
delete $$et{NikonCountKey}; | delete $$et{NikonCountKey}; | |||
return 0; | return 0; | |||
} | } | |||
my $oldOrder = GetByteOrder(); | my $oldOrder = GetByteOrder(); | |||
my $isWriting = $$dirInfo{IsWriting}; | my $isWriting = $$dirInfo{IsWriting}; | |||
my $verbose = $isWriting ? 0 : $et->Options('Verbose'); | my $verbose = $isWriting ? 0 : $et->Options('Verbose'); | |||
my $tagInfo = $$dirInfo{TagInfo}; | my $tagInfo = $$dirInfo{TagInfo}; | |||
my $dirStart = $$dirInfo{DirStart}; | my $dirStart = $$dirInfo{DirStart}; | |||
my $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen}); | my $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen}); | |||
my ($start, $len, $offset, $byteOrder, $recrypt, $newSerial, $newCount, $did Decrypt); | my ($start, $len, $offset, $recrypt, $newSerial, $newCount, $didDecrypt); | |||
# must re-encrypt when writing if serial number or shutter count changes | # must re-encrypt when writing if serial number or shutter count changes | |||
if ($isWriting) { | if ($isWriting) { | |||
if ($$et{NewNikonSerialKey}) { | if ($$et{NewNikonSerialKey}) { | |||
$newSerial = $$et{NewNikonSerialKey}; | $newSerial = $$et{NewNikonSerialKey}; | |||
$recrypt = 1; | $recrypt = 1; | |||
} | } | |||
if ($$et{NewNikonCountKey}) { | if ($$et{NewNikonCountKey}) { | |||
$newCount = $$et{NewNikonCountKey}; | $newCount = $$et{NewNikonCountKey}; | |||
$recrypt = 1; | $recrypt = 1; | |||
} | } | |||
} | } | |||
if ($tagInfo and $$tagInfo{SubDirectory}) { | if ($tagInfo and $$tagInfo{SubDirectory}) { | |||
# initialize SubDirectory entries used in encryption (KnownStart, KnownE | ||||
nd) | ||||
InitEncryptedSubdir($tagInfo, $tagTablePtr); | ||||
my $subdir = $$tagInfo{SubDirectory}; | my $subdir = $$tagInfo{SubDirectory}; | |||
$start = $$subdir{DecryptStart} || 0; | $start = $$subdir{DecryptStart} || 0; | |||
# DirOffset, if specified, is relative to start of encrypted data | # DirOffset, if specified, is the offset to the start of the | |||
# directory relative to start of encrypted data | ||||
$offset = defined $$subdir{DirOffset} ? $$subdir{DirOffset} + $start : 0 ; | $offset = defined $$subdir{DirOffset} ? $$subdir{DirOffset} + $start : 0 ; | |||
$byteOrder = $$subdir{ByteOrder}; | # must set byte ordering before calling PrepareNikonOffsets() | |||
SetByteOrder($byteOrder) if $byteOrder; | SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder}; | |||
# prepare for processing NIKON_OFFSETS directory if necessary | # prepare for processing NIKON_OFFSETS directory if necessary | |||
if ($$tagTablePtr{VARS} and $$tagTablePtr{VARS}{NIKON_OFFSETS}) { | my $unknown = $verbose > 2 || $et->Options('Unknown') > 1; | |||
my $unknown = $et->Options('Verbose') > 2 || $et->Options('Unknown') | # decrypt mode: 0=piecewise, 1=continuous to end of last known section, | |||
> 1; | 2=all | |||
# decrypt mode: 0=piecewise, 1=continuous to end of last known secti | my $dMode = $isWriting ? ($recrypt ? 2 : 1) : ($unknown ? 2 : 0); | |||
on, 2=all | if ($$tagTablePtr{VARS}{NIKON_OFFSETS}) { | |||
my $dMode = $isWriting ? ($recrypt ? 2 : 1) : ($unknown ? 2 : 0); | $len = PrepareNikonOffsets($et, \$data, $tagTablePtr, $start, $dMode | |||
$len = PrepareNikonOffsets($et, \$data, $tagTablePtr, $start, $seria | ); | |||
l, $count, $dMode); | ||||
$didDecrypt = 1; | $didDecrypt = 1; | |||
# may decrypt only part of the information to save time | } elsif ($dMode < 2) { | |||
} elsif ($verbose < 3 and $et->Options('Unknown') < 2 and not $recrypt) | if ($dMode == 0 and $$subdir{KnownStart}) { | |||
{ | # initialize decryption parameters for address DecryptStart addr | |||
$len = $$subdir{DecryptLen}; | ess | |||
Decrypt(\$data, $start, 0, $serial, $count); | ||||
# reset serial/count keys so we don't re-initialize below | ||||
undef $serial; | ||||
undef $count; | ||||
# change decryption start to skip unnecessary data | ||||
$start = $$subdir{KnownStart}; | ||||
} | ||||
$len = $$subdir{KnownEnd} - $start if $$subdir{KnownEnd}; | ||||
} | } | |||
} else { | } else { | |||
$start = $offset = 0; | $start = $offset = 0; | |||
} | } | |||
my $maxLen = length($data) - $start; | my $maxLen = length($data) - $start; | |||
# decrypt all the data unless DecryptLen is given | # decrypt all the data unless the length was specified | |||
$len = $maxLen unless $len and $len < $maxLen; | $len = $maxLen unless $len and $len < $maxLen; | |||
$data = Decrypt(\$data, $start, $len, $serial, $count) unless $didDecrypt; | $data = Decrypt(\$data, $start, $len, $serial, $count) unless $didDecrypt; | |||
if ($verbose > 2) { | if ($verbose > 2) { | |||
$et->VerboseDir("Decrypted $$tagInfo{Name}"); | $et->VerboseDir("Decrypted $$tagInfo{Name}"); | |||
$et->VerboseDump(\$data, | $et->VerboseDump(\$data, | |||
Prefix => $$et{INDENT} . ' ', | Prefix => $$et{INDENT} . ' ', | |||
# (remove this because it is useful to have decrypted offsets start at 0) | # (remove this because it is useful to have decrypted offsets start at 0) | |||
#DataPos => $dirStart + $$dirInfo{DataPos} + ($$dirInfo{Base} || 0), | #DataPos => $dirStart + $$dirInfo{DataPos} + ($$dirInfo{Base} || 0), | |||
End of changes. 86 change blocks. | ||||
118 lines changed or deleted | 494 lines changed or added |