exiftool-vendored.pl 12.56.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 (59) hide show
  1. package/bin/Changes +80 -5
  2. package/bin/MANIFEST +4 -0
  3. package/bin/META.json +1 -1
  4. package/bin/META.yml +1 -1
  5. package/bin/README +2 -2
  6. package/bin/config_files/example.config +1 -0
  7. package/bin/config_files/rotate_regions.config +1 -1
  8. package/bin/exiftool +174 -99
  9. package/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  10. package/bin/lib/Image/ExifTool/APE.pm +2 -2
  11. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +19 -15
  12. package/bin/lib/Image/ExifTool/Canon.pm +26 -6
  13. package/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
  14. package/bin/lib/Image/ExifTool/DJI.pm +28 -2
  15. package/bin/lib/Image/ExifTool/Exif.pm +77 -19
  16. package/bin/lib/Image/ExifTool/FlashPix.pm +32 -10
  17. package/bin/lib/Image/ExifTool/FujiFilm.pm +7 -3
  18. package/bin/lib/Image/ExifTool/GPS.pm +7 -2
  19. package/bin/lib/Image/ExifTool/Geotag.pm +30 -7
  20. package/bin/lib/Image/ExifTool/JPEG.pm +14 -2
  21. package/bin/lib/Image/ExifTool/Jpeg2000.pm +5 -5
  22. package/bin/lib/Image/ExifTool/LIF.pm +10 -2
  23. package/bin/lib/Image/ExifTool/LNK.pm +5 -4
  24. package/bin/lib/Image/ExifTool/MIE.pm +3 -3
  25. package/bin/lib/Image/ExifTool/MPEG.pm +2 -2
  26. package/bin/lib/Image/ExifTool/MakerNotes.pm +3 -2
  27. package/bin/lib/Image/ExifTool/Minolta.pm +6 -7
  28. package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
  29. package/bin/lib/Image/ExifTool/Nikon.pm +1003 -907
  30. package/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
  31. package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
  32. package/bin/lib/Image/ExifTool/Olympus.pm +88 -6
  33. package/bin/lib/Image/ExifTool/PNG.pm +10 -2
  34. package/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
  35. package/bin/lib/Image/ExifTool/Pentax.pm +8 -5
  36. package/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
  37. package/bin/lib/Image/ExifTool/Photoshop.pm +38 -7
  38. package/bin/lib/Image/ExifTool/QuickTime.pm +44 -13
  39. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +40 -6
  40. package/bin/lib/Image/ExifTool/README +19 -2
  41. package/bin/lib/Image/ExifTool/RIFF.pm +34 -13
  42. package/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
  43. package/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
  44. package/bin/lib/Image/ExifTool/Sigma.pm +5 -4
  45. package/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
  46. package/bin/lib/Image/ExifTool/Sony.pm +24 -1
  47. package/bin/lib/Image/ExifTool/TagLookup.pm +4678 -4628
  48. package/bin/lib/Image/ExifTool/TagNames.pod +305 -113
  49. package/bin/lib/Image/ExifTool/Validate.pm +5 -5
  50. package/bin/lib/Image/ExifTool/WriteExif.pl +42 -0
  51. package/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  52. package/bin/lib/Image/ExifTool/Writer.pl +150 -36
  53. package/bin/lib/Image/ExifTool/XMP.pm +19 -4
  54. package/bin/lib/Image/ExifTool/XMP2.pl +2 -1
  55. package/bin/lib/Image/ExifTool.pm +195 -42
  56. package/bin/lib/Image/ExifTool.pod +44 -9
  57. package/bin/perl-Image-ExifTool.spec +1 -1
  58. package/bin/pp_build_exe.args +4 -4
  59. package/package.json +3 -3
@@ -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.18';
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',
@@ -1112,6 +1118,14 @@ my %offLowNormalHighZ7 = (
1112
1118
  3 => 'High',
1113
1119
  );
