"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/Image/ExifTool/Nikon.pm" between
Image-ExifTool-12.57.tar.gz and Image-ExifTool-12.58.tar.gz

About: ExifTool is a platform-independent Perl library plus a command-line application for reading, writing and editing meta information in a wide variety of files.

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

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)