exiftool-vendored.exe 12.55.0 → 12.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/bin/exiftool_files/Changes +97 -4
  2. package/bin/exiftool_files/README +19 -19
  3. package/bin/exiftool_files/arg_files/xmp2exif.args +4 -1
  4. package/bin/exiftool_files/config_files/example.config +1 -0
  5. package/bin/exiftool_files/config_files/rotate_regions.config +1 -1
  6. package/bin/exiftool_files/exiftool.pl +198 -123
  7. package/bin/exiftool_files/fmt_files/kml.fmt +3 -0
  8. package/bin/exiftool_files/fmt_files/kml_track.fmt +3 -0
  9. package/bin/exiftool_files/lib/Image/ExifTool/AIFF.pm +2 -2
  10. package/bin/exiftool_files/lib/Image/ExifTool/APE.pm +2 -2
  11. package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +25 -19
  12. package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +33 -7
  13. package/bin/exiftool_files/lib/Image/ExifTool/CanonRaw.pm +5 -1
  14. package/bin/exiftool_files/lib/Image/ExifTool/DJI.pm +28 -2
  15. package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +107 -20
  16. package/bin/exiftool_files/lib/Image/ExifTool/FlashPix.pm +92 -9
  17. package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +9 -4
  18. package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +7 -2
  19. package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +30 -7
  20. package/bin/exiftool_files/lib/Image/ExifTool/InfiRay.pm +227 -0
  21. package/bin/exiftool_files/lib/Image/ExifTool/JPEG.pm +53 -7
  22. package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +5 -5
  23. package/bin/exiftool_files/lib/Image/ExifTool/LIF.pm +10 -2
  24. package/bin/exiftool_files/lib/Image/ExifTool/LNK.pm +5 -4
  25. package/bin/exiftool_files/lib/Image/ExifTool/MIE.pm +3 -3
  26. package/bin/exiftool_files/lib/Image/ExifTool/MPEG.pm +2 -2
  27. package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +3 -2
  28. package/bin/exiftool_files/lib/Image/ExifTool/Minolta.pm +6 -7
  29. package/bin/exiftool_files/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
  30. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +1199 -1325
  31. package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +2 -2
  32. package/bin/exiftool_files/lib/Image/ExifTool/NikonSettings.pm +1 -1
  33. package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +88 -6
  34. package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +32 -15
  35. package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +89 -3
  36. package/bin/exiftool_files/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
  37. package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +8 -5
  38. package/bin/exiftool_files/lib/Image/ExifTool/PhaseOne.pm +14 -1
  39. package/bin/exiftool_files/lib/Image/ExifTool/Photoshop.pm +38 -7
  40. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +44 -13
  41. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +63 -20
  42. package/bin/exiftool_files/lib/Image/ExifTool/README +19 -2
  43. package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +34 -13
  44. package/bin/exiftool_files/lib/Image/ExifTool/Rawzor.pm +2 -2
  45. package/bin/exiftool_files/lib/Image/ExifTool/Real.pm +2 -2
  46. package/bin/exiftool_files/lib/Image/ExifTool/Ricoh.pm +2 -1
  47. package/bin/exiftool_files/lib/Image/ExifTool/Sigma.pm +5 -4
  48. package/bin/exiftool_files/lib/Image/ExifTool/SigmaRaw.pm +9 -3
  49. package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +28 -1
  50. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4691 -4624
  51. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +511 -117
  52. package/bin/exiftool_files/lib/Image/ExifTool/VCard.pm +19 -5
  53. package/bin/exiftool_files/lib/Image/ExifTool/Validate.pm +5 -5
  54. package/bin/exiftool_files/lib/Image/ExifTool/WriteExif.pl +42 -0
  55. package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +1 -1
  56. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +150 -36
  57. package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +19 -4
  58. package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +2 -1
  59. package/bin/exiftool_files/lib/Image/ExifTool.pm +248 -54
  60. package/bin/exiftool_files/lib/Image/ExifTool.pod +94 -58
  61. package/package.json +2 -2
@@ -64,11 +64,12 @@ use Image::ExifTool::Exif;
64
64
  use Image::ExifTool::GPS;
65
65
  use Image::ExifTool::XMP;
66
66
 
67
- $VERSION = '4.17';
67
+ $VERSION = '4.21';
68
68
 
69
69
  sub LensIDConv($$$);
70
70
  sub ProcessNikonAVI($$$);
71
71
  sub ProcessNikonMOV($$$);
72
+ sub ProcessNikonEncrypted($$$);
72
73
  sub FormatString($);
73
74
  sub ProcessNikonCaptureEditVersions($$$);
74
75
  sub PrintAFPoints($$);
@@ -83,9 +84,8 @@ sub GetAFPointGrid($$;$);
83
84
  The Nikon LensID is constructed as a Composite tag from the raw hex values
84
85
  of 8 other tags: LensIDNumber, LensFStops, MinFocalLength, MaxFocalLength,
85
86
  MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, in
86
- that order. Multiple lenses with the same LensID are differentiated by
87
- decimal values in the list below. The user-defined "Lenses" list may be
88
- used to specify the lens for ExifTool to choose in these cases (see the
87
+ that order. The user-defined "Lenses" list may be used to specify the lens
88
+ for ExifTool to choose in these cases (see the
89
89
  L<sample config file|../config.html> for details).
90
90
  },
91
91
  OTHER => \&LensIDConv,
@@ -880,6 +880,12 @@ my %bracketProgramZ9 = (
880
880
  9 => '9F',
881
881
  );
882
882
 
883
+ my %dynamicAfAreaModesZ9 = (
884
+ 0 => 'Small',
885
+ 1 => 'Medium',
886
+ 2 => 'Large',
887
+ );
888
+
883
889
  my %flashControlModeZ7 = (
884
890
  0 => 'TTL',
885
891
  1 => 'Auto External Flash',
@@ -919,6 +925,14 @@ my %hDMIOutputResolutionZ9 = (
919
925
  #7 => '480p',
920
926
  );
921
927
 
928
+ my %highFrameRateZ9 = (
929
+ 0 => 'Off',
930
+ 1 => 'CH',
931
+ 3 => 'C30',
932
+ 5 => 'C60',
933
+ 4 => 'C120',
934
+ );
935
+
922
936
  my %imageAreaZ9 = (
923
937
  0 => 'FX',
924
938
  1 => 'DX',
@@ -1104,6 +1118,14 @@ my %offLowNormalHighZ7 = (
1104
1118
  3 => 'High',
1105
1119
  );
1106
1120
 
1121
+ my %releaseModeZ7 = (
1122
+ 0 => 'Continuous Low',
1123
+ 1 => 'Continuous High',
1124
+ 2 => 'Continuous High (Extended)',
1125
+ 4 => 'Timer',
1126
+ 5 => 'Single Frame',
1127
+ );
1128
+
1107
1129
  my %secondarySlotFunctionZ9 = (
1108
1130
  0 => 'Overflow',
1109
1131
  1 => 'Backup',
@@ -1501,9 +1523,7 @@ my %base64coord = (
1501
1523
  0x0006 => { Name => 'Sharpness', Writable => 'string' },
1502
1524
  0x0007 => {
1503
1525
  Name => 'FocusMode',
1504
- DataMember => 'FocusMode',
1505
1526
  Writable => 'string',
1506
- RawConv => '$$self{FocusMode} = $val',
1507
1527
  },
1508
1528
  # FlashSetting (better named FlashSyncMode, ref 28) values:
1509
1529
  # "Normal", "Slow", "Rear Slow", "RED-EYE", "RED-EYE SLOW"
@@ -1651,7 +1671,7 @@ my %base64coord = (
1651
1671
  0x0019 => { #5
1652
1672
  Name => 'ExposureBracketValue',
1653
1673
  Writable => 'rational64s',
1654
- PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
1674
+ PrintConv => '$val !~ /undef/ ? Image::ExifTool::Exif::PrintFraction($val) : "n/a" ', #undef observed for Z9 jpgs at C30/C60/C90 [data is 0/0 rather than the usual 0/6]
1655
1675
  PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
1656
1676
  },
1657
1677
  0x001a => { #PH
@@ -1803,6 +1823,8 @@ my %base64coord = (
1803
1823
  0x0034 => { #forum9646
1804
1824
  Name => 'ShutterMode',
1805
1825
  Writable => 'int16u',
1826
+ RawConv => '$$self{ShutterMode} = $val',
1827
+ DataMember => 'ShutterMode',
1806
1828
  PrintConv => {
1807
1829
  0 => 'Mechanical',
1808
1830
  16 => 'Electronic',
@@ -1811,6 +1833,7 @@ my %base64coord = (
1811
1833
  64 => 'Electronic (Movie)', #JanSkoda (Z6II)
1812
1834
  80 => 'Auto (Mechanical)', #JanSkoda (Z6II)
1813
1835
  81 => 'Auto (Electronic Front Curtain)', #JanSkoda (Z6II)
1836
+ 96 => 'Electronic (High Speed)', #28 Z9 at C30/C60/C120 frame rates
1814
1837
  },
1815
1838
  },
1816
1839
  0x0035 => [{ #32
@@ -1874,6 +1897,14 @@ my %base64coord = (
1874
1897
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::MakerNotes0x51' },
1875
1898
  },
1876
1899
  #0x0053 #28 possibly a secondary DistortionControl block (in addition to DistortInfo)? Certainly offset 0x04 within block contains tag AutoDistortionControl for Z72 and D6 (1=>On; 2=> Off)
1900
+ 0x0056 => { #28 (Z9)
1901
+ Name => 'MakerNotes0x56',
1902
+ Writable => 'undef',
1903
+ Hidden => 1,
1904
+ Permanent => 0,
1905
+ Flags => [ 'Binary', 'Protected' ],
1906
+ SubDirectory => { TagTable => 'Image::ExifTool::Nikon::MakerNotes0x56' },
1907
+ },
1877
1908
  #0x005e #28 possibly DiffractionCompensation block? Certainly offset 0x04 within block contains tag DiffractionCompensation
1878
1909
  0x0080 => { Name => 'ImageAdjustment', Writable => 'string' },
1879
1910
  0x0081 => { Name => 'ToneComp', Writable => 'string' }, #2
@@ -2003,6 +2034,7 @@ my %base64coord = (
2003
2034
  6 => 'White-Balance Bracketing',
2004
2035
  7 => 'IR Control',
2005
2036
  8 => 'D-Lighting Bracketing', #forum6281 (NC)
2037
+ 11 => 'Pre-capture', #28 Z9 pre-release burst
2006
2038
  });
2007
2039
  ],
2008
2040
  },
@@ -2040,7 +2072,6 @@ my %base64coord = (
2040
2072
  SubDirectory => {
2041
2073
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD40',
2042
2074
  DecryptStart => 4,
2043
- DecryptLen => 748,
2044
2075
  ByteOrder => 'BigEndian',
2045
2076
  },
2046
2077
  },
@@ -2050,7 +2081,6 @@ my %base64coord = (
2050
2081
  SubDirectory => {
2051
2082
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD80',
2052
2083
  DecryptStart => 4,
2053
- DecryptLen => 765,
2054
2084
  # (Capture NX can change the makernote byte order, but this stays big-endian)
2055
2085
  ByteOrder => 'BigEndian',
2056
2086
  },
@@ -2061,7 +2091,6 @@ my %base64coord = (
2061
2091
  SubDirectory => {
2062
2092
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD90',
2063
2093
  DecryptStart => 4,
2064
- DecryptLen => 0x398,
2065
2094
  ByteOrder => 'BigEndian',
2066
2095
  },
2067
2096
  },
@@ -2071,7 +2100,6 @@ my %base64coord = (
2071
2100
  SubDirectory => {
2072
2101
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD3a',
2073
2102
  DecryptStart => 4,
2074
- DecryptLen => 0x318,
2075
2103
  ByteOrder => 'BigEndian',
2076
2104
  },
2077
2105
  },
@@ -2081,7 +2109,6 @@ my %base64coord = (
2081
2109
  SubDirectory => {
2082
2110
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD3b',
2083
2111
  DecryptStart => 4,
2084
- DecryptLen => 0x321,
2085
2112
  ByteOrder => 'BigEndian',
2086
2113
  },
2087
2114
  },
@@ -2091,7 +2118,6 @@ my %base64coord = (
2091
2118
  SubDirectory => {
2092
2119
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD3X',
2093
2120
  DecryptStart => 4,
2094
- DecryptLen => 0x323,
2095
2121
  ByteOrder => 'BigEndian',
2096
2122
  },
2097
2123
  },
@@ -2101,7 +2127,6 @@ my %base64coord = (
2101
2127
  SubDirectory => {
2102
2128
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD3S',
2103
2129
  DecryptStart => 4,
2104
- DecryptLen => 0x2e9,
2105
2130
  ByteOrder => 'BigEndian',
2106
2131
  },
2107
2132
  },
@@ -2112,7 +2137,6 @@ my %base64coord = (
2112
2137
  SubDirectory => {
2113
2138
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD300a',
2114
2139
  DecryptStart => 4,
2115
- DecryptLen => 813,
2116
2140
  ByteOrder => 'BigEndian',
2117
2141
  },
2118
2142
  },
@@ -2123,7 +2147,6 @@ my %base64coord = (
2123
2147
  SubDirectory => {
2124
2148
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD300b',
2125
2149
  DecryptStart => 4,
2126
- DecryptLen => 825,
2127
2150
  ByteOrder => 'BigEndian',
2128
2151
  },
2129
2152
  },
@@ -2134,7 +2157,6 @@ my %base64coord = (
2134
2157
  SubDirectory => {
2135
2158
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD300S',
2136
2159
  DecryptStart => 4,
2137
- DecryptLen => 827,
2138
2160
  ByteOrder => 'BigEndian',
2139
2161
  },
2140
2162
  },
@@ -2145,17 +2167,33 @@ my %base64coord = (
2145
2167
  SubDirectory => {
2146
2168
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD700',
2147
2169
  DecryptStart => 4,
2148
- DecryptLen => 0x358,
2149
2170
  ByteOrder => 'BigEndian',
2150
2171
  },
2151
2172
  },
2173
+ { #28 (D780 firmware version 1.00)
2174
+ Condition => '$$valPt =~ /^0245/',
2175
+ Name => 'ShotInfoD780',
2176
+ SubDirectory => {
2177
+ TagTable => 'Image::ExifTool::Nikon::ShotInfoD780',
2178
+ DecryptStart => 4,
2179
+ ByteOrder => 'LittleEndian',
2180
+ },
2181
+ },
2182
+ { #28 (D7500 firmware version 1.00h)
2183
+ Condition => '$$valPt =~ /^0242/',
2184
+ Name => 'ShotInfoD7500',
2185
+ SubDirectory => {
2186
+ TagTable => 'Image::ExifTool::Nikon::ShotInfoD7500',
2187
+ DecryptStart => 4,
2188
+ ByteOrder => 'LittleEndian',
2189
+ },
2190
+ },
2152
2191
  { #PH (D800 firmware 1.01a)
2153
2192
  Condition => '$$valPt =~ /^0222/',
2154
2193
  Name => 'ShotInfoD800',
2155
2194
  SubDirectory => {
2156
2195
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD800',
2157
2196
  DecryptStart => 4,
2158
- DecryptLen => 0x720,
2159
2197
  ByteOrder => 'BigEndian',
2160
2198
  },
2161
2199
  },
@@ -2165,8 +2203,6 @@ my %base64coord = (
2165
2203
  SubDirectory => {
2166
2204
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD810',
2167
2205
  DecryptStart => 4,
2168
- DecryptLen => 0x36f4 + 12,
2169
- DecryptMore => 'Get32u(\$data, 0x84) + 12',
2170
2206
  ByteOrder => 'LittleEndian',
2171
2207
  },
2172
2208
  },
@@ -2176,8 +2212,6 @@ my %base64coord = (
2176
2212
  SubDirectory => {
2177
2213
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD850',
2178
2214
  DecryptStart => 4,
2179
- DecryptLen => 0x2efb + 12,
2180
- DecryptMore => 'Get32u(\$data, 0xa0) + 12',
2181
2215
  ByteOrder => 'LittleEndian',
2182
2216
  },
2183
2217
  },
@@ -2190,7 +2224,6 @@ my %base64coord = (
2190
2224
  SubDirectory => {
2191
2225
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD5000',
2192
2226
  DecryptStart => 4,
2193
- DecryptLen => 0x39a,
2194
2227
  ByteOrder => 'BigEndian',
2195
2228
  },
2196
2229
  },
@@ -2200,7 +2233,6 @@ my %base64coord = (
2200
2233
  SubDirectory => {
2201
2234
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD5100',
2202
2235
  DecryptStart => 4,
2203
- DecryptLen => 0x430,
2204
2236
  ByteOrder => 'BigEndian',
2205
2237
  },
2206
2238
  },
@@ -2210,7 +2242,6 @@ my %base64coord = (
2210
2242
  SubDirectory => {
2211
2243
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD5200',
2212
2244
  DecryptStart => 4,
2213
- DecryptLen => 0xd00,
2214
2245
  ByteOrder => 'BigEndian',
2215
2246
  },
2216
2247
  },
@@ -2220,7 +2251,6 @@ my %base64coord = (
2220
2251
  SubDirectory => {
2221
2252
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD7000',
2222
2253
  DecryptStart => 4,
2223
- DecryptLen => 0x448,
2224
2254
  ByteOrder => 'BigEndian',
2225
2255
  },
2226
2256
  },
@@ -2230,7 +2260,6 @@ my %base64coord = (
2230
2260
  SubDirectory => {
2231
2261
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD4',
2232
2262
  DecryptStart => 4,
2233
- DecryptLen => 0x789,
2234
2263
  ByteOrder => 'BigEndian',
2235
2264
  },
2236
2265
  },
@@ -2240,29 +2269,15 @@ my %base64coord = (
2240
2269
  SubDirectory => {
2241
2270
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD4S',
2242
2271
  DecryptStart => 4,
2243
- DecryptLen => 0x3697,
2244
- ByteOrder => 'LittleEndian',
2245
- },
2246
- },
2247
- { #28 (D5 firmware version 1.10a)
2248
- Condition => '$$valPt =~ /^0238/',
2249
- Name => 'ShotInfoD5',
2250
- SubDirectory => {
2251
- TagTable => 'Image::ExifTool::Nikon::ShotInfoD500',
2252
- DecryptStart => 4,
2253
- DecryptLen => 0x2c24 + 12,
2254
- DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90',
2255
2272
  ByteOrder => 'LittleEndian',
2256
2273
  },
2257
2274
  },
2258
- { # (D500 firmware version 1.00)
2259
- Condition => '$$valPt =~ /^0239/',
2275
+ { #28 (D500 firmware version 1.00 and D5 firmware version 1.10a)
2276
+ Condition => '$$valPt =~ /^023[89]/',
2260
2277
  Name => 'ShotInfoD500',
2261
2278
  SubDirectory => {
2262
2279
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD500',
2263
2280
  DecryptStart => 4,
2264
- DecryptLen => 0x2cb2 + 4,
2265
- DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90',
2266
2281
  ByteOrder => 'LittleEndian',
2267
2282
  },
2268
2283
  },
@@ -2272,7 +2287,6 @@ my %base64coord = (
2272
2287
  SubDirectory => {
2273
2288
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD6',
2274
2289
  DecryptStart => 4,
2275
- DecryptLen => 0xc292 + 720, # thru decoded parts of Offset 32
2276
2290
  ByteOrder => 'LittleEndian',
2277
2291
  },
2278
2292
  },
@@ -2282,7 +2296,6 @@ my %base64coord = (
2282
2296
  SubDirectory => {
2283
2297
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD610',
2284
2298
  DecryptStart => 4,
2285
- DecryptLen => 0x7ff,
2286
2299
  ByteOrder => 'BigEndian',
2287
2300
  },
2288
2301
  },
@@ -2293,8 +2306,6 @@ my %base64coord = (
2293
2306
  SubDirectory => {
2294
2307
  TagTable => 'Image::ExifTool::Nikon::ShotInfoZ7II',
2295
2308
  DecryptStart => 4,
2296
- # TODO: eventually set the length dynamically according to actual offsets!
2297
- DecryptLen => 0xd04e + 860, # thru decoded MenuSettingsZ7II
2298
2309
  ByteOrder => 'LittleEndian',
2299
2310
  },
2300
2311
  },
@@ -2304,8 +2315,6 @@ my %base64coord = (
2304
2315
  SubDirectory => {
2305
2316
  TagTable => 'Image::ExifTool::Nikon::ShotInfoZ9',
2306
2317
  DecryptStart => 4,
2307
- # TODO: eventually set the length dynamically according to actual offsets!
2308
- DecryptLen => 0xec4b + 2196, # decoded thru end of Offset26
2309
2318
  ByteOrder => 'LittleEndian',
2310
2319
  },
2311
2320
  },
@@ -2314,10 +2323,9 @@ my %base64coord = (
2314
2323
  Name => 'ShotInfo02xx',
2315
2324
  SubDirectory => {
2316
2325
  TagTable => 'Image::ExifTool::Nikon::ShotInfo',
2317
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2318
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2326
+ ProcessProc => \&ProcessNikonEncrypted,
2327
+ WriteProc => \&ProcessNikonEncrypted,
2319
2328
  DecryptStart => 4,
2320
- DecryptLen => 0x251,
2321
2329
  ByteOrder => 'BigEndian',
2322
2330
  },
2323
2331
  },
@@ -2381,11 +2389,10 @@ my %base64coord = (
2381
2389
  Name => 'ColorBalance0205',
2382
2390
  SubDirectory => {
2383
2391
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2384
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2385
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2392
+ ProcessProc => \&ProcessNikonEncrypted,
2393
+ WriteProc => \&ProcessNikonEncrypted,
2386
2394
  DecryptStart => 4,
2387
- DecryptLen => 22, # 284 bytes encrypted, but don't need to decrypt it all
2388
- DirOffset => 14,
2395
+ DirOffset => 14, # (start of directory relative to DecryptStart)
2389
2396
  },
2390
2397
  },
2391
2398
  { # (D3/D3X/D300/D700=0209,D300S=0212,D3S=0214)
@@ -2393,10 +2400,9 @@ my %base64coord = (
2393
2400
  Name => 'ColorBalance0209',
2394
2401
  SubDirectory => {
2395
2402
  TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
2396
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2397
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2403
+ ProcessProc => \&ProcessNikonEncrypted,
2404
+ WriteProc => \&ProcessNikonEncrypted,
2398
2405
  DecryptStart => 284,
2399
- DecryptLen => 18, # 324 bytes encrypted, but don't need to decrypt it all
2400
2406
  DirOffset => 10,
2401
2407
  },
2402
2408
  },
@@ -2405,10 +2411,9 @@ my %base64coord = (
2405
2411
  Name => 'ColorBalance02',
2406
2412
  SubDirectory => {
2407
2413
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2408
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2409
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2414
+ ProcessProc => \&ProcessNikonEncrypted,
2415
+ WriteProc => \&ProcessNikonEncrypted,
2410
2416
  DecryptStart => 284,
2411
- DecryptLen => 14, # don't need to decrypt it all
2412
2417
  DirOffset => 6,
2413
2418
  },
2414
2419
  },
@@ -2417,10 +2422,9 @@ my %base64coord = (
2417
2422
  Name => 'ColorBalance0211',
2418
2423
  SubDirectory => {
2419
2424
  TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
2420
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2421
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2425
+ ProcessProc => \&ProcessNikonEncrypted,
2426
+ WriteProc => \&ProcessNikonEncrypted,
2422
2427
  DecryptStart => 284,
2423
- DecryptLen => 24, # don't need to decrypt it all
2424
2428
  DirOffset => 16,
2425
2429
  },
2426
2430
  },
@@ -2429,10 +2433,9 @@ my %base64coord = (
2429
2433
  Name => 'ColorBalance0213',
2430
2434
  SubDirectory => {
2431
2435
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2432
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2433
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2436
+ ProcessProc => \&ProcessNikonEncrypted,
2437
+ WriteProc => \&ProcessNikonEncrypted,
2434
2438
  DecryptStart => 284,
2435
- DecryptLen => 18, # don't need to decrypt it all
2436
2439
  DirOffset => 10,
2437
2440
  },
2438
2441
  },
@@ -2441,10 +2444,9 @@ my %base64coord = (
2441
2444
  Name => 'ColorBalance0215',
2442
2445
  SubDirectory => {
2443
2446
  TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
2444
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2445
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2447
+ ProcessProc => \&ProcessNikonEncrypted,
2448
+ WriteProc => \&ProcessNikonEncrypted,
2446
2449
  DecryptStart => 284,
2447
- DecryptLen => 12, # don't need to decrypt it all
2448
2450
  DirOffset => 4,
2449
2451
  },
2450
2452
  },
@@ -2453,9 +2455,9 @@ my %base64coord = (
2453
2455
  Condition => '$$valPt =~ /^0[26]/',
2454
2456
  SubDirectory => {
2455
2457
  TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
2456
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2458
+ ProcessProc => \&ProcessNikonEncrypted,
2459
+ WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt this if serial number changed)
2457
2460
  DecryptStart => 284,
2458
- DecryptLen => 10, # (arbitrary)
2459
2461
  },
2460
2462
  },
2461
2463
  { # (1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403, Z6/Z7=0800)
@@ -2463,9 +2465,9 @@ my %base64coord = (
2463
2465
  Condition => '$$valPt =~ /^0[48]/',
2464
2466
  SubDirectory => {
2465
2467
  TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
2466
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2468
+ ProcessProc => \&ProcessNikonEncrypted,
2469
+ WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt this if serial number changed)
2467
2470
  DecryptStart => 4,
2468
- DecryptLen => 10, # (arbitrary)
2469
2471
  },
2470
2472
  },
2471
2473
  {
@@ -2494,8 +2496,8 @@ my %base64coord = (
2494
2496
  Name => 'LensData0201',
2495
2497
  SubDirectory => {
2496
2498
  TagTable => 'Image::ExifTool::Nikon::LensData01',
2497
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2498
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2499
+ ProcessProc => \&ProcessNikonEncrypted,
2500
+ WriteProc => \&ProcessNikonEncrypted,
2499
2501
  DecryptStart => 4,
2500
2502
  },
2501
2503
  },
@@ -2504,8 +2506,8 @@ my %base64coord = (
2504
2506
  Name => 'LensData0204',
2505
2507
  SubDirectory => {
2506
2508
  TagTable => 'Image::ExifTool::Nikon::LensData0204',
2507
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2508
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2509
+ ProcessProc => \&ProcessNikonEncrypted,
2510
+ WriteProc => \&ProcessNikonEncrypted,
2509
2511
  DecryptStart => 4,
2510
2512
  },
2511
2513
  },
@@ -2514,8 +2516,8 @@ my %base64coord = (
2514
2516
  Name => 'LensData0400',
2515
2517
  SubDirectory => {
2516
2518
  TagTable => 'Image::ExifTool::Nikon::LensData0400',
2517
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2518
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2519
+ ProcessProc => \&ProcessNikonEncrypted,
2520
+ WriteProc => \&ProcessNikonEncrypted,
2519
2521
  DecryptStart => 4,
2520
2522
  },
2521
2523
  },
@@ -2524,8 +2526,8 @@ my %base64coord = (
2524
2526
  Name => 'LensData0402',
2525
2527
  SubDirectory => {
2526
2528
  TagTable => 'Image::ExifTool::Nikon::LensData0402',
2527
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2528
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2529
+ ProcessProc => \&ProcessNikonEncrypted,
2530
+ WriteProc => \&ProcessNikonEncrypted,
2529
2531
  DecryptStart => 4,
2530
2532
  },
2531
2533
  },
@@ -2534,8 +2536,8 @@ my %base64coord = (
2534
2536
  Name => 'LensData0403',
2535
2537
  SubDirectory => {
2536
2538
  TagTable => 'Image::ExifTool::Nikon::LensData0403',
2537
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2538
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2539
+ ProcessProc => \&ProcessNikonEncrypted,
2540
+ WriteProc => \&ProcessNikonEncrypted,
2539
2541
  DecryptStart => 4,
2540
2542
  },
2541
2543
  },
@@ -2544,8 +2546,8 @@ my %base64coord = (
2544
2546
  Name => 'LensData0800',
2545
2547
  SubDirectory => {
2546
2548
  TagTable => 'Image::ExifTool::Nikon::LensData0800',
2547
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2548
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2549
+ ProcessProc => \&ProcessNikonEncrypted,
2550
+ WriteProc => \&ProcessNikonEncrypted,
2549
2551
  DecryptStart => 4,
2550
2552
  ByteOrder => 'LittleEndian',
2551
2553
  },
@@ -2554,8 +2556,8 @@ my %base64coord = (
2554
2556
  Name => 'LensDataUnknown',
2555
2557
  SubDirectory => {
2556
2558
  TagTable => 'Image::ExifTool::Nikon::LensDataUnknown',
2557
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2558
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2559
+ ProcessProc => \&ProcessNikonEncrypted,
2560
+ WriteProc => \&ProcessNikonEncrypted,
2559
2561
  DecryptStart => 4,
2560
2562
  },
2561
2563
  },
@@ -5260,7 +5262,7 @@ my %nikonFocalConversions = (
5260
5262
  Name => 'NewLensData',
5261
5263
  Format => 'undef[17]',
5262
5264
  RawConv => '$$self{NewLensData} = 1 unless $val =~ /^.\0+$/s; undef',
5263
- Hidden => 1,
5265
+ #Hidden => 1,
5264
5266
  },
5265
5267
  0x30 => { #PH
5266
5268
  Name => 'LensID',
@@ -5285,21 +5287,28 @@ my %nikonFocalConversions = (
5285
5287
  22 => 'Nikkor Z 24-50mm f/4-6.3', #IB
5286
5288
  23 => 'Nikkor Z 14-24mm f/2.8 S', #IB
5287
5289
  24 => 'Nikkor Z MC 105mm f/2.8 VR S', #IB
5290
+ 25 => 'Nikkor Z 40mm f/2', #28
5291
+ 26 => 'Nikkor Z DX 18-140mm f/3.5-6.3 VR', #IB
5288
5292
  27 => 'Nikkor Z MC 50mm f/2.8', #IB
5289
5293
  28 => 'Nikkor Z 100-400mm f/4.5-5.6 VR S', #28
5290
5294
  29 => 'Nikkor Z 28mm f/2.8', #IB
5291
5295
  30 => 'Nikkor Z 400mm f/2.8 TC VR S', #28
5292
5296
  31 => 'Nikkor Z 24-120 f/4', #28
5293
5297
  32 => 'Nikkor Z 800mm f/6.3 VR S', #28
5298
+ 35 => 'Nikkor Z 28-75mm f/2.8', #IB
5294
5299
  36 => 'Nikkor Z 400mm f/4.5 VR S', #IB
5300
+ 37 => 'Nikkor Z 600mm f/4 TC VR S', #28
5301
+ 38 => 'Nikkor Z 85mm f/1.2 S', #28
5295
5302
  39 => 'Nikkor Z 17-28mm f/2.8', #IB
5303
+ 32768 => 'Nikkor Z 400mm f/2.8 TC VR S TC-1.4x', #28
5304
+ 32769 => 'Nikkor Z 600mm f/4 TC VR S TC-1.4x', #28
5296
5305
  },
5297
5306
  },
5298
5307
  0x35 => { #28
5299
5308
  Name => 'LensMountType',
5300
5309
  RawConv => '$$self{LensMountType} = $val', # 0=> DSLR lens via FTZ style adapter; 1=> Native Z lens;
5301
5310
  Format => 'int8u',
5302
- Unknown => 1,
5311
+ #Unknown => 1,
5303
5312
  PrintConv => {
5304
5313
  0 => 'F-mount Lens',
5305
5314
  1 => 'Z-mount Lens',
@@ -5362,7 +5371,7 @@ my %nikonFocalConversions = (
5362
5371
  Name => 'LensPositionAbsolute', # <=0 at infinity. Typical value at CFD might be 58000. Only valid for Z-mount lenses.
5363
5372
  Condition => '$$self{NewLensData} and $$self{LensMountType} and $$self{LensMountType} == 1',
5364
5373
  Format => 'int32s',
5365
- Unknown => 1,
5374
+ #Unknown => 1,
5366
5375
  },
5367
5376
  );
5368
5377
 
@@ -5485,8 +5494,6 @@ my %nikonFocalConversions = (
5485
5494
  Format => 'int32u',
5486
5495
  Priority => 0,
5487
5496
  },
5488
- # note: DecryptLen currently set to 0x251
5489
-
5490
5497
  # 0x55c - int16u[2400] TiffMeteringImage2: 60x40 image (ShotInfoVersion 0800, ref JR)
5491
5498
  # 0x181c - int16u[1200] TiffMeteringImage?: 60x20 image for some NEF's (ShotInfoVersion 0800, ref JR)
5492
5499
  # 0x217c - int16u[2400] TiffMeteringImage3: 60x40 image (ShotInfoVersion 0800, ref JR)
@@ -5498,8 +5505,8 @@ my %nikonFocalConversions = (
5498
5505
 
5499
5506
  # shot information for D40 and D40X (encrypted) - ref PH
5500
5507
  %Image::ExifTool::Nikon::ShotInfoD40 = (
5501
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5502
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5508
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5509
+ WRITE_PROC => \&ProcessNikonEncrypted,
5503
5510
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5504
5511
  VARS => { ID_LABEL => 'Index' },
5505
5512
  IS_SUBDIR => [ 729 ],
@@ -5529,13 +5536,12 @@ my %nikonFocalConversions = (
5529
5536
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD40',
5530
5537
  },
5531
5538
  },
5532
- # note: DecryptLen currently set to 748
5533
5539
  );
5534
5540
 
5535
5541
  # shot information for D80 (encrypted) - ref JD
5536
5542
  %Image::ExifTool::Nikon::ShotInfoD80 = (
5537
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5538
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5543
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5544
+ WRITE_PROC => \&ProcessNikonEncrypted,
5539
5545
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5540
5546
  VARS => { ID_LABEL => 'Index' },
5541
5547
  IS_SUBDIR => [ 748 ],
@@ -5609,13 +5615,12 @@ my %nikonFocalConversions = (
5609
5615
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD80',
5610
5616
  },
5611
5617
  },
5612
- # note: DecryptLen currently set to 765
5613
5618
  );
5614
5619
 
5615
5620
  # shot information for D90 (encrypted) - ref PH
5616
5621
  %Image::ExifTool::Nikon::ShotInfoD90 = (
5617
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5618
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5622
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5623
+ WRITE_PROC => \&ProcessNikonEncrypted,
5619
5624
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5620
5625
  VARS => { ID_LABEL => 'Index' },
5621
5626
  IS_SUBDIR => [ 0x374 ],
@@ -5655,13 +5660,12 @@ my %nikonFocalConversions = (
5655
5660
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD90',
5656
5661
  },
5657
5662
  },
5658
- # note: DecryptLen currently set to 0x398
5659
5663
  );
5660
5664
 
5661
5665
  # shot information for the D3 firmware 0.37 and 1.00 (encrypted) - ref PH
5662
5666
  %Image::ExifTool::Nikon::ShotInfoD3a = (
5663
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5664
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5667
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5668
+ WRITE_PROC => \&ProcessNikonEncrypted,
5665
5669
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5666
5670
  VARS => { ID_LABEL => 'Index' },
5667
5671
  IS_SUBDIR => [ 0x301 ],
@@ -5719,13 +5723,12 @@ my %nikonFocalConversions = (
5719
5723
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5720
5724
  },
5721
5725
  },
5722
- # note: DecryptLen currently set to 0x318
5723
5726
  );
5724
5727
 
5725
5728
  # shot information for the D3 firmware 1.10, 2.00 and 2.01 (encrypted) - ref PH
5726
5729
  %Image::ExifTool::Nikon::ShotInfoD3b = (
5727
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5728
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5730
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5731
+ WRITE_PROC => \&ProcessNikonEncrypted,
5729
5732
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5730
5733
  VARS => { ID_LABEL => 'Index' },
5731
5734
  IS_SUBDIR => [ 0x30a ],
@@ -5814,13 +5817,12 @@ my %nikonFocalConversions = (
5814
5817
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5815
5818
  },
5816
5819
  },
5817
- # note: DecryptLen currently set to 0x321
5818
5820
  );
5819
5821
 
5820
5822
  # shot information for the D3X firmware 1.00 (encrypted) - ref PH
5821
5823
  %Image::ExifTool::Nikon::ShotInfoD3X = (
5822
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5823
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5824
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5825
+ WRITE_PROC => \&ProcessNikonEncrypted,
5824
5826
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5825
5827
  VARS => { ID_LABEL => 'Index' },
5826
5828
  IS_SUBDIR => [ 0x30b ],
@@ -5860,13 +5862,12 @@ my %nikonFocalConversions = (
5860
5862
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5861
5863
  },
5862
5864
  },
5863
- # note: DecryptLen currently set to 0x323
5864
5865
  );
5865
5866
 
5866
5867
  # shot information for the D3S firmware 0.16 and 1.00 (encrypted) - ref PH
5867
5868
  %Image::ExifTool::Nikon::ShotInfoD3S = (
5868
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5869
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5869
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5870
+ WRITE_PROC => \&ProcessNikonEncrypted,
5870
5871
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5871
5872
  VARS => { ID_LABEL => 'Index' },
5872
5873
  IS_SUBDIR => [ 0x2ce ],
@@ -5915,13 +5916,12 @@ my %nikonFocalConversions = (
5915
5916
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5916
5917
  },
5917
5918
  },
5918
- # note: DecryptLen currently set to 0x2e9
5919
5919
  );
5920
5920
 
5921
5921
  # shot information for the D300 firmware 1.00 (encrypted) - ref JD
5922
5922
  %Image::ExifTool::Nikon::ShotInfoD300a = (
5923
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5924
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5923
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5924
+ WRITE_PROC => \&ProcessNikonEncrypted,
5925
5925
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5926
5926
  VARS => { ID_LABEL => 'Index' },
5927
5927
  IS_SUBDIR => [ 790 ],
@@ -6008,13 +6008,12 @@ my %nikonFocalConversions = (
6008
6008
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6009
6009
  },
6010
6010
  },
6011
- # note: DecryptLen currently set to 813
6012
6011
  );
6013
6012
 
6014
6013
  # shot information for the D300 firmware 1.10 (encrypted) - ref PH
6015
6014
  %Image::ExifTool::Nikon::ShotInfoD300b = (
6016
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6017
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6015
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6016
+ WRITE_PROC => \&ProcessNikonEncrypted,
6018
6017
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6019
6018
  VARS => { ID_LABEL => 'Index' },
6020
6019
  DATAMEMBER => [ 4 ],
@@ -6159,13 +6158,12 @@ my %nikonFocalConversions = (
6159
6158
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6160
6159
  },
6161
6160
  },
6162
- # note: DecryptLen currently set to 825
6163
6161
  );
6164
6162
 
6165
6163
  # shot information for the D300S firmware 1.00 (encrypted) - ref PH
6166
6164
  %Image::ExifTool::Nikon::ShotInfoD300S = (
6167
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6168
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6165
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6166
+ WRITE_PROC => \&ProcessNikonEncrypted,
6169
6167
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6170
6168
  VARS => { ID_LABEL => 'Index' },
6171
6169
  IS_SUBDIR => [ 804 ],
@@ -6205,13 +6203,12 @@ my %nikonFocalConversions = (
6205
6203
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6206
6204
  },
6207
6205
  },
6208
- # note: DecryptLen currently set to 827
6209
6206
  );
6210
6207
 
6211
6208
  # shot information for the D700 firmware 1.02f (encrypted) - ref 29
6212
6209
  %Image::ExifTool::Nikon::ShotInfoD700 = (
6213
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6214
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6210
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6211
+ WRITE_PROC => \&ProcessNikonEncrypted,
6215
6212
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6216
6213
  VARS => { ID_LABEL => 'Index' },
6217
6214
  IS_SUBDIR => [ 804 ],
@@ -6251,13 +6248,45 @@ my %nikonFocalConversions = (
6251
6248
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD700',
6252
6249
  },
6253
6250
  },
6254
- # note: DecryptLen currently set to 852
6251
+ );
6252
+
6253
+ # shot information for the D780 - ref #28
6254
+ %Image::ExifTool::Nikon::ShotInfoD780 = (
6255
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6256
+ WRITE_PROC => \&ProcessNikonEncrypted,
6257
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6258
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
6259
+ DATAMEMBER => [ 0x04 ],
6260
+ IS_SUBDIR => [ 0x9c ],
6261
+ WRITABLE => 1,
6262
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6263
+ NOTES => 'These tags are extracted from encrypted data in images from the D780.',
6264
+ 0x00 => {
6265
+ Name => 'ShotInfoVersion',
6266
+ Format => 'string[4]',
6267
+ Writable => 0,
6268
+ },
6269
+ 0x04 => {
6270
+ Name => 'FirmwareVersion',
6271
+ DataMember => 'FirmwareVersion',
6272
+ Format => 'string[5]',
6273
+ Writable => 0,
6274
+ RawConv => '$$self{FirmwareVersion} = $val',
6275
+ },
6276
+ 0x9c => {
6277
+ Name => 'OrientOffset',
6278
+ Format => 'int32u',
6279
+ SubDirectory => {
6280
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
6281
+ Start => '$val',
6282
+ },
6283
+ },
6255
6284
  );
6256
6285
 
6257
6286
  # shot information for the D5000 firmware 1.00 (encrypted) - ref PH
6258
6287
  %Image::ExifTool::Nikon::ShotInfoD5000 = (
6259
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6260
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6288
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6289
+ WRITE_PROC => \&ProcessNikonEncrypted,
6261
6290
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6262
6291
  VARS => { ID_LABEL => 'Index' },
6263
6292
  IS_SUBDIR => [ 0x378 ],
@@ -6297,13 +6326,12 @@ my %nikonFocalConversions = (
6297
6326
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5000',
6298
6327
  },
6299
6328
  },
6300
- # note: DecryptLen currently set to 0x39a
6301
6329
  );
6302
6330
 
6303
6331
  # shot information for the D5100 firmware 1.00f (encrypted) - ref PH
6304
6332
  %Image::ExifTool::Nikon::ShotInfoD5100 = (
6305
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6306
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6333
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6334
+ WRITE_PROC => \&ProcessNikonEncrypted,
6307
6335
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6308
6336
  VARS => { ID_LABEL => 'Index' },
6309
6337
  IS_SUBDIR => [ 0x407 ],
@@ -6332,13 +6360,12 @@ my %nikonFocalConversions = (
6332
6360
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5100',
6333
6361
  },
6334
6362
  },
6335
- # note: DecryptLen currently set to 0x430
6336
6363
  );