1114
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
+
1115
1129
  my %secondarySlotFunctionZ9 = (
1116
1130
  0 => 'Overflow',
1117
1131
  1 => 'Backup',
@@ -1509,9 +1523,7 @@ my %base64coord = (
1509
1523
  0x0006 => { Name => 'Sharpness', Writable => 'string' },
1510
1524
  0x0007 => {
1511
1525
  Name => 'FocusMode',
1512
- DataMember => 'FocusMode',
1513
1526
  Writable => 'string',
1514
- RawConv => '$$self{FocusMode} = $val',
1515
1527
  },
1516
1528
  # FlashSetting (better named FlashSyncMode, ref 28) values:
1517
1529
  # "Normal", "Slow", "Rear Slow", "RED-EYE", "RED-EYE SLOW"
@@ -1812,6 +1824,7 @@ my %base64coord = (
1812
1824
  Name => 'ShutterMode',
1813
1825
  Writable => 'int16u',
1814
1826
  RawConv => '$$self{ShutterMode} = $val',
1827
+ DataMember => 'ShutterMode',
1815
1828
  PrintConv => {
1816
1829
  0 => 'Mechanical',
1817
1830
  16 => 'Electronic',
@@ -2059,7 +2072,6 @@ my %base64coord = (
2059
2072
  SubDirectory => {
2060
2073
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD40',
2061
2074
  DecryptStart => 4,
2062
- DecryptLen => 748,
2063
2075
  ByteOrder => 'BigEndian',
2064
2076
  },
2065
2077
  },
@@ -2069,7 +2081,6 @@ my %base64coord = (
2069
2081
  SubDirectory => {
2070
2082
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD80',
2071
2083
  DecryptStart => 4,
2072
- DecryptLen => 765,
2073
2084
  # (Capture NX can change the makernote byte order, but this stays big-endian)
2074
2085
  ByteOrder => 'BigEndian',
2075
2086
  },
@@ -2080,7 +2091,6 @@ my %base64coord = (
2080
2091
  SubDirectory => {
2081
2092
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD90',
2082
2093
  DecryptStart => 4,
2083
- DecryptLen => 0x398,
2084
2094
  ByteOrder => 'BigEndian',
2085
2095
  },
2086
2096
  },
@@ -2090,7 +2100,6 @@ my %base64coord = (
2090
2100
  SubDirectory => {
2091
2101
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD3a',
2092
2102
  DecryptStart => 4,
2093
- DecryptLen => 0x318,
2094
2103
  ByteOrder => 'BigEndian',
2095
2104
  },
2096
2105
  },
@@ -2100,7 +2109,6 @@ my %base64coord = (
2100
2109
  SubDirectory => {
2101
2110
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD3b',
2102
2111
  DecryptStart => 4,
2103
- DecryptLen => 0x321,
2104
2112
  ByteOrder => 'BigEndian',
2105
2113
  },
2106
2114
  },
@@ -2110,7 +2118,6 @@ my %base64coord = (
2110
2118
  SubDirectory => {
2111
2119
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD3X',
2112
2120
  DecryptStart => 4,
2113
- DecryptLen => 0x323,
2114
2121
  ByteOrder => 'BigEndian',
2115
2122
  },
2116
2123
  },
@@ -2120,7 +2127,6 @@ my %base64coord = (
2120
2127
  SubDirectory => {
2121
2128
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD3S',
2122
2129
  DecryptStart => 4,
2123
- DecryptLen => 0x2e9,
2124
2130
  ByteOrder => 'BigEndian',
2125
2131
  },
2126
2132
  },
@@ -2131,7 +2137,6 @@ my %base64coord = (
2131
2137
  SubDirectory => {
2132
2138
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD300a',
2133
2139
  DecryptStart => 4,
2134
- DecryptLen => 813,
2135
2140
  ByteOrder => 'BigEndian',
2136
2141
  },
2137
2142
  },
@@ -2142,7 +2147,6 @@ my %base64coord = (
2142
2147
  SubDirectory => {
2143
2148
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD300b',
2144
2149
  DecryptStart => 4,
2145
- DecryptLen => 825,
2146
2150
  ByteOrder => 'BigEndian',
2147
2151
  },
2148
2152
  },
@@ -2153,7 +2157,6 @@ my %base64coord = (
2153
2157
  SubDirectory => {
2154
2158
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD300S',
2155
2159
  DecryptStart => 4,
2156
- DecryptLen => 827,
2157
2160
  ByteOrder => 'BigEndian',
2158
2161
  },
2159
2162
  },
@@ -2164,17 +2167,33 @@ my %base64coord = (
2164
2167
  SubDirectory => {
2165
2168
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD700',
2166
2169
  DecryptStart => 4,
2167
- DecryptLen => 0x358,
2168
2170
  ByteOrder => 'BigEndian',
2169
2171
  },
2170
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
+ },
2171
2191
  { #PH (D800 firmware 1.01a)
2172
2192
  Condition => '$$valPt =~ /^0222/',
2173
2193
  Name => 'ShotInfoD800',
2174
2194
  SubDirectory => {
2175
2195
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD800',
2176
2196
  DecryptStart => 4,
2177
- DecryptLen => 0x720,
2178
2197
  ByteOrder => 'BigEndian',
2179
2198
  },
2180
2199
  },
@@ -2184,8 +2203,6 @@ my %base64coord = (
2184
2203
  SubDirectory => {
2185
2204
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD810',
2186
2205
  DecryptStart => 4,
2187
- DecryptLen => 0x36f4 + 12,
2188
- DecryptMore => 'Get32u(\$data, 0x84) + 12',
2189
2206
  ByteOrder => 'LittleEndian',
2190
2207
  },
2191
2208
  },
@@ -2195,8 +2212,6 @@ my %base64coord = (
2195
2212
  SubDirectory => {
2196
2213
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD850',
2197
2214
  DecryptStart => 4,
2198
- DecryptLen => 0x2efb + 12,
2199
- DecryptMore => 'Get32u(\$data, 0xa0) + 12',
2200
2215
  ByteOrder => 'LittleEndian',
2201
2216
  },
2202
2217
  },
@@ -2209,7 +2224,6 @@ my %base64coord = (
2209
2224
  SubDirectory => {
2210
2225
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD5000',
2211
2226
  DecryptStart => 4,
2212
- DecryptLen => 0x39a,
2213
2227
  ByteOrder => 'BigEndian',
2214
2228
  },
2215
2229
  },
@@ -2219,7 +2233,6 @@ my %base64coord = (
2219
2233
  SubDirectory => {
2220
2234
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD5100',
2221
2235
  DecryptStart => 4,
2222
- DecryptLen => 0x430,
2223
2236
  ByteOrder => 'BigEndian',
2224
2237
  },
2225
2238
  },
@@ -2229,7 +2242,6 @@ my %base64coord = (
2229
2242
  SubDirectory => {
2230
2243
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD5200',
2231
2244
  DecryptStart => 4,
2232
- DecryptLen => 0xd00,
2233
2245
  ByteOrder => 'BigEndian',
2234
2246
  },
2235
2247
  },
@@ -2239,7 +2251,6 @@ my %base64coord = (
2239
2251
  SubDirectory => {
2240
2252
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD7000',
2241
2253
  DecryptStart => 4,
2242
- DecryptLen => 0x448,
2243
2254
  ByteOrder => 'BigEndian',
2244
2255
  },
2245
2256
  },
@@ -2249,7 +2260,6 @@ my %base64coord = (
2249
2260
  SubDirectory => {
2250
2261
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD4',
2251
2262
  DecryptStart => 4,
2252
- DecryptLen => 0x789,
2253
2263
  ByteOrder => 'BigEndian',
2254
2264
  },
2255
2265
  },
@@ -2259,29 +2269,15 @@ my %base64coord = (
2259
2269
  SubDirectory => {
2260
2270
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD4S',
2261
2271
  DecryptStart => 4,
2262
- DecryptLen => 0x3697,
2263
- ByteOrder => 'LittleEndian',
2264
- },
2265
- },
2266
- { #28 (D5 firmware version 1.10a)
2267
- Condition => '$$valPt =~ /^0238/',
2268
- Name => 'ShotInfoD5',
2269
- SubDirectory => {
2270
- TagTable => 'Image::ExifTool::Nikon::ShotInfoD500',
2271
- DecryptStart => 4,
2272
- DecryptLen => 0x2c24 + 12,
2273
- DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90',
2274
2272
  ByteOrder => 'LittleEndian',
2275
2273
  },
2276
2274
  },
2277
- { # (D500 firmware version 1.00)
2278
- Condition => '$$valPt =~ /^0239/',
2275
+ { #28 (D500 firmware version 1.00 and D5 firmware version 1.10a)
2276
+ Condition => '$$valPt =~ /^023[89]/',
2279
2277
  Name => 'ShotInfoD500',
2280
2278
  SubDirectory => {
2281
2279
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD500',
2282
2280
  DecryptStart => 4,
2283
- DecryptLen => 0x2cb2 + 4,
2284
- DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90',
2285
2281
  ByteOrder => 'LittleEndian',
2286
2282
  },
2287
2283
  },
@@ -2291,7 +2287,6 @@ my %base64coord = (
2291
2287
  SubDirectory => {
2292
2288
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD6',
2293
2289
  DecryptStart => 4,
2294
- DecryptLen => 0xc292 + 720, # thru decoded parts of Offset 32
2295
2290
  ByteOrder => 'LittleEndian',
2296
2291
  },
2297
2292
  },
@@ -2301,7 +2296,6 @@ my %base64coord = (
2301
2296
  SubDirectory => {
2302
2297
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD610',
2303
2298
  DecryptStart => 4,
2304
- DecryptLen => 0x7ff,
2305
2299
  ByteOrder => 'BigEndian',
2306
2300
  },
2307
2301
  },
@@ -2312,8 +2306,6 @@ my %base64coord = (
2312
2306
  SubDirectory => {
2313
2307
  TagTable => 'Image::ExifTool::Nikon::ShotInfoZ7II',
2314
2308
  DecryptStart => 4,
2315
- # TODO: eventually set the length dynamically according to actual offsets!
2316
- DecryptLen => 0xd04e + 860, # thru decoded MenuSettingsZ7II
2317
2309
  ByteOrder => 'LittleEndian',
2318
2310
  },
2319
2311
  },
@@ -2323,8 +2315,6 @@ my %base64coord = (
2323
2315
  SubDirectory => {
2324
2316
  TagTable => 'Image::ExifTool::Nikon::ShotInfoZ9',
2325
2317
  DecryptStart => 4,
2326
- # TODO: eventually set the length dynamically according to actual offsets!
2327
- DecryptLen => 0xec4b + 2196, # decoded thru end of Offset26
2328
2318
  ByteOrder => 'LittleEndian',
2329
2319
  },
2330
2320
  },
@@ -2333,10 +2323,9 @@ my %base64coord = (
2333
2323
  Name => 'ShotInfo02xx',
2334
2324
  SubDirectory => {
2335
2325
  TagTable => 'Image::ExifTool::Nikon::ShotInfo',
2336
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2337
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2326
+ ProcessProc => \&ProcessNikonEncrypted,
2327
+ WriteProc => \&ProcessNikonEncrypted,
2338
2328
  DecryptStart => 4,
2339
- DecryptLen => 0x251,
2340
2329
  ByteOrder => 'BigEndian',
2341
2330
  },
2342
2331
  },
@@ -2400,11 +2389,10 @@ my %base64coord = (
2400
2389
  Name => 'ColorBalance0205',
2401
2390
  SubDirectory => {
2402
2391
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2403
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2404
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2392
+ ProcessProc => \&ProcessNikonEncrypted,
2393
+ WriteProc => \&ProcessNikonEncrypted,
2405
2394
  DecryptStart => 4,
2406
- DecryptLen => 22, # 284 bytes encrypted, but don't need to decrypt it all
2407
- DirOffset => 14,
2395
+ DirOffset => 14, # (start of directory relative to DecryptStart)
2408
2396
  },
2409
2397
  },
2410
2398
  { # (D3/D3X/D300/D700=0209,D300S=0212,D3S=0214)
@@ -2412,10 +2400,9 @@ my %base64coord = (
2412
2400
  Name => 'ColorBalance0209',
2413
2401
  SubDirectory => {
2414
2402
  TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
2415
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2416
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2403
+ ProcessProc => \&ProcessNikonEncrypted,
2404
+ WriteProc => \&ProcessNikonEncrypted,
2417
2405
  DecryptStart => 284,
2418
- DecryptLen => 18, # 324 bytes encrypted, but don't need to decrypt it all
2419
2406
  DirOffset => 10,
2420
2407
  },
2421
2408
  },
@@ -2424,10 +2411,9 @@ my %base64coord = (
2424
2411
  Name => 'ColorBalance02',
2425
2412
  SubDirectory => {
2426
2413
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2427
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2428
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2414
+ ProcessProc => \&ProcessNikonEncrypted,
2415
+ WriteProc => \&ProcessNikonEncrypted,
2429
2416
  DecryptStart => 284,
2430
- DecryptLen => 14, # don't need to decrypt it all
2431
2417
  DirOffset => 6,
2432
2418
  },
2433
2419
  },
@@ -2436,10 +2422,9 @@ my %base64coord = (
2436
2422
  Name => 'ColorBalance0211',
2437
2423
  SubDirectory => {
2438
2424
  TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
2439
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2440
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2425
+ ProcessProc => \&ProcessNikonEncrypted,
2426
+ WriteProc => \&ProcessNikonEncrypted,
2441
2427
  DecryptStart => 284,
2442
- DecryptLen => 24, # don't need to decrypt it all
2443
2428
  DirOffset => 16,
2444
2429
  },
2445
2430
  },
@@ -2448,10 +2433,9 @@ my %base64coord = (
2448
2433
  Name => 'ColorBalance0213',
2449
2434
  SubDirectory => {
2450
2435
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2451
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2452
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2436
+ ProcessProc => \&ProcessNikonEncrypted,
2437
+ WriteProc => \&ProcessNikonEncrypted,
2453
2438
  DecryptStart => 284,
2454
- DecryptLen => 18, # don't need to decrypt it all
2455
2439
  DirOffset => 10,
2456
2440
  },
2457
2441
  },
@@ -2460,10 +2444,9 @@ my %base64coord = (
2460
2444
  Name => 'ColorBalance0215',
2461
2445
  SubDirectory => {
2462
2446
  TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
2463
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2464
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2447
+ ProcessProc => \&ProcessNikonEncrypted,
2448
+ WriteProc => \&ProcessNikonEncrypted,
2465
2449
  DecryptStart => 284,
2466
- DecryptLen => 12, # don't need to decrypt it all
2467
2450
  DirOffset => 4,
2468
2451
  },
2469
2452
  },
@@ -2472,9 +2455,9 @@ my %base64coord = (
2472
2455
  Condition => '$$valPt =~ /^0[26]/',
2473
2456
  SubDirectory => {
2474
2457
  TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
2475
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2458
+ ProcessProc => \&ProcessNikonEncrypted,
2459
+ WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt this if serial number changed)
2476
2460
  DecryptStart => 284,
2477
- DecryptLen => 10, # (arbitrary)
2478
2461
  },
2479
2462
  },
2480
2463
  { # (1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403, Z6/Z7=0800)
@@ -2482,9 +2465,9 @@ my %base64coord = (
2482
2465
  Condition => '$$valPt =~ /^0[48]/',
2483
2466
  SubDirectory => {
2484
2467
  TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
2485
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2468
+ ProcessProc => \&ProcessNikonEncrypted,
2469
+ WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt this if serial number changed)
2486
2470
  DecryptStart => 4,
2487
- DecryptLen => 10, # (arbitrary)
2488
2471
  },
2489
2472
  },
2490
2473
  {
@@ -2513,8 +2496,8 @@ my %base64coord = (
2513
2496
  Name => 'LensData0201',
2514
2497
  SubDirectory => {
2515
2498
  TagTable => 'Image::ExifTool::Nikon::LensData01',
2516
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2517
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2499
+ ProcessProc => \&ProcessNikonEncrypted,
2500
+ WriteProc => \&ProcessNikonEncrypted,
2518
2501
  DecryptStart => 4,
2519
2502
  },
2520
2503
  },
@@ -2523,8 +2506,8 @@ my %base64coord = (
2523
2506
  Name => 'LensData0204',
2524
2507
  SubDirectory => {
2525
2508
  TagTable => 'Image::ExifTool::Nikon::LensData0204',
2526
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2527
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2509
+ ProcessProc => \&ProcessNikonEncrypted,
2510
+ WriteProc => \&ProcessNikonEncrypted,
2528
2511
  DecryptStart => 4,
2529
2512
  },
2530
2513
  },
@@ -2533,8 +2516,8 @@ my %base64coord = (
2533
2516
  Name => 'LensData0400',
2534
2517
  SubDirectory => {
2535
2518
  TagTable => 'Image::ExifTool::Nikon::LensData0400',
2536
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2537
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2519
+ ProcessProc => \&ProcessNikonEncrypted,
2520
+ WriteProc => \&ProcessNikonEncrypted,
2538
2521
  DecryptStart => 4,
2539
2522
  },
2540
2523
  },
@@ -2543,8 +2526,8 @@ my %base64coord = (
2543
2526
  Name => 'LensData0402',
2544
2527
  SubDirectory => {
2545
2528
  TagTable => 'Image::ExifTool::Nikon::LensData0402',
2546
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2547
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2529
+ ProcessProc => \&ProcessNikonEncrypted,
2530
+ WriteProc => \&ProcessNikonEncrypted,
2548
2531
  DecryptStart => 4,
2549
2532
  },
2550
2533
  },
@@ -2553,8 +2536,8 @@ my %base64coord = (
2553
2536
  Name => 'LensData0403',
2554
2537
  SubDirectory => {
2555
2538
  TagTable => 'Image::ExifTool::Nikon::LensData0403',
2556
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2557
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2539
+ ProcessProc => \&ProcessNikonEncrypted,
2540
+ WriteProc => \&ProcessNikonEncrypted,
2558
2541
  DecryptStart => 4,
2559
2542
  },
2560
2543
  },
@@ -2563,8 +2546,8 @@ my %base64coord = (
2563
2546
  Name => 'LensData0800',
2564
2547
  SubDirectory => {
2565
2548
  TagTable => 'Image::ExifTool::Nikon::LensData0800',
2566
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2567
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2549
+ ProcessProc => \&ProcessNikonEncrypted,
2550
+ WriteProc => \&ProcessNikonEncrypted,
2568
2551
  DecryptStart => 4,
2569
2552
  ByteOrder => 'LittleEndian',
2570
2553
  },
@@ -2573,8 +2556,8 @@ my %base64coord = (
2573
2556
  Name => 'LensDataUnknown',
2574
2557
  SubDirectory => {
2575
2558
  TagTable => 'Image::ExifTool::Nikon::LensDataUnknown',
2576
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2577
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2559
+ ProcessProc => \&ProcessNikonEncrypted,
2560
+ WriteProc => \&ProcessNikonEncrypted,
2578
2561
  DecryptStart => 4,
2579
2562
  },
2580
2563
  },
@@ -5279,7 +5262,7 @@ my %nikonFocalConversions = (
5279
5262
  Name => 'NewLensData',
5280
5263
  Format => 'undef[17]',
5281
5264
  RawConv => '$$self{NewLensData} = 1 unless $val =~ /^.\0+$/s; undef',
5282
- Hidden => 1,
5265
+ #Hidden => 1,
5283
5266
  },
5284
5267
  0x30 => { #PH
5285
5268
  Name => 'LensID',
@@ -5305,14 +5288,17 @@ my %nikonFocalConversions = (
5305
5288
  23 => 'Nikkor Z 14-24mm f/2.8 S', #IB
5306
5289
  24 => 'Nikkor Z MC 105mm f/2.8 VR S', #IB
5307
5290
  25 => 'Nikkor Z 40mm f/2', #28
5291
+ 26 => 'Nikkor Z DX 18-140mm f/3.5-6.3 VR', #IB
5308
5292
  27 => 'Nikkor Z MC 50mm f/2.8', #IB
5309
5293
  28 => 'Nikkor Z 100-400mm f/4.5-5.6 VR S', #28
5310
5294
  29 => 'Nikkor Z 28mm f/2.8', #IB
5311
5295
  30 => 'Nikkor Z 400mm f/2.8 TC VR S', #28
5312
5296
  31 => 'Nikkor Z 24-120 f/4', #28
5313
5297
  32 => 'Nikkor Z 800mm f/6.3 VR S', #28
5298
+ 35 => 'Nikkor Z 28-75mm f/2.8', #IB
5314
5299
  36 => 'Nikkor Z 400mm f/4.5 VR S', #IB
5315
5300
  37 => 'Nikkor Z 600mm f/4 TC VR S', #28
5301
+ 38 => 'Nikkor Z 85mm f/1.2 S', #28
5316
5302
  39 => 'Nikkor Z 17-28mm f/2.8', #IB
5317
5303
  32768 => 'Nikkor Z 400mm f/2.8 TC VR S TC-1.4x', #28
5318
5304
  32769 => 'Nikkor Z 600mm f/4 TC VR S TC-1.4x', #28
@@ -5322,7 +5308,7 @@ my %nikonFocalConversions = (
5322
5308
  Name => 'LensMountType',
5323
5309
  RawConv => '$$self{LensMountType} = $val', # 0=> DSLR lens via FTZ style adapter; 1=> Native Z lens;
5324
5310
  Format => 'int8u',
5325
- Unknown => 1,
5311
+ #Unknown => 1,
5326
5312
  PrintConv => {
5327
5313
  0 => 'F-mount Lens',
5328
5314
  1 => 'Z-mount Lens',
@@ -5385,7 +5371,7 @@ my %nikonFocalConversions = (
5385
5371
  Name => 'LensPositionAbsolute', # <=0 at infinity. Typical value at CFD might be 58000. Only valid for Z-mount lenses.
5386
5372
  Condition => '$$self{NewLensData} and $$self{LensMountType} and $$self{LensMountType} == 1',
5387
5373
  Format => 'int32s',
5388
- Unknown => 1,
5374
+ #Unknown => 1,
5389
5375
  },
5390
5376
  );
5391
5377
 
@@ -5508,8 +5494,6 @@ my %nikonFocalConversions = (
5508
5494
  Format => 'int32u',
5509
5495
  Priority => 0,
5510
5496
  },
5511
- # note: DecryptLen currently set to 0x251
5512
-
5513
5497
  # 0x55c - int16u[2400] TiffMeteringImage2: 60x40 image (ShotInfoVersion 0800, ref JR)
5514
5498
  # 0x181c - int16u[1200] TiffMeteringImage?: 60x20 image for some NEF's (ShotInfoVersion 0800, ref JR)
5515
5499
  # 0x217c - int16u[2400] TiffMeteringImage3: 60x40 image (ShotInfoVersion 0800, ref JR)
@@ -5521,8 +5505,8 @@ my %nikonFocalConversions = (
5521
5505
 
5522
5506
  # shot information for D40 and D40X (encrypted) - ref PH
5523
5507
  %Image::ExifTool::Nikon::ShotInfoD40 = (
5524
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5525
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5508
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5509
+ WRITE_PROC => \&ProcessNikonEncrypted,
5526
5510
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5527
5511
  VARS => { ID_LABEL => 'Index' },
5528
5512
  IS_SUBDIR => [ 729 ],
@@ -5552,13 +5536,12 @@ my %nikonFocalConversions = (
5552
5536
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD40',
5553
5537
  },
5554
5538
  },
5555
- # note: DecryptLen currently set to 748
5556
5539
  );
5557
5540
 
5558
5541
  # shot information for D80 (encrypted) - ref JD
5559
5542
  %Image::ExifTool::Nikon::ShotInfoD80 = (
5560
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5561
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5543
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5544
+ WRITE_PROC => \&ProcessNikonEncrypted,
5562
5545
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5563
5546
  VARS => { ID_LABEL => 'Index' },
5564
5547
  IS_SUBDIR => [ 748 ],
@@ -5632,13 +5615,12 @@ my %nikonFocalConversions = (
5632
5615
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD80',
5633
5616
  },
5634
5617
  },
5635
- # note: DecryptLen currently set to 765
5636
5618
  );
5637
5619
 
5638
5620
  # shot information for D90 (encrypted) - ref PH
5639
5621
  %Image::ExifTool::Nikon::ShotInfoD90 = (
5640
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5641
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5622
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5623
+ WRITE_PROC => \&ProcessNikonEncrypted,
5642
5624
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5643
5625
  VARS => { ID_LABEL => 'Index' },
5644
5626
  IS_SUBDIR => [ 0x374 ],
@@ -5678,13 +5660,12 @@ my %nikonFocalConversions = (
5678
5660
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD90',
5679
5661
  },
5680
5662
  },
5681
- # note: DecryptLen currently set to 0x398
5682
5663
  );
5683
5664
 
5684
5665
  # shot information for the D3 firmware 0.37 and 1.00 (encrypted) - ref PH
5685
5666
  %Image::ExifTool::Nikon::ShotInfoD3a = (
5686
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5687
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5667
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5668
+ WRITE_PROC => \&ProcessNikonEncrypted,
5688
5669
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5689
5670
  VARS => { ID_LABEL => 'Index' },
5690
5671
  IS_SUBDIR => [ 0x301 ],
@@ -5742,13 +5723,12 @@ my %nikonFocalConversions = (
5742
5723
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5743
5724
  },
5744
5725
  },
5745
- # note: DecryptLen currently set to 0x318
5746
5726
  );
5747
5727
 
5748
5728
  # shot information for the D3 firmware 1.10, 2.00 and 2.01 (encrypted) - ref PH
5749
5729
  %Image::ExifTool::Nikon::ShotInfoD3b = (
5750
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5751
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5730
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5731
+ WRITE_PROC => \&ProcessNikonEncrypted,
5752
5732
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5753
5733
  VARS => { ID_LABEL => 'Index' },
5754
5734
  IS_SUBDIR => [ 0x30a ],
@@ -5837,13 +5817,12 @@ my %nikonFocalConversions = (
5837
5817
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5838
5818
  },
5839
5819
  },
5840
- # note: DecryptLen currently set to 0x321
5841
5820
  );
5842
5821
 
5843
5822
  # shot information for the D3X firmware 1.00 (encrypted) - ref PH
5844
5823
  %Image::ExifTool::Nikon::ShotInfoD3X = (
5845
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5846
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5824
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5825
+ WRITE_PROC => \&ProcessNikonEncrypted,
5847
5826
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5848
5827
  VARS => { ID_LABEL => 'Index' },
5849
5828
  IS_SUBDIR => [ 0x30b ],
@@ -5883,13 +5862,12 @@ my %nikonFocalConversions = (
5883
5862
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5884
5863
  },
5885
5864
  },
5886
- # note: DecryptLen currently set to 0x323
5887
5865
  );
5888
5866
 
5889
5867
  # shot information for the D3S firmware 0.16 and 1.00 (encrypted) - ref PH
5890
5868
  %Image::ExifTool::Nikon::ShotInfoD3S = (
5891
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5892
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5869
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5870
+ WRITE_PROC => \&ProcessNikonEncrypted,
5893
5871
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5894
5872
  VARS => { ID_LABEL => 'Index' },
5895
5873
  IS_SUBDIR => [ 0x2ce ],
@@ -5938,13 +5916,12 @@ my %nikonFocalConversions = (
5938
5916
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5939
5917
  },
5940
5918
  },
5941
- # note: DecryptLen currently set to 0x2e9
5942
5919
  );
5943
5920
 
5944
5921
  # shot information for the D300 firmware 1.00 (encrypted) - ref JD
5945
5922
  %Image::ExifTool::Nikon::ShotInfoD300a = (
5946
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5947
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5923
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5924
+ WRITE_PROC => \&ProcessNikonEncrypted,
5948
5925
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5949
5926
  VARS => { ID_LABEL => 'Index' },
5950
5927
  IS_SUBDIR => [ 790 ],
@@ -6031,13 +6008,12 @@ my %nikonFocalConversions = (
6031
6008
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6032
6009
  },
6033
6010
  },
6034
- # note: DecryptLen currently set to 813
6035
6011
  );
6036
6012
 
6037
6013
  # shot information for the D300 firmware 1.10 (encrypted) - ref PH
6038
6014
  %Image::ExifTool::Nikon::ShotInfoD300b = (
6039
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6040
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6015
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6016
+ WRITE_PROC => \&ProcessNikonEncrypted,
6041
6017
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6042
6018
  VARS => { ID_LABEL => 'Index' },
6043
6019
  DATAMEMBER => [ 4 ],
@@ -6182,13 +6158,12 @@ my %nikonFocalConversions = (
6182
6158
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6183
6159
  },
6184
6160
  },
6185
- # note: DecryptLen currently set to 825
6186
6161
  );
6187
6162
 
6188
6163
  # shot information for the D300S firmware 1.00 (encrypted) - ref PH
6189
6164
  %Image::ExifTool::Nikon::ShotInfoD300S = (
6190
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6191
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6165
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6166
+ WRITE_PROC => \&ProcessNikonEncrypted,
6192
6167
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6193
6168
  VARS => { ID_LABEL => 'Index' },
6194
6169
  IS_SUBDIR => [ 804 ],
@@ -6228,13 +6203,12 @@ my %nikonFocalConversions = (
6228
6203
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6229
6204
  },
6230
6205
  },
6231
- # note: DecryptLen currently set to 827
6232
6206
  );
6233
6207
 
6234
6208
  # shot information for the D700 firmware 1.02f (encrypted) - ref 29
6235
6209
  %Image::ExifTool::Nikon::ShotInfoD700 = (
6236
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6237
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6210
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6211
+ WRITE_PROC => \&ProcessNikonEncrypted,
6238
6212
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6239
6213
  VARS => { ID_LABEL => 'Index' },
6240
6214
  IS_SUBDIR => [ 804 ],
@@ -6274,13 +6248,45 @@ my %nikonFocalConversions = (
6274
6248
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD700',
6275
6249
  },
6276
6250
  },
6277
- # 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
+ },
6278
6284
  );
6279
6285
 
6280
6286
  # shot information for the D5000 firmware 1.00 (encrypted) - ref PH
6281
6287
  %Image::ExifTool::Nikon::ShotInfoD5000 = (
6282
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6283
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6288
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6289
+ WRITE_PROC => \&ProcessNikonEncrypted,
6284
6290
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6285
6291
  VARS => { ID_LABEL => 'Index' },
6286
6292
  IS_SUBDIR => [ 0x378 ],
@@ -6320,13 +6326,12 @@ my %nikonFocalConversions = (
6320
6326
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5000',
6321
6327
  },
6322
6328
  },
6323
- # note: DecryptLen currently set to 0x39a
6324
6329
  );
6325
6330
 
6326
6331
  # shot information for the D5100 firmware 1.00f (encrypted) - ref PH
6327
6332
  %Image::ExifTool::Nikon::ShotInfoD5100 = (
6328
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6329
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6333
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6334
+ WRITE_PROC => \&ProcessNikonEncrypted,
6330
6335
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6331
6336
  VARS => { ID_LABEL => 'Index' },
6332
6337
  IS_SUBDIR => [ 0x407 ],
@@ -6355,13 +6360,12 @@ my %nikonFocalConversions = (
6355
6360
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5100',
6356
6361
  },
6357
6362
  },
6358
- # note: DecryptLen currently set to 0x430
6359
6363
  );
6360
6364
 
6361
6365
  # shot information for the D5200 firmware 1.00 (encrypted) - ref PH
6362
6366
  %Image::ExifTool::Nikon::ShotInfoD5200 = (
6363
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6364
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6367
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6368
+ WRITE_PROC => \&ProcessNikonEncrypted,
6365
6369
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6366
6370
  VARS => { ID_LABEL => 'Index' },
6367
6371
  IS_SUBDIR => [ 0xcd5 ],
@@ -6393,13 +6397,12 @@ my %nikonFocalConversions = (
6393
6397
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5200',
6394
6398
  },
6395
6399
  },
6396
- # note: DecryptLen currently set to 0xd00
6397
6400
  );
6398
6401
 
6399
6402
  # shot information for the D7000 firmware 1.01d (encrypted) - ref 29
6400
6403
  %Image::ExifTool::Nikon::ShotInfoD7000 = (
6401
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6402
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6404
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6405
+ WRITE_PROC => \&ProcessNikonEncrypted,
6403
6406
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6404
6407
  VARS => { ID_LABEL => 'Index' },
6405
6408
  IS_SUBDIR => [ 1028 ],
@@ -6441,10 +6444,43 @@ my %nikonFocalConversions = (
6441
6444
  },
6442
6445
  );
6443
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
+
6444
6480
  # shot information for the D800 firmware 1.01a (encrypted) - ref PH
6445
6481
  %Image::ExifTool::Nikon::ShotInfoD800 = (
6446
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6447
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6482
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6483
+ WRITE_PROC => \&ProcessNikonEncrypted,
6448
6484
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6449
6485
  VARS => { ID_LABEL => 'Index' },
6450
6486
  IS_SUBDIR => [ 0x6ec ],
@@ -6559,20 +6595,17 @@ my %nikonFocalConversions = (
6559
6595
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD800',
6560
6596
  },
6561
6597
  },
6562
- # note: DecryptLen currently set to 0x720
6563
6598
  );
6564
6599
 
6565
6600
  # shot information for the D5 firmware 1.10a and D500 firmware 1.01 (encrypted) - ref 28