6337
6364
 
6338
6365
  # shot information for the D5200 firmware 1.00 (encrypted) - ref PH
6339
6366
  %Image::ExifTool::Nikon::ShotInfoD5200 = (
6340
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6341
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6367
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6368
+ WRITE_PROC => \&ProcessNikonEncrypted,
6342
6369
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6343
6370
  VARS => { ID_LABEL => 'Index' },
6344
6371
  IS_SUBDIR => [ 0xcd5 ],
@@ -6370,13 +6397,12 @@ my %nikonFocalConversions = (
6370
6397
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5200',
6371
6398
  },
6372
6399
  },
6373
- # note: DecryptLen currently set to 0xd00
6374
6400
  );
6375
6401
 
6376
6402
  # shot information for the D7000 firmware 1.01d (encrypted) - ref 29
6377
6403
  %Image::ExifTool::Nikon::ShotInfoD7000 = (
6378
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6379
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6404
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6405
+ WRITE_PROC => \&ProcessNikonEncrypted,
6380
6406
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6381
6407
  VARS => { ID_LABEL => 'Index' },
6382
6408
  IS_SUBDIR => [ 1028 ],
@@ -6418,10 +6444,43 @@ my %nikonFocalConversions = (
6418
6444
  },
6419
6445
  );
6420
6446
 
6447
+ # shot information for the D7500 - ref #28
6448
+ %Image::ExifTool::Nikon::ShotInfoD7500 = (
6449
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6450
+ WRITE_PROC => \&ProcessNikonEncrypted,
6451
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6452
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
6453
+ DATAMEMBER => [ 0x04 ],
6454
+ IS_SUBDIR => [ 0xa0 ],
6455
+ WRITABLE => 1,
6456
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6457
+ NOTES => 'These tags are extracted from encrypted data in images from the D7500.',
6458
+ 0x00 => {
6459
+ Name => 'ShotInfoVersion',
6460
+ Format => 'string[4]',
6461
+ Writable => 0,
6462
+ },
6463
+ 0x04 => {
6464
+ Name => 'FirmwareVersion',
6465
+ DataMember => 'FirmwareVersion',
6466
+ Format => 'string[5]',
6467
+ Writable => 0,
6468
+ RawConv => '$$self{FirmwareVersion} = $val',
6469
+ },
6470
+ 0xa0 => {
6471
+ Name => 'OrientOffset',
6472
+ Format => 'int32u',
6473
+ SubDirectory => {
6474
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
6475
+ Start => '$val',
6476
+ },
6477
+ },
6478
+ );
6479
+
6421
6480
  # shot information for the D800 firmware 1.01a (encrypted) - ref PH
6422
6481
  %Image::ExifTool::Nikon::ShotInfoD800 = (
6423
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6424
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6482
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6483
+ WRITE_PROC => \&ProcessNikonEncrypted,
6425
6484
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6426
6485
  VARS => { ID_LABEL => 'Index' },
6427
6486
  IS_SUBDIR => [ 0x6ec ],
@@ -6536,20 +6595,17 @@ my %nikonFocalConversions = (
6536
6595
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD800',
6537
6596
  },
6538
6597
  },
6539
- # note: DecryptLen currently set to 0x720
6540
6598
  );
6541
6599
 
6542
6600
  # shot information for the D5 firmware 1.10a and D500 firmware 1.01 (encrypted) - ref 28