6566
6601
  %Image::ExifTool::Nikon::ShotInfoD500 = (
6567
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6568
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6602
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6603
+ WRITE_PROC => \&ProcessNikonEncrypted,
6569
6604
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6570
- VARS => { ID_LABEL => 'Index' },
6571
- DATAMEMBER => [ 0x04, 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8, 0xb0,
6572
- 0x07b0, 0x086c, 0x0e7c, 0x0eea, 0x2c23, 0x2c8f ],
6573
- IS_SUBDIR => [ 0x0eeb ],
6605
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
6606
+ DATAMEMBER => [ 0x04 ],
6607
+ IS_SUBDIR => [ 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8 ],
6574
6608
  WRITABLE => 1,
6575
- FIRST_ENTRY => 0,
6576
6609
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6577
6610
  NOTES => 'These tags are extracted from encrypted data in images from the D5 and D500.',
6578
6611
  0x00 => {
@@ -6589,73 +6622,66 @@ my %nikonFocalConversions = (
6589
6622
  },
6590
6623
  0x10 => {
6591
6624
  Name => 'RotationInfoOffset',
6592
- DataMember => 'RotationInfoOffset',
6593
6625
  Format => 'int32u',
6594
- Writable => 0,
6595
- Hidden => 1,
6596
- RawConv => '$$self{RotationInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6626
+ SubDirectory => {
6627
+ TagTable => 'Image::ExifTool::Nikon::RotationInfoD500',
6628
+ Start => '$val',
6629
+ }
6597
6630
  },
6598
6631
  0x14 => {
6599
6632
  Name => 'JPGInfoOffset',
6600
- DataMember => 'JPGInfoOffset',
6601
6633
  Format => 'int32u',
6602
- Writable => 0,
6603
- Hidden => 1,
6604
- RawConv => '$$self{JPGInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6634
+ SubDirectory => {
6635
+ TagTable => 'Image::ExifTool::Nikon::JPGInfoD500',
6636
+ Start => '$val',
6637
+ }
6605
6638
  },
6606
6639
  0x2c => {
6607
- Name => 'BracketingInfoOffset',
6608
- DataMember => 'BracketingInfoOffset',
6640
+ Name => 'BracketingOffset',
6609
6641
  Format => 'int32u',
6610
- Writable => 0,
6611
- Hidden => 1,
6612
- RawConv => '$$self{BracketingInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6642
+ SubDirectory => {
6643
+ TagTable => 'Image::ExifTool::Nikon::BracketingInfoD500',
6644
+ Start => '$val',
6645
+ }
6613
6646
  },
6614
6647
  0x50 => {
6615
6648
  Name => 'ShootingMenuOffset',
6616
- DataMember => 'ShootingMenuOffset',
6617
6649
  Format => 'int32u',
6618
- Writable => 0,
6619
- Hidden => 1,
6620
- RawConv => '$$self{ShootingMenuOffset} = $val || 0x10000000; undef', # (ignore if 0)
6650
+ SubDirectory => {
6651
+ TagTable => 'Image::ExifTool::Nikon::ShootingMenuD500',
6652
+ Start => '$val',
6653
+ }
6621
6654
  },
6622
6655
  0x58 => {
6623
6656
  Name => 'CustomSettingsOffset',
6624
- DataMember => 'CustomSettingsOffset',
6625
6657
  Format => 'int32u',
6626
- Writable => 0,
6627
- Hidden => 1,
6628
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef', # (ignore if 0)
6658
+ SubDirectory => {
6659
+ TagTable => 'Image::ExifTool::Nikon::CustomSettingsD500',
6660
+ Start => '$val',
6661
+ }
6629
6662
  },
6630
6663
  0xa0 => {
6631
6664
  Name => 'OrientationOffset',
6632
- DataMember => 'OrientationOffset',
6633
6665
  Format => 'int32u',
6634
- Writable => 0,
6635
- Hidden => 1,
6636
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
6666
+ SubDirectory => {
6667
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
6668
+ Start => '$val',
6669
+ }
6637
6670
  },
6638
6671
  0xa8 => {
6639
6672
  Name => 'OtherOffset',
6640
- DataMember => 'OtherOffset',
6641
6673
  Format => 'int32u',
6642
- Writable => 0,
6643
- Hidden => 1,
6644
- RawConv => '$$self{OtherOffset} = $val || 0x10000000; undef', # (ignore if 0)
6645
- },
6646
- #
6647
- # Tag ID's below are the offsets for a D500 JPEG image, but these offsets change
6648
- # for various image types according to the offset table above
6649
- #
6650
- ### 0xb0 - RotationInfo start
6651
- 0xb0 => {
6652
- Name => 'Hook1',
6653
- Hidden => 1,
6654
- RawConv => 'undef',
6655
- # account for variable location of Rotation data
6656
- Hook => '$varSize = $$self{RotationInfoOffset} - 0xb0',
6674
+ SubDirectory => {
6675
+ TagTable => 'Image::ExifTool::Nikon::OtherInfoD500',
6676
+ Start => '$val',
6677
+ }
6657
6678
  },
6658
- 0xca => {
6679
+ );
6680
+
6681
+ %Image::ExifTool::Nikon::RotationInfoD500 = (
6682
+ %binaryDataAttrs,
6683
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6684
+ 0x1a => {
6659
6685
  Name => 'Rotation',
6660
6686
  Mask => 0x03,
6661
6687
  PrintConv => {
@@ -6665,32 +6691,29 @@ my %nikonFocalConversions = (
6665
6691
  3 => 'Rotate 180',
6666
6692
  },
6667
6693
  },
6668
- 0x0d0 => {
6694
+ 0x20 => {
6669
6695
  Name => 'Interval',
6670
6696
  # prior version of the d% firmware do not support this tag, nor does the D500 (at least thru firmware 1.3)
6671
6697
  Condition => '$$self{Model} eq "NIKON D5" and $$self{FirmwareVersion} ge "1.40"',
6672
6698
  PrintConv => '$val > 0 ? sprintf("%.0f", $val) : ""',
6673
6699
  },
6674
- 0x0d4 => {
6700
+ 0x24 => {
6675
6701
  Name => 'IntervalFrame',
6676
6702
  # prior version of the d% firmware do not support this tag, nor does the D500 (at least thru firmware 1.3)
6677
6703
  Condition => '$$self{Model} eq "NIKON D5" and $$self{FirmwareVersion} ge "1.40"',
6678
6704
  PrintConv => '$val > 0 ? sprintf("%.0f", $val) : ""',
6679
6705
  },
6680
- 0x05e2 => {
6706
+ 0x0532 => {
6681
6707
  Name => 'FlickerReductionIndicator',
6682
6708
  Mask => 0x01,
6683
6709
  PrintConv => { 0 => 'On', 1 => 'Off' },
6684
6710
  },
6685
- ### 0x07b0 - JPEGInfo start
6686
- 0x07b0 => {
6687
- Name => 'Hook2',
6688
- Hidden => 1,
6689
- RawConv => 'undef',
6690
- # account for variable location of Shooting Menu data
6691
- Hook => '$varSize = $$self{JPGInfoOffset} - 0x07b0',
6692
- },
6693
- 0x07d4 => {
6711
+ );
6712
+
6713
+ %Image::ExifTool::Nikon::JPGInfoD500 = (
6714
+ %binaryDataAttrs,
6715
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6716
+ 0x24 => {
6694
6717
  Name => 'JPGCompression',
6695
6718
  Mask => 0x01,
6696
6719
  PrintConv => {
@@ -6698,16 +6721,12 @@ my %nikonFocalConversions = (
6698
6721
  1 => 'Optimal Quality',
6699
6722
  },
6700
6723
  },
6701
- ### 0x0830 - ? start
6702
- ### 0x086c - BracketingInfo start
6703
- 0x086c => {
6704
- Name => 'Hook3',
6705
- Hidden => 1,
6706
- RawConv => 'undef',
6707
- # account for variable location of Shooting Menu data
6708
- Hook => '$varSize = $$self{BracketingInfoOffset} - 0x086c',
6709
- },
6710
- 0x087b => {
6724
+ );
6725
+
6726
+ %Image::ExifTool::Nikon::BracketingInfoD500 = (
6727
+ %binaryDataAttrs,
6728
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6729
+ 0x0f => {
6711
6730
  Name => 'AEBracketingSteps',
6712
6731
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
6713
6732
  Mask => 0xff,
@@ -6765,7 +6784,7 @@ my %nikonFocalConversions = (
6765
6784
  0xd6 => '5F3',
6766
6785
  },
6767
6786
  },
6768
- 0x087c => {
6787
+ 0x10 => {
6769
6788
  Name => 'WBBracketingSteps',
6770
6789
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
6771
6790
  Mask => 0xff,
@@ -6808,7 +6827,7 @@ my %nikonFocalConversions = (
6808
6827
  0x28 => '9F 3',
6809
6828
  },
6810
6829
  },
6811
- 0x0883 => {
6830
+ 0x17 => {
6812
6831
  Name => 'ADLBracketingStep',
6813
6832
  Mask => 0xf0,
6814
6833
  PrintConv => {
@@ -6820,7 +6839,7 @@ my %nikonFocalConversions = (
6820
6839
  8 => 'Auto',
6821
6840
  },
6822
6841
  },
6823
- 0x0884 => {
6842
+ 0x18 => {
6824
6843
  Name => 'ADLBracketingType',
6825
6844
  Mask => 0x0f,
6826
6845
  PrintConv => {
@@ -6831,23 +6850,12 @@ my %nikonFocalConversions = (
6831
6850
  4 => '5 Shots',
6832
6851
  },
6833
6852
  },
6834
- ### 0x0887 - ? start
6835
- ### 0x089f - ? start
6836
- ### 0x0929 - ? start
6837
- ### 0x09c9 - ? start
6838
- ### 0x0ac5 - ? start
6839
- ### 0x0bc1 - ? start
6840
- ### 0x0cbd - ? start
6841
- ### 0x0d98 - ? start
6842
- ### 0x0e7d - ShootingMenuOffset start
6843
- 0x0e7c => {
6844
- Name => 'Hook4',
6845
- Hidden => 1,
6846
- RawConv => 'undef',
6847
- # account for variable location of Shooting Menu data
6848
- Hook => '$varSize = $$self{ShootingMenuOffset} - 0x0e7d',
6849
- },
6850
- 0x0e7d => {
6853
+ );
6854
+
6855
+ %Image::ExifTool::Nikon::ShootingMenuD500 = (
6856
+ %binaryDataAttrs,
6857
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6858
+ 0x00 => {
6851
6859
  Name => 'PhotoShootingMenuBank',
6852
6860
  Mask => 0x03,
6853
6861
  PrintConv => {
@@ -6857,7 +6865,7 @@ my %nikonFocalConversions = (
6857
6865
  3 => 'D',
6858
6866
  },
6859
6867
  },
6860
- 0x0e7f => {
6868
+ 0x02 => {
6861
6869
  Name => 'PrimarySlot',
6862
6870
  Condition => '$$self{Model} =~ /\bD500\b/',
6863
6871
  Notes => 'D500 only',
@@ -6867,7 +6875,7 @@ my %nikonFocalConversions = (
6867
6875
  1 => 'SD Card',
6868
6876
  },
6869
6877
  },
6870
- 0x0e81 => {
6878
+ 0x04 => {
6871
6879
  Name => 'ISOAutoShutterTime',
6872
6880
  Mask => 0x3f,
6873
6881
  PrintConv => {
@@ -6910,7 +6918,7 @@ my %nikonFocalConversions = (
6910
6918
  36 => 'Auto (Fastest)',
6911
6919
  },
6912
6920
  },
6913
- 0x0e82 => {
6921
+ 0x05 => {
6914
6922
  Name => 'ISOAutoHiLimit',
6915
6923
  Mask => 0xff,
6916
6924
  PrintHex => 1,
@@ -6958,7 +6966,7 @@ my %nikonFocalConversions = (
6958
6966
  0x72 => 'ISO Hi 5.0',
6959
6967
  },
6960
6968
  },
6961
- 0x0e84 => {
6969
+ 0x07 => {
6962
6970
  Name => 'FlickerReduction',
6963
6971
  Mask => 0x20,
6964
6972
  PrintConv => {
@@ -6966,7 +6974,7 @@ my %nikonFocalConversions = (
6966
6974
  1 => 'Disable',
6967
6975
  },
6968
6976
  },
6969
- 3716.1 => { # (0x0e84)
6977
+ 7.1 => {
6970
6978
  Name => 'PhotoShootingMenuBankImageArea',
6971
6979
  Mask => 0x07,
6972
6980
  PrintConv => {
@@ -6977,16 +6985,14 @@ my %nikonFocalConversions = (
6977
6985
  4 => '1.3x (18x12)',
6978
6986
  },
6979
6987
  },
6980
- ### 0x0ec4 - ? start
6981
- ### 0x0eeb - CustomSettings start
6982
- 0x0eea => {
6983
- Name => 'Hook5',
6984
- Hidden => 1,
6985
- RawConv => 'undef',
6986
- # account for variable location of CustomSettings data
6987
- Hook => '$varSize = $$self{CustomSettingsOffset} - 0x0eeb',
6988
- },
6989
- 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 => [{
6990
6996
  Name => 'CustomSettingsD5',
6991
6997
  Condition => '$$self{Model} =~ /\bD5\b/',
6992
6998
  Format => 'undef[90]',
@@ -7000,7 +7006,7 @@ my %nikonFocalConversions = (
7000
7006
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD500',
7001
7007
  },
7002
7008
  }],
7003
- # 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
7004
7010
  # Name => 'ShutterTrigger',
7005
7011
  # Mask => 0xff,
7006
7012
  # PrintConv => {
@@ -7009,51 +7015,13 @@ my %nikonFocalConversions = (
7009
7015
  # 195 => 'Shutter Button',
7010
7016
  # },
7011
7017
  # },
7012
- ### 0x2c24 - OrientationInfo start (D5 firmware 1.10b)
7013
- 0x2c23 => {
7014
- Name => 'Hook6',
7015
- Hidden => 1,
7016
- RawConv => 'undef',
7017
- # account for variable location of OrientationInfo data
7018
- Hook => '$varSize = $$self{OrientationOffset} - 0x2c24',
7019
- },
7020
- 0x2c24 => {
7021
- Name => 'RollAngle',
7022
- Format => 'fixed32u',
7023
- Notes => 'converted to degrees of clockwise camera roll',
7024
- ValueConv => '$val <= 180 ? $val : $val - 360',
7025
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7026
- PrintConv => 'sprintf("%.1f", $val)',
7027
- PrintConvInv => '$val',
7028
- },
7029
- 0x2c28 => {
7030
- Name => 'PitchAngle',
7031
- Format => 'fixed32u',
7032
- Notes => 'converted to degrees of upward camera tilt',
7033
- ValueConv => '$val <= 180 ? $val : $val - 360',
7034
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7035
- PrintConv => 'sprintf("%.1f", $val)',
7036
- PrintConvInv => '$val',
7037
- },
7038
- 0x2c2c => {
7039
- Name => 'YawAngle',
7040
- Format => 'fixed32u',
7041
- Notes => 'the camera yaw angle when shooting in portrait orientation',
7042
- ValueConv => '$val <= 180 ? $val : $val - 360',
7043
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7044
- PrintConv => 'sprintf("%.1f", $val)',
7045
- PrintConvInv => '$val',
7046
- },
7047
- ### 0x2c90 - OtherInfo start (D500 firmware 1.20d)
7048
- 0x2c8f => {
7049
- Name => 'Hook7',
7050
- Hidden => 1,
7051
- RawConv => 'undef',
7052
- # account for variable location of OtherInfo data
7053
- Hook => '$varSize = $$self{OtherOffset} - 0x2c90',
7054
- },
7018
+ );
7019
+
7020
+ %Image::ExifTool::Nikon::OtherInfoD500 = (
7021
+ %binaryDataAttrs,
7022
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7055
7023
  # (needs testing)
7056
- #0x2cb2 => {
7024
+ #0x22 => {
7057
7025
  # Name => 'ExtendedPhotoShootingBanks',
7058
7026
  # Mask => 0x01,
7059
7027
  # PrintConv => {
@@ -7062,7 +7030,7 @@ my %nikonFocalConversions = (
7062
7030
  # },
7063
7031
  #},
7064
7032
  # (may not be reliable and is found elsewhere)
7065
- #0x2ea2 => {
7033
+ #0x212 => {
7066
7034
  # Name => 'Rotation',
7067
7035
  # Condition => '$$self{Model} =~ /\bD500\b/',
7068
7036
  # Notes => 'D500 firmware 1.1x',
@@ -7074,7 +7042,7 @@ my %nikonFocalConversions = (
7074
7042
  # 3 => 'Rotate 180',
7075
7043
  # },
7076
7044
  #},
7077
- 0x2ea4 => { #PH
7045
+ 0x214 => { #PH
7078
7046
  Name => 'NikonMeteringMode',
7079
7047
  Condition => '$$self{Model} =~ /\bD500\b/', # (didn't seem to work for D5, but I need more samples)
7080
7048
  Notes => 'D500 only',
@@ -7086,18 +7054,16 @@ my %nikonFocalConversions = (
7086
7054
  3 => 'Highlight'
7087
7055
  },
7088
7056
  },
7089
- # note: DecryptLen currently set to OtherOffset + 0x2ea5 - 0x2c90
7090
7057
  );
7091
7058
 
7092
7059
  # shot information for the D6 firmware 1.00 (encrypted) - ref 28
7093
7060
  %Image::ExifTool::Nikon::ShotInfoD6 = (
7094
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7095
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7061
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7062
+ WRITE_PROC => \&ProcessNikonEncrypted,
7096
7063
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7097
- VARS => { ID_LABEL => 'Index' },
7098
- 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 ],
7099
7066
  WRITABLE => 1,
7100
- FIRST_ENTRY => 0,
7101
7067
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7102
7068
  NOTES => 'These tags are extracted from encrypted data in images from the D6.',
7103
7069
  0x00 => {
@@ -7112,159 +7078,111 @@ my %nikonFocalConversions = (
7112
7078
  },
7113
7079
  0x24 => {
7114
7080
  Name => 'NumberOffsets', # (number of entries in offset table. offsets are from start of ShotInfo data)
7115
- DataMember => 'NumberOffsets',
7116
7081
  Format => 'int32u',
7117
7082
  Writable => 0,
7118
7083
  Hidden => 1,
7119
7084
  },
7120
7085
  0x30 => {
7121
- Name => 'Offset3',
7122
- DataMember => 'Offset3',
7086
+ Name => 'SequenceOffset',
7123
7087
  Format => 'int32u',
7124
- Writable => 0,
7125
- Hidden => 1,
7126
- RawConv => '$$self{Offset3} = $val || 0x10000000; undef', # (ignore if 0)
7127
- },
7128
- 0x60 => {
7129
- Name => 'Offset15',
7130
- DataMember => 'Offset15',
7131
- Format => 'int32u',
7132
- Writable => 0,
7133
- Hidden => 1,
7134
- RawConv => '$$self{Offset15} = $val || 0x10000000; undef', # (ignore if 0)
7088
+ SubDirectory => {
7089
+ TagTable => 'Image::ExifTool::Nikon::SeqInfoD6',
7090
+ Start => '$val',
7091
+ },
7135
7092
  },
7136
7093
  0x9c => {
7137
7094
  Name => 'OrientationOffset',
7138
- DataMember => 'OrientationOffset',
7139
7095
  Format => 'int32u',
7140
- Writable => 0,
7141
- Hidden => 1,
7142
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
7096
+ SubDirectory => {
7097
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7098
+ Start => '$val',
7099
+ },
7143
7100
  },
7144
7101
  0xa4 => {
7145
- Name => 'Offset32',
7146
- DataMember => 'Offset32',
7102
+ Name => 'IntervalOffset',
7147
7103
  Format => 'int32u',
7148
- Writable => 0,
7149
- Hidden => 1,
7150
- RawConv => '$$self{Offset32} = $val || 0x10000000; undef', # (ignore if 0)
7151
- },
7152
- ### 0x75e8 - Offset3 info start (D6 firmware 1.33)
7153
- 0x75e7 => {
7154
- Name => 'Hook1',
7155
- Hidden => 1,
7156
- RawConv => 'undef',
7157
- # account for variable location of Offset5 data
7158
- Hook => '$varSize = $$self{Offset3} - 0x75e8',
7104
+ SubDirectory => {
7105
+ TagTable => 'Image::ExifTool::Nikon::IntervalInfoD6',
7106
+ Start => '$val',
7107
+ }
7159
7108
  },
7160
- 0x760c => {
7109
+ );
7110
+
7111
+ %Image::ExifTool::Nikon::SeqInfoD6 = (
7112
+ %binaryDataAttrs,
7113
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7114
+ DATAMEMBER => [ 0x24, 0x28 ],
7115
+ 0x24 => {
7161
7116
  Name => 'IntervalShooting',
7162
7117
  RawConv => '$$self{IntervalShooting} = $val',
7163
7118
  Format => 'int16u',
7164
7119
  PrintConv => q{
7165
7120
  return 'Off' if $val == 0 ;
7166
- my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}); #something like "Interval 1 of 3"
7167
- 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
7168
7123
  return "On: $i$f"
7169
- #$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),
7170
7125
  },
7171
7126
  },
7172
- 0x7610 => {
7127
+ 0x28 => {
7173
7128
  Name => 'IntervalFrame',
7174
7129
  RawConv => '$$self{IntervalFrame} = $val',
7175
7130
  Condition => '$$self{IntervalShooting} > 0',
7176
7131
  Format => 'int16u',
7177
7132
  Hidden => 1,
7178
7133
  },
7179
- ### 0xc21a - OrientationInfo start (D6 firmware 1.00) (0xc952 for firmware 1.33)
7180
- 0xc219 => {
7181
- Name => 'Hook2',
7182
- Hidden => 1,
7183
- RawConv => 'undef',
7184
- # account for variable location of OrientationInfo data
7185
- Hook => '$varSize = $$self{OrientationOffset} - 0xc21a',
7186
- },
7187
- 0xc21a => {
7188
- Name => 'RollAngle',
7189
- Format => 'fixed32u',
7190
- Notes => 'converted to degrees of clockwise camera roll',
7191
- ValueConv => '$val <= 180 ? $val : $val - 360',
7192
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7193
- PrintConv => 'sprintf("%.1f", $val)',
7194
- PrintConvInv => '$val',
7195
- },
7196
- 0xc21e => {
7197
- Name => 'PitchAngle',
7198
- Format => 'fixed32u',
7199
- Notes => 'converted to degrees of upward camera tilt',
7200
- ValueConv => '$val <= 180 ? $val : $val - 360',
7201
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7202
- PrintConv => 'sprintf("%.1f", $val)',
7203
- PrintConvInv => '$val',
7204
- },
7205
- 0xc222 => {
7206
- Name => 'YawAngle',
7207
- Format => 'fixed32u',
7208
- Notes => 'the camera yaw angle when shooting in portrait orientation',
7209
- ValueConv => '$val <= 180 ? $val : $val - 360',
7210
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7211
- PrintConv => 'sprintf("%.1f", $val)',
7212
- PrintConvInv => '$val',
7213
- },
7214
- ### 0xc9c6 - Offset32 start (D6 firmware 1.33)
7215
- 0xc292 => {
7216
- Name => 'Hook3',
7217
- Hidden => 1,
7218
- RawConv => 'undef',
7219
- # account for variable location of data
7220
- Hook => '$varSize = $$self{Offset32} - 0xc292',
7221
- },
7222
- 0xc40e => {
7134
+ );
7135
+
7136
+ %Image::ExifTool::Nikon::IntervalInfoD6 = (
7137
+ %binaryDataAttrs,
7138
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7139
+ DATAMEMBER => [ 0x17c, 0x180, 0x214, 0x22c ],
7140
+ 0x17c => {
7223
7141
  Name => 'Intervals',
7224
7142
  Format => 'int32u',
7225
7143
  RawConv => '$$self{IntervalShootingIntervals} = $val',
7226
7144
  Condition => '$$self{IntervalShooting} > 0',
7227
7145
  },
7228
- 0xc412 => {
7146
+ 0x180 => {
7229
7147
  Name => 'ShotsPerInterval',
7230
7148
  Format => 'int32u',
7231
7149
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
7232
7150
  Condition => '$$self{IntervalShooting} > 0',
7233
7151
  },
7234
- 0xc416 => {
7152
+ 0x184 => {
7235
7153
  Name => 'IntervalExposureSmoothing',
7236
7154
  Condition => '$$self{IntervalShooting} > 0',
7237
7155
  Format => 'int8u',
7238
7156
  PrintConv => \%offOn,
7239
7157
  },
7240
- 0xc418 => {
7158
+ 0x186 => {
7241
7159
  Name => 'IntervalPriority',
7242
7160
  Condition => '$$self{IntervalShooting} > 0',
7243
7161
  Format => 'int8u',
7244
7162
  PrintConv => \%offOn,
7245
7163
  },
7246
- 0xc43a => {
7164
+ 0x1a8 => {
7247
7165
  Name => 'FocusShiftNumberShots',
7248
7166
  },
7249
- 0xc43e => {
7167
+ 0x1ac => {
7250
7168
  Name => 'FocusShiftStepWidth',
7251
7169
  },
7252
- 0xc442 => {
7170
+ 0x1b0 => {
7253
7171
  Name => 'FocusShiftInterval',
7254
7172
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
7255
7173
  },
7256
- 0xc446 => {
7174
+ 0x1b4 => {
7257
7175
  Name => 'FocusShiftExposureLock',
7258
7176
  PrintConv => \%offOn,
7259
7177
  },
7260
- #0xc49c => HighISONoiseReduction
7261
- 0xc4a0 => {
7178
+ #0x20a => HighISONoiseReduction
7179
+ 0x20e => {
7262
7180
  Name => 'DiffractionCompensation',
7263
7181
  Format => 'int8u',
7264
7182
  PrintConv => \%offOn,
7265
7183
  },
7266
- #0xc4a1 => {Name => 'FlickerReductionShooting',}, #redundant with tag in NikonSettings
7267
- 0xc4a6 => {
7184
+ #0x20f => {Name => 'FlickerReductionShooting',}, #redundant with tag in NikonSettings
7185
+ 0x214 => {
7268
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
7269
7187
  RawConv => '$$self{FlashControlMode} = $val',
7270
7188
  PrintConv => {
@@ -7275,14 +7193,14 @@ my %nikonFocalConversions = (
7275
7193
  4 => 'Repeating Flash',
7276
7194
  },
7277
7195
  },
7278
- 0xc4ac => {
7196
+ 0x21a => {
7279
7197
  Name => 'FlashGNDistance',
7280
7198
  Condition => '$$self{FlashControlMode} == 2',
7281
7199
  Unknown => 1,
7282
7200
  ValueConv => '$val + 3',
7283
7201
  PrintConv => \%flashGNDistance,
7284
7202
  },
7285
- 0xc4b0 => {
7203
+ 0x21e => {
7286
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)
7287
7205
  Condition => '$$self{FlashControlMode} >= 3',
7288
7206
  Unknown => 1,
@@ -7291,7 +7209,7 @@ my %nikonFocalConversions = (
7291
7209
  PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
7292
7210
  PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
7293
7211
  },
7294
- 0xc4ba => {
7212
+ 0x228 => {
7295
7213
  Name => 'FlashRemoteControl',
7296
7214
  Unknown => 1,
7297
7215
  PrintConv => {
@@ -7300,12 +7218,12 @@ my %nikonFocalConversions = (
7300
7218
  2 => 'Remote Repeating',
7301
7219
  },
7302
7220
  },
7303
- 0xc4be => {
7221
+ 0x22c => {
7304
7222
  Name => 'FlashMasterControlMode', #tag name chosen for compatibility with those found in FlashInfo0102 & FlashInfo0103
7305
7223
  RawConv => '$$self{FlashGroupOptionsMasterMode} = $val',
7306
7224
  PrintConv => \%flashGroupOptionsMode,
7307
7225
  },
7308
- 0xc4c0 => {
7226
+ 0x22e => {
7309
7227
  Name => 'FlashMasterCompensation',
7310
7228
  Unknown => 1,
7311
7229
  Format => 'int8s',
@@ -7315,7 +7233,7 @@ my %nikonFocalConversions = (
7315
7233
  PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
7316
7234
  PrintConvInv => '$val',
7317
7235
  },
7318
- 0xc4c4 => {
7236
+ 0x232 => {
7319
7237
  Name => 'FlashMasterOutput',
7320
7238
  Unknown => 1,
7321
7239
  Condition => '$$self{FlashGroupOptionsMasterMode} == 1', #only for Mode=M
@@ -7324,7 +7242,7 @@ my %nikonFocalConversions = (
7324
7242
  PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
7325
7243
  PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
7326
7244
  },
7327
- 0xc4c6 => {
7245
+ 0x234 => {
7328
7246
  Name => 'FlashWirelessOption',
7329
7247
  Unknown => 1,
7330
7248
  PrintConv => {
@@ -7332,7 +7250,7 @@ my %nikonFocalConversions = (
7332
7250
  1 => 'Off',
7333
7251
  },
7334
7252
  },
7335
- 0xc55c => {
7253
+ 0x2ca => {
7336
7254
  Name => 'MovieType',
7337
7255
  Unknown => 1,
7338
7256
  PrintConv => {
@@ -7340,13 +7258,12 @@ my %nikonFocalConversions = (
7340
7258
  1 => 'MP4',
7341
7259
  },
7342
7260
  },
7343
- # note: DecryptLen currently set to 0xc9c6 + 720
7344
7261
  );
7345
7262
 
7346
7263
  # shot information for the D610 firmware 1.00 (encrypted) - ref PH
7347
7264
  %Image::ExifTool::Nikon::ShotInfoD610 = (
7348
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7349
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7265
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7266
+ WRITE_PROC => \&ProcessNikonEncrypted,
7350
7267
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7351
7268
  VARS => { ID_LABEL => 'Index' },
7352
7269
  IS_SUBDIR => [ 0x07cf ],
@@ -7371,25 +7288,19 @@ my %nikonFocalConversions = (
7371
7288
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD610',
7372
7289
  },
7373
7290
  },
7374
- # note: DecryptLen currently set to 0x7ff
7375
7291
  );
7376
7292
 
7377
7293
  # shot information for the D810 firmware 1.00(PH)/1.01 (encrypted) - ref 28
7378
7294
  %Image::ExifTool::Nikon::ShotInfoD810 = (
7379
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7380
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7295
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7296
+ WRITE_PROC => \&ProcessNikonEncrypted,
7381
7297
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7382
- VARS => { ID_LABEL => 'Index' },
7383
- DATAMEMBER => [ 0x04, 0x24, 0x38, 0x40, 0x84, 0x01d0, 0x175e, 0x185d, 0x18ab ],
7384
- IS_SUBDIR => [ 0x18ab ],
7298
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
7299
+ DATAMEMBER => [ 0x04 ],
7300
+ IS_SUBDIR => [ 0x10, 0x24, 0x38, 0x40, 0x84 ],
7385
7301
  WRITABLE => 1,
7386
- FIRST_ENTRY => 0,
7387
7302
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7388
- NOTES => q{
7389
- These tags are extracted from encrypted data in images from the D810. Note
7390
- that the indices listed below are for firmware version 1.0, but they may be
7391
- different for other firmware versions.
7392
- },
7303
+ NOTES => 'These tags are extracted from encrypted data in images from the D810.',
7393
7304
  0x00 => {
7394
7305
  Name => 'ShotInfoVersion',
7395
7306
  Format => 'string[4]',
@@ -7404,39 +7315,64 @@ my %nikonFocalConversions = (
7404
7315
  },
7405
7316
  # 0x0c - number of entries in offset table (= 0x21)
7406
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
+ },
7407
7326
  0x24 => {
7408
7327
  Name => 'BracketingOffset',
7409
- DataMember => 'BracketingOffset',
7410
7328
  Format => 'int32u',
7411
- Writable => 0,
7412
- Hidden => 1,
7413
- RawConv => '$$self{BracketingOffset} = $val || 0x10000000; undef',
7329
+ SubDirectory => {
7330
+ TagTable => 'Image::ExifTool::Nikon::BracketingInfoD810',
7331
+ Start => '$val',
7332
+ },
7414
7333
  },
7415
7334
  0x38 => {
7416
7335
  Name => 'ISOAutoOffset',
7417
- DataMember => 'ISOAutoOffset',
7418
7336
  Format => 'int32u',
7419
- Writable => 0,
7420
- Hidden => 1,
7421
- RawConv => '$$self{ISOAutoOffset} = $val || 0x10000000; undef',
7337
+ SubDirectory => {
7338
+ TagTable => 'Image::ExifTool::Nikon::ISOAutoInfoD810',
7339
+ Start => '$val',
7340
+ },
7422
7341
  },
7423
7342
  0x40 => {
7424
7343
  Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
7425
- DataMember => 'CustomSettingsOffset',
7426
7344
  Format => 'int32u',
7427
- Writable => 0,
7428
- Hidden => 1,
7429
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
7345
+ SubDirectory => {
7346
+ TagTable => 'Image::ExifTool::NikonCustom::SettingsD810',
7347
+ Start => '$val',
7348
+ },
7430
7349
  },
7431
7350
  0x84 => {
7432
7351
  Name => 'OrientationOffset',
7433
- DataMember => 'OrientationOffset',
7434
7352
  Format => 'int32u',
7435
- Writable => 0,
7436
- Hidden => 1,
7437
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
7353
+ SubDirectory => {
7354
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7355
+ Start => '$val',
7356
+ }
7438
7357
  },
7439
- 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 => {
7440
7376
  Name => 'SecondarySlotFunction',
7441
7377
  Mask => 0x03,
7442
7378
  PrintConv => {
@@ -7444,9 +7380,13 @@ my %nikonFocalConversions = (
7444
7380
  2 => 'Backup',
7445
7381
  3 => 'NEF Primary + JPG Secondary',
7446
7382
  },
7447
- Hook => '$varSize = $$self{BracketingOffset} - 0x1747',
7448
7383
  },
7449
- 0x1756 => {
7384
+ );
7385
+
7386
+ %Image::ExifTool::Nikon::BracketingInfoD810 = (
7387
+ %binaryDataAttrs,
7388
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7389
+ 0x0f => {
7450
7390
  Name => 'AEBracketingSteps',
7451
7391
  Mask => 0xff,
7452
7392
  PrintHex => 1,
@@ -7503,7 +7443,7 @@ my %nikonFocalConversions = (
7503
7443
  0xd6 => '5F3',
7504
7444
  },
7505
7445
  },
7506
- 0x1757 => {
7446
+ 0x10 => {
7507
7447
  Name => 'WBBracketingSteps',
7508
7448
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
7509
7449
  Mask => 0xff,
@@ -7546,7 +7486,7 @@ my %nikonFocalConversions = (
7546
7486
  0x28 => '9F 3',
7547
7487
  },
7548
7488
  },
7549
- 0x175e => {
7489
+ 0x17 => {
7550
7490
  Name => 'NikonMeteringMode',
7551
7491
  Mask => 0x03,
7552
7492
  PrintConv => {
@@ -7555,9 +7495,13 @@ my %nikonFocalConversions = (
7555
7495
  2 => 'Spot',
7556
7496
  3 => 'Highlight'
7557
7497
  },
7558
- Hook => '$varSize = $$self{ISOAutoOffset} - 0x1858',
7559
7498
  },
7560
- 0x185c => {
7499
+ );
7500
+
7501
+ %Image::ExifTool::Nikon::ISOAutoInfoD810 = (
7502
+ %binaryDataAttrs,
7503
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7504
+ 0x04 => {
7561
7505
  Name => 'ISOAutoShutterTime',
7562
7506
  Mask => 0x3f,
7563
7507
  PrintConv => {
@@ -7600,7 +7544,7 @@ my %nikonFocalConversions = (
7600
7544
  36 => 'Auto (Fastest)',
7601
7545
  },
7602
7546
  },
7603
- 0x185d => {
7547
+ 0x05 => {
7604
7548
  Name => 'ISOAutoHiLimit',
7605
7549
  Mask => 0xff,
7606
7550
  PrintHex => 1,
@@ -7647,69 +7591,18 @@ my %nikonFocalConversions = (
7647
7591
  0x6c => 'ISO Hi 4.0',
7648
7592
  0x72 => 'ISO Hi 5.0',
7649
7593
  },
7650
- Hook => '$varSize = $$self{CustomSettingsOffset} - 0x18ab',
7651
7594
  },
7652
- 0x18ab => { # (actual offset adjusted by Hook above)
7653
- Name => 'CustomSettingsD810',
7654
- Format => 'undef[53]',
7655
- SubDirectory => {
7656
- TagTable => 'Image::ExifTool::NikonCustom::SettingsD810',
7657
- },
7658
- Hook => '$varSize = $$self{OrientationOffset} - 0x36f4',
7659
- },
7660
- 0x36f4 => {
7661
- Name => 'RollAngle',
7662
- Format => 'fixed32u',
7663
- Notes => 'converted to degrees of clockwise camera roll',
7664
- ValueConv => '$val <= 180 ? $val : $val - 360',
7665
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7666
- PrintConv => 'sprintf("%.1f", $val)',
7667
- PrintConvInv => '$val',
7668
- },
7669
- 0x36f8 => {
7670
- Name => 'PitchAngle',
7671
- Format => 'fixed32u',
7672
- Notes => 'converted to degrees of upward camera tilt',
7673
- ValueConv => '$val <= 180 ? $val : $val - 360',
7674
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7675
- PrintConv => 'sprintf("%.1f", $val)',
7676
- PrintConvInv => '$val',
7677
- },
7678
- 0x36fc => {
7679
- Name => 'YawAngle',
7680
- Format => 'fixed32u',
7681
- Notes => 'the camera yaw angle when shooting in portrait orientation',
7682
- ValueConv => '$val <= 180 ? $val : $val - 360',
7683
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7684
- PrintConv => 'sprintf("%.1f", $val)',
7685
- PrintConvInv => '$val',
7686
- },
7687
- # note: DecryptLen currently set to OrientationOffset + 12
7688
-
7689
- # (moves around too much and doesn't fit cleanly in the offset table)
7690
- #0x38be => {
7691
- # Name => 'Rotation',
7692
- # Condition => '$$self{FirmwareVersion} =~ /^1\.0/',
7693
- # Mask => 0x30,
7694
- # PrintConv => {
7695
- # 0 => 'Horizontal',
7696
- # 1 => 'Rotate 270 CW',
7697
- # 2 => 'Rotate 90 CW',
7698
- # 3 => 'Rotate 180',
7699
- # },
7700
- #},
7701
7595
  );
7702
7596
 
7703
7597
  # shot information for the D850 firmware 1.00b (encrypted) - ref 28
7704
7598
  %Image::ExifTool::Nikon::ShotInfoD850 = (
7705
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7706
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7599
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7600
+ WRITE_PROC => \&ProcessNikonEncrypted,
7707
7601
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7708
- VARS => { ID_LABEL => 'Index' },
7709
- DATAMEMBER => [ 0x04, 0x58, 0xa0, 0x0fbf, 0x2efa ],
7710
- IS_SUBDIR => [ 0x1038 ],
7602
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
7603
+ DATAMEMBER => [ 0x04 ],
7604
+ IS_SUBDIR => [ 0x10, 0x4c, 0x58, 0xa0 ],
7711
7605
  WRITABLE => 1,
7712
- FIRST_ENTRY => 0,
7713
7606
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7714
7607
  NOTES => 'These tags are extracted from encrypted data in images from the D850.',
7715
7608
  0x00 => {
@@ -7724,23 +7617,44 @@ my %nikonFocalConversions = (
7724
7617
  Writable => 0,
7725
7618
  RawConv => '$$self{FirmwareVersion} = $val',
7726
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
+ },
7727
7636
  0x58 => {
7728
- Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
7729
- DataMember => 'CustomSettingsOffset',
7637
+ Name => 'CustomSettingsOffset',
7730
7638
  Format => 'int32u',
7731
- Writable => 0,
7732
- Hidden => 1,
7733
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
7639
+ SubDirectory => {
7640
+ TagTable => 'Image::ExifTool::NikonCustom::SettingsD850',
7641
+ Start => '$val',
7642
+ },
7734
7643
  },
7735
7644
  0xa0 => {
7736
7645
  Name => 'OrientationOffset',
7737
- DataMember => 'OrientationOffset',
7738
7646
  Format => 'int32u',
7739
- Writable => 0,
7740
- Hidden => 1,
7741
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
7647
+ SubDirectory => {
7648
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7649
+ Start => '$val',
7650
+ },
7742
7651
  },
7743
- 0x0791 => {
7652
+ );
7653
+
7654
+ %Image::ExifTool::Nikon::MenuSettingsD850 = (
7655
+ %binaryDataAttrs,
7656
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7657
+ 0x06dd => {
7744
7658
  Name => 'PhotoShootingMenuBankImageArea',
7745
7659
  Mask => 0x07,
7746
7660
  PrintConv => {
@@ -7751,7 +7665,12 @@ my %nikonFocalConversions = (
7751
7665
  4 => '1:1 (24x24)',
7752
7666
  },
7753
7667
  },
7754
- 0x0fbd => {
7668
+ );
7669
+
7670
+ %Image::ExifTool::Nikon::MoreSettingsD850 = (
7671
+ %binaryDataAttrs,
7672
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7673
+ 0x24 => {
7755
7674
  Name => 'PhotoShootingMenuBank',
7756
7675
  Condition => '$$self{FILE_TYPE} eq "JPEG"',
7757
7676
  Notes => 'valid for JPEG images only',
@@ -7763,63 +7682,20 @@ my %nikonFocalConversions = (
7763
7682
  3 => 'D',
7764
7683
  },
7765
7684
  },
7766
- 0x0fbf => {
7685
+ 0x25 => {
7767
7686
  Name => 'PrimarySlot',
7768
7687
  Mask => 0x80,
7769
7688
  PrintConv => {
7770
7689
  0 => 'XQD Card',
7771
7690
  1 => 'SD Card',
7772
7691
  },
7773
- Hook => '$varSize = $$self{CustomSettingsOffset} - 0x1038',
7774
- },
7775
- 0x1038 => {
7776
- Name => 'CustomSettingsD850',
7777
- Format => 'undef[90]',
7778
- SubDirectory => {
7779
- TagTable => 'Image::ExifTool::NikonCustom::SettingsD850',
7780
- },
7781
- },
7782
- ### 0x2efb - OrientationInfo start (D850 firmware 1.01a)
7783
- 0x2efa => {
7784
- Name => 'Hook1',
7785
- Hidden => 1,
7786
- RawConv => 'undef',
7787
- # account for variable location of OrientationInfo data
7788
- Hook => '$varSize = $$self{OrientationOffset} - 0x2efb',
7789
- },
7790
- 0x2efb => { #28
7791
- Name => 'RollAngle',
7792
- Format => 'fixed32u',
7793
- Notes => 'converted to degrees of clockwise camera roll',
7794
- ValueConv => '$val <= 180 ? $val : $val - 360',
7795
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7796
- PrintConv => 'sprintf("%.1f", $val)',
7797
- PrintConvInv => '$val',
7798
7692
  },
7799
- 0x2eff => { #28
7800
- Name => 'PitchAngle',
7801
- Format => 'fixed32u',
7802
- Notes => 'converted to degrees of upward camera tilt',
7803
- ValueConv => '$val <= 180 ? $val : $val - 360',
7804
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7805
- PrintConv => 'sprintf("%.1f", $val)',
7806
- PrintConvInv => '$val',
7807
- },
7808
- 0x2f03 => { #28
7809
- Name => 'YawAngle',
7810
- Format => 'fixed32u',
7811
- Notes => 'the camera yaw angle when shooting in portrait orientation',
7812
- ValueConv => '$val <= 180 ? $val : $val - 360',
7813
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
7814
- PrintConv => 'sprintf("%.1f", $val)',
7815
- PrintConvInv => '$val',
7816
- },
7817
- # note: DecryptLen currently set to 0x2f07
7818
7693
  );
7694
+
7819
7695
  # shot information for the D4 firmware 1.00g (ref PH)
7820
7696
  %Image::ExifTool::Nikon::ShotInfoD4 = (
7821
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7822
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7697
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7698
+ WRITE_PROC => \&ProcessNikonEncrypted,
7823
7699
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7824
7700
  VARS => { ID_LABEL => 'Index' },
7825
7701
  IS_SUBDIR => [ 0x0751 ],
@@ -7845,17 +7721,16 @@ my %nikonFocalConversions = (
7845
7721
  Format => 'undef[56]',
7846
7722
  SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsD4' },
7847
7723
  },
7848
- # note: DecryptLen currently set to 0x789
7849
7724
  );
7850
7725
 
7851
7726
  # shot information for the D4S firmware 1.01a (ref 28, encrypted)
7852
7727
  %Image::ExifTool::Nikon::ShotInfoD4S = (
7853
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7854
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7728
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7729
+ WRITE_PROC => \&ProcessNikonEncrypted,
7855
7730
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7856
7731
  VARS => { ID_LABEL => 'Index' },
7857
7732
  DATAMEMBER => [ 4 ],
7858
- IS_SUBDIR => [ 0x189d, 0x193d ],
7733
+ IS_SUBDIR => [ 0x189d, 0x193d, 0x350b ],
7859
7734
  WRITABLE => 1,
7860
7735
  FIRST_ENTRY => 0,
7861
7736
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
@@ -8119,31 +7994,13 @@ my %nikonFocalConversions = (
8119
7994
  # },
8120
7995
  # },
8121
7996
  0x350b => {
8122
- Name => 'RollAngle',
8123
- Format => 'fixed32u',
8124
- Notes => 'converted to degrees of clockwise camera roll',
8125
- ValueConv => '$val < 180 ? -$val : 360 - $val',
8126
- ValueConvInv => '$val <= 0 ? -$val : 360 - $val',
8127
- PrintConv => 'sprintf("%.1f", $val)',
8128
- PrintConvInv => '$val',
8129
- },
8130
- 0x350f => {
8131
- Name => 'PitchAngle',
8132
- Format => 'fixed32u',
8133
- Notes => 'converted to degrees of upward camera tilt',
8134
- ValueConv => '$val <= 180 ? $val : $val - 360',
8135
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8136
- PrintConv => 'sprintf("%.1f", $val)',
8137
- PrintConvInv => '$val',
8138
- },
8139
- 0x3513 => {
8140
- Name => 'YawAngle',
8141
- Format => 'fixed32u',
8142
- Notes => 'the camera yaw angle when shooting in portrait orientation',
8143
- ValueConv => '$val <= 180 ? $val : $val - 360',
8144
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8145
- PrintConv => 'sprintf("%.1f", $val)',
8146
- 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
+ },
8147
8004
  },
8148
8005
  0x3693 => {
8149
8006
  Name => 'Rotation',
@@ -8155,20 +8012,17 @@ my %nikonFocalConversions = (
8155
8012
  3 => 'Rotate 180',
8156
8013
  },
8157
8014
  },
8158
- # note: DecryptLen currently set to 0x3697
8159
8015
  );
8160
8016
 
8161
8017
  # shot information for the Z7II firmware 1.00 (encrypted) - ref 28
8162
8018
  %Image::ExifTool::Nikon::ShotInfoZ7II = (
8163
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8164
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8019
+ PROCESS_PROC => \&ProcessNikonEncrypted,
8020
+ WRITE_PROC => \&ProcessNikonEncrypted,
8165
8021
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
8166
- VARS => { ID_LABEL => 'Index' },
8167
- DATAMEMBER => [ 0x04, 0x30, 0x38, 0x98, 0xa0, 0x75e7, 0x760c,
8168
- 0x7610, 0x7eff, 0xce31, 0xcea5, 0xceb6, 0xceb7 ],
8169
- IS_SUBDIR => [ 0xceb8 ],
8022
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
8023
+ DATAMEMBER => [ 0x04 ],
8024
+ IS_SUBDIR => [ 0x30, 0x38, 0x98, 0xa0 ],
8170
8025
  WRITABLE => 1,
8171
- FIRST_ENTRY => 0,
8172
8026
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8173
8027
  NOTES => 'These tags are extracted from encrypted data in images from the Z7II.',
8174
8028
  0x00 => {
@@ -8197,79 +8051,73 @@ my %nikonFocalConversions = (
8197
8051
  },
8198
8052
  0x24 => {
8199
8053
  Name => 'NumberOffsets', # number of entries in offset table. offsets are from start of ShotInfo data.
8200
- DataMember => 'NumberOffsets',
8201
8054
  Format => 'int32u',
8202
8055
  Writable => 0,
8203
8056
  Hidden => 1,
8204
8057
  },
8205
8058
  0x30 => {
8206
- Name => 'Offset3',
8207
- DataMember => 'Offset3',
8059
+ Name => 'IntervalOffset',
8208
8060
  Format => 'int32u',
8209
- Writable => 0,
8210
- Hidden => 1,
8211
- RawConv => '$$self{Offset3} = $val || 0x10000000; undef', # (ignore if 0)
8061
+ SubDirectory => {
8062
+ TagTable => 'Image::ExifTool::Nikon::IntervalInfoZ7II',
8063
+ Start => '$val',
8064
+ }
8212
8065
  },
8213
8066
  0x38 => {
8214
- Name => 'Offset5',
8215
- DataMember => 'Offset5',
8067
+ Name => 'PortraitOffset',
8216
8068
  Format => 'int32u',
8217
- Writable => 0,
8218
- Hidden => 1,
8219
- RawConv => '$$self{Offset5} = $val || 0x10000000; undef', # (ignore if 0)
8069
+ SubDirectory => {
8070
+ TagTable => 'Image::ExifTool::Nikon::PortraitInfoZ7II',
8071
+ Start => '$val',
8072
+ }
8220
8073
  },
8221
8074
  0x98 => {
8222
8075
  Name => 'OrientationOffset',
8223
- DataMember => 'OrientationOffset',
8224
8076
  Format => 'int32u',
8225
- Writable => 0,
8226
- Hidden => 1,
8227
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
8077
+ SubDirectory => {
8078
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8079
+ Start => '$val',
8080
+ }
8228
8081
  },
8229
8082
  0xa0 => {
8230
- Name => 'Offset31',
8231
- DataMember => 'Offset31',
8083
+ Name => 'MenuOffset',
8232
8084
  Format => 'int32u',
8233
- Writable => 0,
8234
- Hidden => 1,
8235
- RawConv => '$$self{Offset31} = $val || 0x10000000; undef', # (ignore if 0)
8236
- },
8237
- ### 0x75e8 - Offset3 info start (Z7II firmware 1.30)
8238
- 0x75e7 => {
8239
- Name => 'Hook1',
8240
- Hidden => 1,
8241
- RawConv => 'undef',
8242
- # account for variable location of Offset3 data
8243
- Hook => '$varSize = $$self{Offset3} - 0x75e8',
8085
+ SubDirectory => {
8086
+ TagTable => 'Image::ExifTool::Nikon::MenuInfoZ7II',
8087
+ Start => '$val',
8088
+ },
8244
8089
  },
8245
- 0x760c => {
8090
+ );
8091
+
8092
+ %Image::ExifTool::Nikon::IntervalInfoZ7II = (
8093
+ %binaryDataAttrs,
8094
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8095
+ DATAMEMBER => [ 0x24, 0x28 ],
8096
+ 0x24 => {
8246
8097
  Name => 'IntervalShooting',
8247
8098
  RawConv => '$$self{IntervalShooting} = $val',
8248
8099
  Format => 'int16u',
8249
8100
  PrintConv => q{
8250
8101
  return 'Off' if $val == 0 ;
8251
- my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}); # something like "Interval 1 of 3"
8252
- 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
8253
8104
  return "On: $i$f"
8254
- #$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),
8255
8106
  },
8256
8107
  },
8257
- 0x7610 => {
8108
+ 0x28 => {
8258
8109
  Name => 'IntervalFrame',
8259
8110
  RawConv => '$$self{IntervalFrame} = $val',
8260
8111
  Condition => '$$self{IntervalShooting} > 0',
8261
8112
  Format => 'int16u',
8262
8113
  Hidden => 1,
8263
8114
  },
8264
- ### 0x7f00 - Offset5 info start (Z7II firmware 1.30)
8265
- 0x7eff => {
8266
- Name => 'Hook2',
8267
- Hidden => 1,
8268
- RawConv => 'undef',
8269
- # account for variable location of Offset5 data
8270
- Hook => '$varSize = $$self{Offset5} - 0x7f00',
8271
- },
8272
- 0x7fa0 => { #28
8115
+ );
8116
+
8117
+ %Image::ExifTool::Nikon::PortraitInfoZ7II = (
8118
+ %binaryDataAttrs,
8119
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8120
+ 0xa0 => { #28
8273
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
8274
8122
  # offset5+160; 128 is neutral; >128 increases Yellow; <128 increases Magenta; increments of 4 result from 1 full unit adjustment on the camera
8275
8123
  # offset5+161 128 is neutral; >128 increases Brightness; <128 decreases Brightness
@@ -8285,83 +8133,31 @@ my %nikonFocalConversions = (
8285
8133
  return "$color $brightness"
8286
8134
  },
8287
8135
  },
8288
- ### 0xce32 - OrientationInfo start (Z7II firmware 1.00)
8289
- 0xce31 => {
8290
- Name => 'Hook3',
8291
- Hidden => 1,
8292
- RawConv => 'undef',
8293
- # account for variable location of OrientationInfo data
8294
- Hook => '$varSize = $$self{OrientationOffset} - 0xce32',
8295
- },
8136
+ );
8296
8137
 
8297
- 0xce32 => {
8298
- Name => 'RollAngle',
8299
- Format => 'fixed32u',
8300
- Notes => 'converted to degrees of clockwise camera roll',
8301
- ValueConv => '$val <= 180 ? $val : $val - 360',
8302
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8303
- PrintConv => 'sprintf("%.1f", $val)',
8304
- PrintConvInv => '$val',
8305
- },
8306
- 0xce36 => {
8307
- Name => 'PitchAngle',
8308
- Format => 'fixed32u',
8309
- Notes => 'converted to degrees of upward camera tilt',
8310
- ValueConv => '$val <= 180 ? $val : $val - 360',
8311
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8312
- PrintConv => 'sprintf("%.1f", $val)',
8313
- PrintConvInv => '$val',
8314
- },
8315
- 0xce3a => {
8316
- Name => 'YawAngle',
8317
- Format => 'fixed32u',
8318
- Notes => 'the camera yaw angle when shooting in portrait orientation',
8319
- ValueConv => '$val <= 180 ? $val : $val - 360',
8320
- ValueConvInv => '$val >= 0 ? $val : $val + 360',
8321
- PrintConv => 'sprintf("%.1f", $val)',
8322
- PrintConvInv => '$val',
8323
- },
8324
- 0xcea5 => {
8325
- Name => 'Hook4',
8326
- Hidden => 1,
8327
- RawConv => 'undef',
8328
- # account for variable location of Offset31 data
8329
- Hook => '$varSize = $$self{Offset31} - 0xcea6',
8330
- },
8331
- ### 0xcea6 - Offset31 info start (Z7II firmware 1.30)
8332
- 0xceb6 => {
8333
- Name => 'MenuSettingsZ7IIOffset',
8334
- # offset to MenuSettingsZ7II is relative to start of Offset31 block
8335
- RawConv => '$$self{MenuSettingsZ7IIOffset} = ($val || 0x10000000) + $$self{Offset31}; undef', # (ignore if 0)
8336
- },
8337
- 0xceb7 => {
8338
- Name => 'Hook5',
8339
- Hidden => 1,
8340
- RawConv => 'undef',
8341
- # account for variable location of Offset5 data
8342
- Hook => '$varSize = $$self{MenuSettingsZ7IIOffset} - 0xceb8',
8343
- },
8344
- 0xceb8 => { # (this is 0xd04e for the Z50)
8345
- Name => 'MenuSettingsZ7II',
8346
- Format => 'undef[860]',
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',
8347
8145
  SubDirectory => {
8348
8146
  TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ7II',
8147
+ Start => '$dirStart + $val',
8349
8148
  },
8350
- }
8351
- # note: DecryptLen currently set to 0xd04e + 860 (offset for Z50 is 0xd04e)
8149
+ },
8352
8150
  );
8353
8151
 
8354
8152
  # shot information for the Z9 firmware 1.00 (encrypted) - ref 28
8355
8153
  %Image::ExifTool::Nikon::ShotInfoZ9 = (
8356
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8357
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8154
+ PROCESS_PROC => \&ProcessNikonEncrypted,
8155
+ WRITE_PROC => \&ProcessNikonEncrypted,
8358
8156
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
8359
- VARS => { ID_LABEL => 'Index' },
8360
- DATAMEMBER => [ 0x04, 0x30, 0x84, 0x8c,0x93, 0xb4, 0xbc, 0xbe,
8361
- 0x4410, 0x4411, 0x80c4, 0x8149, 0x814a ],
8362
- IS_SUBDIR => [ 0x44ec, 0x8225 ],
8157
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
8158
+ DATAMEMBER => [ 0x04 ],
8159
+ IS_SUBDIR => [ 0x30, 0x58, 0x84, 0x8c ],
8363
8160
  WRITABLE => 1,
8364
- FIRST_ENTRY => 0,
8365
8161
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8366
8162
  NOTES => 'These tags are extracted from encrypted data in images from the Z9.',
8367
8163
  0x00 => {
@@ -8390,47 +8186,55 @@ my %nikonFocalConversions = (
8390
8186
  },
8391
8187
  0x24 => {
8392
8188
  Name => 'NumberOffsets', # number of entries in offset table. offsets are from start of ShotInfo data.
8393
- DataMember => 'NumberOffsets',
8394
8189
  Format => 'int32u',
8395
8190
  Writable => 0,
8396
8191
  Hidden => 1,
8397
8192
  },
8193
+ # subdirectories, referenced by offsets (not processed if offset is zero)
8398
8194
  0x30 => {
8399
- Name => 'SequenceOffset', #offset3 - length 2528 (Z9 firmware 1.0)
8400
- DataMember => 'SequenceOffset',
8195
+ Name => 'SequenceOffset',
8401
8196
  Format => 'int32u',
8402
- Writable => 0,
8403
- Hidden => 1,
8404
- RawConv => '$$self{SequenceOffset} = $val || 0x10000000; undef', # (ignore if 0)
8197
+ SubDirectory => {
8198
+ TagTable => 'Image::ExifTool::Nikon::SeqInfoZ9',
8199
+ Start => '$val',
8200
+ },
8201
+ },
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"',
8205
+ Format => 'int32u',
8206
+ SubDirectory => {
8207
+ TagTable => 'Image::ExifTool::Nikon::Offset13InfoZ9',
8208
+ Start => '$val',
8209
+ },
8405
8210
  },
8406
8211
  0x84 => {
8407
- Name => 'OrientationOffset', #offset24 - length 108 (Z9 firmware 1.0)
8408
- DataMember => 'OrientationOffset',
8212
+ Name => 'OrientOffset',
8213
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8409
8214
  Format => 'int32u',
8410
- Writable => 0,
8411
- Hidden => 1,
8412
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
8215
+ SubDirectory => {
8216
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8217
+ Start => '$val',
8218
+ },
8413
8219
  },
8414
8220
  0x8c => {
8415
- Name => 'MenuOffset', #offset26 - length 1895 (Z9 firmware 1.0)
8416
- DataMember => 'MenuOffset6',
8221
+ Name => 'MenuOffset',
8417
8222
  Format => 'int32u',
8418
- Writable => 0,
8419
- Hidden => 1,
8420
- RawConv => '$$self{MenuOffset} = $val || 0x10000000; undef', # (ignore if 0)
8421
- },
8422
- ### 0x0094 - SequenceOffset info start (Z9 firmware 1.00)
8423
- 0x0093 => {
8424
- Name => 'SequenceOffsetHook',
8425
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8426
- Hidden => 1,
8427
- RawConv => 'undef',
8428
- # account for variable location of SequenceOffset data
8429
- Hook => '$varSize = $$self{SequenceOffset} - 0x0094',
8223
+ SubDirectory => {
8224
+ TagTable => 'Image::ExifTool::Nikon::MenuInfoZ9',
8225
+ Start => '$val',
8226
+ },
8430
8227
  },
8431
- 0x00b4 => {
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 => {
8432
8236
  Name => 'FocusShiftShooting',
8433
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8237
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8434
8238
  RawConv => '$$self{FocusShiftShooting} = $val',
8435
8239
  PrintConv => q{
8436
8240
  return 'Off' if $val == 0 ;
@@ -8438,86 +8242,215 @@ my %nikonFocalConversions = (
8438
8242
  return "On: $i"
8439
8243
  },
8440
8244
  },
8441
- 0x00bc => {
8245
+ 0x0028 => {
8442
8246
  Name => 'IntervalShooting',
8443
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8247
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8444
8248
  RawConv => '$$self{IntervalShooting} = $val',
8445
8249
  Format => 'int16u',
8446
8250
  PrintConv => q{
8447
8251
  return 'Off' if $val == 0 ;
8448
- my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}); # something like "Interval 1 of 3"
8449
- 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
8450
8254
  return "On: $i$f"
8451
- #$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),
8452
8256
  },
8453
8257
  },
8454
- 0x00be => {
8455
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8258
+ 0x002a => {
8456
8259
  Name => 'IntervalFrame',
8457
8260
  RawConv => '$$self{IntervalFrame} = $val',
8458
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8261
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8459
8262
  Format => 'int16u',
8460
8263
  Hidden => 1,
8461
8264
  },
8462
- ### 0x4400 - Offset26 info start (Z9 firmware 3.01 C30/C60/C120 )
8463
- 0x4410 => {
8464
- Name => 'MenuSettingsZ9Offset',
8465
- Condition => '$$self{ShutterMode} eq 96', # C30/C60/C120 jpgs only
8466
- Writable => 0,
8467
- Hidden => 1,
8468
- # offset to MenuSettingsZ9 is relative to start of Offset26 block
8469
- RawConv => '$$self{MenuSettingsZ9Offset} = ($val || 0x10000000) + $$self{MenuOffset}; undef', # (ignore if 0)
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)
8470
8403
  },
8471
- 0x4411 => {
8472
- Name => 'Hook5',
8473
- Condition => '$$self{ShutterMode} eq 96', # C30/C60/C120 jpgs only
8474
- Hidden => 1,
8475
- RawConv => 'undef',
8476
- # account for variable location of menu settings data
8477
- Hook => '$varSize = $$self{MenuSettingsZ9Offset} - 0x44ec',
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)
8478
8409
  },
8479
- 0x44ec => [
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 => [
8480
8418
  {
8481
- Name => 'MenuSettingsZ9',
8482
- Condition => '$$self{ShutterMode} eq 96 and $$self{FirmwareVersion} lt "03.00"', # C30/C60/C120 jpgs only
8483
- Format => 'undef[1646]',
8419
+ Name => 'MenuSettingsOffsetZ9',
8420
+ Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} lt "03.00"',
8421
+ Format => 'int32u',
8484
8422
  Notes => 'Firmware versions 2.11 and earlier',
8485
8423
  SubDirectory => {
8486
8424
  TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9',
8425
+ Start => '$dirStart + $val',
8487
8426
  },
8488
8427
  },
8489
8428
  {
8490
- Name => 'MenuSettingsZ9',
8429
+ Name => 'MenuSettingsOffsetZ9v3',
8491
8430
  Notes => 'Firmware versions 3.0 and later',
8492
- Condition => '$$self{ShutterMode} eq 96', # C30/C60/C120 jpgs only
8493
- Format => 'undef[1948]',
8431
+ Format => 'int32u',
8494
8432
  SubDirectory => {
8495
- TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9Firmware3',
8433
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9v3',
8434
+ Start => '$dirStart + $val',
8496
8435
  },
8497
8436
  },
8498
8437
  ],
8499
- ### 0x80c5 - OrientationInfo start (Z9 firmware 3.01)
8500
- 0x80c4 => {
8501
- Name => 'OrientationHook',
8502
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8503
- Hidden => 1,
8504
- RawConv => 'undef',
8505
- # account for variable location of OrientationInfo data
8506
- Hook => '$varSize = $$self{OrientationOffset} - 0x80c5',
8507
- },
8508
- 0x80c5 => {
8438
+ );
8439
+
8440
+ %Image::ExifTool::Nikon::OrientationInfo = (
8441
+ %binaryDataAttrs,
8442
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8443
+ 0 => {
8509
8444
  Name => 'RollAngle',
8510
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8511
- Format => 'fixed32u',
8445
+ Format => 'fixed32u',
8512
8446
  Notes => 'converted to degrees of clockwise camera roll',
8513
8447
  ValueConv => '$val <= 180 ? $val : $val - 360',
8514
8448
  ValueConvInv => '$val >= 0 ? $val : $val + 360',
8515
8449
  PrintConv => 'sprintf("%.1f", $val)',
8516
8450
  PrintConvInv => '$val',
8517
8451
  },
8518
- 0x80c9 => {
8452
+ 4 => {
8519
8453
  Name => 'PitchAngle',
8520
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8521
8454
  Format => 'fixed32u',
8522
8455
  Notes => 'converted to degrees of upward camera tilt',
8523
8456
  ValueConv => '$val <= 180 ? $val : $val - 360',
@@ -8525,9 +8458,8 @@ my %nikonFocalConversions = (
8525
8458
  PrintConv => 'sprintf("%.1f", $val)',
8526
8459
  PrintConvInv => '$val',
8527
8460
  },
8528
- 0x80cd => {
8461
+ 8 => {
8529
8462
  Name => 'YawAngle',
8530
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8531
8463
  Format => 'fixed32u',
8532
8464
  Notes => 'the camera yaw angle when shooting in portrait orientation',
8533
8465
  ValueConv => '$val <= 180 ? $val : $val - 360',
@@ -8535,51 +8467,25 @@ my %nikonFocalConversions = (
8535
8467
  PrintConv => 'sprintf("%.1f", $val)',
8536
8468
  PrintConvInv => '$val',
8537
8469
  },
8538
- ### 0x8139 - Offset26 info start (Z9 firmware 3.01)
8539
- 0x8149 => {
8540
- Name => 'MenuSettingsZ9Offset',
8541
- Condition => '$$self{ShutterMode} ne 96', # C30/C60/C120 jpgs handled at 0x4410
8542
- Writable => 0,
8543
- Hidden => 1,
8544
- # offset to MenuSettingsZ9 is relative to start of Offset26 block
8545
- RawConv => '$$self{MenuSettingsZ9Offset} = ($val || 0x10000000) + $$self{MenuOffset}; undef', # (ignore if 0)
8546
- },
8547
- 0x814a => {
8548
- Name => 'Hook5',
8549
- Condition => '$$self{ShutterMode} ne 96', # C30/C60/C120 jpgs handled at 0x4410
8550
- Hidden => 1,
8551
- RawConv => 'undef',
8552
- # account for variable location of menu settings data
8553
- Hook => '$varSize = $$self{MenuSettingsZ9Offset} - 0x8225',
8554
- },
8555
- 0x8225 => [
8556
- {
8557
- Name => 'MenuSettingsZ9',
8558
- Condition => '$$self{ShutterMode} ne 96 and $$self{FirmwareVersion} lt "03.00"', # C30/C60/C120 jpgs handled at 0x4410
8559
- Format => 'undef[1646]',
8560
- Notes => 'Firmware versions 2.11 and earlier',
8561
- SubDirectory => {
8562
- TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9',
8563
- },
8564
- },
8565
- {
8566
- Name => 'MenuSettingsZ9',
8567
- Notes => 'Firmware versions 3.0 and later',
8568
- Condition => '$$self{ShutterMode} ne 96', # C30/C60/C120 jpgs handled at 0x4410
8569
- Format => 'undef[1948]',
8570
- SubDirectory => {
8571
- TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9Firmware3',
8572
- },
8573
- },
8574
- ],
8575
- # note: DecryptLen currently set to 0xec4b + 2196
8576
8470
  );
8577
8471
 
8578
8472
  %Image::ExifTool::Nikon::MenuSettingsZ7II = (
8579
8473
  %binaryDataAttrs,
8580
8474
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8581
- DATAMEMBER => [ 176, 180, 328, 352, 858 ],
8475
+ DATAMEMBER => [ 90, 176, 180, 328, 352, 858 ],
8582
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
+ },
8583
8489
  160 => {
8584
8490
  Name => 'IntervalDurationHours',
8585
8491
  Format => 'int32u',
@@ -8800,7 +8706,7 @@ my %nikonFocalConversions = (
8800
8706
  %Image::ExifTool::Nikon::MenuSettingsZ9 = (
8801
8707
  %binaryDataAttrs,
8802
8708
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8803
- DATAMEMBER => [ 140, 188, 192, 232, 424, 534 ],
8709
+ DATAMEMBER => [ 140, 188, 192, 232, 424, 534, 576 ],
8804
8710
  IS_SUBDIR => [ 799 ],
8805
8711
  NOTES => 'These tags are used by the Z9.',
8806
8712
  #90 ISO
@@ -8814,34 +8720,34 @@ my %nikonFocalConversions = (
8814
8720
  Name => 'Intervals',
8815
8721
  Format => 'int32u',
8816
8722
  RawConv => '$$self{IntervalShootingIntervals} = $val',
8817
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8723
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8818
8724
  },
8819
8725
  192 => {
8820
8726
  Name => 'ShotsPerInterval',
8821
8727
  Format => 'int32u',
8822
8728
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
8823
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8729
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8824
8730
  },
8825
8731
  #220 NEFCompression 0=> 'Lossless' 1=> 'High Efficiency*' 4=> 'High Efficientcy'
8826
8732
  232 => {
8827
8733
  Name => 'FocusShiftNumberShots', #1-300
8828
8734
  RawConv => '$$self{FocusShiftNumberShots} = $val',
8829
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8735
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8830
8736
  },
8831
8737
  236 => {
8832
8738
  Name => 'FocusShiftStepWidth', #1(Narrow) to 10 (Wide)
8833
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8739
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8834
8740
  },
8835
8741
  240 => {
8836
8742
  Name => 'FocusShiftInterval',
8837
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8743
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8838
8744
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
8839
8745
  },
8840
8746
  244 => {
8841
8747
  Name => 'FocusShiftExposureLock',
8842
8748
  Unknown => 1,
8843
8749
  PrintConv => \%offOn,
8844
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8750
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8845
8751
  },
8846
8752
  274 => { Name => 'PhotoShootingMenuBank', PrintConv => \%banksZ9 },
8847
8753
  276 => { Name => 'ExtendedMenuBanks', PrintConv => \%offOn }, #single tag from both Photo & Video menus
@@ -8940,6 +8846,12 @@ my %nikonFocalConversions = (
8940
8846
  556 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFunctionZ9 },
8941
8847
  572 => { Name => 'DXCropAlert', PrintConv => \%offOn },
8942
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
+ },
8943
8855
  604 => {
8944
8856
  Name => 'MovieImageArea',
8945
8857
  Unknown => 1,
@@ -8996,16 +8908,16 @@ my %nikonFocalConversions = (
8996
8908
  1565 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
8997
8909
  1572 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
8998
8910
  1573 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
8999
- 1608 => { Name => 'EnergySavingMode', PrintConv =>\%offOn, Unknown => 1 },
8911
+ 1608 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
9000
8912
  1632 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
9001
8913
  1636 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
9002
8914
  1645 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
9003
8915
  );
9004
8916
 
9005
- %Image::ExifTool::Nikon::MenuSettingsZ9Firmware3 = ( #starts at Offset26 + 248
8917
+ %Image::ExifTool::Nikon::MenuSettingsZ9v3 = (
9006
8918
  %binaryDataAttrs,
9007
8919
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
9008
- DATAMEMBER => [ 154, 204, 208, 248, 444, 554 ],
8920
+ DATAMEMBER => [ 154, 204, 208, 248, 444, 554, 596 ],
9009
8921
  IS_SUBDIR => [ 847 ],
9010
8922
  NOTES => 'These tags are used by the Z9 firmware 3.00.',
9011
8923
  72 => {
@@ -9022,33 +8934,33 @@ my %nikonFocalConversions = (
9022
8934
  Name => 'Intervals',
9023
8935
  Format => 'int32u',
9024
8936
  RawConv => '$$self{IntervalShootingIntervals} = $val',
9025
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8937
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9026
8938
  },
9027
8939
  208 => {
9028
8940
  Name => 'ShotsPerInterval',
9029
8941
  Format => 'int32u',
9030
8942
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
9031
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8943
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9032
8944
  },
9033
8945
  248 => {
9034
8946
  Name => 'FocusShiftNumberShots', #1-300
9035
8947
  RawConv => '$$self{FocusShiftNumberShots} = $val',
9036
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8948
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9037
8949
  },
9038
8950
  252 => {
9039
8951
  Name => 'FocusShiftStepWidth', #1(Narrow) to 10 (Wide)
9040
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8952
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9041
8953
  },
9042
8954
  256 => {
9043
8955
  Name => 'FocusShiftInterval',
9044
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8956
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9045
8957
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
9046
8958
  },
9047
8959
  260 => {
9048
8960
  Name => 'FocusShiftExposureLock',
9049
8961
  Unknown => 1,
9050
8962
  PrintConv => \%offOn,
9051
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8963
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9052
8964
  },
9053
8965
  290 => { Name => 'PhotoShootingMenuBank', PrintConv => \%banksZ9 },
9054
8966
  292 => { Name => 'ExtendedMenuBanks', PrintConv => \%offOn }, # single tag from both Photo & Video menus
@@ -9134,6 +9046,12 @@ my %nikonFocalConversions = (
9134
9046
  576 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFunctionZ9 },
9135
9047
  592 => { Name => 'DXCropAlert', PrintConv => \%offOn },
9136
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
+ },
9137
9055
  636 => { Name => 'HighFrequencyFlickerReductionShooting', PrintConv => \%offOn, Unknown => 1 }, # new with firmware 3.0
9138
9056
  646 => {
9139
9057
  Name => 'MovieImageArea',
@@ -9192,7 +9110,7 @@ my %nikonFocalConversions = (
9192
9110
  1613 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
9193
9111
  1620 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
9194
9112
  1621 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
9195
- 1656 => { Name => 'EnergySavingMode', PrintConv =>\%offOn, Unknown => 1 },
9113
+ 1656 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
9196
9114
  1680 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
9197
9115
  1684 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
9198
9116
  1693 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
@@ -9200,7 +9118,7 @@ my %nikonFocalConversions = (
9200
9118
  Name => 'FocusShiftAutoReset',
9201
9119
  Unknown => 1,
9202
9120
  PrintConv => \%offOn,
9203
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9121
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9204
9122
  },
9205
9123
  1810 => { #CSd4-a
9206
9124
  Name => 'PreReleaseBurstLength',
@@ -11258,8 +11176,8 @@ my %nikonFocalConversions = (
11258
11176
  Name => 'LensData0201',
11259
11177
  SubDirectory => {
11260
11178
  TagTable => 'Image::ExifTool::Nikon::LensData01',
11261
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11262
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11179
+ ProcessProc => \&ProcessNikonEncrypted,
11180
+ WriteProc => \&ProcessNikonEncrypted,
11263
11181
  DecryptStart => 4,
11264
11182
  },
11265
11183
  },
@@ -11268,8 +11186,8 @@ my %nikonFocalConversions = (
11268
11186
  Name => 'LensData0204',
11269
11187
  SubDirectory => {
11270
11188
  TagTable => 'Image::ExifTool::Nikon::LensData0204',
11271
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11272
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11189
+ ProcessProc => \&ProcessNikonEncrypted,
11190
+ WriteProc => \&ProcessNikonEncrypted,
11273
11191
  DecryptStart => 4,
11274
11192
  },
11275
11193
  },
@@ -11278,8 +11196,8 @@ my %nikonFocalConversions = (
11278
11196
  Name => 'LensData0400',
11279
11197
  SubDirectory => {
11280
11198
  TagTable => 'Image::ExifTool::Nikon::LensData0400',
11281
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11282
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11199
+ ProcessProc => \&ProcessNikonEncrypted,
11200
+ WriteProc => \&ProcessNikonEncrypted,
11283
11201
  DecryptStart => 4,
11284
11202
  },
11285
11203
  },
@@ -11288,8 +11206,8 @@ my %nikonFocalConversions = (
11288
11206
  Name => 'LensData0402',
11289
11207
  SubDirectory => {
11290
11208
  TagTable => 'Image::ExifTool::Nikon::LensData0402',
11291
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11292
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11209
+ ProcessProc => \&ProcessNikonEncrypted,
11210
+ WriteProc => \&ProcessNikonEncrypted,
11293
11211
  DecryptStart => 4,
11294
11212
  },
11295
11213
  },
@@ -11298,8 +11216,8 @@ my %nikonFocalConversions = (
11298
11216
  Name => 'LensData0403',
11299
11217
  SubDirectory => {
11300
11218
  TagTable => 'Image::ExifTool::Nikon::LensData0403',
11301
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11302
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11219
+ ProcessProc => \&ProcessNikonEncrypted,
11220
+ WriteProc => \&ProcessNikonEncrypted,
11303
11221
  DecryptStart => 4,
11304
11222
  },
11305
11223
  },
@@ -11308,8 +11226,8 @@ my %nikonFocalConversions = (
11308
11226
  Name => 'LensData0800',
11309
11227
  SubDirectory => {
11310
11228
  TagTable => 'Image::ExifTool::Nikon::LensData0800',
11311
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11312
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11229
+ ProcessProc => \&ProcessNikonEncrypted,
11230
+ WriteProc => \&ProcessNikonEncrypted,
11313
11231
  DecryptStart => 4,
11314
11232
  ByteOrder => 'LittleEndian',
11315
11233
  # 0x5a0c - NikonMeteringMode for some Z6 ver1.00 samples (ref PH)
@@ -11319,8 +11237,8 @@ my %nikonFocalConversions = (
11319
11237
  Name => 'LensDataUnknown',
11320
11238
  SubDirectory => {
11321
11239
  TagTable => 'Image::ExifTool::Nikon::LensDataUnknown',
11322
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11323
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11240
+ ProcessProc => \&ProcessNikonEncrypted,
11241
+ WriteProc => \&ProcessNikonEncrypted,
11324
11242
  DecryptStart => 4,
11325
11243
  },
11326
11244
  },
@@ -11512,6 +11430,7 @@ my %nikonFocalConversions = (
11512
11430
  # construct lens ID string as per ref 11
11513
11431
  ValueConv => 'sprintf("%.2X"." %.2X"x7, @raw)',
11514
11432
  PrintConv => \%nikonLensIDs,
11433
+ PrintInt => 1,
11515
11434
  },
11516
11435
  AutoFocus => {
11517
11436
  Require => {
@@ -11835,37 +11754,54 @@ my @xlat = (
11835
11754
  0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f ]
11836
11755
  );
11837
11756
 
11757
+ my ($ci0, $cj0, $ck0, $decryptStart); # decryption parameters
11758
+
11838
11759
  # Decrypt Nikon data block (ref 4)
11839
- # Inputs: 0) reference to data block, 1) serial number key, 2) shutter count key
11840
- # 4) optional start offset (default 0)
11841
- # 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
11842
11764
  # Returns: data block with specified data decrypted
11843
- 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($;$$$$)
11844
11772
  {
11845
- my ($dataPt, $serial, $count, $start, $len) = @_;
11846
- my ($i, $dat);
11773
+ my ($dataPt, $start, $len, $serial, $count) = @_;
11774
+ my ($ch, $cj, $ck);
11847
11775
 
11848
11776
  $start or $start = 0;
11849
11777
  my $maxLen = length($$dataPt) - $start;
11850
11778
  $len = $maxLen if not defined $len or $len > $maxLen;
11851
- return $$dataPt if $len <= 0;
11852
- my $key = 0;
11853
- for ($i=0; $i<4; ++$i) {
11854
- $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;
11855
11787
  }
11856
- my $ci = $xlat[0][$serial & 0xff];
11857
- my $cj = $xlat[1][$key];
11858
- my $ck = 0x60;
11859
- my @data = unpack("x${start}C$len", $$dataPt);
11860
- foreach $dat (@data) {
11861
- $cj = ($cj + $ci * $ck) & 0xff;
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);
11796
+ }
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;
11862
11801
  $ck = ($ck + 1) & 0xff;
11863
- $dat ^= $cj;
11802
+ $ch ^= $cj;
11864
11803
  }
11865
- my $end = $start + $len;
11866
- my $pre = $start ? substr($$dataPt, 0, $start) : '';
11867
- my $post = $end < length($$dataPt) ? substr($$dataPt, $end) : '';
11868
- return $pre . pack('C*',@data) . $post;
11804
+ return substr($$dataPt, 0, $start) . pack('C*', @data) . substr($$dataPt, $start+$len);
11869
11805
  }
11870
11806
 
11871
11807
  #------------------------------------------------------------------------------
@@ -11901,19 +11837,19 @@ sub ProcessNikonApp($;$)
11901
11837
  my $trailerLen = unpack('N', $buff);
11902
11838
  $trailerLen > $fileEnd and $et->Warn('Bad NikonApp trailer size'), return 0;
11903
11839
  if ($dirInfo) {
11904
- $$dirInfo{DirLen} = $trailerLen if $dirInfo;
11840
+ $$dirInfo{DirLen} = $trailerLen;
11905
11841
  $$dirInfo{DataPos} = $fileEnd - $trailerLen;
11906
11842
  if ($$dirInfo{OutFile}) {
11907
11843
  if ($$et{DEL_GROUP}{NikonApp}) {
11844
+ $et->VPrint(0, " Deleting NikonApp trailer ($trailerLen bytes)\n");
11908
11845
  ++$$et{CHANGED};
11909
- # just copy the trailer when writing
11846
+ # just copy the trailer when writing (read directly into output buffer)
11910
11847
  } elsif ($trailerLen > $fileEnd or not $raf->Seek($$dirInfo{DataPos}, 0) or
11911
11848
  $raf->Read(${$$dirInfo{OutFile}}, $trailerLen) != $trailerLen)
11912
11849
  {
11913
11850
  return 0;
11914
- } else {
11915
- return 1;
11916
11851
  }
11852
+ return 1;
11917
11853
  }
11918
11854
  $et->DumpTrailer($dirInfo) if $verbose or $$et{HTML_DUMP};
11919
11855
  }
@@ -12001,6 +11937,166 @@ sub ProcessNikonMOV($$$)
12001
11937
  return 1;
12002
11938
  }
12003
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
+
12004
12100
  #------------------------------------------------------------------------------
12005
12101
  # Read/Write Nikon Encrypted data block
12006
12102
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -12025,15 +12121,17 @@ sub ProcessNikonEncrypted($$$)
12025
12121
  delete $$et{NikonCountKey};
12026
12122
  return 0;
12027
12123
  }
12028
- 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');
12029
12127
  my $tagInfo = $$dirInfo{TagInfo};
12030
12128
  my $dirStart = $$dirInfo{DirStart};
12031
12129
  my $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen});
12032
12130
 
12033
- my ($start, $len, $more, $offset, $byteOrder, $recrypt, $newSerial, $newCount);
12131
+ my ($start, $len, $offset, $recrypt, $newSerial, $newCount, $didDecrypt);
12034
12132
 
12035
12133
  # must re-encrypt when writing if serial number or shutter count changes
12036
- if ($$dirInfo{IsWriting}) {
12134
+ if ($isWriting) {
12037
12135
  if ($$et{NewNikonSerialKey}) {
12038
12136
  $newSerial = $$et{NewNikonSerialKey};
12039
12137
  $recrypt = 1;
@@ -12044,46 +12142,43 @@ sub ProcessNikonEncrypted($$$)
12044
12142
  }
12045
12143
  }
12046
12144
  if ($tagInfo and $$tagInfo{SubDirectory}) {
12047
- $start = $$tagInfo{SubDirectory}{DecryptStart};
12048
- # may decrypt only part of the information to save time
12049
- if ($verbose < 3 and $et->Options('Unknown') < 2 and not $recrypt) {
12050
- $len = $$tagInfo{SubDirectory}{DecryptLen};
12051
- $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};
12052
12172
  }
12053
- $offset = $$tagInfo{SubDirectory}{DirOffset};
12054
- $byteOrder = $$tagInfo{SubDirectory}{ByteOrder};
12055
- }
12056
- $start or $start = 0;
12057
- if (defined $offset) {
12058
- # offset, if specified, is relative to start of encrypted data
12059
- $offset += $start;
12060
12173
  } else {
12061
- $offset = 0;
12174
+ $start = $offset = 0;
12062
12175
  }
12063
12176
  my $maxLen = length($data) - $start;
12064
- # decrypt all the data unless DecryptLen is given
12065
- unless ($len and $len < $maxLen) {
12066
- $len = $maxLen;
12067
- undef $more; # (can't decrypt more than this)
12068
- }
12177
+ # decrypt all the data unless the length was specified
12178
+ $len = $maxLen unless $len and $len < $maxLen;
12069
12179
 
12070
- $data = Decrypt(\$data, $serial, $count, $start, $len);
12180
+ $data = Decrypt(\$data, $start, $len, $serial, $count) unless $didDecrypt;
12071
12181
 
12072
- # set appropriate byte ordering before evaluating DecryptMore
12073
- my $oldOrder = GetByteOrder();
12074
- SetByteOrder($byteOrder) if $byteOrder;
12075
-
12076
- if ($more) {
12077
- #### eval DecryptMore ($data)
12078
- my $moreLen = eval $more;
12079
- $moreLen = $maxLen if $moreLen > $maxLen;
12080
- # re-decrypt with new length
12081
- if ($len < $moreLen) {
12082
- $len = $moreLen;
12083
- $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen});
12084
- $data = Decrypt(\$data, $serial, $count, $start, $len);
12085
- }
12086
- }
12087
12182
  if ($verbose > 2) {
12088
12183
  $et->VerboseDir("Decrypted $$tagInfo{Name}");
12089
12184
  $et->VerboseDump(\$data,
@@ -12102,7 +12197,7 @@ sub ProcessNikonEncrypted($$$)
12102
12197
  Base => $$dirInfo{Base},
12103
12198
  );
12104
12199
  my $rtnVal;
12105
- if ($$dirInfo{IsWriting}) {
12200
+ if ($isWriting) {
12106
12201
  my $changed = $$et{CHANGED};
12107
12202
  $rtnVal = $et->WriteBinaryData(\%subdirInfo, $tagTablePtr);
12108
12203
  # must re-encrypt if serial number or shutter count changes
@@ -12117,7 +12212,8 @@ sub ProcessNikonEncrypted($$$)
12117
12212
  # add back any un-encrypted data at start
12118
12213
  $rtnVal = substr($data, 0, $offset) . $rtnVal if $offset;
12119
12214
  # re-encrypt data (symmetrical algorithm)
12120
- $rtnVal = Decrypt(\$rtnVal, $serial, $count, $start, $len);
12215
+ $rtnVal = Decrypt(\$rtnVal, $start, $len, $serial, $count);
12216
+ $et->VPrint(2, $$et{INDENT}, " [recrypted $$tagInfo{Name}]");
12121
12217
  }
12122
12218
  } else {
12123
12219
  $rtnVal = $et->ProcessBinaryData(\%subdirInfo, $tagTablePtr);