6543
6601
  %Image::ExifTool::Nikon::ShotInfoD500 = (
6544
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6545
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6602
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6603
+ WRITE_PROC => \&ProcessNikonEncrypted,
6546
6604
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6547
- VARS => { ID_LABEL => 'Index' },
6548
- DATAMEMBER => [ 0x04, 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8, 0xb0,
6549
- 0x07b0, 0x086c, 0x0e7c, 0x0eea, 0x2c23, 0x2c8f ],
6550
- IS_SUBDIR => [ 0x0eeb ],
6605
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
6606
+ DATAMEMBER => [ 0x04 ],
6607
+ IS_SUBDIR => [ 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8 ],
6551
6608
  WRITABLE => 1,
6552
- FIRST_ENTRY => 0,
6553
6609
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6554
6610
  NOTES => 'These tags are extracted from encrypted data in images from the D5 and D500.',
6555
6611
  0x00 => {
@@ -6566,73 +6622,66 @@ my %nikonFocalConversions = (
6566
6622
  },
6567
6623
  0x10 => {
6568
6624
  Name => 'RotationInfoOffset',
6569
- DataMember => 'RotationInfoOffset',
6570
6625
  Format => 'int32u',
6571
- Writable => 0,
6572
- Hidden => 1,
6573
- RawConv => '$$self{RotationInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6626
+ SubDirectory => {
6627
+ TagTable => 'Image::ExifTool::Nikon::RotationInfoD500',
6628
+ Start => '$val',
6629
+ }
6574
6630
  },
6575
6631
  0x14 => {
6576
6632
  Name => 'JPGInfoOffset',
6577
- DataMember => 'JPGInfoOffset',
6578
6633
  Format => 'int32u',
6579
- Writable => 0,
6580
- Hidden => 1,
6581
- RawConv => '$$self{JPGInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6634
+ SubDirectory => {
6635
+ TagTable => 'Image::ExifTool::Nikon::JPGInfoD500',
6636
+ Start => '$val',
6637
+ }
6582
6638
  },
6583
6639
  0x2c => {
6584
- Name => 'BracketingInfoOffset',
6585
- DataMember => 'BracketingInfoOffset',
6640
+ Name => 'BracketingOffset',
6586
6641
  Format => 'int32u',
6587
- Writable => 0,
6588
- Hidden => 1,
6589
- RawConv => '$$self{BracketingInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6642
+ SubDirectory => {
6643
+ TagTable => 'Image::ExifTool::Nikon::BracketingInfoD500',
6644
+ Start => '$val',
6645
+ }
6590
6646
  },
6591
6647
  0x50 => {
6592
6648
  Name => 'ShootingMenuOffset',
6593
- DataMember => 'ShootingMenuOffset',
6594
6649
  Format => 'int32u',
6595
- Writable => 0,
6596
- Hidden => 1,
6597
- RawConv => '$$self{ShootingMenuOffset} = $val || 0x10000000; undef', # (ignore if 0)
6650
+ SubDirectory => {
6651
+ TagTable => 'Image::ExifTool::Nikon::ShootingMenuD500',
6652
+ Start => '$val',
6653
+ }
6598
6654
  },
6599
6655
  0x58 => {
6600
6656
  Name => 'CustomSettingsOffset',
6601
- DataMember => 'CustomSettingsOffset',
6602
6657
  Format => 'int32u',
6603
- Writable => 0,
6604
- Hidden => 1,
6605
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef', # (ignore if 0)
6658
+ SubDirectory => {
6659
+ TagTable => 'Image::ExifTool::Nikon::CustomSettingsD500',
6660
+ Start => '$val',
6661
+ }
6606
6662
  },
6607
6663
  0xa0 => {
6608
6664
  Name => 'OrientationOffset',
6609
- DataMember => 'OrientationOffset',
6610
6665
  Format => 'int32u',
6611
- Writable => 0,
6612
- Hidden => 1,
6613
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
6666
+ SubDirectory => {
6667
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
6668
+ Start => '$val',
6669
+ }
6614
6670
  },
6615
6671
  0xa8 => {
6616
6672
  Name => 'OtherOffset',
6617
- DataMember => 'OtherOffset',
6618
6673
  Format => 'int32u',
6619
- Writable => 0,
6620
- Hidden => 1,
6621
- RawConv => '$$self{OtherOffset} = $val || 0x10000000; undef', # (ignore if 0)
6622
- },
6623
- #
6624
- # Tag ID's below are the offsets for a D500 JPEG image, but these offsets change
6625
- # for various image types according to the offset table above
6626
- #
6627
- ### 0xb0 - RotationInfo start
6628
- 0xb0 => {
6629
- Name => 'Hook1',
6630
- Hidden => 1,
6631
- RawConv => 'undef',
6632
- # account for variable location of Rotation data
6633
- Hook => '$varSize = $$self{RotationInfoOffset} - 0xb0',
6674
+ SubDirectory => {
6675
+ TagTable => 'Image::ExifTool::Nikon::OtherInfoD500',
6676
+ Start => '$val',
6677
+ }
6634
6678
  },
6635
- 0xca => {
6679
+ );
6680
+
6681
+ %Image::ExifTool::Nikon::RotationInfoD500 = (
6682
+ %binaryDataAttrs,
6683
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6684
+ 0x1a => {
6636
6685
  Name => 'Rotation',
6637
6686
  Mask => 0x03,
6638
6687
  PrintConv => {
@@ -6642,32 +6691,29 @@ my %nikonFocalConversions = (
6642
6691
  3 => 'Rotate 180',
6643
6692
  },
6644
6693
  },
6645
- 0x0d0 => {
6694
+ 0x20 => {
6646
6695
  Name => 'Interval',
6647
6696
  # prior version of the d% firmware do not support this tag, nor does the D500 (at least thru firmware 1.3)
6648
6697
  Condition => '$$self{Model} eq "NIKON D5" and $$self{FirmwareVersion} ge "1.40"',
6649
6698
  PrintConv => '$val > 0 ? sprintf("%.0f", $val) : ""',
6650
6699
  },
6651
- 0x0d4 => {
6700
+ 0x24 => {
6652
6701
  Name => 'IntervalFrame',
6653
6702
  # prior version of the d% firmware do not support this tag, nor does the D500 (at least thru firmware 1.3)
6654
6703
  Condition => '$$self{Model} eq "NIKON D5" and $$self{FirmwareVersion} ge "1.40"',
6655
6704
  PrintConv => '$val > 0 ? sprintf("%.0f", $val) : ""',
6656
6705
  },
6657
- 0x05e2 => {
6706
+ 0x0532 => {
6658
6707
  Name => 'FlickerReductionIndicator',
6659
6708
  Mask => 0x01,
6660
6709
  PrintConv => { 0 => 'On', 1 => 'Off' },
6661
6710
  },
6662
- ### 0x07b0 - JPEGInfo start
6663
- 0x07b0 => {
6664
- Name => 'Hook2',
6665
- Hidden => 1,
6666
- RawConv => 'undef',
6667
- # account for variable location of Shooting Menu data
6668
- Hook => '$varSize = $$self{JPGInfoOffset} - 0x07b0',
6669
- },
6670
- 0x07d4 => {
6711
+ );
6712
+
6713
+ %Image::ExifTool::Nikon::JPGInfoD500 = (
6714
+ %binaryDataAttrs,
6715
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6716
+ 0x24 => {
6671
6717
  Name => 'JPGCompression',
6672
6718
  Mask => 0x01,
6673
6719
  PrintConv => {
@@ -6675,16 +6721,12 @@ my %nikonFocalConversions = (
6675
6721
  1 => 'Optimal Quality',
6676
6722
  },
6677
6723
  },
6678
- ### 0x0830 - ? start
6679
- ### 0x086c - BracketingInfo start
6680
- 0x086c => {
6681
- Name => 'Hook3',
6682
- Hidden => 1,
6683
- RawConv => 'undef',
6684
- # account for variable location of Shooting Menu data
6685
- Hook => '$varSize = $$self{BracketingInfoOffset} - 0x086c',
6686
- },
6687
- 0x087b => {
6724
+ );
6725
+
6726
+ %Image::ExifTool::Nikon::BracketingInfoD500 = (
6727
+ %binaryDataAttrs,
6728
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6729
+ 0x0f => {
6688
6730
  Name => 'AEBracketingSteps',
6689
6731
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
6690
6732
  Mask => 0xff,
@@ -6742,7 +6784,7 @@ my %nikonFocalConversions = (
6742
6784
  0xd6 => '5F3',
6743
6785
  },
6744
6786
  },
6745
- 0x087c => {
6787
+ 0x10 => {
6746
6788
  Name => 'WBBracketingSteps',
6747
6789
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
6748
6790
  Mask => 0xff,
@@ -6785,7 +6827,7 @@ my %nikonFocalConversions = (
6785
6827
  0x28 => '9F 3',
6786
6828
  },
6787
6829
  },
6788
- 0x0883 => {
6830
+ 0x17 => {
6789
6831
  Name => 'ADLBracketingStep',
6790
6832
  Mask => 0xf0,
6791
6833
  PrintConv => {
@@ -6797,7 +6839,7 @@ my %nikonFocalConversions = (
6797
6839
  8 => 'Auto',
6798
6840
  },
6799
6841
  },
6800
- 0x0884 => {
6842
+ 0x18 => {
6801
6843
  Name => 'ADLBracketingType',
6802
6844
  Mask => 0x0f,
6803
6845
  PrintConv => {
@@ -6808,23 +6850,12 @@ my %nikonFocalConversions = (
6808
6850
  4 => '5 Shots',
6809
6851
  },
6810
6852
  },
6811
- ### 0x0887 - ? start
6812
- ### 0x089f - ? start
6813
- ### 0x0929 - ? start
6814
- ### 0x09c9 - ? start
6815
- ### 0x0ac5 - ? start
6816
- ### 0x0bc1 - ? start
6817
- ### 0x0cbd - ? start
6818
- ### 0x0d98 - ? start
6819
- ### 0x0e7d - ShootingMenuOffset start
6820
- 0x0e7c => {
6821
- Name => 'Hook4',
6822
- Hidden => 1,
6823
- RawConv => 'undef',
6824
- # account for variable location of Shooting Menu data
6825
- Hook => '$varSize = $$self{ShootingMenuOffset} - 0x0e7d',
6826
- },
6827
- 0x0e7d => {
6853
+ );
6854
+
6855
+ %Image::ExifTool::Nikon::ShootingMenuD500 = (
6856
+ %binaryDataAttrs,
6857
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6858
+ 0x00 => {
6828
6859
  Name => 'PhotoShootingMenuBank',
6829
6860
  Mask => 0x03,
6830
6861
  PrintConv => {
@@ -6834,7 +6865,7 @@ my %nikonFocalConversions = (
6834
6865
  3 => 'D',
6835
6866
  },
6836
6867
  },
6837
- 0x0e7f => {
6868
+ 0x02 => {
6838
6869
  Name => 'PrimarySlot',
6839
6870
  Condition => '$$self{Model} =~ /\bD500\b/',
6840
6871
  Notes => 'D500 only',
@@ -6844,7 +6875,7 @@ my %nikonFocalConversions = (
6844
6875
  1 => 'SD Card',
6845
6876
  },
6846
6877
  },
6847
- 0x0e81 => {
6878
+ 0x04 => {
6848
6879
  Name => 'ISOAutoShutterTime',
6849
6880
  Mask => 0x3f,
6850
6881
  PrintConv => {
@@ -6887,7 +6918,7 @@ my %nikonFocalConversions = (
6887
6918
  36 => 'Auto (Fastest)',
6888
6919
  },
6889
6920
  },
6890
- 0x0e82 => {
6921
+ 0x05 => {
6891
6922
  Name => 'ISOAutoHiLimit',
6892
6923
  Mask => 0xff,
6893
6924
  PrintHex => 1,
@@ -6935,7 +6966,7 @@ my %nikonFocalConversions = (
6935
6966
  0x72 => 'ISO Hi 5.0',
6936
6967
  },
6937
6968
  },
6938
- 0x0e84 => {
6969
+ 0x07 => {
6939
6970
  Name => 'FlickerReduction',
6940
6971
  Mask => 0x20,
6941
6972
  PrintConv => {
@@ -6943,7 +6974,7 @@ my %nikonFocalConversions = (
6943
6974
  1 => 'Disable',
6944
6975
  },
6945
6976
  },
6946
- 3716.1 => { # (0x0e84)
6977
+ 7.1 => {
6947
6978
  Name => 'PhotoShootingMenuBankImageArea',
6948
6979
  Mask => 0x07,
6949
6980
  PrintConv => {
@@ -6954,16 +6985,14 @@ my %nikonFocalConversions = (
6954
6985
  4 => '1.3x (18x12)',
6955
6986
  },
6956
6987
  },
6957
- ### 0x0ec4 - ? start
6958
- ### 0x0eeb - CustomSettings start
6959
- 0x0eea => {
6960
- Name => 'Hook5',
6961
- Hidden => 1,
6962
- RawConv => 'undef',
6963
- # account for variable location of CustomSettings data
6964
- Hook => '$varSize = $$self{CustomSettingsOffset} - 0x0eeb',
6965
- },
6966
- 0x0eeb => [{
6988
+ );
6989
+
6990
+ %Image::ExifTool::Nikon::CustomSettingsD500 = (
6991
+ %binaryDataAttrs,
6992
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6993
+ IS_SUBDIR => [ 0x00 ],
6994
+ VARS => { ALLOW_REPROCESS => 1 }, # (necessary because subdirectory is at offset 0)
6995
+ 0x00 => [{
6967
6996
  Name => 'CustomSettingsD5',
6968
6997
  Condition => '$$self{Model} =~ /\bD5\b/',
6969
6998
  Format => 'undef[90]',
@@ -6977,7 +7006,7 @@ my %nikonFocalConversions = (
6977
7006
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD500',
6978
7007
  },
6979
7008
  }],
6980
- # 0x0f68 => { #this decode works, but involves more bits than should be necessary
7009
+ # 0x7d => { #this decode works, but involves more bits than should be necessary
6981
7010
  # Name => 'ShutterTrigger',
6982
7011
  # Mask => 0xff,
6983
7012
  # PrintConv => {
@@ -6986,51 +7015,13 @@ my %nikonFocalConversions = (
6986
7015
  # 195 => 'Shutter Button',
6987
7016
  # },
6988
7017
  # },
6989
- ### 0x2c24 - OrientationInfo start (D5 firmware 1.10b)
6990
- 0x2c23 => {
6991
- Name => 'Hook6',
6992
- Hidden => 1,
6993
- RawConv => 'undef',
6994
- # account for variable location of OrientationInfo data
6995
- Hook => '$varSize = $$self{OrientationOffset} - 0x2c24',
6996
- },
6997
- 0x2c24 => {
6998
- Name => 'RollAngle',
6999
- Format => 'fixed32u',
7000
- Notes => 'converted to degrees of clockwise camera roll',
7001
- ValueConv => '$val <= 180 ? $val : $val - 360',
7002
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7003
- PrintConv => 'sprintf("%.1f", $val)',
7004
- PrintConvInv => '$val',
7005
- },
7006
- 0x2c28 => {
7007
- Name => 'PitchAngle',
7008
- Format => 'fixed32u',
7009
- Notes => 'converted to degrees of upward camera tilt',
7010
- ValueConv => '$val <= 180 ? $val : $val - 360',
7011
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7012
- PrintConv => 'sprintf("%.1f", $val)',
7013
- PrintConvInv => '$val',
7014
- },
7015
- 0x2c2c => {
7016
- Name => 'YawAngle',
7017
- Format => 'fixed32u',
7018
- Notes => 'the camera yaw angle when shooting in portrait orientation',
7019
- ValueConv => '$val <= 180 ? $val : $val - 360',
7020
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7021
- PrintConv => 'sprintf("%.1f", $val)',
7022
- PrintConvInv => '$val',
7023
- },
7024
- ### 0x2c90 - OtherInfo start (D500 firmware 1.20d)
7025
- 0x2c8f => {
7026
- Name => 'Hook7',
7027
- Hidden => 1,
7028
- RawConv => 'undef',
7029
- # account for variable location of OtherInfo data
7030
- Hook => '$varSize = $$self{OtherOffset} - 0x2c90',
7031
- },
7018
+ );
7019
+
7020
+ %Image::ExifTool::Nikon::OtherInfoD500 = (
7021
+ %binaryDataAttrs,
7022
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7032
7023
  # (needs testing)
7033
- #0x2cb2 => {
7024
+ #0x22 => {
7034
7025
  # Name => 'ExtendedPhotoShootingBanks',
7035
7026
  # Mask => 0x01,
7036
7027
  # PrintConv => {
@@ -7039,7 +7030,7 @@ my %nikonFocalConversions = (
7039
7030
  # },
7040
7031
  #},
7041
7032
  # (may not be reliable and is found elsewhere)
7042
- #0x2ea2 => {
7033
+ #0x212 => {
7043
7034
  # Name => 'Rotation',
7044
7035
  # Condition => '$$self{Model} =~ /\bD500\b/',
7045
7036
  # Notes => 'D500 firmware 1.1x',
@@ -7051,7 +7042,7 @@ my %nikonFocalConversions = (
7051
7042
  # 3 => 'Rotate 180',
7052
7043
  # },
7053
7044
  #},
7054
- 0x2ea4 => { #PH
7045
+ 0x214 => { #PH
7055
7046
  Name => 'NikonMeteringMode',
7056
7047
  Condition => '$$self{Model} =~ /\bD500\b/', # (didn't seem to work for D5, but I need more samples)
7057
7048
  Notes => 'D500 only',
@@ -7063,18 +7054,16 @@ my %nikonFocalConversions = (
7063
7054
  3 => 'Highlight'
7064
7055
  },
7065
7056
  },
7066
- # note: DecryptLen currently set to OtherOffset + 0x2ea5 - 0x2c90
7067
7057
  );
7068
7058
 
7069
7059
  # shot information for the D6 firmware 1.00 (encrypted) - ref 28
7070
7060
  %Image::ExifTool::Nikon::ShotInfoD6 = (
7071
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7072
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7061
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7062
+ WRITE_PROC => \&ProcessNikonEncrypted,
7073
7063
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7074
- VARS => { ID_LABEL => 'Index' },
7075
- DATAMEMBER => [ 0x30, 0x60, 0x9c, 0xa4, 0x75e7, 0x760c, 0x7610, 0xc219, 0xc292, 0xc40e, 0xc412, 0xc4a6, 0xc4be ],
7064
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
7065
+ IS_SUBDIR => [ 0x30, 0x9c, 0xa4 ],
7076
7066
  WRITABLE => 1,
7077
- FIRST_ENTRY => 0,
7078
7067
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7079
7068
  NOTES => 'These tags are extracted from encrypted data in images from the D6.',
7080
7069
  0x00 => {
@@ -7089,159 +7078,111 @@ my %nikonFocalConversions = (
7089
7078
  },
7090
7079
  0x24 => {
7091
7080
  Name => 'NumberOffsets', # (number of entries in offset table. offsets are from start of ShotInfo data)
7092
- DataMember => 'NumberOffsets',
7093
7081
  Format => 'int32u',
7094
7082
  Writable => 0,
7095
7083
  Hidden => 1,
7096
7084
  },
7097
7085
  0x30 => {
7098
- Name => 'Offset3',
7099
- DataMember => 'Offset3',
7100
- Format => 'int32u',
7101
- Writable => 0,
7102
- Hidden => 1,
7103
- RawConv => '$$self{Offset3} = $val || 0x10000000; undef', # (ignore if 0)
7104
- },
7105
- 0x60 => {
7106
- Name => 'Offset15',
7107
- DataMember => 'Offset15',
7086
+ Name => 'SequenceOffset',
7108
7087
  Format => 'int32u',
7109
- Writable => 0,
7110
- Hidden => 1,
7111
- RawConv => '$$self{Offset15} = $val || 0x10000000; undef', # (ignore if 0)
7088
+ SubDirectory => {
7089
+ TagTable => 'Image::ExifTool::Nikon::SeqInfoD6',
7090
+ Start => '$val',
7091
+ },
7112
7092
  },
7113
7093
  0x9c => {
7114
7094
  Name => 'OrientationOffset',
7115
- DataMember => 'OrientationOffset',
7116
7095
  Format => 'int32u',
7117
- Writable => 0,
7118
- Hidden => 1,
7119
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
7096
+ SubDirectory => {
7097
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7098
+ Start => '$val',
7099
+ },
7120
7100
  },
7121
7101
  0xa4 => {
7122
- Name => 'Offset32',
7123
- DataMember => 'Offset32',
7102
+ Name => 'IntervalOffset',
7124
7103
  Format => 'int32u',
7125
- Writable => 0,
7126
- Hidden => 1,
7127
- RawConv => '$$self{Offset32} = $val || 0x10000000; undef', # (ignore if 0)
7128
- },
7129
- ### 0x75e8 - Offset3 info start (D6 firmware 1.33)
7130
- 0x75e7 => {
7131
- Name => 'Hook1',
7132
- Hidden => 1,
7133
- RawConv => 'undef',
7134
- # account for variable location of Offset5 data
7135
- Hook => '$varSize = $$self{Offset3} - 0x75e8',
7104
+ SubDirectory => {
7105
+ TagTable => 'Image::ExifTool::Nikon::IntervalInfoD6',
7106
+ Start => '$val',
7107
+ }
7136
7108
  },
7137
- 0x760c => {
7109
+ );
7110
+
7111
+ %Image::ExifTool::Nikon::SeqInfoD6 = (
7112
+ %binaryDataAttrs,
7113
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7114
+ DATAMEMBER => [ 0x24, 0x28 ],
7115
+ 0x24 => {
7138
7116
  Name => 'IntervalShooting',
7139
7117
  RawConv => '$$self{IntervalShooting} = $val',
7140
7118
  Format => 'int16u',
7141
7119
  PrintConv => q{
7142
7120
  return 'Off' if $val == 0 ;
7143
- my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}); #something like "Interval 1 of 3"
7144
- my $f = $$self{IntervalShootingShotsPerInterval} > 1 ? sprintf(" Frame %.0f of %.0f",$$self{IntervalFrame}, $$self{IntervalShootingShotsPerInterval}): '' ; #something like "Frame 1 of 3" or blank
7121
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); #something like "Interval 1 of 3"
7122
+ my $f = ($$self{IntervalShootingShotsPerInterval}||0) > 1 ? sprintf(" Frame %.0f of %.0f",$$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0): '' ; #something like "Frame 1 of 3" or blank
7145
7123
  return "On: $i$f"
7146
- #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}, $$self{IntervalFrame}, $$self{IntervalShootingShotsPerInterval}),
7124
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
7147
7125
  },
7148
7126
  },
7149
- 0x7610 => {
7127
+ 0x28 => {
7150
7128
  Name => 'IntervalFrame',
7151
7129
  RawConv => '$$self{IntervalFrame} = $val',
7152
7130
  Condition => '$$self{IntervalShooting} > 0',
7153
7131
  Format => 'int16u',
7154
7132
  Hidden => 1,
7155
7133
  },
7156
- ### 0xc21a - OrientationInfo start (D6 firmware 1.00) (0xc952 for firmware 1.33)
7157
- 0xc219 => {
7158
- Name => 'Hook2',
7159
- Hidden => 1,
7160
- RawConv => 'undef',
7161
- # account for variable location of OrientationInfo data
7162
- Hook => '$varSize = $$self{OrientationOffset} - 0xc21a',
7163
- },
7164
- 0xc21a => {
7165
- Name => 'RollAngle',
7166
- Format => 'fixed32u',
7167
- Notes => 'converted to degrees of clockwise camera roll',
7168
- ValueConv => '$val <= 180 ? $val : $val - 360',
7169
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7170
- PrintConv => 'sprintf("%.1f", $val)',
7171
- PrintConvInv => '$val',
7172
- },
7173
- 0xc21e => {
7174
- Name => 'PitchAngle',
7175
- Format => 'fixed32u',
7176
- Notes => 'converted to degrees of upward camera tilt',
7177
- ValueConv => '$val <= 180 ? $val : $val - 360',
7178
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7179
- PrintConv => 'sprintf("%.1f", $val)',
7180
- PrintConvInv => '$val',
7181
- },
7182
- 0xc222 => {
7183
- Name => 'YawAngle',
7184
- Format => 'fixed32u',
7185
- Notes => 'the camera yaw angle when shooting in portrait orientation',
7186
- ValueConv => '$val <= 180 ? $val : $val - 360',
7187
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7188
- PrintConv => 'sprintf("%.1f", $val)',
7189
- PrintConvInv => '$val',
7190
- },
7191
- ### 0xc9c6 - Offset32 start (D6 firmware 1.33)
7192
- 0xc292 => {
7193
- Name => 'Hook3',
7194
- Hidden => 1,
7195
- RawConv => 'undef',
7196
- # account for variable location of data
7197
- Hook => '$varSize = $$self{Offset32} - 0xc292',
7198
- },
7199
- 0xc40e => {
7134
+ );
7135
+
7136
+ %Image::ExifTool::Nikon::IntervalInfoD6 = (
7137
+ %binaryDataAttrs,
7138
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7139
+ DATAMEMBER => [ 0x17c, 0x180, 0x214, 0x22c ],
7140
+ 0x17c => {
7200
7141
  Name => 'Intervals',
7201
7142
  Format => 'int32u',
7202
7143
  RawConv => '$$self{IntervalShootingIntervals} = $val',
7203
7144
  Condition => '$$self{IntervalShooting} > 0',
7204
7145
  },
7205
- 0xc412 => {
7146
+ 0x180 => {
7206
7147
  Name => 'ShotsPerInterval',
7207
7148
  Format => 'int32u',
7208
7149
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
7209
7150
  Condition => '$$self{IntervalShooting} > 0',
7210
7151
  },
7211
- 0xc416 => {
7152
+ 0x184 => {
7212
7153
  Name => 'IntervalExposureSmoothing',
7213
7154
  Condition => '$$self{IntervalShooting} > 0',
7214
7155
  Format => 'int8u',
7215
7156
  PrintConv => \%offOn,
7216
7157
  },
7217
- 0xc418 => {
7158
+ 0x186 => {
7218
7159
  Name => 'IntervalPriority',
7219
7160
  Condition => '$$self{IntervalShooting} > 0',
7220
7161
  Format => 'int8u',
7221
7162
  PrintConv => \%offOn,
7222
7163
  },
7223
- 0xc43a => {
7164
+ 0x1a8 => {
7224
7165
  Name => 'FocusShiftNumberShots',
7225
7166
  },
7226
- 0xc43e => {
7167
+ 0x1ac => {
7227
7168
  Name => 'FocusShiftStepWidth',
7228
7169
  },
7229
- 0xc442 => {
7170
+ 0x1b0 => {
7230
7171
  Name => 'FocusShiftInterval',
7231
7172
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
7232
7173
  },
7233
- 0xc446 => {
7174
+ 0x1b4 => {
7234
7175
  Name => 'FocusShiftExposureLock',
7235
7176
  PrintConv => \%offOn,
7236
7177
  },
7237
- #0xc49c => HighISONoiseReduction
7238
- 0xc4a0 => {
7178
+ #0x20a => HighISONoiseReduction
7179
+ 0x20e => {
7239
7180
  Name => 'DiffractionCompensation',
7240
7181
  Format => 'int8u',
7241
7182
  PrintConv => \%offOn,
7242
7183
  },
7243
- #0xc4a1 => {Name => 'FlickerReductionShooting',}, #redundant with tag in NikonSettings
7244
- 0xc4a6 => {
7184
+ #0x20f => {Name => 'FlickerReductionShooting',}, #redundant with tag in NikonSettings
7185
+ 0x214 => {
7245
7186
  Name => 'FlashControlMode', #this and nearby tag values for flash may be set from either the Photo Shooting Menu or using the Flash unit menu
7246
7187
  RawConv => '$$self{FlashControlMode} = $val',
7247
7188
  PrintConv => {
@@ -7252,14 +7193,14 @@ my %nikonFocalConversions = (
7252
7193
  4 => 'Repeating Flash',
7253
7194
  },
7254
7195
  },
7255
- 0xc4ac => {
7196
+ 0x21a => {
7256
7197
  Name => 'FlashGNDistance',
7257
7198
  Condition => '$$self{FlashControlMode} == 2',
7258
7199
  Unknown => 1,
7259
7200
  ValueConv => '$val + 3',
7260
7201
  PrintConv => \%flashGNDistance,
7261
7202
  },
7262
- 0xc4b0 => {
7203
+ 0x21e => {
7263
7204
  Name => 'FlashOutput', #range[0,24] with 0=>Full; 1=>50%; then decreasing flash power in 1/3 stops to 0.39% (1/256 full power). #also found in FlashInfoUnknown at offset 0x0a (with different mappings)
7264
7205
  Condition => '$$self{FlashControlMode} >= 3',
7265
7206
  Unknown => 1,
@@ -7268,7 +7209,7 @@ my %nikonFocalConversions = (
7268
7209
  PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
7269
7210
  PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
7270
7211
  },
7271
- 0xc4ba => {
7212
+ 0x228 => {
7272
7213
  Name => 'FlashRemoteControl',
7273
7214
  Unknown => 1,
7274
7215
  PrintConv => {
@@ -7277,12 +7218,12 @@ my %nikonFocalConversions = (
7277
7218
  2 => 'Remote Repeating',
7278
7219
  },
7279
7220
  },
7280
- 0xc4be => {
7221
+ 0x22c => {
7281
7222
  Name => 'FlashMasterControlMode', #tag name chosen for compatibility with those found in FlashInfo0102 & FlashInfo0103
7282
7223
  RawConv => '$$self{FlashGroupOptionsMasterMode} = $val',
7283
7224
  PrintConv => \%flashGroupOptionsMode,
7284
7225
  },
7285
- 0xc4c0 => {
7226
+ 0x22e => {
7286
7227
  Name => 'FlashMasterCompensation',
7287
7228
  Unknown => 1,
7288
7229
  Format => 'int8s',
@@ -7292,7 +7233,7 @@ my %nikonFocalConversions = (
7292
7233
  PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
7293
7234
  PrintConvInv => '$val',
7294
7235
  },
7295
- 0xc4c4 => {
7236
+ 0x232 => {
7296
7237
  Name => 'FlashMasterOutput',
7297
7238
  Unknown => 1,
7298
7239
  Condition => '$$self{FlashGroupOptionsMasterMode} == 1', #only for Mode=M
@@ -7301,7 +7242,7 @@ my %nikonFocalConversions = (
7301
7242
  PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
7302
7243
  PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
7303
7244
  },
7304
- 0xc4c6 => {
7245
+ 0x234 => {
7305
7246
  Name => 'FlashWirelessOption',
7306
7247
  Unknown => 1,
7307
7248
  PrintConv => {
@@ -7309,7 +7250,7 @@ my %nikonFocalConversions = (
7309
7250
  1 => 'Off',
7310
7251
  },
7311
7252
  },
7312
- 0xc55c => {
7253
+ 0x2ca => {
7313
7254
  Name => 'MovieType',
7314
7255
  Unknown => 1,
7315
7256
  PrintConv => {
@@ -7317,13 +7258,12 @@ my %nikonFocalConversions = (
7317
7258
  1 => 'MP4',
7318
7259
  },
7319
7260
  },
7320
- # note: DecryptLen currently set to 0xc9c6 + 720
7321
7261
  );
7322
7262
 
7323
7263
  # shot information for the D610 firmware 1.00 (encrypted) - ref PH
7324
7264
  %Image::ExifTool::Nikon::ShotInfoD610 = (
7325
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7326
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7265
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7266
+ WRITE_PROC => \&ProcessNikonEncrypted,
7327
7267
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7328
7268
  VARS => { ID_LABEL => 'Index' },
7329
7269
  IS_SUBDIR => [ 0x07cf ],
@@ -7348,25 +7288,19 @@ my %nikonFocalConversions = (
7348
7288
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD610',
7349
7289
  },
7350
7290
  },
7351
- # note: DecryptLen currently set to 0x7ff
7352
7291
  );
7353
7292
 
7354
7293
  # shot information for the D810 firmware 1.00(PH)/1.01 (encrypted) - ref 28
7355
7294
  %Image::ExifTool::Nikon::ShotInfoD810 = (
7356
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7357
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7295
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7296
+ WRITE_PROC => \&ProcessNikonEncrypted,
7358
7297
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7359
- VARS => { ID_LABEL => 'Index' },
7360
- DATAMEMBER => [ 0x04, 0x24, 0x38, 0x40, 0x84, 0x01d0, 0x175e, 0x185d, 0x18ab ],
7361
- IS_SUBDIR => [ 0x18ab ],
7298
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
7299
+ DATAMEMBER => [ 0x04 ],
7300
+ IS_SUBDIR => [ 0x10, 0x24, 0x38, 0x40, 0x84 ],
7362
7301
  WRITABLE => 1,
7363
- FIRST_ENTRY => 0,
7364
7302
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7365
- NOTES => q{
7366
- These tags are extracted from encrypted data in images from the D810. Note
7367
- that the indices listed below are for firmware version 1.0, but they may be
7368
- different for other firmware versions.
7369
- },
7303
+ NOTES => 'These tags are extracted from encrypted data in images from the D810.',
7370
7304
  0x00 => {
7371
7305
  Name => 'ShotInfoVersion',
7372
7306
  Format => 'string[4]',
@@ -7381,39 +7315,64 @@ my %nikonFocalConversions = (
7381
7315
  },
7382
7316
  # 0x0c - number of entries in offset table (= 0x21)
7383
7317
  # 0x10 - int32u[val 0x0c]: offset table
7318
+ 0x10 => {
7319
+ Name => 'SettingsOffset',
7320
+ Format => 'int32u',
7321
+ SubDirectory => {
7322
+ TagTable => 'Image::ExifTool::Nikon::SettingsInfoD810',
7323
+ Start => '$val',
7324
+ },
7325
+ },
7384
7326
  0x24 => {
7385
7327
  Name => 'BracketingOffset',
7386
- DataMember => 'BracketingOffset',
7387
7328
  Format => 'int32u',
7388
- Writable => 0,
7389
- Hidden => 1,
7390
- RawConv => '$$self{BracketingOffset} = $val || 0x10000000; undef',
7329
+ SubDirectory => {
7330
+ TagTable => 'Image::ExifTool::Nikon::BracketingInfoD810',
7331
+ Start => '$val',
7332
+ },
7391
7333
  },
7392
7334
  0x38 => {
7393
7335
  Name => 'ISOAutoOffset',
7394
- DataMember => 'ISOAutoOffset',
7395
7336
  Format => 'int32u',
7396
- Writable => 0,
7397
- Hidden => 1,
7398
- RawConv => '$$self{ISOAutoOffset} = $val || 0x10000000; undef',
7337
+ SubDirectory => {
7338
+ TagTable => 'Image::ExifTool::Nikon::ISOAutoInfoD810',
7339
+ Start => '$val',
7340
+ },
7399
7341
  },
7400
7342
  0x40 => {
7401
7343
  Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
7402
- DataMember => 'CustomSettingsOffset',
7403
7344
  Format => 'int32u',
7404
- Writable => 0,
7405
- Hidden => 1,
7406
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
7345
+ SubDirectory => {
7346
+ TagTable => 'Image::ExifTool::NikonCustom::SettingsD810',
7347
+ Start => '$val',
7348
+ },
7407
7349
  },
7408
7350
  0x84 => {
7409
7351
  Name => 'OrientationOffset',
7410
- DataMember => 'OrientationOffset',
7411
7352
  Format => 'int32u',
7412
- Writable => 0,
7413
- Hidden => 1,
7414
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
7353
+ SubDirectory => {
7354
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7355
+ Start => '$val',
7356
+ }
7415
7357
  },
7416
- 0x01d0 => {
7358
+ # (moves around too much and doesn't fit cleanly in the offset table)
7359
+ #0x38be => {
7360
+ # Name => 'Rotation',
7361
+ # Condition => '$$self{FirmwareVersion} =~ /^1\.0/',
7362
+ # Mask => 0x30,
7363
+ # PrintConv => {
7364
+ # 0 => 'Horizontal',
7365
+ # 1 => 'Rotate 270 CW',
7366
+ # 2 => 'Rotate 90 CW',
7367
+ # 3 => 'Rotate 180',
7368
+ # },
7369
+ #},
7370
+ );
7371
+
7372
+ %Image::ExifTool::Nikon::SettingsInfoD810 = (
7373
+ %binaryDataAttrs,
7374
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7375
+ 0x13c => {
7417
7376
  Name => 'SecondarySlotFunction',
7418
7377
  Mask => 0x03,
7419
7378
  PrintConv => {
@@ -7421,9 +7380,13 @@ my %nikonFocalConversions = (
7421
7380
  2 => 'Backup',
7422
7381
  3 => 'NEF Primary + JPG Secondary',
7423
7382
  },
7424
- Hook => '$varSize = $$self{BracketingOffset} - 0x1747',
7425
7383
  },
7426
- 0x1756 => {
7384
+ );
7385
+
7386
+ %Image::ExifTool::Nikon::BracketingInfoD810 = (
7387
+ %binaryDataAttrs,
7388
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7389
+ 0x0f => {
7427
7390
  Name => 'AEBracketingSteps',
7428
7391
  Mask => 0xff,
7429
7392
  PrintHex => 1,
@@ -7480,7 +7443,7 @@ my %nikonFocalConversions = (
7480
7443
  0xd6 => '5F3',
7481
7444
  },
7482
7445
  },
7483
- 0x1757 => {
7446
+ 0x10 => {
7484
7447
  Name => 'WBBracketingSteps',
7485
7448
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
7486
7449
  Mask => 0xff,
@@ -7523,7 +7486,7 @@ my %nikonFocalConversions = (
7523
7486
  0x28 => '9F 3',
7524
7487
  },
7525
7488
  },
7526
- 0x175e => {
7489
+ 0x17 => {
7527
7490
  Name => 'NikonMeteringMode',
7528
7491
  Mask => 0x03,
7529
7492
  PrintConv => {
@@ -7532,9 +7495,13 @@ my %nikonFocalConversions = (
7532
7495
  2 => 'Spot',
7533
7496
  3 => 'Highlight'
7534
7497
  },
7535
- Hook => '$varSize = $$self{ISOAutoOffset} - 0x1858',
7536
7498
  },
7537
- 0x185c => {
7499
+ );
7500
+
7501
+ %Image::ExifTool::Nikon::ISOAutoInfoD810 = (
7502
+ %binaryDataAttrs,
7503
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7504
+ 0x04 => {
7538
7505
  Name => 'ISOAutoShutterTime',
7539
7506
  Mask => 0x3f,
7540
7507
  PrintConv => {
@@ -7577,7 +7544,7 @@ my %nikonFocalConversions = (
7577
7544
  36 => 'Auto (Fastest)',
7578
7545
  },
7579
7546
  },
7580
- 0x185d => {
7547
+ 0x05 => {
7581
7548
  Name => 'ISOAutoHiLimit',
7582
7549
  Mask => 0xff,
7583
7550
  PrintHex => 1,
@@ -7624,69 +7591,18 @@ my %nikonFocalConversions = (
7624
7591
  0x6c => 'ISO Hi 4.0',
7625
7592
  0x72 => 'ISO Hi 5.0',
7626
7593
  },
7627
- Hook => '$varSize = $$self{CustomSettingsOffset} - 0x18ab',
7628
- },
7629
- 0x18ab => { # (actual offset adjusted by Hook above)
7630
- Name => 'CustomSettingsD810',
7631
- Format => 'undef[53]',
7632
- SubDirectory => {
7633
- TagTable => 'Image::ExifTool::NikonCustom::SettingsD810',
7634
- },
7635
- Hook => '$varSize = $$self{OrientationOffset} - 0x36f4',
7636
- },
7637
- 0x36f4 => {
7638
- Name => 'RollAngle',
7639
- Format => 'fixed32u',
7640
- Notes => 'converted to degrees of clockwise camera roll',
7641
- ValueConv => '$val <= 180 ? $val : $val - 360',
7642
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7643
- PrintConv => 'sprintf("%.1f", $val)',
7644
- PrintConvInv => '$val',
7645
- },
7646
- 0x36f8 => {
7647
- Name => 'PitchAngle',
7648
- Format => 'fixed32u',
7649
- Notes => 'converted to degrees of upward camera tilt',
7650
- ValueConv => '$val <= 180 ? $val : $val - 360',
7651
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7652
- PrintConv => 'sprintf("%.1f", $val)',
7653
- PrintConvInv => '$val',
7654
- },
7655
- 0x36fc => {
7656
- Name => 'YawAngle',
7657
- Format => 'fixed32u',
7658
- Notes => 'the camera yaw angle when shooting in portrait orientation',
7659
- ValueConv => '$val <= 180 ? $val : $val - 360',
7660
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7661
- PrintConv => 'sprintf("%.1f", $val)',
7662
- PrintConvInv => '$val',
7663
7594
  },
7664
- # note: DecryptLen currently set to OrientationOffset + 12
7665
-
7666
- # (moves around too much and doesn't fit cleanly in the offset table)
7667
- #0x38be => {
7668
- # Name => 'Rotation',
7669
- # Condition => '$$self{FirmwareVersion} =~ /^1\.0/',
7670
- # Mask => 0x30,
7671
- # PrintConv => {
7672
- # 0 => 'Horizontal',
7673
- # 1 => 'Rotate 270 CW',
7674
- # 2 => 'Rotate 90 CW',
7675
- # 3 => 'Rotate 180',
7676
- # },
7677
- #},
7678
7595
  );
7679
7596
 
7680
7597
  # shot information for the D850 firmware 1.00b (encrypted) - ref 28
7681
7598
  %Image::ExifTool::Nikon::ShotInfoD850 = (
7682
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7683
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7599
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7600
+ WRITE_PROC => \&ProcessNikonEncrypted,
7684
7601
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7685
- VARS => { ID_LABEL => 'Index' },
7686
- DATAMEMBER => [ 0x04, 0x58, 0xa0, 0x0fbf, 0x2efa ],
7687
- IS_SUBDIR => [ 0x1038 ],
7602
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
7603
+ DATAMEMBER => [ 0x04 ],
7604
+ IS_SUBDIR => [ 0x10, 0x4c, 0x58, 0xa0 ],
7688
7605
  WRITABLE => 1,
7689
- FIRST_ENTRY => 0,
7690
7606
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7691
7607
  NOTES => 'These tags are extracted from encrypted data in images from the D850.',
7692
7608
  0x00 => {
@@ -7701,23 +7617,44 @@ my %nikonFocalConversions = (
7701
7617
  Writable => 0,
7702
7618
  RawConv => '$$self{FirmwareVersion} = $val',
7703
7619
  },
7620
+ 0x10 => {
7621
+ Name => 'MenuSettingsOffset',
7622
+ Format => 'int32u',
7623
+ SubDirectory => {
7624
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsD850',
7625
+ Start => '$val',
7626
+ },
7627
+ },
7628
+ 0x4c => {
7629
+ Name => 'MoreSettingsOffset',
7630
+ Format => 'int32u',
7631
+ SubDirectory => {
7632
+ TagTable => 'Image::ExifTool::Nikon::MoreSettingsD850',
7633
+ Start => '$val',
7634
+ },
7635
+ },
7704
7636
  0x58 => {
7705
- Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
7706
- DataMember => 'CustomSettingsOffset',
7637
+ Name => 'CustomSettingsOffset',
7707
7638
  Format => 'int32u',
7708
- Writable => 0,
7709
- Hidden => 1,
7710
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
7639
+ SubDirectory => {
7640
+ TagTable => 'Image::ExifTool::NikonCustom::SettingsD850',
7641
+ Start => '$val',
7642
+ },
7711
7643
  },
7712
7644
  0xa0 => {
7713
7645
  Name => 'OrientationOffset',
7714
- DataMember => 'OrientationOffset',
7715
7646
  Format => 'int32u',
7716
- Writable => 0,
7717
- Hidden => 1,
7718
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
7647
+ SubDirectory => {
7648
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7649
+ Start => '$val',
7650
+ },
7719
7651
  },
7720
- 0x0791 => {
7652
+ );
7653
+
7654
+ %Image::ExifTool::Nikon::MenuSettingsD850 = (
7655
+ %binaryDataAttrs,
7656
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7657
+ 0x06dd => {
7721
7658
  Name => 'PhotoShootingMenuBankImageArea',
7722
7659
  Mask => 0x07,
7723
7660
  PrintConv => {
@@ -7728,7 +7665,12 @@ my %nikonFocalConversions = (
7728
7665
  4 => '1:1 (24x24)',
7729
7666
  },
7730
7667
  },
7731
- 0x0fbd => {
7668
+ );
7669
+
7670
+ %Image::ExifTool::Nikon::MoreSettingsD850 = (
7671
+ %binaryDataAttrs,
7672
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7673
+ 0x24 => {
7732
7674
  Name => 'PhotoShootingMenuBank',
7733
7675
  Condition => '$$self{FILE_TYPE} eq "JPEG"',
7734
7676
  Notes => 'valid for JPEG images only',
@@ -7740,63 +7682,20 @@ my %nikonFocalConversions = (
7740
7682
  3 => 'D',
7741
7683
  },
7742
7684
  },
7743
- 0x0fbf => {
7685
+ 0x25 => {
7744
7686
  Name => 'PrimarySlot',
7745
7687
  Mask => 0x80,
7746
7688
  PrintConv => {
7747
7689
  0 => 'XQD Card',
7748
7690
  1 => 'SD Card',
7749
7691
  },
7750
- Hook => '$varSize = $$self{CustomSettingsOffset} - 0x1038',
7751
- },
7752
- 0x1038 => {
7753
- Name => 'CustomSettingsD850',
7754
- Format => 'undef[90]',
7755
- SubDirectory => {
7756
- TagTable => 'Image::ExifTool::NikonCustom::SettingsD850',
7757
- },
7758
- },
7759
- ### 0x2efb - OrientationInfo start (D850 firmware 1.01a)
7760
- 0x2efa => {
7761
- Name => 'Hook1',
7762
- Hidden => 1,
7763
- RawConv => 'undef',
7764
- # account for variable location of OrientationInfo data
7765
- Hook => '$varSize = $$self{OrientationOffset} - 0x2efb',
7766
- },
7767
- 0x2efb => { #28
7768
- Name => 'RollAngle',
7769
- Format => 'fixed32u',
7770
- Notes => 'converted to degrees of clockwise camera roll',
7771
- ValueConv => '$val <= 180 ? $val : $val - 360',
7772
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7773
- PrintConv => 'sprintf("%.1f", $val)',
7774
- PrintConvInv => '$val',
7775
- },
7776
- 0x2eff => { #28
7777
- Name => 'PitchAngle',
7778
- Format => 'fixed32u',
7779
- Notes => 'converted to degrees of upward camera tilt',
7780
- ValueConv => '$val <= 180 ? $val : $val - 360',
7781
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7782
- PrintConv => 'sprintf("%.1f", $val)',
7783
- PrintConvInv => '$val',
7784
- },
7785
- 0x2f03 => { #28
7786
- Name => 'YawAngle',
7787
- Format => 'fixed32u',
7788
- Notes => 'the camera yaw angle when shooting in portrait orientation',
7789
- ValueConv => '$val <= 180 ? $val : $val - 360',
7790
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7791
- PrintConv => 'sprintf("%.1f", $val)',
7792
- PrintConvInv => '$val',
7793
7692
  },
7794
- # note: DecryptLen currently set to 0x2f07
7795
7693
  );
7694
+
7796
7695
  # shot information for the D4 firmware 1.00g (ref PH)
7797
7696
  %Image::ExifTool::Nikon::ShotInfoD4 = (
7798
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7799
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7697
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7698
+ WRITE_PROC => \&ProcessNikonEncrypted,
7800
7699
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7801
7700
  VARS => { ID_LABEL => 'Index' },
7802
7701
  IS_SUBDIR => [ 0x0751 ],
@@ -7822,17 +7721,16 @@ my %nikonFocalConversions = (
7822
7721
  Format => 'undef[56]',
7823
7722
  SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsD4' },
7824
7723
  },
7825
- # note: DecryptLen currently set to 0x789
7826
7724
  );
7827
7725
 
7828
7726
  # shot information for the D4S firmware 1.01a (ref 28, encrypted)
7829
7727
  %Image::ExifTool::Nikon::ShotInfoD4S = (
7830
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7831
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7728
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7729
+ WRITE_PROC => \&ProcessNikonEncrypted,
7832
7730
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7833
7731
  VARS => { ID_LABEL => 'Index' },
7834
7732
  DATAMEMBER => [ 4 ],
7835
- IS_SUBDIR => [ 0x189d, 0x193d ],
7733
+ IS_SUBDIR => [ 0x189d, 0x193d, 0x350b ],
7836
7734
  WRITABLE => 1,
7837
7735
  FIRST_ENTRY => 0,
7838
7736
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
@@ -8096,31 +7994,13 @@ my %nikonFocalConversions = (
8096
7994
  # },
8097
7995
  # },
8098
7996
  0x350b => {
8099
- Name => 'RollAngle',
8100
- Format => 'fixed32u',
8101
- Notes => 'converted to degrees of clockwise camera roll',
8102
- ValueConv => '$val < 180 ? -$val : 360 - $val',
8103
- ValueConvInv => '$val <= 0 ? -$val : 360 - $val',
8104
- PrintConv => 'sprintf("%.1f", $val)',
8105
- PrintConvInv => '$val',
8106
- },
8107
- 0x350f => {
8108
- Name => 'PitchAngle',
8109
- Format => 'fixed32u',
8110
- Notes => 'converted to degrees of upward camera tilt',
8111
- ValueConv => '$val <= 180 ? $val : $val - 360',
8112
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8113
- PrintConv => 'sprintf("%.1f", $val)',
8114
- PrintConvInv => '$val',
8115
- },
8116
- 0x3513 => {
8117
- Name => 'YawAngle',
8118
- Format => 'fixed32u',
8119
- Notes => 'the camera yaw angle when shooting in portrait orientation',
8120
- ValueConv => '$val <= 180 ? $val : $val - 360',
8121
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8122
- PrintConv => 'sprintf("%.1f", $val)',
8123
- PrintConvInv => '$val',
7997
+ Name => 'OrientationInfo',
7998
+ Format => 'undef[12]',
7999
+ SubDirectory => {
8000
+ # Note: pitch angle may be wrong sign for this model?
8001
+ # (pitch sign was changed without verification to use same decoding as other models)
8002
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8003
+ },
8124
8004
  },
8125
8005
  0x3693 => {
8126
8006
  Name => 'Rotation',
@@ -8132,20 +8012,17 @@ my %nikonFocalConversions = (
8132
8012
  3 => 'Rotate 180',
8133
8013
  },
8134
8014
  },
8135
- # note: DecryptLen currently set to 0x3697
8136
8015
  );
8137
8016
 
8138
8017
  # shot information for the Z7II firmware 1.00 (encrypted) - ref 28
8139
8018
  %Image::ExifTool::Nikon::ShotInfoZ7II = (
8140
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8141
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8019
+ PROCESS_PROC => \&ProcessNikonEncrypted,
8020
+ WRITE_PROC => \&ProcessNikonEncrypted,
8142
8021
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
8143
- VARS => { ID_LABEL => 'Index' },
8144
- DATAMEMBER => [ 0x04, 0x30, 0x38, 0x98, 0xa0, 0x75e7, 0x760c,
8145
- 0x7610, 0x7eff, 0xce31, 0xcea5, 0xceb6, 0xceb7 ],
8146
- IS_SUBDIR => [ 0xceb8 ],
8022
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
8023
+ DATAMEMBER => [ 0x04 ],
8024
+ IS_SUBDIR => [ 0x30, 0x38, 0x98, 0xa0 ],
8147
8025
  WRITABLE => 1,
8148
- FIRST_ENTRY => 0,
8149
8026
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8150
8027
  NOTES => 'These tags are extracted from encrypted data in images from the Z7II.',
8151
8028
  0x00 => {
@@ -8174,79 +8051,73 @@ my %nikonFocalConversions = (
8174
8051
  },
8175
8052
  0x24 => {
8176
8053
  Name => 'NumberOffsets', # number of entries in offset table. offsets are from start of ShotInfo data.
8177
- DataMember => 'NumberOffsets',
8178
8054
  Format => 'int32u',
8179
8055
  Writable => 0,
8180
8056
  Hidden => 1,
8181
8057
  },
8182
8058
  0x30 => {
8183
- Name => 'Offset3',
8184
- DataMember => 'Offset3',
8059
+ Name => 'IntervalOffset',
8185
8060
  Format => 'int32u',
8186
- Writable => 0,
8187
- Hidden => 1,
8188
- RawConv => '$$self{Offset3} = $val || 0x10000000; undef', # (ignore if 0)
8061
+ SubDirectory => {
8062
+ TagTable => 'Image::ExifTool::Nikon::IntervalInfoZ7II',
8063
+ Start => '$val',
8064
+ }
8189
8065
  },
8190
8066
  0x38 => {
8191
- Name => 'Offset5',
8192
- DataMember => 'Offset5',
8067
+ Name => 'PortraitOffset',
8193
8068
  Format => 'int32u',
8194
- Writable => 0,
8195
- Hidden => 1,
8196
- RawConv => '$$self{Offset5} = $val || 0x10000000; undef', # (ignore if 0)
8069
+ SubDirectory => {
8070
+ TagTable => 'Image::ExifTool::Nikon::PortraitInfoZ7II',
8071
+ Start => '$val',
8072
+ }
8197
8073
  },
8198
8074
  0x98 => {
8199
8075
  Name => 'OrientationOffset',
8200
- DataMember => 'OrientationOffset',
8201
8076
  Format => 'int32u',
8202
- Writable => 0,
8203
- Hidden => 1,
8204
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
8077
+ SubDirectory => {
8078
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8079
+ Start => '$val',
8080
+ }
8205
8081
  },
8206
8082
  0xa0 => {
8207
- Name => 'Offset31',
8208
- DataMember => 'Offset31',
8083
+ Name => 'MenuOffset',
8209
8084
  Format => 'int32u',
8210
- Writable => 0,
8211
- Hidden => 1,
8212
- RawConv => '$$self{Offset31} = $val || 0x10000000; undef', # (ignore if 0)
8213
- },
8214
- ### 0x75e8 - Offset3 info start (Z7II firmware 1.30)
8215
- 0x75e7 => {
8216
- Name => 'Hook1',
8217
- Hidden => 1,
8218
- RawConv => 'undef',
8219
- # account for variable location of Offset3 data
8220
- Hook => '$varSize = $$self{Offset3} - 0x75e8',
8085
+ SubDirectory => {
8086
+ TagTable => 'Image::ExifTool::Nikon::MenuInfoZ7II',
8087
+ Start => '$val',
8088
+ },
8221
8089
  },
8222
- 0x760c => {
8090
+ );
8091
+
8092
+ %Image::ExifTool::Nikon::IntervalInfoZ7II = (
8093
+ %binaryDataAttrs,
8094
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8095
+ DATAMEMBER => [ 0x24, 0x28 ],
8096
+ 0x24 => {
8223
8097
  Name => 'IntervalShooting',
8224
8098
  RawConv => '$$self{IntervalShooting} = $val',
8225
8099
  Format => 'int16u',
8226
8100
  PrintConv => q{
8227
8101
  return 'Off' if $val == 0 ;
8228
- my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}); # something like "Interval 1 of 3"
8229
- my $f = $$self{IntervalShootingShotsPerInterval} > 1 ? sprintf(" Frame %.0f of %.0f",$$self{IntervalFrame}, $$self{IntervalShootingShotsPerInterval}): '' ; # something like "Frame 1 of 3" or blank
8102
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); # something like "Interval 1 of 3"
8103
+ my $f = ($$self{IntervalShootingShotsPerInterval}||0) > 1 ? sprintf(" Frame %.0f of %.0f",$$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0): '' ; # something like "Frame 1 of 3" or blank
8230
8104
  return "On: $i$f"
8231
- #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}, $$self{IntervalFrame}, $$self{IntervalShootingShotsPerInterval}),
8105
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
8232
8106
  },
8233
8107
  },
8234
- 0x7610 => {
8108
+ 0x28 => {
8235
8109
  Name => 'IntervalFrame',
8236
8110
  RawConv => '$$self{IntervalFrame} = $val',
8237
8111
  Condition => '$$self{IntervalShooting} > 0',
8238
8112
  Format => 'int16u',
8239
8113
  Hidden => 1,
8240
8114
  },
8241
- ### 0x7f00 - Offset5 info start (Z7II firmware 1.30)
8242
- 0x7eff => {
8243
- Name => 'Hook2',
8244
- Hidden => 1,
8245
- RawConv => 'undef',
8246
- # account for variable location of Offset5 data
8247
- Hook => '$varSize = $$self{Offset5} - 0x7f00',
8248
- },
8249
- 0x7fa0 => { #28
8115
+ );
8116
+
8117
+ %Image::ExifTool::Nikon::PortraitInfoZ7II = (
8118
+ %binaryDataAttrs,
8119
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8120
+ 0xa0 => { #28
8250
8121
  Name => 'PortraitImpressionBalance', # will be 0 for firmware 1.21 and earlier; firmware 1.30 onward: will be set by Photo Shooting Menu entry Portrait Impression Balance
8251
8122
  # offset5+160; 128 is neutral; >128 increases Yellow; <128 increases Magenta; increments of 4 result from 1 full unit adjustment on the camera
8252
8123
  # offset5+161 128 is neutral; >128 increases Brightness; <128 decreases Brightness
@@ -8262,89 +8133,37 @@ my %nikonFocalConversions = (
8262
8133
  return "$color $brightness"
8263
8134
  },
8264
8135
  },
8265
- ### 0xce32 - OrientationInfo start (Z7II firmware 1.00)
8266
- 0xce31 => {
8267
- Name => 'Hook3',
8268
- Hidden => 1,
8269
- RawConv => 'undef',
8270
- # account for variable location of OrientationInfo data
8271
- Hook => '$varSize = $$self{OrientationOffset} - 0xce32',
8136
+ );
8137
+
8138
+ %Image::ExifTool::Nikon::MenuInfoZ7II = (
8139
+ %binaryDataAttrs,
8140
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8141
+ IS_SUBDIR => [ 0x10 ],
8142
+ 0x10 => {
8143
+ Name => 'MenuSettingsOffsetZ7II',
8144
+ Format => 'int32u',
8145
+ SubDirectory => {
8146
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ7II',
8147
+ Start => '$dirStart + $val',
8148
+ },
8272
8149
  },
8150
+ );
8273
8151
 
8274
- 0xce32 => {
8275
- Name => 'RollAngle',
8276
- Format => 'fixed32u',
8277
- Notes => 'converted to degrees of clockwise camera roll',
8278
- ValueConv => '$val <= 180 ? $val : $val - 360',
8279
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8280
- PrintConv => 'sprintf("%.1f", $val)',
8281
- PrintConvInv => '$val',
8282
- },
8283
- 0xce36 => {
8284
- Name => 'PitchAngle',
8285
- Format => 'fixed32u',
8286
- Notes => 'converted to degrees of upward camera tilt',
8287
- ValueConv => '$val <= 180 ? $val : $val - 360',
8288
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8289
- PrintConv => 'sprintf("%.1f", $val)',
8290
- PrintConvInv => '$val',
8291
- },
8292
- 0xce3a => {
8293
- Name => 'YawAngle',
8294
- Format => 'fixed32u',
8295
- Notes => 'the camera yaw angle when shooting in portrait orientation',
8296
- ValueConv => '$val <= 180 ? $val : $val - 360',
8297
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8298
- PrintConv => 'sprintf("%.1f", $val)',
8299
- PrintConvInv => '$val',
8300
- },
8301
- 0xcea5 => {
8302
- Name => 'Hook4',
8303
- Hidden => 1,
8304
- RawConv => 'undef',
8305
- # account for variable location of Offset31 data
8306
- Hook => '$varSize = $$self{Offset31} - 0xcea6',
8307
- },
8308
- ### 0xcea6 - Offset31 info start (Z7II firmware 1.30)
8309
- 0xceb6 => {
8310
- Name => 'MenuSettingsZ7IIOffset',
8311
- # offset to MenuSettingsZ7II is relative to start of Offset31 block
8312
- RawConv => '$$self{MenuSettingsZ7IIOffset} = ($val || 0x10000000) + $$self{Offset31}; undef', # (ignore if 0)
8313
- },
8314
- 0xceb7 => {
8315
- Name => 'Hook5',
8316
- Hidden => 1,
8317
- RawConv => 'undef',
8318
- # account for variable location of Offset5 data
8319
- Hook => '$varSize = $$self{MenuSettingsZ7IIOffset} - 0xceb8',
8320
- },
8321
- 0xceb8 => { # (this is 0xd04e for the Z50)
8322
- Name => 'MenuSettingsZ7II',
8323
- Format => 'undef[860]',
8324
- SubDirectory => {
8325
- TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ7II',
8326
- },
8327
- }
8328
- # note: DecryptLen currently set to 0xd04e + 860 (offset for Z50 is 0xd04e)
8329
- );
8330
-
8331
- # shot information for the Z9 firmware 1.00 (encrypted) - ref 28
8332
- %Image::ExifTool::Nikon::ShotInfoZ9 = (
8333
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8334
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8335
- CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
8336
- VARS => { ID_LABEL => 'Index' },
8337
- DATAMEMBER => [ 0x04, 0x30, 0x38, 0x84, 0x8c, 0x6c6f, 0x6c90, 0x6c98,
8338
- 0x6c9a, 0xeaea, 0xeb6f, 0xeb70 ],
8339
- IS_SUBDIR => [ 0xec4b ],
8340
- WRITABLE => 1,
8341
- FIRST_ENTRY => 0,
8342
- GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8343
- NOTES => 'These tags are extracted from encrypted data in images from the Z9.',
8344
- 0x00 => {
8345
- Name => 'ShotInfoVersion',
8346
- Format => 'string[4]',
8347
- Writable => 0,
8152
+ # shot information for the Z9 firmware 1.00 (encrypted) - ref 28
8153
+ %Image::ExifTool::Nikon::ShotInfoZ9 = (
8154
+ PROCESS_PROC => \&ProcessNikonEncrypted,
8155
+ WRITE_PROC => \&ProcessNikonEncrypted,
8156
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
8157
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
8158
+ DATAMEMBER => [ 0x04 ],
8159
+ IS_SUBDIR => [ 0x30, 0x58, 0x84, 0x8c ],
8160
+ WRITABLE => 1,
8161
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8162
+ NOTES => 'These tags are extracted from encrypted data in images from the Z9.',
8163
+ 0x00 => {
8164
+ Name => 'ShotInfoVersion',
8165
+ Format => 'string[4]',
8166
+ Writable => 0,
8348
8167
  },
8349
8168
  0x04 => {
8350
8169
  Name => 'FirmwareVersion',
@@ -8367,53 +8186,55 @@ my %nikonFocalConversions = (
8367
8186
  },
8368
8187
  0x24 => {
8369
8188
  Name => 'NumberOffsets', # number of entries in offset table. offsets are from start of ShotInfo data.
8370
- DataMember => 'NumberOffsets',
8371
8189
  Format => 'int32u',
8372
8190
  Writable => 0,
8373
8191
  Hidden => 1,
8374
8192
  },
8193
+ # subdirectories, referenced by offsets (not processed if offset is zero)
8375
8194
  0x30 => {
8376
- Name => 'Offset3', #offset3 - length 2528 (Z9 firmware 1.0)
8377
- DataMember => 'Offset3',
8195
+ Name => 'SequenceOffset',
8378
8196
  Format => 'int32u',
8379
- Writable => 0,
8380
- Hidden => 1,
8381
- RawConv => '$$self{Offset3} = $val || 0x10000000; undef', # (ignore if 0)
8197
+ SubDirectory => {
8198
+ TagTable => 'Image::ExifTool::Nikon::SeqInfoZ9',
8199
+ Start => '$val',
8200
+ },
8382
8201
  },
8383
- 0x38 => {
8384
- Name => 'Offset5', #offset5 - length 2488 (Z9 firmware 1.0)
8385
- DataMember => 'Offset5',
8202
+ 0x58 => {
8203
+ 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 offset a more meaningful name at this point.
8204
+ Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} ge "03.01"',
8386
8205
  Format => 'int32u',
8387
- Writable => 0,
8388
- Hidden => 1,
8389
- RawConv => '$$self{Offset5} = $val || 0x10000000; undef', # (ignore if 0)
8206
+ SubDirectory => {
8207
+ TagTable => 'Image::ExifTool::Nikon::Offset13InfoZ9',
8208
+ Start => '$val',
8209
+ },
8390
8210
  },
8391
8211
  0x84 => {
8392
- Name => 'OrientationOffset', #offset24 - length 108 (Z9 firmware 1.0)
8393
- DataMember => 'OrientationOffset',
8212
+ Name => 'OrientOffset',
8213
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8394
8214
  Format => 'int32u',
8395
- Writable => 0,
8396
- Hidden => 1,
8397
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
8215
+ SubDirectory => {
8216
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8217
+ Start => '$val',
8218
+ },
8398
8219
  },
8399
8220
  0x8c => {
8400
- Name => 'Offset26', #offset26 - length 1895 (Z9 firmware 1.0)
8401
- DataMember => 'Offset26',
8221
+ Name => 'MenuOffset',
8402
8222
  Format => 'int32u',
8403
- Writable => 0,
8404
- Hidden => 1,
8405
- RawConv => '$$self{Offset26} = $val || 0x10000000; undef', # (ignore if 0)
8406
- },
8407
- ### 0x6c70 - Offset3 info start (Z9 firmware 1.00)
8408
- 0x6c6f => {
8409
- Name => 'Offset3Hook',
8410
- Hidden => 1,
8411
- RawConv => 'undef',
8412
- # account for variable location of Offset3 data
8413
- Hook => '$varSize = $$self{Offset3} - 0x6c70',
8223
+ SubDirectory => {
8224
+ TagTable => 'Image::ExifTool::Nikon::MenuInfoZ9',
8225
+ Start => '$val',
8226
+ },
8414
8227
  },
8415
- 0x6c90 => {
8228
+ );
8229
+
8230
+ # ref 28
8231
+ %Image::ExifTool::Nikon::SeqInfoZ9 = (
8232
+ %binaryDataAttrs,
8233
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8234
+ DATAMEMBER => [ 0x20, 0x28, 0x2a ],
8235
+ 0x0020 => {
8416
8236
  Name => 'FocusShiftShooting',
8237
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8417
8238
  RawConv => '$$self{FocusShiftShooting} = $val',
8418
8239
  PrintConv => q{
8419
8240
  return 'Off' if $val == 0 ;
@@ -8421,34 +8242,205 @@ my %nikonFocalConversions = (
8421
8242
  return "On: $i"
8422
8243
  },
8423
8244
  },
8424
- 0x6c98 => {
8245
+ 0x0028 => {
8425
8246
  Name => 'IntervalShooting',
8247
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8426
8248
  RawConv => '$$self{IntervalShooting} = $val',
8427
8249
  Format => 'int16u',
8428
8250
  PrintConv => q{
8429
8251
  return 'Off' if $val == 0 ;
8430
- my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}); # something like "Interval 1 of 3"
8431
- my $f = $$self{IntervalShootingShotsPerInterval} > 1 ? sprintf(" Frame %.0f of %.0f",$$self{IntervalFrame}, $$self{IntervalShootingShotsPerInterval}): '' ; # something like "Frame 1 of 3" or blank
8252
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); # something like "Interval 1 of 3"
8253
+ my $f = ($$self{IntervalShootingShotsPerInterval}||0) > 1 ? sprintf(" Frame %.0f of %.0f",$$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0): '' ; # something like "Frame 1 of 3" or blank
8432
8254
  return "On: $i$f"
8433
- #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}, $$self{IntervalFrame}, $$self{IntervalShootingShotsPerInterval}),
8255
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
8434
8256
  },
8435
8257
  },
8436
- 0x6c9a => {
8258
+ 0x002a => {
8437
8259
  Name => 'IntervalFrame',
8438
8260
  RawConv => '$$self{IntervalFrame} = $val',
8439
- Condition => '$$self{IntervalShooting} > 0',
8261
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8440
8262
  Format => 'int16u',
8441
8263
  Hidden => 1,
8442
8264
  },
8443
- ### 0xeaeb - OrientationInfo start (Z9 firmware 1.00)
8444
- 0xeaea => {
8445
- Name => 'OrientationHook',
8446
- Hidden => 1,
8447
- RawConv => 'undef',
8448
- # account for variable location of OrientationInfo data
8449
- Hook => '$varSize = $$self{OrientationOffset} - 0xeaeb',
8265
+ );
8266
+
8267
+ # ref 28
8268
+ %Image::ExifTool::Nikon::Offset13InfoZ9 = (
8269
+ %binaryDataAttrs,
8270
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8271
+ DATAMEMBER => [ 0x0bea, 0x0beb ],
8272
+ 0x0be8 => {
8273
+ 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 potentially refines focus)
8274
+ Condition => '$$self{ShutterMode} ne 96 and $$self{AFAreaMode} < 2 ', #not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19
8275
+ Format => 'int8s',
8276
+ PrintConv => q{
8277
+ #in FX mode and Single-point, the 29 horizontal focus points are spaced 259 pixels apart starting at pixel 502 and ending at 7754. Spacing is the same for Wide(L/C1/C2) with different start points.
8278
+ #in FX mode and Dynamic(L), the 27 horizontal focus points are spaced 259 pixels apart starting at pixel 761 and ending at 7495
8279
+ #in FX mode and Dynamic(M), the 29 horizontal focus points are spaced 259 pixels apart starting at pixel 502 and ending at 7754
8280
+ #in DX mode and Single-point, the 19 horizontal focus points are spaced 388 pixels apart starting at pixel 636 and ending at 7620. [These correspond to FX positions and match the corresponding values in AFAreaMode tag AFAreaXPosition].
8281
+ #in DX mode and Wide(S), the 17 horizontal focus points are spaced 393 pixels apart starting at pixel 591 and ending at 7272.
8282
+ #in DX mode and Dynamic(L), the 17 horizontal focus points are spaced 388 pixels apart starting at pixel 1024 and ending at 7232
8283
+ #in DX mode and Dynamic(M), the 19 horizontal focus points are spaced 388 pixels apart starting at pixel 636 and ending at 7620
8284
+
8285
+ my $areaMode = $$self{VALUE}{PhotoShootingMenuBankImageArea};
8286
+ my $afAreaMode = $$self{VALUE}{AFAreaMode};
8287
+ my $dynamicAFAreaSize = $$self{VALUE}{DynamicAFAreaSize};
8288
+
8289
+ my $FX = 0;
8290
+ my $DX = 1;
8291
+
8292
+ my $Single = 1;
8293
+ my $Dynamic = 2;
8294
+ my $WideS = 3;
8295
+ my $WideL = 4;
8296
+ my $ThreeD = 5;
8297
+ my $Auto = 6;
8298
+ my $WideC1 = 12;
8299
+
8300
+ my $DynamicS = 0;
8301
+ my $DynamicM = 1;
8302
+ my $DynamicL = 2;
8303
+
8304
+ my $start = 502; #FX - all flavors
8305
+ $start = 636 if $areaMode == $DX and ($afAreaMode == $Dynamic or $afAreaMode == $WideL or $afAreaMode == $ThreeD or $afAreaMode == $Auto or $afAreaMode >= $WideC1); #DX Wide(L/C1/C2) + Dynamic (L/M/S) + 3D + Auto
8306
+ $start = 591 if $areaMode == $DX and $afAreaMode == $WideS ; #DX Wide(S)
8307
+
8308
+ my $increment = 259; #FX - all flavors
8309
+ $increment = 388 if $areaMode == $DX and ($afAreaMode == $Dynamic or $afAreaMode == $WideL or $afAreaMode == $ThreeD or $afAreaMode == $Auto or $afAreaMode >= $WideC1); #DX Wide(L/C1/C2) + Dynamic (L/M/S) + 3D + Auto
8310
+ $increment = 393 if $areaMode == $DX and $afAreaMode == $WideS ; #DX Wide(S)
8311
+
8312
+ my $divisor = 4;
8313
+ $divisor = 6 if $areaMode == $DX ;
8314
+
8315
+ my $offsetVal = 0;
8316
+ $offsetVal = 12 if $areaMode == $FX and $afAreaMode == $Dynamic ; #FX Dynamic (L/M) - force positive values so perl rounding toward zero isn't an issue
8317
+ $offsetVal = 18 if $areaMode == $DX and $afAreaMode == $Dynamic ; #DX Dynamic (L/M)
8318
+
8319
+ my $offsetSum = -1;
8320
+ $offsetSum = -4 if $afAreaMode == $Dynamic ; # Dynamic (L/M)
8321
+
8322
+ my $ncol = $$self{AFAreaInitialWidth};
8323
+ $ncol = int($ncol * 2 / 3) if $areaMode == $DX ; #DX
8324
+
8325
+ #some sample mappings:
8326
+ #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, 4128, 4387, 4646, 4905, 5164, 5423, 5682, 5941, 6200, 6459, 6718, 6977, 7236, 7495, 7754]
8327
+ #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, 2188, 2576, 2964, 3352, 3740, 4128, 4516, 4904, 5292, 5680, 6068, 6456, 6844, 7232, 7620]
8328
+ #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]
8329
+ #FX Dynamic (L) map [-9, -5, -1, 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 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, 4905, 5164, 5423, 5682, 5941, 6200, 6459, 6718, 6977, 7236, 7495]
8330
+
8331
+ return $start + $increment * (int(($val + $offsetVal) / $divisor) + int($ncol / 2) + $offsetSum) ; #do not use simple int() becuase it rounds negative fractions toward zero resulting in duplicate values - instead use the 10xdivisor to force positive values
8332
+ },
8333
+ },
8334
+ 0x0be9 => {
8335
+ Name =>'AFAreaInitialYPosition', #stored as a representation of the vertical 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 potentially refines focus)
8336
+ Condition => '$$self{ShutterMode} ne 96 and $$self{AFAreaMode} < 2', #not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19
8337
+ Format => 'int8s',
8338
+ PrintConv => q{
8339
+ #in FX mode and Single-point, the 17 vertical focus points are spaced 291 pixels apart starting at pixel 424 and ending at 5080. Spacing is the same for Wide(L/C1/C2)
8340
+ #in FX mode and Dynamic(L), the 15 vertical focus points are spaced 291 pixels apart starting at pixel 715 and ending at 4789
8341
+ #in FX mode and Dynamic(M), the 17 vertical l focus points are spaced 291 pixels apart starting at pixel 424 and ending at 5080
8342
+ #in DX mode and Single-point, the 11 vertical focus points are spaced 436 pixels apart starting at pixel 572 and ending at 4932. [These correspond to FX positions and match the corresponding values in AFAreaMode tag AFAreaYPosition].
8343
+ #in DX Mode and Wide(S) the 9 vertical focus points are spaced 442 pixels apart starting at pixel 542 and ending at 4520
8344
+ #in DX mode and Dynamic(L), the 9 vertical focus points are spaced 436 pixels apart starting at pixel 1008 and ending at 4496
8345
+
8346
+ my $areaMode = $$self{VALUE}{PhotoShootingMenuBankImageArea};
8347
+ my $afAreaMode = $$self{VALUE}{AFAreaMode};
8348
+ my $dynamicAFAreaSize = $$self{VALUE}{DynamicAFAreaSize};
8349
+
8350
+ my $FX = 0;
8351
+ my $DX = 1;
8352
+
8353
+ my $Single = 1;
8354
+ my $Dynamic = 2;
8355
+ my $WideS = 3;
8356
+ my $WideL = 4;
8357
+ my $ThreeD = 5;
8358
+ my $Auto = 6;
8359
+ my $WideC1 = 12;
8360
+
8361
+ my $DynamicS = 0;
8362
+ my $DynamicM = 1;
8363
+ my $DynamicL = 2;
8364
+
8365
+ my $start = 424; #FX - all flavors
8366
+ $start = 572 if $areaMode == $DX and ($afAreaMode == $Dynamic or $afAreaMode == $WideL or $afAreaMode == $ThreeD or $afAreaMode == $Auto or $afAreaMode >= $WideC1); #DX Wide(L/C1/C2) + Dynamic(L/M/S) + 3D + Auto
8367
+ $start = 542 if $areaMode == $DX and $afAreaMode == 3 ; #DX Wide(S)
8368
+
8369
+ my $increment = 291; #FX - all flavors
8370
+ $increment = 436 if $areaMode == $DX and ($afAreaMode == $Dynamic or $afAreaMode == $WideL or $afAreaMode == $ThreeD or $afAreaMode == $Auto or $afAreaMode >= $WideC1); #DX Wide(L/C1/C2) + Dynamic (L/M/S) +3D + Auto
8371
+ $increment = 442 if $areaMode == $DX and $afAreaMode == 3 ; #DX Wide(S)
8372
+
8373
+ my $divisor = 7;
8374
+ $divisor = 10 if $areaMode == $DX ; #DX
8375
+
8376
+ my $offsetVal = -1;
8377
+ $offsetVal = 39 if $afAreaMode == $Dynamic and ( $dynamicAFAreaSize == $DynamicL ) ; #Dynamic (L) - force positive values so perl rounding toward zero isn't an issue
8378
+ $offsetVal = 40 if $afAreaMode == $Dynamic and $dynamicAFAreaSize == $DynamicM ; #Dynamic (M)
8379
+ $offsetVal = 40 if $areaMode == $FX and (($afAreaMode == $Dynamic and $dynamicAFAreaSize == $DynamicS) or $afAreaMode == $ThreeD) ; #FX Dynamic (S) or 3D
8380
+ $offsetVal = 38 if $areaMode == $DX and ($afAreaMode == $Dynamic and $dynamicAFAreaSize == $DynamicS ) ; #DX Dynamic (S)or 3D
8381
+
8382
+ my $offsetSum = 0;
8383
+ $offsetSum = -6 if $areaMode == $FX and ($afAreaMode == $Dynamic or $afAreaMode == $ThreeD); #FX Dynamic (L/M/S) or 3D
8384
+ $offsetSum = -4 if $areaMode == $DX and ($afAreaMode == $Dynamic or $afAreaMode == $ThreeD ); #DX Dynamic (L/M/S) or 3D
8385
+
8386
+ my $nrow = $$self{AFAreaInitialHeight};
8387
+ $nrow = int($nrow * 2 / 3) if $areaMode == $DX; #DX
8388
+
8389
+ #some sample mappings:
8390
+ #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, 2752, 3043, 3334, 3625, 3916, 4207, 4498, 4789, 5080]
8391
+ #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]
8392
+ #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]
8393
+ #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]
8394
+
8395
+ return $start + $increment * (int(($val + $offsetVal) / $divisor) + int($nrow / 2) + $offsetSum) ;;
8396
+ },
8397
+ },
8398
+ 0x0bea => {
8399
+ Name => 'AFAreaInitialWidth',
8400
+ Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8401
+ ValueConv => '$$self{VALUE}{PhotoShootingMenuBankImageArea} eq 0 ? $val : int($val * 2 / 3)', #DX mode requires scaling down TODO: add support ImageAreas 1:1 and 16:9
8402
+ RawConv => '$$self{AFAreaInitialWidth} = 1 + int ($val / 4)', #convert from [3, 11, 19, 35, 51, 75] to [1, 3, 5, 9 13, 19] to match camera options for C1/C2 focus modes .. input/output of 11/3 is for Wide(S)
8450
8403
  },
8451
- 0xeaeb => {
8404
+ 0x0beb => {
8405
+ Name => 'AFAreaInitialHeight',
8406
+ Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8407
+ ValueConv => '$$self{VALUE}{PhotoShootingMenuBankImageArea} eq 0 ? $val : int($val * 2 / 3)', #DX mode requires scaling down TODO: add support ImageAreas 1:1 and 16:9
8408
+ RawConv => '$$self{AFAreaInitialHeight} = 1 + int ($val / 7) ', #convert 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)
8409
+ },
8410
+ );
8411
+
8412
+ %Image::ExifTool::Nikon::MenuInfoZ9 = (
8413
+ %binaryDataAttrs,
8414
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8415
+ IS_SUBDIR => [ 0x10 ],
8416
+ # 0x00 - int32u size of this directory
8417
+ 0x10 => [
8418
+ {
8419
+ Name => 'MenuSettingsOffsetZ9',
8420
+ Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} lt "03.00"',
8421
+ Format => 'int32u',
8422
+ Notes => 'Firmware versions 2.11 and earlier',
8423
+ SubDirectory => {
8424
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9',
8425
+ Start => '$dirStart + $val',
8426
+ },
8427
+ },
8428
+ {
8429
+ Name => 'MenuSettingsOffsetZ9v3',
8430
+ Notes => 'Firmware versions 3.0 and later',
8431
+ Format => 'int32u',
8432
+ SubDirectory => {
8433
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9v3',
8434
+ Start => '$dirStart + $val',
8435
+ },
8436
+ },
8437
+ ],
8438
+ );
8439
+
8440
+ %Image::ExifTool::Nikon::OrientationInfo = (
8441
+ %binaryDataAttrs,
8442
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8443
+ 0 => {
8452
8444
  Name => 'RollAngle',
8453
8445
  Format => 'fixed32u',
8454
8446
  Notes => 'converted to degrees of clockwise camera roll',
@@ -8457,7 +8449,7 @@ my %nikonFocalConversions = (
8457
8449
  PrintConv => 'sprintf("%.1f", $val)',
8458
8450
  PrintConvInv => '$val',
8459
8451
  },
8460
- 0xeaef => {
8452
+ 4 => {
8461
8453
  Name => 'PitchAngle',
8462
8454
  Format => 'fixed32u',
8463
8455
  Notes => 'converted to degrees of upward camera tilt',
@@ -8466,7 +8458,7 @@ my %nikonFocalConversions = (
8466
8458
  PrintConv => 'sprintf("%.1f", $val)',
8467
8459
  PrintConvInv => '$val',
8468
8460
  },
8469
- 0xeaf3 => {
8461
+ 8 => {
8470
8462
  Name => 'YawAngle',
8471
8463
  Format => 'fixed32u',
8472
8464
  Notes => 'the camera yaw angle when shooting in portrait orientation',
@@ -8475,48 +8467,25 @@ my %nikonFocalConversions = (
8475
8467
  PrintConv => 'sprintf("%.1f", $val)',
8476
8468
  PrintConvInv => '$val',
8477
8469
  },
8478
- ### 0xeb5f - Offset26 info start (Z9 firmware 1.00)
8479
- 0xeb6f => {
8480
- Name => 'MenuSettingsZ9Offset',
8481
- Writable => 0,
8482
- Hidden => 1,
8483
- # offset to MenuSettingsZ9 is relative to start of Offset26 block
8484
- RawConv => '$$self{MenuSettingsZ9Offset} = ($val || 0x10000000) + $$self{Offset26}; undef', # (ignore if 0)
8485
- },
8486
- 0xeb70 => {
8487
- Name => 'Hook5',
8488
- Hidden => 1,
8489
- RawConv => 'undef',
8490
- # account for variable location of menu settings data
8491
- Hook => '$varSize = $$self{MenuSettingsZ9Offset} - 0xec4b',
8492
- },
8493
- 0xec4b => [
8494
- {
8495
- Name => 'MenuSettingsZ9',
8496
- Condition => '$$self{FirmwareVersion} lt "03.00"',
8497
- Format => 'undef[1646]',
8498
- Notes => 'Firmware versions 2.11 and earlier',
8499
- SubDirectory => {
8500
- TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9',
8501
- },
8502
- },
8503
- {
8504
- Name => 'MenuSettingsZ9',
8505
- Notes => 'Firmware versions 3.0 and later',
8506
- Format => 'undef[1948]',
8507
- SubDirectory => {
8508
- TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9Firmware3',
8509
- },
8510
- },
8511
- ],
8512
- # note: DecryptLen currently set to 0xec4b + 2196
8513
8470
  );
8514
8471
 
8515
8472
  %Image::ExifTool::Nikon::MenuSettingsZ7II = (
8516
8473
  %binaryDataAttrs,
8517
8474
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8518
- DATAMEMBER => [ 176, 180, 328, 352, 858 ],
8475
+ DATAMEMBER => [ 90, 176, 180, 328, 352, 858 ],
8519
8476
  NOTES => 'These tags are used by the Z5, Z6, Z7, Z6II, Z7II, Z50 and Zfc.',
8477
+ #48 SelfTimer' #0=> no 1=> yes works for Z7II firmware 1.40, but not 1.30. Follow-up required.
8478
+ 90 => {
8479
+ Name => 'SingleFrame', #0=> Single Frame 1=> one of the continuous modes
8480
+ Hidden => 1,
8481
+ RawConv => '$$self{SingleFrame} = $val',
8482
+ },
8483
+ 92 => {
8484
+ Name => 'ReleaseMode',
8485
+ #ValueConv => '$$self{SelfTimer} == 1 ? 4 : $$self{SingleFrame} == 0 ? 5 : $val', #map single frame and timer to a unique values for PrintConv. Activate when SelfTimer tag is clarified for cameras other than Z7II fw 1.40
8486
+ ValueConv => '$$self{SingleFrame} == 0 ? 5 : $val', #map single frame to a unique value for PrintConv
8487
+ PrintConv => \%releaseModeZ7,
8488
+ },
8520
8489
  160 => {
8521
8490
  Name => 'IntervalDurationHours',
8522
8491
  Format => 'int32u',
@@ -8737,7 +8706,7 @@ my %nikonFocalConversions = (
8737
8706
  %Image::ExifTool::Nikon::MenuSettingsZ9 = (
8738
8707
  %binaryDataAttrs,
8739
8708
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8740
- DATAMEMBER => [ 140, 188, 192, 232, 424, 534 ],
8709
+ DATAMEMBER => [ 140, 188, 192, 232, 424, 534, 576 ],
8741
8710
  IS_SUBDIR => [ 799 ],
8742
8711
  NOTES => 'These tags are used by the Z9.',
8743
8712
  #90 ISO
@@ -8751,34 +8720,34 @@ my %nikonFocalConversions = (
8751
8720
  Name => 'Intervals',
8752
8721
  Format => 'int32u',
8753
8722
  RawConv => '$$self{IntervalShootingIntervals} = $val',
8754
- Condition => '$$self{IntervalShooting} > 0',
8723
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8755
8724
  },
8756
8725
  192 => {
8757
8726
  Name => 'ShotsPerInterval',
8758
8727
  Format => 'int32u',
8759
8728
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
8760
- Condition => '$$self{IntervalShooting} > 0',
8729
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8761
8730
  },
8762
8731
  #220 NEFCompression 0=> 'Lossless' 1=> 'High Efficiency*' 4=> 'High Efficientcy'
8763
8732
  232 => {
8764
8733
  Name => 'FocusShiftNumberShots', #1-300
8765
8734
  RawConv => '$$self{FocusShiftNumberShots} = $val',
8766
- Condition => '$$self{FocusShiftShooting} > 0',
8735
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8767
8736
  },
8768
8737
  236 => {
8769
8738
  Name => 'FocusShiftStepWidth', #1(Narrow) to 10 (Wide)
8770
- Condition => '$$self{FocusShiftShooting} > 0',
8739
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8771
8740
  },
8772
8741
  240 => {
8773
8742
  Name => 'FocusShiftInterval',
8774
- Condition => '$$self{FocusShiftShooting} > 0',
8743
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8775
8744
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
8776
8745
  },
8777
8746
  244 => {
8778
8747
  Name => 'FocusShiftExposureLock',
8779
8748
  Unknown => 1,
8780
8749
  PrintConv => \%offOn,
8781
- Condition => '$$self{FocusShiftShooting} > 0',
8750
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8782
8751
  },
8783
8752
  274 => { Name => 'PhotoShootingMenuBank', PrintConv => \%banksZ9 },
8784
8753
  276 => { Name => 'ExtendedMenuBanks', PrintConv => \%offOn }, #single tag from both Photo & Video menus
@@ -8877,6 +8846,12 @@ my %nikonFocalConversions = (
8877
8846
  556 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFunctionZ9 },
8878
8847
  572 => { Name => 'DXCropAlert', PrintConv => \%offOn },
8879
8848
  574 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 },
8849
+ 576 => {
8850
+ Name => 'DynamicAFAreaSize',
8851
+ Condition => '$$self{AFAraMode} = 2',
8852
+ RawConv => '$$self{DynamicAFAreaSize} = $val',
8853
+ PrintConv => \%dynamicAfAreaModesZ9,
8854
+ },
8880
8855
  604 => {
8881
8856
  Name => 'MovieImageArea',
8882
8857
  Unknown => 1,
@@ -8933,17 +8908,22 @@ my %nikonFocalConversions = (
8933
8908
  1565 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
8934
8909
  1572 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
8935
8910
  1573 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
8936
- 1608 => { Name => 'EnergySavingMode', PrintConv =>\%offOn, Unknown => 1 },
8911
+ 1608 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
8937
8912
  1632 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
8938
8913
  1636 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
8939
8914
  1645 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
8940
8915
  );
8941
- %Image::ExifTool::Nikon::MenuSettingsZ9Firmware3 = ( #starts at Offset26 + 248
8916
+
8917
+ %Image::ExifTool::Nikon::MenuSettingsZ9v3 = (
8942
8918
  %binaryDataAttrs,
8943
8919
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8944
- DATAMEMBER => [ 154, 204, 208, 248, 444, 554 ],
8920
+ DATAMEMBER => [ 154, 204, 208, 248, 444, 554, 596 ],
8945
8921
  IS_SUBDIR => [ 847 ],
8946
8922
  NOTES => 'These tags are used by the Z9 firmware 3.00.',
8923
+ 72 => {
8924
+ Name => 'HighFrameRate', #CH and C30/C60/C120 but not CL
8925
+ PrintConv => \%highFrameRateZ9,
8926
+ },
8947
8927
  154 => {
8948
8928
  Name => 'MultipleExposureMode',
8949
8929
  RawConv => '$$self{MultipleExposureMode} = $val',
@@ -8954,33 +8934,33 @@ my %nikonFocalConversions = (
8954
8934
  Name => 'Intervals',
8955
8935
  Format => 'int32u',
8956
8936
  RawConv => '$$self{IntervalShootingIntervals} = $val',
8957
- Condition => '$$self{IntervalShooting} > 0',
8937
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8958
8938
  },
8959
8939
  208 => {
8960
8940
  Name => 'ShotsPerInterval',
8961
8941
  Format => 'int32u',
8962
8942
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
8963
- Condition => '$$self{IntervalShooting} > 0',
8943
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8964
8944
  },
8965
8945
  248 => {
8966
8946
  Name => 'FocusShiftNumberShots', #1-300
8967
8947
  RawConv => '$$self{FocusShiftNumberShots} = $val',
8968
- Condition => '$$self{FocusShiftShooting} > 0',
8948
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8969
8949
  },
8970
8950
  252 => {
8971
8951
  Name => 'FocusShiftStepWidth', #1(Narrow) to 10 (Wide)
8972
- Condition => '$$self{FocusShiftShooting} > 0',
8952
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8973
8953
  },
8974
8954
  256 => {
8975
8955
  Name => 'FocusShiftInterval',
8976
- Condition => '$$self{FocusShiftShooting} > 0',
8956
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8977
8957
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
8978
8958
  },
8979
8959
  260 => {
8980
8960
  Name => 'FocusShiftExposureLock',
8981
8961
  Unknown => 1,
8982
8962
  PrintConv => \%offOn,
8983
- Condition => '$$self{FocusShiftShooting} > 0',
8963
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8984
8964
  },
8985
8965
  290 => { Name => 'PhotoShootingMenuBank', PrintConv => \%banksZ9 },
8986
8966
  292 => { Name => 'ExtendedMenuBanks', PrintConv => \%offOn }, # single tag from both Photo & Video menus
@@ -9022,450 +9002,149 @@ my %nikonFocalConversions = (
9022
9002
  Unknown => 1,
9023
9003
  ValueConv => '$val/6',
9024
9004
  ValueConvInv => '6 * $val',
9025
- PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
9026
- PrintConvInv => '$val',
9027
- },
9028
- 450 => {
9029
- Name => 'FlashGNDistance',
9030
- Condition => '$$self{FlashControlMode} == 2',
9031
- Unknown => 1,
9032
- ValueConv => '$val + 3',
9033
- PrintConv => \%flashGNDistance,
9034
- },
9035
- 454 => {
9036
- Name => 'FlashOutput', # range[0,24] with 0=>Full; 1=>50%; then decreasing flash power in 1/3 stops to 0.39% (1/256 full power). also found in FlashInfoUnknown at offset 0x0a (with different mappings)
9037
- Condition => '$$self{FlashControlMode} >= 3',
9038
- Unknown => 1,
9039
- ValueConv => '2 ** (-$val/3)',
9040
- ValueConvInv => '$val>0 ? -3*log($val)/log(2) : 0',
9041
- PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
9042
- PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9043
- },
9044
- #462 flash wireless control 0=> 'Off' 1=> 'Optical AWL'
9045
- #464 => { Name => 'FlashRemoteControl', PrintConv => \%flashRemoteControlZ7, Unknown => 1 },
9046
- #476 => { Name => 'FlashWirelessOption', PrintConv => \%flashWirelessOptionZ7, Unknown => 1 },
9047
- 548 => { Name => 'AFAreaMode', PrintConv => \%aFAreaModeZ9},
9048
- 550 => { Name => 'VRMode', PrintConv => \%vRModeZ9},
9049
- 554 => {
9050
- Name => 'BracketSet',
9051
- RawConv => '$$self{BracketSet} = $val',
9052
- PrintConv => \%bracketSetZ9,
9053
- },
9054
- 556 => {
9055
- Name => 'BracketProgram',
9056
- Condition => '$$self{BracketSet} < 3',
9057
- Notes => 'AE and/or Flash Bracketing',
9058
- PrintConv => \%bracketProgramZ9,
9059
- },
9060
- 558 => {
9061
- Name => 'BracketIncrement',
9062
- Condition => '$$self{BracketSet} < 3',
9063
- Notes => 'AE and/or Flash Bracketing',
9064
- PrintConv => \%bracketIncrementZ9,
9065
- },
9066
- 576 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFunctionZ9 },
9067
- 592 => { Name => 'DXCropAlert', PrintConv => \%offOn },
9068
- 594 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 },
9069
- 636 => { Name => 'HighFrequencyFlickerReductionShooting', PrintConv => \%offOn, Unknown => 1 }, # new with firmware 3.0
9070
- 646 => {
9071
- Name => 'MovieImageArea',
9072
- Unknown => 1,
9073
- Mask => 0x01, # without the mask 4 => 'FX' 5 => DX only the 2nd Z-series field encountered with a mask.
9074
- PrintConv => \%imageAreaZ9b,
9075
- },
9076
- 656 => { Name => 'MovieType', PrintConv => \%movieTypeZ9, Unknown => 1 },
9077
- 658 => {
9078
- Name => 'MovieISOAutoHiLimit',
9079
- Format => 'int16u',
9080
- Unknown => 1,
9081
- ValueConv => '($val-104)/8',
9082
- ValueConvInv => '8 * ($val + 104)',
9083
- PrintConv => \%iSOAutoHiLimitZ7,
9084
- },
9085
- 660 => { Name => 'MovieISOAutoControlManualMode', PrintConv => \%offOn, Unknown => 1 },
9086
- 662 => {
9087
- Name => 'MovieISOAutoManualMode',
9088
- Format => 'int16u',
9089
- Unknown => 1,
9090
- ValueConv => '($val-104)/8',
9091
- ValueConvInv => '8 * ($val + 104)',
9092
- PrintConv => \%iSOAutoHiLimitZ7,
9093
- },
9094
- 736 => { Name => 'MovieActiveD-Lighting', PrintConv => \%activeDLightingZ7, Unknown => 1 },
9095
- 738 => { Name => 'MovieHighISONoiseReduction', PrintConv => \%offLowNormalHighZ7, Unknown => 1 },
9096
- 744 => { Name => 'MovieFlickerReduction', PrintConv => \%movieFlickerReductionZ9 },
9097
- 746 => { Name => 'MovieMeteringMode', PrintConv => \%meteringModeZ7, Unknown => 1 },
9098
- 748 => { Name => 'MovieFocusMode', PrintConv => \%focusModeZ7, Unknown => 1 },
9099
- 750 => { Name => 'MovieAFAreaMode', PrintConv => \%aFAreaModeZ9 },
9100
- 752 => { Name => 'MovieVRMode', PrintConv => \%vRModeZ9, Unknown => 1 },
9101
- 756 => { Name => 'MovieElectronicVR', PrintConv => \%offOn, Unknown => 1 }, # distinct from MoveieVRMode
9102
- 758 => { Name => 'MovieSoundRecording', PrintConv => { 0 => 'Off', 1 => 'Auto', 2 => 'Manual' }, Unknown => 1 },
9103
- 760 => { Name => 'MicrophoneSensitivity', Unknown => 1 }, # 1-20
9104
- 762 => { Name => 'MicrophoneAttenuator', PrintConv => \%offOn, Unknown => 1 }, # distinct from MoveieVRMode
9105
- 764 => { Name => 'MicrophoneFrequencyResponse',PrintConv => { 0 => 'Wide Range', 1 => 'Vocal Range' }, Unknown => 1 },
9106
- 766 => { Name => 'WindNoiseReduction', PrintConv => \%offOn, Unknown => 1 },
9107
- 788 => { Name => 'MovieToneMap', PrintConv => \%movieToneMapZ9, Unknown => 1 },
9108
- 794 => { Name => 'MovieFrameSize', PrintConv => \%movieFrameSizeZ9, Unknown => 1 },
9109
- 796 => { Name => 'MovieFrameRate', PrintConv => \%movieFrameRateZ7, Unknown => 1 },
9110
- 802 => { Name => 'MicrophoneJackPower', PrintConv => \%offOn, Unknown => 1 },
9111
- 803 => { Name => 'MovieDXCropAlert', PrintConv => \%offOn, Unknown => 1 },
9112
- 804 => { Name => 'MovieSubjectDetection', PrintConv => \%subjectDetectionZ9, Unknown => 1 },
9113
- 812 => { Name => 'MovieHighResZoom', PrintConv => \%offOn, Unknown => 1 },
9114
- 847 => {
9115
- Name => 'CustomSettingsZ9',
9116
- Format => 'undef[608]',
9117
- SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsZ9' },
9118
- },
9119
- 1474 => { Name => 'Language', PrintConv => \%languageZ9, Unknown => 1 },
9120
- 1476 => { Name => 'TimeZone', PrintConv => \%timeZoneZ9 },
9121
- 1482 => { Name => 'MonitorBrightness', PrintConv => \%monitorBrightnessZ9, Unknown => 1 }, # settings: -5 to +5. Added with firmware 3.0: Lo1, Lo2, Hi1, Hi2
9122
- 1504 => { Name => 'AFFineTune', PrintConv => \%offOn, Unknown => 1 },
9123
- 1600 => { Name => 'HDMIOutputResolution', PrintConv => \%hDMIOutputResolutionZ9 },
9124
- 1613 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
9125
- 1620 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
9126
- 1621 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
9127
- 1656 => { Name => 'EnergySavingMode', PrintConv =>\%offOn, Unknown => 1 },
9128
- 1680 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
9129
- 1684 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
9130
- 1693 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
9131
- 1754 => {
9132
- Name => 'FocusShiftAutoReset',
9133
- Unknown => 1,
9134
- PrintConv => \%offOn,
9135
- Condition => '$$self{FocusShiftShooting} > 0',
9136
- },
9137
- #1824 ReleaseTimingIndicatorTypeADelay CSd14-b 0 => '1/200' ... 15 => '1/6'
9138
- #1826 VerticalISOButton CSf2
9139
- #1828 ExposureCompensationButton CSf2
9140
- #1830 ISOButton CSf2
9141
- #1890 ViewModeShowEffectsOfSettings CSd9-a 0=>'Always', 1=> 'Only When Flash Not Used'
9142
- #1892 DispButton CSf2
9143
- #1936 FocusPointDisplayOption3DTrackingColor CSa11-d 0=> 'White', 1= => 'Red'
9144
- );
9145
-
9146
- # Flash information (ref JD)
9147
- %Image::ExifTool::Nikon::FlashInfo0100 = (
9148
- %binaryDataAttrs,
9149
- DATAMEMBER => [ 9.2, 15, 16 ],
9150
- GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
9151
- NOTES => q{
9152
- These tags are used by the D2H, D2Hs, D2X, D2Xs, D50, D70, D70s, D80 and
9153
- D200.
9154
- },
9155
- # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
9156
- 0 => {
9157
- Name => 'FlashInfoVersion',
9158
- Format => 'string[4]',
9159
- Writable => 0,
9160
- },
9161
- 4 => { #PH
9162
- Name => 'FlashSource',
9163
- PrintConv => {
9164
- 0 => 'None',
9165
- 1 => 'External',
9166
- 2 => 'Internal',
9167
- },
9168
- },
9169
- # 5 - values: 46,48,50,54,78
9170
- 6 => {
9171
- Format => 'int8u[2]',
9172
- Name => 'ExternalFlashFirmware',
9173
- SeparateTable => 'FlashFirmware',
9174
- PrintConv => \%flashFirmware,
9175
- },
9176
- 8 => {
9177
- Name => 'ExternalFlashFlags',
9178
- PrintConv => { 0 => '(none)',
9179
- BITMASK => {
9180
- 0 => 'Fired', #28
9181
- 2 => 'Bounce Flash', #PH
9182
- 4 => 'Wide Flash Adapter',
9183
- 5 => 'Dome Diffuser', #28
9184
- },
9185
- },
9186
- },
9187
- 9.1 => {
9188
- Name => 'FlashCommanderMode',
9189
- Mask => 0x80,
9190
- PrintConv => { 0 => 'Off', 1 => 'On' },
9191
- },
9192
- 9.2 => {
9193
- Name => 'FlashControlMode',
9194
- Mask => 0x7f,
9195
- DataMember => 'FlashControlMode',
9196
- RawConv => '$$self{FlashControlMode} = $val',
9197
- PrintConv => \%flashControlMode,
9198
- SeparateTable => 'FlashControlMode',
9199
- },
9200
- 10 => [
9201
- {
9202
- Name => 'FlashOutput',
9203
- Condition => '$$self{FlashControlMode} >= 0x06',
9204
- ValueConv => '2 ** (-$val/6)',
9205
- ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
9206
- PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
9207
- PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9208
- },
9209
- {
9210
- Name => 'FlashCompensation',
9211
- Format => 'int8s',
9212
- Priority => 0,
9213
- ValueConv => '-$val/6',
9214
- ValueConvInv => '-6 * $val',
9215
- PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
9216
- PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
9217
- },
9218
- ],
9219
- 11 => {
9220
- Name => 'FlashFocalLength',
9221
- RawConv => '$val ? $val : undef',
9222
- PrintConv => '"$val mm"',
9223
- PrintConvInv => '$val=~/(\d+)/; $1 || 0',
9224
- },
9225
- 12 => {
9226
- Name => 'RepeatingFlashRate',
9227
- RawConv => '$val ? $val : undef',
9228
- PrintConv => '"$val Hz"',
9229
- PrintConvInv => '$val=~/(\d+)/; $1 || 0',
9230
- },
9231
- 13 => {
9232
- Name => 'RepeatingFlashCount',
9233
- RawConv => '$val ? $val : undef',
9234
- },
9235
- 14 => { #PH
9236
- Name => 'FlashGNDistance',
9237
- SeparateTable => 1,
9238
- PrintConv => \%flashGNDistance,
9239
- },
9240
- 15 => {
9241
- Name => 'FlashGroupAControlMode',
9242
- Mask => 0x0f,
9243
- DataMember => 'FlashGroupAControlMode',
9244
- RawConv => '$$self{FlashGroupAControlMode} = $val',
9245
- PrintConv => \%flashControlMode,
9246
- SeparateTable => 'FlashControlMode',
9247
- },
9248
- 16 => {
9249
- Name => 'FlashGroupBControlMode',
9250
- Mask => 0x0f,
9251
- DataMember => 'FlashGroupBControlMode',
9252
- RawConv => '$$self{FlashGroupBControlMode} = $val',
9253
- PrintConv => \%flashControlMode,
9254
- SeparateTable => 'FlashControlMode',
9255
- },
9256
- 17 => [
9257
- {
9258
- Name => 'FlashGroupAOutput',
9259
- Condition => '$$self{FlashGroupAControlMode} >= 0x06',
9260
- ValueConv => '2 ** (-$val/6)',
9261
- ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
9262
- PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
9263
- PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9264
- },
9265
- {
9266
- Name => 'FlashGroupACompensation',
9267
- Format => 'int8s',
9268
- ValueConv => '-$val/6',
9269
- ValueConvInv => '-6 * $val',
9270
- PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
9271
- PrintConvInv => '$val',
9272
- },
9273
- ],
9274
- 18 => [
9275
- {
9276
- Name => 'FlashGroupBOutput',
9277
- Condition => '$$self{FlashGroupBControlMode} >= 0x06',
9278
- ValueConv => '2 ** (-$val/6)',
9279
- ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
9280
- PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
9281
- PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9282
- },
9283
- {
9284
- Name => 'FlashGroupBCompensation',
9285
- Format => 'int8s',
9286
- ValueConv => '-$val/6',
9287
- ValueConvInv => '-6 * $val',
9288
- PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
9289
- PrintConvInv => '$val',
9290
- },
9291
- ],
9292
- );
9293
-
9294
- # Flash information for D40, D40x, D3 and D300 (ref JD)
9295
- %Image::ExifTool::Nikon::FlashInfo0102 = (
9296
- %binaryDataAttrs,
9297
- DATAMEMBER => [ 9.2, 16.1, 17.1, 17.2 ],
9298
- GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
9299
- NOTES => q{
9300
- These tags are used by the D3 (firmware 1.x), D40, D40X, D60 and D300
9301
- (firmware 1.00).
9302
- },
9303
- # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
9304
- 0 => {
9305
- Name => 'FlashInfoVersion',
9306
- Format => 'string[4]',
9307
- Writable => 0,
9308
- },
9309
- 4 => { #PH
9310
- Name => 'FlashSource',
9311
- PrintConv => {
9312
- 0 => 'None',
9313
- 1 => 'External',
9314
- 2 => 'Internal',
9315
- },
9316
- },
9317
- # 5 - values: 46,48,50,54,78
9318
- 6 => {
9319
- Format => 'int8u[2]',
9320
- Name => 'ExternalFlashFirmware',
9321
- SeparateTable => 'FlashFirmware',
9322
- PrintConv => \%flashFirmware,
9323
- },
9324
- 8 => {
9325
- Name => 'ExternalFlashFlags',
9326
- PrintConv => { BITMASK => {
9327
- 0 => 'Fired', #28
9328
- 2 => 'Bounce Flash', #PH
9329
- 4 => 'Wide Flash Adapter',
9330
- 5 => 'Dome Diffuser', #28
9331
- }},
9332
- },
9333
- 9.1 => {
9334
- Name => 'FlashCommanderMode',
9335
- Mask => 0x80,
9336
- PrintConv => { 0 => 'Off', 1 => 'On' },
9337
- },
9338
- 9.2 => {
9339
- Name => 'FlashControlMode',
9340
- Mask => 0x7f,
9341
- DataMember => 'FlashControlMode',
9342
- RawConv => '$$self{FlashControlMode} = $val',
9343
- PrintConv => \%flashControlMode,
9344
- SeparateTable => 'FlashControlMode',
9345
- },
9346
- 10 => [
9347
- {
9348
- Name => 'FlashOutput',
9349
- Condition => '$$self{FlashControlMode} >= 0x06',
9350
- ValueConv => '2 ** (-$val/6)',
9351
- ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
9352
- PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
9353
- PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9354
- },
9355
- {
9356
- Name => 'FlashCompensation',
9357
- # this is the compensation from the camera (0x0012) for "Built-in" FlashType, or
9358
- # the compensation from the external unit (0x0017) for "Optional" FlashType - PH
9359
- Format => 'int8s',
9360
- Priority => 0,
9361
- ValueConv => '-$val/6',
9362
- ValueConvInv => '-6 * $val',
9363
- PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
9364
- PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
9365
- },
9366
- ],
9367
- 12 => {
9368
- Name => 'FlashFocalLength',
9369
- RawConv => '$val ? $val : undef',
9370
- PrintConv => '"$val mm"',
9371
- PrintConvInv => '$val=~/(\d+)/; $1 || 0',
9372
- },
9373
- 13 => {
9374
- Name => 'RepeatingFlashRate',
9375
- RawConv => '$val ? $val : undef',
9376
- PrintConv => '"$val Hz"',
9377
- PrintConvInv => '$val=~/(\d+)/; $1 || 0',
9378
- },
9379
- 14 => {
9380
- Name => 'RepeatingFlashCount',
9381
- RawConv => '$val ? $val : undef',
9005
+ PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
9006
+ PrintConvInv => '$val',
9382
9007
  },
9383
- 15 => { #PH
9008
+ 450 => {
9384
9009
  Name => 'FlashGNDistance',
9385
- SeparateTable => 1,
9010
+ Condition => '$$self{FlashControlMode} == 2',
9011
+ Unknown => 1,
9012
+ ValueConv => '$val + 3',
9386
9013
  PrintConv => \%flashGNDistance,
9387
9014
  },
9388
- 16.1 => {
9389
- Name => 'FlashGroupAControlMode',
9390
- Mask => 0x0f,
9391
- Notes => 'note: group A tags may apply to the built-in flash settings for some models',
9392
- DataMember => 'FlashGroupAControlMode',
9393
- RawConv => '$$self{FlashGroupAControlMode} = $val',
9394
- PrintConv => \%flashControlMode,
9395
- SeparateTable => 'FlashControlMode',
9015
+ 454 => {
9016
+ Name => 'FlashOutput', # range[0,24] with 0=>Full; 1=>50%; then decreasing flash power in 1/3 stops to 0.39% (1/256 full power). also found in FlashInfoUnknown at offset 0x0a (with different mappings)
9017
+ Condition => '$$self{FlashControlMode} >= 3',
9018
+ Unknown => 1,
9019
+ ValueConv => '2 ** (-$val/3)',
9020
+ ValueConvInv => '$val>0 ? -3*log($val)/log(2) : 0',
9021
+ PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
9022
+ PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9396
9023
  },
9397
- 17.1 => {
9398
- Name => 'FlashGroupBControlMode',
9399
- Mask => 0xf0,
9400
- Notes => 'note: group B tags may apply to group A settings for some models',
9401
- DataMember => 'FlashGroupBControlMode',
9402
- RawConv => '$$self{FlashGroupBControlMode} = $val',
9403
- PrintConv => \%flashControlMode,
9404
- SeparateTable => 'FlashControlMode',
9024
+ #462 flash wireless control 0=> 'Off' 1=> 'Optical AWL'
9025
+ #464 => { Name => 'FlashRemoteControl', PrintConv => \%flashRemoteControlZ7, Unknown => 1 },
9026
+ #476 => { Name => 'FlashWirelessOption', PrintConv => \%flashWirelessOptionZ7, Unknown => 1 },
9027
+ 548 => { Name => 'AFAreaMode', PrintConv => \%aFAreaModeZ9},
9028
+ 550 => { Name => 'VRMode', PrintConv => \%vRModeZ9},
9029
+ 554 => {
9030
+ Name => 'BracketSet',
9031
+ RawConv => '$$self{BracketSet} = $val',
9032
+ PrintConv => \%bracketSetZ9,
9405
9033
  },
9406
- 17.2 => { #PH
9407
- Name => 'FlashGroupCControlMode',
9408
- Mask => 0x0f,
9409
- Notes => 'note: group C tags may apply to group B settings for some models',
9410
- DataMember => 'FlashGroupCControlMode',
9411
- RawConv => '$$self{FlashGroupCControlMode} = $val',
9412
- PrintConv => \%flashControlMode,
9413
- SeparateTable => 'FlashControlMode',
9034
+ 556 => {
9035
+ Name => 'BracketProgram',
9036
+ Condition => '$$self{BracketSet} < 3',
9037
+ Notes => 'AE and/or Flash Bracketing',
9038
+ PrintConv => \%bracketProgramZ9,
9414
9039
  },
9415
- 18 => [
9416
- {
9417
- Name => 'FlashGroupAOutput',
9418
- Condition => '$$self{FlashGroupAControlMode} >= 0x06',
9419
- ValueConv => '2 ** (-$val/6)',
9420
- ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
9421
- PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
9422
- PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9423
- },
9424
- {
9425
- Name => 'FlashGroupACompensation',
9426
- Format => 'int8s',
9427
- ValueConv => '-$val/6',
9428
- ValueConvInv => '-6 * $val',
9429
- PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
9430
- PrintConvInv => '$val',
9431
- },
9432
- ],
9433
- 19 => [
9434
- {
9435
- Name => 'FlashGroupBOutput',
9436
- Condition => '$$self{FlashGroupBControlMode} >= 0x60',
9437
- ValueConv => '2 ** (-$val/6)',
9438
- ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
9439
- PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
9440
- PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9441
- },
9442
- {
9443
- Name => 'FlashGroupBCompensation',
9444
- Format => 'int8s',
9445
- ValueConv => '-$val/6',
9446
- ValueConvInv => '-6 * $val',
9447
- PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
9448
- PrintConvInv => '$val',
9449
- },
9450
- ],
9451
- 20 => [ #PH
9452
- {
9453
- Name => 'FlashGroupCOutput',
9454
- Condition => '$$self{FlashGroupCControlMode} >= 0x06',
9455
- ValueConv => '2 ** (-$val/6)',
9456
- ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
9457
- PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
9458
- PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
9040
+ 558 => {
9041
+ Name => 'BracketIncrement',
9042
+ Condition => '$$self{BracketSet} < 3',
9043
+ Notes => 'AE and/or Flash Bracketing',
9044
+ PrintConv => \%bracketIncrementZ9,
9045
+ },
9046
+ 576 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFunctionZ9 },
9047
+ 592 => { Name => 'DXCropAlert', PrintConv => \%offOn },
9048
+ 594 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 },
9049
+ 596 => {
9050
+ Name => 'DynamicAFAreaSize',
9051
+ Condition => '$$self{AFAraMode} = 2',
9052
+ RawConv => '$$self{DynamicAFAreaSize} = $val',
9053
+ PrintConv => \%dynamicAfAreaModesZ9,
9054
+ },
9055
+ 636 => { Name => 'HighFrequencyFlickerReductionShooting', PrintConv => \%offOn, Unknown => 1 }, # new with firmware 3.0
9056
+ 646 => {
9057
+ Name => 'MovieImageArea',
9058
+ Unknown => 1,
9059
+ Mask => 0x01, # without the mask 4 => 'FX' 5 => DX only the 2nd Z-series field encountered with a mask.
9060
+ PrintConv => \%imageAreaZ9b,
9061
+ },
9062
+ 656 => { Name => 'MovieType', PrintConv => \%movieTypeZ9, Unknown => 1 },
9063
+ 658 => {
9064
+ Name => 'MovieISOAutoHiLimit',
9065
+ Format => 'int16u',
9066
+ Unknown => 1,
9067
+ ValueConv => '($val-104)/8',
9068
+ ValueConvInv => '8 * ($val + 104)',
9069
+ PrintConv => \%iSOAutoHiLimitZ7,
9070
+ },
9071
+ 660 => { Name => 'MovieISOAutoControlManualMode', PrintConv => \%offOn, Unknown => 1 },
9072
+ 662 => {
9073
+ Name => 'MovieISOAutoManualMode',
9074
+ Format => 'int16u',
9075
+ Unknown => 1,
9076
+ ValueConv => '($val-104)/8',
9077
+ ValueConvInv => '8 * ($val + 104)',
9078
+ PrintConv => \%iSOAutoHiLimitZ7,
9079
+ },
9080
+ 736 => { Name => 'MovieActiveD-Lighting', PrintConv => \%activeDLightingZ7, Unknown => 1 },
9081
+ 738 => { Name => 'MovieHighISONoiseReduction', PrintConv => \%offLowNormalHighZ7, Unknown => 1 },
9082
+ 744 => { Name => 'MovieFlickerReduction', PrintConv => \%movieFlickerReductionZ9 },
9083
+ 746 => { Name => 'MovieMeteringMode', PrintConv => \%meteringModeZ7, Unknown => 1 },
9084
+ 748 => { Name => 'MovieFocusMode', PrintConv => \%focusModeZ7, Unknown => 1 },
9085
+ 750 => { Name => 'MovieAFAreaMode', PrintConv => \%aFAreaModeZ9 },
9086
+ 752 => { Name => 'MovieVRMode', PrintConv => \%vRModeZ9, Unknown => 1 },
9087
+ 756 => { Name => 'MovieElectronicVR', PrintConv => \%offOn, Unknown => 1 }, # distinct from MoveieVRMode
9088
+ 758 => { Name => 'MovieSoundRecording', PrintConv => { 0 => 'Off', 1 => 'Auto', 2 => 'Manual' }, Unknown => 1 },
9089
+ 760 => { Name => 'MicrophoneSensitivity', Unknown => 1 }, # 1-20
9090
+ 762 => { Name => 'MicrophoneAttenuator', PrintConv => \%offOn, Unknown => 1 }, # distinct from MoveieVRMode
9091
+ 764 => { Name => 'MicrophoneFrequencyResponse',PrintConv => { 0 => 'Wide Range', 1 => 'Vocal Range' }, Unknown => 1 },
9092
+ 766 => { Name => 'WindNoiseReduction', PrintConv => \%offOn, Unknown => 1 },
9093
+ 788 => { Name => 'MovieToneMap', PrintConv => \%movieToneMapZ9, Unknown => 1 },
9094
+ 794 => { Name => 'MovieFrameSize', PrintConv => \%movieFrameSizeZ9, Unknown => 1 },
9095
+ 796 => { Name => 'MovieFrameRate', PrintConv => \%movieFrameRateZ7, Unknown => 1 },
9096
+ 802 => { Name => 'MicrophoneJackPower', PrintConv => \%offOn, Unknown => 1 },
9097
+ 803 => { Name => 'MovieDXCropAlert', PrintConv => \%offOn, Unknown => 1 },
9098
+ 804 => { Name => 'MovieSubjectDetection', PrintConv => \%subjectDetectionZ9, Unknown => 1 },
9099
+ 812 => { Name => 'MovieHighResZoom', PrintConv => \%offOn, Unknown => 1 },
9100
+ 847 => {
9101
+ Name => 'CustomSettingsZ9',
9102
+ Format => 'undef[608]',
9103
+ SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsZ9' },
9104
+ },
9105
+ 1474 => { Name => 'Language', PrintConv => \%languageZ9, Unknown => 1 },
9106
+ 1476 => { Name => 'TimeZone', PrintConv => \%timeZoneZ9 },
9107
+ 1482 => { Name => 'MonitorBrightness', PrintConv => \%monitorBrightnessZ9, Unknown => 1 }, # settings: -5 to +5. Added with firmware 3.0: Lo1, Lo2, Hi1, Hi2
9108
+ 1504 => { Name => 'AFFineTune', PrintConv => \%offOn, Unknown => 1 },
9109
+ 1600 => { Name => 'HDMIOutputResolution', PrintConv => \%hDMIOutputResolutionZ9 },
9110
+ 1613 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
9111
+ 1620 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
9112
+ 1621 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
9113
+ 1656 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
9114
+ 1680 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
9115
+ 1684 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
9116
+ 1693 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
9117
+ 1754 => {
9118
+ Name => 'FocusShiftAutoReset',
9119
+ Unknown => 1,
9120
+ PrintConv => \%offOn,
9121
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9122
+ },
9123
+ 1810 => { #CSd4-a
9124
+ Name => 'PreReleaseBurstLength',
9125
+ PrintConv => {
9126
+ 0 => 'None',
9127
+ 1 => '0.3 Sec',
9128
+ 2 => '0.5 Sec',
9129
+ 3 => '1 Sec',
9459
9130
  },
9460
- {
9461
- Name => 'FlashGroupCCompensation',
9462
- Format => 'int8s',
9463
- ValueConv => '-$val/6',
9464
- ValueConvInv => '-6 * $val',
9465
- PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
9466
- PrintConvInv => '$val',
9131
+ },
9132
+ 1812 => { #CSd4-b
9133
+ Name => 'PostReleaseBurstLength',
9134
+ PrintConv => {
9135
+ 0 => '1 Sec',
9136
+ 1 => '2 Sec',
9137
+ 2 => '3 Sec',
9138
+ 3 => 'Max',
9467
9139
  },
9468
- ],
9140
+ },
9141
+ #1824 ReleaseTimingIndicatorTypeADelay CSd14-b 0 => '1/200' ... 15 => '1/6'
9142
+ #1826 VerticalISOButton CSf2
9143
+ #1828 ExposureCompensationButton CSf2
9144
+ #1830 ISOButton CSf2
9145
+ #1890 ViewModeShowEffectsOfSettings CSd9-a 0=>'Always', 1=> 'Only When Flash Not Used'
9146
+ #1892 DispButton CSf2
9147
+ #1936 FocusPointDisplayOption3DTrackingColor CSa11-d 0=> 'White', 1= => 'Red'
9469
9148
  );
9470
9149
 
9471
9150
  # Flash information (ref JD)
@@ -10749,6 +10428,21 @@ my %nikonFocalConversions = (
10749
10428
  },
10750
10429
  );
10751
10430
 
10431
+ # MakerNotes0x56 - burst info for Z9
10432
+ %Image::ExifTool::Nikon::MakerNotes0x56 = (
10433
+ %binaryDataAttrs,
10434
+ GROUPS => { 0 => 'MakerNotes' },
10435
+ 0 => {
10436
+ Name => 'FirmwareVersion',
10437
+ Format => 'string[4]',
10438
+ Writable => 0,
10439
+ },
10440
+ 4 => {
10441
+ Name => 'BurstGroupID', #all frames shot within a burst (using CL/CH/C30/C60/C120) will share the same BurstGroupID. Value will be > 0 for all images shot in continuous modes. 0 for single-frame.
10442
+ Format => 'int16u'
10443
+ },
10444
+ );
10445
+
10752
10446
  # extra info found in IFD0 of NEF files (ref PH, Z6/Z7)
10753
10447
  %Image::ExifTool::Nikon::NEFInfo = (
10754
10448
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
@@ -11482,8 +11176,8 @@ my %nikonFocalConversions = (
11482
11176
  Name => 'LensData0201',
11483
11177
  SubDirectory => {
11484
11178
  TagTable => 'Image::ExifTool::Nikon::LensData01',
11485
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11486
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11179
+ ProcessProc => \&ProcessNikonEncrypted,
11180
+ WriteProc => \&ProcessNikonEncrypted,
11487
11181
  DecryptStart => 4,
11488
11182
  },
11489
11183
  },
@@ -11492,8 +11186,8 @@ my %nikonFocalConversions = (
11492
11186
  Name => 'LensData0204',
11493
11187
  SubDirectory => {
11494
11188
  TagTable => 'Image::ExifTool::Nikon::LensData0204',
11495
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11496
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11189
+ ProcessProc => \&ProcessNikonEncrypted,
11190
+ WriteProc => \&ProcessNikonEncrypted,
11497
11191
  DecryptStart => 4,
11498
11192
  },
11499
11193
  },
@@ -11502,8 +11196,8 @@ my %nikonFocalConversions = (
11502
11196
  Name => 'LensData0400',
11503
11197
  SubDirectory => {
11504
11198
  TagTable => 'Image::ExifTool::Nikon::LensData0400',
11505
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11506
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11199
+ ProcessProc => \&ProcessNikonEncrypted,
11200
+ WriteProc => \&ProcessNikonEncrypted,
11507
11201
  DecryptStart => 4,
11508
11202
  },
11509
11203
  },
@@ -11512,8 +11206,8 @@ my %nikonFocalConversions = (
11512
11206
  Name => 'LensData0402',
11513
11207
  SubDirectory => {
11514
11208
  TagTable => 'Image::ExifTool::Nikon::LensData0402',
11515
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11516
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11209
+ ProcessProc => \&ProcessNikonEncrypted,
11210
+ WriteProc => \&ProcessNikonEncrypted,
11517
11211
  DecryptStart => 4,
11518
11212
  },
11519
11213
  },
@@ -11522,8 +11216,8 @@ my %nikonFocalConversions = (
11522
11216
  Name => 'LensData0403',
11523
11217
  SubDirectory => {
11524
11218
  TagTable => 'Image::ExifTool::Nikon::LensData0403',
11525
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11526
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11219
+ ProcessProc => \&ProcessNikonEncrypted,
11220
+ WriteProc => \&ProcessNikonEncrypted,
11527
11221
  DecryptStart => 4,
11528
11222
  },
11529
11223
  },
@@ -11532,8 +11226,8 @@ my %nikonFocalConversions = (
11532
11226
  Name => 'LensData0800',
11533
11227
  SubDirectory => {
11534
11228
  TagTable => 'Image::ExifTool::Nikon::LensData0800',
11535
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11536
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11229
+ ProcessProc => \&ProcessNikonEncrypted,
11230
+ WriteProc => \&ProcessNikonEncrypted,
11537
11231
  DecryptStart => 4,
11538
11232
  ByteOrder => 'LittleEndian',
11539
11233
  # 0x5a0c - NikonMeteringMode for some Z6 ver1.00 samples (ref PH)
@@ -11543,8 +11237,8 @@ my %nikonFocalConversions = (
11543
11237
  Name => 'LensDataUnknown',
11544
11238
  SubDirectory => {
11545
11239
  TagTable => 'Image::ExifTool::Nikon::LensDataUnknown',
11546
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11547
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11240
+ ProcessProc => \&ProcessNikonEncrypted,
11241
+ WriteProc => \&ProcessNikonEncrypted,
11548
11242
  DecryptStart => 4,
11549
11243
  },
11550
11244
  },
@@ -11736,6 +11430,7 @@ my %nikonFocalConversions = (
11736
11430
  # construct lens ID string as per ref 11
11737
11431
  ValueConv => 'sprintf("%.2X"." %.2X"x7, @raw)',
11738
11432
  PrintConv => \%nikonLensIDs,
11433
+ PrintInt => 1,
11739
11434
  },
11740
11435
  AutoFocus => {
11741
11436
  Require => {
@@ -11894,6 +11589,7 @@ sub PrintAFPointsLeftRight($$)
11894
11589
  {
11895
11590
  my ($col, $ncol) = @_;
11896
11591
  my $center = 1 + ($ncol + 1)/2;
11592
+ return 'n/a' if $col == 0; #out of focus
11897
11593
  return 'C' if $col == $center;
11898
11594
  return sprintf('%d', $center - $col) . 'L of Center' if $col < $center;
11899
11595
  return sprintf('%d', $col - $center) . 'R of Center' if $col > $center;
@@ -11907,6 +11603,7 @@ sub PrintAFPointsUpDown($$)
11907
11603
  {
11908
11604
  my ($row, $nrow) = @_;
11909
11605
  my $center = 1 + ($nrow + 1)/2;
11606
+ return 'n/a' if $row == 0; #out of focus
11910
11607
  return 'C' if $row == $center;
11911
11608
  return sprintf('%d', $center - $row) . 'U from Center' if $row < $center;
11912
11609
  return sprintf('%d', $row - $center) . 'D from Center' if $row > $center;
@@ -12057,37 +11754,54 @@ my @xlat = (
12057
11754
  0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f ]
12058
11755
  );
12059
11756
 
11757
+ my ($ci0, $cj0, $ck0, $decryptStart); # decryption parameters
11758
+
12060
11759
  # Decrypt Nikon data block (ref 4)
12061
- # Inputs: 0) reference to data block, 1) serial number key, 2) shutter count key
12062
- # 4) optional start offset (default 0)
12063
- # 5) optional number of bytes to decode (default to the end of the data)
11760
+ # Inputs: 0) reference to data block, 1) optional start offset (default 0)
11761
+ # 2) optional number of bytes to decode (default to the end of the data)
11762
+ # 3) optional serial number key (undef to continue previous decryption)
11763
+ # 4) optional shutter count key
12064
11764
  # Returns: data block with specified data decrypted
12065
- sub Decrypt($$$;$$)
11765
+ # Notes: The first time this is called for a given encrypted data block the serial/count
11766
+ # keys must be defined, and $start must be the offset for initialization of the
11767
+ # decryption parameters (ie. the beginning of the encrypted data, which isn't
11768
+ # necessarily inside the data block if $len is zero). Subsequent calls for
11769
+ # the same data block do not specify the serial/count keys, and may be used
11770
+ # to decrypt data at any start point within the full data block.
11771
+ sub Decrypt($;$$$$)
12066
11772
  {
12067
- my ($dataPt, $serial, $count, $start, $len) = @_;
12068
- my ($i, $dat);
11773
+ my ($dataPt, $start, $len, $serial, $count) = @_;
11774
+ my ($ch, $cj, $ck);
12069
11775
 
12070
11776
  $start or $start = 0;
12071
11777
  my $maxLen = length($$dataPt) - $start;
12072
11778
  $len = $maxLen if not defined $len or $len > $maxLen;
12073
- return $$dataPt if $len <= 0;
12074
- my $key = 0;
12075
- for ($i=0; $i<4; ++$i) {
12076
- $key ^= ($count >> ($i*8)) & 0xff;
11779
+ if (defined $serial and defined $count) {
11780
+ # initialize decryption parameters
11781
+ my $key = 0;
11782
+ $key ^= ($count >> ($_*8)) & 0xff foreach 0..3;
11783
+ $ci0 = $xlat[0][$serial & 0xff];
11784
+ $cj0 = $xlat[1][$key];
11785
+ $ck0 = 0x60;
11786
+ undef $decryptStart;
11787
+ }
11788
+ if (defined $decryptStart) {
11789
+ # initialize decryption parameters for this start position
11790
+ my $n = $start - $decryptStart;
11791
+ $cj = ($cj0 + $ci0 * ($n * $ck0 + ($n * ($n - 1))/2)) & 0xff;
11792
+ $ck = ($ck0 + $n) & 0xff;
11793
+ } else {
11794
+ $decryptStart = $start;
11795
+ ($cj, $ck) = ($cj0, $ck0);
12077
11796
  }
12078
- my $ci = $xlat[0][$serial & 0xff];
12079
- my $cj = $xlat[1][$key];
12080
- my $ck = 0x60;
12081
- my @data = unpack("x${start}C$len", $$dataPt);
12082
- foreach $dat (@data) {
12083
- $cj = ($cj + $ci * $ck) & 0xff;
11797
+ return $$dataPt if $len <= 0;
11798
+ my @data = unpack('C*', substr($$dataPt, $start, $len));
11799
+ foreach $ch (@data) {
11800
+ $cj = ($cj + $ci0 * $ck) & 0xff;
12084
11801
  $ck = ($ck + 1) & 0xff;
12085
- $dat ^= $cj;
11802
+ $ch ^= $cj;
12086
11803
  }
12087
- my $end = $start + $len;
12088
- my $pre = $start ? substr($$dataPt, 0, $start) : '';
12089
- my $post = $end < length($$dataPt) ? substr($$dataPt, $end) : '';
12090
- return $pre . pack('C*',@data) . $post;
11804
+ return substr($$dataPt, 0, $start) . pack('C*', @data) . substr($$dataPt, $start+$len);
12091
11805
  }
12092
11806
 
12093
11807
  #------------------------------------------------------------------------------
@@ -12123,19 +11837,19 @@ sub ProcessNikonApp($;$)
12123
11837
  my $trailerLen = unpack('N', $buff);
12124
11838
  $trailerLen > $fileEnd and $et->Warn('Bad NikonApp trailer size'), return 0;
12125
11839
  if ($dirInfo) {
12126
- $$dirInfo{DirLen} = $trailerLen if $dirInfo;
11840
+ $$dirInfo{DirLen} = $trailerLen;
12127
11841
  $$dirInfo{DataPos} = $fileEnd - $trailerLen;
12128
11842
  if ($$dirInfo{OutFile}) {
12129
11843
  if ($$et{DEL_GROUP}{NikonApp}) {
11844
+ $et->VPrint(0, " Deleting NikonApp trailer ($trailerLen bytes)\n");
12130
11845
  ++$$et{CHANGED};
12131
- # just copy the trailer when writing
11846
+ # just copy the trailer when writing (read directly into output buffer)
12132
11847
  } elsif ($trailerLen > $fileEnd or not $raf->Seek($$dirInfo{DataPos}, 0) or
12133
11848
  $raf->Read(${$$dirInfo{OutFile}}, $trailerLen) != $trailerLen)
12134
11849
  {
12135
11850
  return 0;
12136
- } else {
12137
- return 1;
12138
11851
  }
11852
+ return 1;
12139
11853
  }
12140
11854
  $et->DumpTrailer($dirInfo) if $verbose or $$et{HTML_DUMP};
12141
11855
  }
@@ -12223,6 +11937,166 @@ sub ProcessNikonMOV($$$)
12223
11937
  return 1;
12224
11938
  }
12225
11939
 
11940
+ #------------------------------------------------------------------------------
11941
+ # Get offset of end-of-data for a tag
11942
+ # Inputs: 0) tag table ref, 1) tag ID, 2) true to not calculate end for a SubDirectory
11943
+ # Returns: offset of tag value end, undef if it can't be determined
11944
+ sub GetTagEnd($$;$)
11945
+ {
11946
+ my ($tagTablePtr, $tagID, $ignoreSubdir) = @_;
11947
+ my $tagInfo = $$tagTablePtr{$tagID};
11948
+ $tagInfo = $$tagInfo[0] if ref $tagInfo eq 'ARRAY';
11949
+ # (can't pre-determine position of offset-based subdirectories)
11950
+ return undef if $ignoreSubdir and $$tagInfo{SubDirectory};
11951
+ my $fmt = $$tagInfo{Format} || $$tagTablePtr{FORMAT} || 'int8u';
11952
+ my $nm = $fmt =~ s/\[(\d+)\]$// ? $1 : 1;
11953
+ my $sz = Image::ExifTool::FormatSize($fmt) or return undef;
11954
+ return int($tagID) + $sz * $nm;
11955
+ }
11956
+
11957
+ #------------------------------------------------------------------------------
11958
+ # Initialize SubDirectory KnownStart/KnownEnd limits of known tags (used in decryption)
11959
+ # Inputs: 0) tagInfo ref containing this SubDirectory, 2) tag table ref for encrypted subdir
11960
+ # Notes: KnownStart/KnownEnd are relative to the SubDirectory Start. If KnownStart/KnownEnd
11961
+ # aren't set then the entire data is decrypted, so all of this effort is just for speed.
11962
+ sub InitEncryptedSubdir($$)
11963
+ {
11964
+ my ($tagInfo, $tagTablePtr) = @_;
11965
+ #
11966
+ # for encrypted NIKON_OFFSETS tables we loop through all SubDirectory tags in this table
11967
+ # and set the KnownEnd for each of these according to the last tag in the child tables
11968
+ #
11969
+ my $vars = $$tagTablePtr{VARS};
11970
+ $vars or $vars = $$tagTablePtr{VARS} = { };
11971
+ if ($$vars{NIKON_OFFSETS} and not $$vars{NIKON_INITIALIZED}) {
11972
+ $$vars{NIKON_INITIALIZED} = 1;
11973
+ my $tagID;
11974
+ foreach $tagID (TagTableKeys($tagTablePtr)) {
11975
+ my $tagInfo = $$tagTablePtr{$tagID};
11976
+ next unless ref $tagInfo eq 'HASH';
11977
+ my $subdir = $$tagInfo{SubDirectory} or next;
11978
+ my $tbl = GetTagTable($$subdir{TagTable});
11979
+ my ($last) = sort { $b <=> $a } TagTableKeys($tbl); # (reverse sort)
11980
+ $$subdir{KnownEnd} = GetTagEnd($tbl, $last, 1);
11981
+ }
11982
+ }
11983
+ #
11984
+ # for other encrypted Nikon tables we set the KnownStart/KnownEnd entries in the
11985
+ # SubDirectory of the parent tag
11986
+ #
11987
+ unless ($$tagInfo{NikonInitialized}) {
11988
+ $$tagInfo{NikonInitialized} = 1;
11989
+ my $subdir = $$tagInfo{SubDirectory};
11990
+ my $start = $$subdir{DecryptStart} || 0;
11991
+ my $off = $$subdir{DirOffset};
11992
+ my @tagIDs = sort { $a <=> $b } TagTableKeys($tagTablePtr);
11993
+ if (defined $off) {
11994
+ $off += $start; # (DirOffset, if specified, is relative to DecryptStart)
11995
+ } else {
11996
+ # ignore tags that come before the start of encryption
11997
+ shift @tagIDs while @tagIDs and $tagIDs[0] < $start;
11998
+ $off = 0;
11999
+ }
12000
+ if (@tagIDs) {
12001
+ my ($first, $last) = @tagIDs[0,-1];
12002
+ my $lastInfo = $$tagTablePtr{$last};
12003
+ $lastInfo = $$lastInfo[0] if ref $lastInfo eq 'ARRAY';
12004
+ $$subdir{KnownStart} = int($first) + $off if $first + $off > $start;
12005
+ $$subdir{KnownEnd} = GetTagEnd($tagTablePtr, $last);
12006
+ if (defined $$subdir{KnownEnd}) {
12007
+ $$subdir{KnownEnd} += $off;
12008
+ } else {
12009
+ warn "Internal error setting KnownEnd for $$tagTablePtr{SHORT_NAME}\n";
12010
+ }
12011
+ } else {
12012
+ $$subdir{KnownStart} = $$subdir{KnownEnd} = $start;
12013
+ }
12014
+ }
12015
+ }
12016
+
12017
+ #------------------------------------------------------------------------------
12018
+ # Prepare to process NIKON_OFFSETS directory and decrypt necessary data
12019
+ # Inputs: 0) ExifTool ref, 1) data ref, 2) tag table ref, 3) decrypt start,
12020
+ # 4) decrypt mode (0=piecewise, 1=continuous to end of last known section, 2=all)
12021
+ # Returns: end of decrypted data (or undef for piecewise decryption)
12022
+ sub PrepareNikonOffsets($$$$$)
12023
+ {
12024
+ my ($et, $dataPt, $tagTablePtr, $start, $decryptMode) = @_;
12025
+ my $offset = $$tagTablePtr{VARS}{NIKON_OFFSETS};
12026
+ my $dataLen = length $$dataPt;
12027
+ return undef if $offset + 4 > $dataLen or $offset < $start;
12028
+ my $serial = $$et{NikonSerialKey};
12029
+ my $count = $$et{NikonCountKey};
12030
+ my $dpos = $offset + 4; # decrypt up to NumberOffsets
12031
+ $$dataPt = Decrypt($dataPt, $start, $dpos - $start, $serial, $count);
12032
+ my $numOffsets = Get32u($dataPt, $offset);
12033
+ my $more = $numOffsets * 4; # more bytes to decrypt entire offsets table
12034
+ return undef if $offset + 4 + $more > $dataLen;
12035
+ $$dataPt = Decrypt($dataPt, $dpos, $more);
12036
+ $dpos += $more;
12037
+ my $unknown = $et->Options('Unknown');
12038
+ my ($i, @offInfo, $end);
12039
+ # extract non-zero offsets and create unknown subdirectories if Unknown > 1
12040
+ for ($i=0; $i<$numOffsets; ++$i) {
12041
+ my $pos = $offset + 4 + 4 * $i;
12042
+ my $off = Get32u($dataPt, $pos) or next;
12043
+ my $tagInfo = $$tagTablePtr{$pos};
12044
+ my $known = 0;
12045
+ if ($tagInfo) {
12046
+ $known = 1 if ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown};
12047
+ } elsif ($unknown > 1) {
12048
+ # create new table for unknown information
12049
+ my $tbl = sprintf('Image::ExifTool::Nikon::UnknownInfo%.2x', $pos);
12050
+ no strict 'refs';
12051
+ unless (%$tbl) {
12052
+ %$tbl = ( %binaryDataAttrs, GROUPS => { 0=>'MakerNotes', 2=>'Unknown' } );
12053
+ GetTagTable($tbl);
12054
+ }
12055
+ # add unknown entry in offset table for this subdirectory
12056
+ $tagInfo = AddTagToTable($tagTablePtr, $pos, {
12057
+ Name => sprintf('UnknownOffset%.2x', $pos),
12058
+ Format => 'int32u',
12059
+ SubDirectory => { TagTable => $tbl },
12060
+ Unknown => 2,
12061
+ });
12062
+ }
12063
+ push @offInfo, [ $pos, $off, $known ]; # save parameters for non-zero offsets
12064
+ }
12065
+ # sort offsets in ascending order, and use the differences to calculate
12066
+ # directory lengths and update the SubDirectory DirLen's accordingly
12067
+ my @sorted = sort { $$a[1] <=> $$b[1] or $$a[0] <=> $$b[0] } @offInfo;
12068
+ push @sorted, [ 0, length($$dataPt), 0 ];
12069
+ for ($i=0; $i<@sorted-1; ++$i) {
12070
+ my $pos = $sorted[$i][0];
12071
+ my $len = $sorted[$i+1][1] - $sorted[$i][1];
12072
+ # set DirLen in SubDirectory entry
12073
+ my $tagInfo = $$tagTablePtr{$pos};
12074
+ my $subdir;
12075
+ $$subdir{DirLen} = $len if ref $tagInfo eq 'HASH' and defined($subdir=$$tagInfo{SubDirectory});
12076
+ if ($decryptMode) {
12077
+ # keep track of end of last known directory
12078
+ $end = $sorted[$i+1][1] if $sorted[$i][2];
12079
+ } elsif ($tagInfo and (ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown})) {
12080
+ # decrypt data piecewise as necessary
12081
+ my $n = $len;
12082
+ if ($subdir and $$subdir{KnownEnd}) {
12083
+ $n = $$subdir{KnownEnd};
12084
+ if ($n > $len) {
12085
+ $et->Warn("Data too short for $$tagInfo{Name}",1);
12086
+ $n = $len;
12087
+ }
12088
+ }
12089
+ $$dataPt = Decrypt($dataPt, $sorted[$i][1], $n);
12090
+ }
12091
+ }
12092
+ if ($decryptMode) {
12093
+ # decrypt the remaining required data
12094
+ $end = length $$dataPt if $decryptMode == 2 or not $end or $end < $dpos;
12095
+ $$dataPt = Decrypt($dataPt, $dpos, $end - $dpos);
12096
+ }
12097
+ return $end;
12098
+ }
12099
+
12226
12100
  #------------------------------------------------------------------------------
12227
12101
  # Read/Write Nikon Encrypted data block
12228
12102
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -12247,15 +12121,17 @@ sub ProcessNikonEncrypted($$$)
12247
12121
  delete $$et{NikonCountKey};
12248
12122
  return 0;
12249
12123
  }
12250
- my $verbose = $$dirInfo{IsWriting} ? 0 : $et->Options('Verbose');
12124
+ my $oldOrder = GetByteOrder();
12125
+ my $isWriting = $$dirInfo{IsWriting};
12126
+ my $verbose = $isWriting ? 0 : $et->Options('Verbose');
12251
12127
  my $tagInfo = $$dirInfo{TagInfo};
12252
12128
  my $dirStart = $$dirInfo{DirStart};
12253
12129
  my $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen});
12254
12130
 
12255
- my ($start, $len, $more, $offset, $byteOrder, $recrypt, $newSerial, $newCount);
12131
+ my ($start, $len, $offset, $recrypt, $newSerial, $newCount, $didDecrypt);
12256
12132
 
12257
12133
  # must re-encrypt when writing if serial number or shutter count changes
12258
- if ($$dirInfo{IsWriting}) {
12134
+ if ($isWriting) {
12259
12135
  if ($$et{NewNikonSerialKey}) {
12260
12136
  $newSerial = $$et{NewNikonSerialKey};
12261
12137
  $recrypt = 1;
@@ -12266,46 +12142,43 @@ sub ProcessNikonEncrypted($$$)
12266
12142
  }
12267
12143
  }
12268
12144
  if ($tagInfo and $$tagInfo{SubDirectory}) {
12269
- $start = $$tagInfo{SubDirectory}{DecryptStart};
12270
- # may decrypt only part of the information to save time
12271
- if ($verbose < 3 and $et->Options('Unknown') < 2 and not $recrypt) {
12272
- $len = $$tagInfo{SubDirectory}{DecryptLen};
12273
- $more = $$tagInfo{SubDirectory}{DecryptMore};
12145
+ # initialize SubDirectory entries used in encryption (KnownStart, KnownEnd)
12146
+ InitEncryptedSubdir($tagInfo, $tagTablePtr);
12147
+ my $subdir = $$tagInfo{SubDirectory};
12148
+ $start = $$subdir{DecryptStart} || 0;
12149
+ # DirOffset, if specified, is the offset to the start of the
12150
+ # directory relative to start of encrypted data
12151
+ $offset = defined $$subdir{DirOffset} ? $$subdir{DirOffset} + $start : 0;
12152
+ # must set byte ordering before calling PrepareNikonOffsets()
12153
+ SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
12154
+ # prepare for processing NIKON_OFFSETS directory if necessary
12155
+ my $unknown = $verbose > 2 || $et->Options('Unknown') > 1;
12156
+ # decrypt mode: 0=piecewise, 1=continuous to end of last known section, 2=all
12157
+ my $dMode = $isWriting ? ($recrypt ? 2 : 1) : ($unknown ? 2 : 0);
12158
+ if ($$tagTablePtr{VARS}{NIKON_OFFSETS}) {
12159
+ $len = PrepareNikonOffsets($et, \$data, $tagTablePtr, $start, $dMode);
12160
+ $didDecrypt = 1;
12161
+ } elsif ($dMode < 2) {
12162
+ if ($dMode == 0 and $$subdir{KnownStart}) {
12163
+ # initialize decryption parameters for address DecryptStart address
12164
+ Decrypt(\$data, $start, 0, $serial, $count);
12165
+ # reset serial/count keys so we don't re-initialize below
12166
+ undef $serial;
12167
+ undef $count;
12168
+ # change decryption start to skip unnecessary data
12169
+ $start = $$subdir{KnownStart};
12170
+ }
12171
+ $len = $$subdir{KnownEnd} - $start if $$subdir{KnownEnd};
12274
12172
  }
12275
- $offset = $$tagInfo{SubDirectory}{DirOffset};
12276
- $byteOrder = $$tagInfo{SubDirectory}{ByteOrder};
12277
- }
12278
- $start or $start = 0;
12279
- if (defined $offset) {
12280
- # offset, if specified, is relative to start of encrypted data
12281
- $offset += $start;
12282
12173
  } else {
12283
- $offset = 0;
12174
+ $start = $offset = 0;
12284
12175
  }
12285
12176
  my $maxLen = length($data) - $start;
12286
- # decrypt all the data unless DecryptLen is given
12287
- unless ($len and $len < $maxLen) {
12288
- $len = $maxLen;
12289
- undef $more; # (can't decrypt more than this)
12290
- }
12177
+ # decrypt all the data unless the length was specified
12178
+ $len = $maxLen unless $len and $len < $maxLen;
12291
12179
 
12292
- $data = Decrypt(\$data, $serial, $count, $start, $len);
12180
+ $data = Decrypt(\$data, $start, $len, $serial, $count) unless $didDecrypt;
12293
12181
 
12294
- # set appropriate byte ordering before evaluating DecryptMore
12295
- my $oldOrder = GetByteOrder();
12296
- SetByteOrder($byteOrder) if $byteOrder;
12297
-
12298
- if ($more) {
12299
- #### eval DecryptMore ($data)
12300
- my $moreLen = eval $more;
12301
- $moreLen = $maxLen if $moreLen > $maxLen;
12302
- # re-decrypt with new length
12303
- if ($len < $moreLen) {
12304
- $len = $moreLen;
12305
- $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen});
12306
- $data = Decrypt(\$data, $serial, $count, $start, $len);
12307
- }
12308
- }
12309
12182
  if ($verbose > 2) {
12310
12183
  $et->VerboseDir("Decrypted $$tagInfo{Name}");
12311
12184
  $et->VerboseDump(\$data,
@@ -12324,7 +12197,7 @@ sub ProcessNikonEncrypted($$$)
12324
12197
  Base => $$dirInfo{Base},
12325
12198
  );
12326
12199
  my $rtnVal;
12327
- if ($$dirInfo{IsWriting}) {
12200
+ if ($isWriting) {
12328
12201
  my $changed = $$et{CHANGED};
12329
12202
  $rtnVal = $et->WriteBinaryData(\%subdirInfo, $tagTablePtr);
12330
12203
  # must re-encrypt if serial number or shutter count changes
@@ -12339,7 +12212,8 @@ sub ProcessNikonEncrypted($$$)
12339
12212
  # add back any un-encrypted data at start
12340
12213
  $rtnVal = substr($data, 0, $offset) . $rtnVal if $offset;
12341
12214
  # re-encrypt data (symmetrical algorithm)
12342
- $rtnVal = Decrypt(\$rtnVal, $serial, $count, $start, $len);
12215
+ $rtnVal = Decrypt(\$rtnVal, $start, $len, $serial, $count);
12216
+ $et->VPrint(2, $$et{INDENT}, " [recrypted $$tagInfo{Name}]");
12343
12217
  }
12344
12218
  } else {
12345
12219
  $rtnVal = $et->ProcessBinaryData(\%subdirInfo, $tagTablePtr);