exiftool_vendored 12.56.0 → 12.58.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +35 -2
  3. data/bin/META.json +1 -1
  4. data/bin/META.yml +1 -1
  5. data/bin/README +2 -2
  6. data/bin/config_files/rotate_regions.config +1 -1
  7. data/bin/exiftool +95 -47
  8. data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  9. data/bin/lib/Image/ExifTool/APE.pm +2 -2
  10. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +19 -15
  11. data/bin/lib/Image/ExifTool/Canon.pm +26 -6
  12. data/bin/lib/Image/ExifTool/DJI.pm +28 -2
  13. data/bin/lib/Image/ExifTool/Exif.pm +24 -5
  14. data/bin/lib/Image/ExifTool/FlashPix.pm +6 -2
  15. data/bin/lib/Image/ExifTool/FujiFilm.pm +1 -0
  16. data/bin/lib/Image/ExifTool/GPS.pm +7 -2
  17. data/bin/lib/Image/ExifTool/JPEG.pm +14 -2
  18. data/bin/lib/Image/ExifTool/Jpeg2000.pm +5 -5
  19. data/bin/lib/Image/ExifTool/LNK.pm +5 -4
  20. data/bin/lib/Image/ExifTool/MIE.pm +3 -3
  21. data/bin/lib/Image/ExifTool/MPEG.pm +2 -2
  22. data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -2
  23. data/bin/lib/Image/ExifTool/Minolta.pm +6 -7
  24. data/bin/lib/Image/ExifTool/Nikon.pm +998 -903
  25. data/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
  26. data/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
  27. data/bin/lib/Image/ExifTool/Olympus.pm +3 -1
  28. data/bin/lib/Image/ExifTool/Pentax.pm +8 -5
  29. data/bin/lib/Image/ExifTool/Photoshop.pm +38 -7
  30. data/bin/lib/Image/ExifTool/QuickTime.pm +23 -7
  31. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +3 -1
  32. data/bin/lib/Image/ExifTool/README +19 -2
  33. data/bin/lib/Image/ExifTool/RIFF.pm +3 -3
  34. data/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
  35. data/bin/lib/Image/ExifTool/Sigma.pm +5 -4
  36. data/bin/lib/Image/ExifTool/Sony.pm +23 -1
  37. data/bin/lib/Image/ExifTool/TagLookup.pm +4670 -4628
  38. data/bin/lib/Image/ExifTool/TagNames.pod +261 -89
  39. data/bin/lib/Image/ExifTool/Validate.pm +5 -5
  40. data/bin/lib/Image/ExifTool/WriteExif.pl +42 -0
  41. data/bin/lib/Image/ExifTool/Writer.pl +39 -17
  42. data/bin/lib/Image/ExifTool/XMP.pm +2 -2
  43. data/bin/lib/Image/ExifTool.pm +94 -33
  44. data/bin/lib/Image/ExifTool.pod +4 -4
  45. data/bin/perl-Image-ExifTool.spec +1 -1
  46. data/lib/exiftool_vendored/version.rb +1 -1
  47. metadata +2 -2
@@ -64,11 +64,12 @@ use Image::ExifTool::Exif;
64
64
  use Image::ExifTool::GPS;
65
65
  use Image::ExifTool::XMP;
66
66
 
67
- $VERSION = '4.18';
67
+ $VERSION = '4.20';
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,12 +5288,14 @@ 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
5316
5301
  39 => 'Nikkor Z 17-28mm f/2.8', #IB
@@ -5322,7 +5307,7 @@ my %nikonFocalConversions = (
5322
5307
  Name => 'LensMountType',
5323
5308
  RawConv => '$$self{LensMountType} = $val', # 0=> DSLR lens via FTZ style adapter; 1=> Native Z lens;
5324
5309
  Format => 'int8u',
5325
- Unknown => 1,
5310
+ #Unknown => 1,
5326
5311
  PrintConv => {
5327
5312
  0 => 'F-mount Lens',
5328
5313
  1 => 'Z-mount Lens',
@@ -5385,7 +5370,7 @@ my %nikonFocalConversions = (
5385
5370
  Name => 'LensPositionAbsolute', # <=0 at infinity. Typical value at CFD might be 58000. Only valid for Z-mount lenses.
5386
5371
  Condition => '$$self{NewLensData} and $$self{LensMountType} and $$self{LensMountType} == 1',
5387
5372
  Format => 'int32s',
5388
- Unknown => 1,
5373
+ #Unknown => 1,
5389
5374
  },
5390
5375
  );
5391
5376
 
@@ -5508,8 +5493,6 @@ my %nikonFocalConversions = (
5508
5493
  Format => 'int32u',
5509
5494
  Priority => 0,
5510
5495
  },
5511
- # note: DecryptLen currently set to 0x251
5512
-
5513
5496
  # 0x55c - int16u[2400] TiffMeteringImage2: 60x40 image (ShotInfoVersion 0800, ref JR)
5514
5497
  # 0x181c - int16u[1200] TiffMeteringImage?: 60x20 image for some NEF's (ShotInfoVersion 0800, ref JR)
5515
5498
  # 0x217c - int16u[2400] TiffMeteringImage3: 60x40 image (ShotInfoVersion 0800, ref JR)
@@ -5521,8 +5504,8 @@ my %nikonFocalConversions = (
5521
5504
 
5522
5505
  # shot information for D40 and D40X (encrypted) - ref PH
5523
5506
  %Image::ExifTool::Nikon::ShotInfoD40 = (
5524
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5525
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5507
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5508
+ WRITE_PROC => \&ProcessNikonEncrypted,
5526
5509
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5527
5510
  VARS => { ID_LABEL => 'Index' },
5528
5511
  IS_SUBDIR => [ 729 ],
@@ -5552,13 +5535,12 @@ my %nikonFocalConversions = (
5552
5535
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD40',
5553
5536
  },
5554
5537
  },
5555
- # note: DecryptLen currently set to 748
5556
5538
  );
5557
5539
 
5558
5540
  # shot information for D80 (encrypted) - ref JD
5559
5541
  %Image::ExifTool::Nikon::ShotInfoD80 = (
5560
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5561
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5542
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5543
+ WRITE_PROC => \&ProcessNikonEncrypted,
5562
5544
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5563
5545
  VARS => { ID_LABEL => 'Index' },
5564
5546
  IS_SUBDIR => [ 748 ],
@@ -5632,13 +5614,12 @@ my %nikonFocalConversions = (
5632
5614
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD80',
5633
5615
  },
5634
5616
  },
5635
- # note: DecryptLen currently set to 765
5636
5617
  );
5637
5618
 
5638
5619
  # shot information for D90 (encrypted) - ref PH
5639
5620
  %Image::ExifTool::Nikon::ShotInfoD90 = (
5640
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5641
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5621
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5622
+ WRITE_PROC => \&ProcessNikonEncrypted,
5642
5623
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5643
5624
  VARS => { ID_LABEL => 'Index' },
5644
5625
  IS_SUBDIR => [ 0x374 ],
@@ -5678,13 +5659,12 @@ my %nikonFocalConversions = (
5678
5659
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD90',
5679
5660
  },
5680
5661
  },
5681
- # note: DecryptLen currently set to 0x398
5682
5662
  );
5683
5663
 
5684
5664
  # shot information for the D3 firmware 0.37 and 1.00 (encrypted) - ref PH
5685
5665
  %Image::ExifTool::Nikon::ShotInfoD3a = (
5686
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5687
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5666
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5667
+ WRITE_PROC => \&ProcessNikonEncrypted,
5688
5668
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5689
5669
  VARS => { ID_LABEL => 'Index' },
5690
5670
  IS_SUBDIR => [ 0x301 ],
@@ -5742,13 +5722,12 @@ my %nikonFocalConversions = (
5742
5722
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5743
5723
  },
5744
5724
  },
5745
- # note: DecryptLen currently set to 0x318
5746
5725
  );
5747
5726
 
5748
5727
  # shot information for the D3 firmware 1.10, 2.00 and 2.01 (encrypted) - ref PH
5749
5728
  %Image::ExifTool::Nikon::ShotInfoD3b = (
5750
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5751
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5729
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5730
+ WRITE_PROC => \&ProcessNikonEncrypted,
5752
5731
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5753
5732
  VARS => { ID_LABEL => 'Index' },
5754
5733
  IS_SUBDIR => [ 0x30a ],
@@ -5837,13 +5816,12 @@ my %nikonFocalConversions = (
5837
5816
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5838
5817
  },
5839
5818
  },
5840
- # note: DecryptLen currently set to 0x321
5841
5819
  );
5842
5820
 
5843
5821
  # shot information for the D3X firmware 1.00 (encrypted) - ref PH
5844
5822
  %Image::ExifTool::Nikon::ShotInfoD3X = (
5845
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5846
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5823
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5824
+ WRITE_PROC => \&ProcessNikonEncrypted,
5847
5825
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5848
5826
  VARS => { ID_LABEL => 'Index' },
5849
5827
  IS_SUBDIR => [ 0x30b ],
@@ -5883,13 +5861,12 @@ my %nikonFocalConversions = (
5883
5861
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5884
5862
  },
5885
5863
  },
5886
- # note: DecryptLen currently set to 0x323
5887
5864
  );
5888
5865
 
5889
5866
  # shot information for the D3S firmware 0.16 and 1.00 (encrypted) - ref PH
5890
5867
  %Image::ExifTool::Nikon::ShotInfoD3S = (
5891
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5892
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5868
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5869
+ WRITE_PROC => \&ProcessNikonEncrypted,
5893
5870
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5894
5871
  VARS => { ID_LABEL => 'Index' },
5895
5872
  IS_SUBDIR => [ 0x2ce ],
@@ -5938,13 +5915,12 @@ my %nikonFocalConversions = (
5938
5915
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
5939
5916
  },
5940
5917
  },
5941
- # note: DecryptLen currently set to 0x2e9
5942
5918
  );
5943
5919
 
5944
5920
  # shot information for the D300 firmware 1.00 (encrypted) - ref JD
5945
5921
  %Image::ExifTool::Nikon::ShotInfoD300a = (
5946
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5947
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5922
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5923
+ WRITE_PROC => \&ProcessNikonEncrypted,
5948
5924
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5949
5925
  VARS => { ID_LABEL => 'Index' },
5950
5926
  IS_SUBDIR => [ 790 ],
@@ -6031,13 +6007,12 @@ my %nikonFocalConversions = (
6031
6007
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6032
6008
  },
6033
6009
  },
6034
- # note: DecryptLen currently set to 813
6035
6010
  );
6036
6011
 
6037
6012
  # shot information for the D300 firmware 1.10 (encrypted) - ref PH
6038
6013
  %Image::ExifTool::Nikon::ShotInfoD300b = (
6039
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6040
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6014
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6015
+ WRITE_PROC => \&ProcessNikonEncrypted,
6041
6016
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6042
6017
  VARS => { ID_LABEL => 'Index' },
6043
6018
  DATAMEMBER => [ 4 ],
@@ -6182,13 +6157,12 @@ my %nikonFocalConversions = (
6182
6157
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6183
6158
  },
6184
6159
  },
6185
- # note: DecryptLen currently set to 825
6186
6160
  );
6187
6161
 
6188
6162
  # shot information for the D300S firmware 1.00 (encrypted) - ref PH
6189
6163
  %Image::ExifTool::Nikon::ShotInfoD300S = (
6190
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6191
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6164
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6165
+ WRITE_PROC => \&ProcessNikonEncrypted,
6192
6166
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6193
6167
  VARS => { ID_LABEL => 'Index' },
6194
6168
  IS_SUBDIR => [ 804 ],
@@ -6228,13 +6202,12 @@ my %nikonFocalConversions = (
6228
6202
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
6229
6203
  },
6230
6204
  },
6231
- # note: DecryptLen currently set to 827
6232
6205
  );
6233
6206
 
6234
6207
  # shot information for the D700 firmware 1.02f (encrypted) - ref 29
6235
6208
  %Image::ExifTool::Nikon::ShotInfoD700 = (
6236
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6237
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6209
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6210
+ WRITE_PROC => \&ProcessNikonEncrypted,
6238
6211
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6239
6212
  VARS => { ID_LABEL => 'Index' },
6240
6213
  IS_SUBDIR => [ 804 ],
@@ -6274,13 +6247,45 @@ my %nikonFocalConversions = (
6274
6247
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD700',
6275
6248
  },
6276
6249
  },
6277
- # note: DecryptLen currently set to 852
6250
+ );
6251
+
6252
+ # shot information for the D780 - ref #28
6253
+ %Image::ExifTool::Nikon::ShotInfoD780 = (
6254
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6255
+ WRITE_PROC => \&ProcessNikonEncrypted,
6256
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6257
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
6258
+ DATAMEMBER => [ 0x04 ],
6259
+ IS_SUBDIR => [ 0x9c ],
6260
+ WRITABLE => 1,
6261
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6262
+ NOTES => 'These tags are extracted from encrypted data in images from the D780.',
6263
+ 0x00 => {
6264
+ Name => 'ShotInfoVersion',
6265
+ Format => 'string[4]',
6266
+ Writable => 0,
6267
+ },
6268
+ 0x04 => {
6269
+ Name => 'FirmwareVersion',
6270
+ DataMember => 'FirmwareVersion',
6271
+ Format => 'string[5]',
6272
+ Writable => 0,
6273
+ RawConv => '$$self{FirmwareVersion} = $val',
6274
+ },
6275
+ 0x9c => {
6276
+ Name => 'OrientOffset',
6277
+ Format => 'int32u',
6278
+ SubDirectory => {
6279
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
6280
+ Start => '$val',
6281
+ },
6282
+ },
6278
6283
  );
6279
6284
 
6280
6285
  # shot information for the D5000 firmware 1.00 (encrypted) - ref PH
6281
6286
  %Image::ExifTool::Nikon::ShotInfoD5000 = (
6282
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6283
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6287
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6288
+ WRITE_PROC => \&ProcessNikonEncrypted,
6284
6289
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6285
6290
  VARS => { ID_LABEL => 'Index' },
6286
6291
  IS_SUBDIR => [ 0x378 ],
@@ -6320,13 +6325,12 @@ my %nikonFocalConversions = (
6320
6325
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5000',
6321
6326
  },
6322
6327
  },
6323
- # note: DecryptLen currently set to 0x39a
6324
6328
  );
6325
6329
 
6326
6330
  # shot information for the D5100 firmware 1.00f (encrypted) - ref PH
6327
6331
  %Image::ExifTool::Nikon::ShotInfoD5100 = (
6328
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6329
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6332
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6333
+ WRITE_PROC => \&ProcessNikonEncrypted,
6330
6334
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6331
6335
  VARS => { ID_LABEL => 'Index' },
6332
6336
  IS_SUBDIR => [ 0x407 ],
@@ -6355,13 +6359,12 @@ my %nikonFocalConversions = (
6355
6359
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5100',
6356
6360
  },
6357
6361
  },
6358
- # note: DecryptLen currently set to 0x430
6359
6362
  );
6360
6363
 
6361
6364
  # shot information for the D5200 firmware 1.00 (encrypted) - ref PH
6362
6365
  %Image::ExifTool::Nikon::ShotInfoD5200 = (
6363
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6364
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6366
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6367
+ WRITE_PROC => \&ProcessNikonEncrypted,
6365
6368
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6366
6369
  VARS => { ID_LABEL => 'Index' },
6367
6370
  IS_SUBDIR => [ 0xcd5 ],
@@ -6393,13 +6396,12 @@ my %nikonFocalConversions = (
6393
6396
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD5200',
6394
6397
  },
6395
6398
  },
6396
- # note: DecryptLen currently set to 0xd00
6397
6399
  );
6398
6400
 
6399
6401
  # shot information for the D7000 firmware 1.01d (encrypted) - ref 29
6400
6402
  %Image::ExifTool::Nikon::ShotInfoD7000 = (
6401
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6402
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6403
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6404
+ WRITE_PROC => \&ProcessNikonEncrypted,
6403
6405
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6404
6406
  VARS => { ID_LABEL => 'Index' },
6405
6407
  IS_SUBDIR => [ 1028 ],
@@ -6441,10 +6443,43 @@ my %nikonFocalConversions = (
6441
6443
  },
6442
6444
  );
6443
6445
 
6446
+ # shot information for the D7500 - ref #28
6447
+ %Image::ExifTool::Nikon::ShotInfoD7500 = (
6448
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6449
+ WRITE_PROC => \&ProcessNikonEncrypted,
6450
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6451
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
6452
+ DATAMEMBER => [ 0x04 ],
6453
+ IS_SUBDIR => [ 0xa0 ],
6454
+ WRITABLE => 1,
6455
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6456
+ NOTES => 'These tags are extracted from encrypted data in images from the D7500.',
6457
+ 0x00 => {
6458
+ Name => 'ShotInfoVersion',
6459
+ Format => 'string[4]',
6460
+ Writable => 0,
6461
+ },
6462
+ 0x04 => {
6463
+ Name => 'FirmwareVersion',
6464
+ DataMember => 'FirmwareVersion',
6465
+ Format => 'string[5]',
6466
+ Writable => 0,
6467
+ RawConv => '$$self{FirmwareVersion} = $val',
6468
+ },
6469
+ 0xa0 => {
6470
+ Name => 'OrientOffset',
6471
+ Format => 'int32u',
6472
+ SubDirectory => {
6473
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
6474
+ Start => '$val',
6475
+ },
6476
+ },
6477
+ );
6478
+
6444
6479
  # shot information for the D800 firmware 1.01a (encrypted) - ref PH
6445
6480
  %Image::ExifTool::Nikon::ShotInfoD800 = (
6446
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6447
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6481
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6482
+ WRITE_PROC => \&ProcessNikonEncrypted,
6448
6483
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6449
6484
  VARS => { ID_LABEL => 'Index' },
6450
6485
  IS_SUBDIR => [ 0x6ec ],
@@ -6559,20 +6594,17 @@ my %nikonFocalConversions = (
6559
6594
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD800',
6560
6595
  },
6561
6596
  },
6562
- # note: DecryptLen currently set to 0x720
6563
6597
  );
6564
6598
 
6565
6599
  # shot information for the D5 firmware 1.10a and D500 firmware 1.01 (encrypted) - ref 28
6566
6600
  %Image::ExifTool::Nikon::ShotInfoD500 = (
6567
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6568
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6601
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6602
+ WRITE_PROC => \&ProcessNikonEncrypted,
6569
6603
  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 ],
6604
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
6605
+ DATAMEMBER => [ 0x04 ],
6606
+ IS_SUBDIR => [ 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8 ],
6574
6607
  WRITABLE => 1,
6575
- FIRST_ENTRY => 0,
6576
6608
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6577
6609
  NOTES => 'These tags are extracted from encrypted data in images from the D5 and D500.',
6578
6610
  0x00 => {
@@ -6589,73 +6621,66 @@ my %nikonFocalConversions = (
6589
6621
  },
6590
6622
  0x10 => {
6591
6623
  Name => 'RotationInfoOffset',
6592
- DataMember => 'RotationInfoOffset',
6593
6624
  Format => 'int32u',
6594
- Writable => 0,
6595
- Hidden => 1,
6596
- RawConv => '$$self{RotationInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6625
+ SubDirectory => {
6626
+ TagTable => 'Image::ExifTool::Nikon::RotationInfoD500',
6627
+ Start => '$val',
6628
+ }
6597
6629
  },
6598
6630
  0x14 => {
6599
6631
  Name => 'JPGInfoOffset',
6600
- DataMember => 'JPGInfoOffset',
6601
6632
  Format => 'int32u',
6602
- Writable => 0,
6603
- Hidden => 1,
6604
- RawConv => '$$self{JPGInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6633
+ SubDirectory => {
6634
+ TagTable => 'Image::ExifTool::Nikon::JPGInfoD500',
6635
+ Start => '$val',
6636
+ }
6605
6637
  },
6606
6638
  0x2c => {
6607
- Name => 'BracketingInfoOffset',
6608
- DataMember => 'BracketingInfoOffset',
6639
+ Name => 'BracketingOffset',
6609
6640
  Format => 'int32u',
6610
- Writable => 0,
6611
- Hidden => 1,
6612
- RawConv => '$$self{BracketingInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6641
+ SubDirectory => {
6642
+ TagTable => 'Image::ExifTool::Nikon::BracketingInfoD500',
6643
+ Start => '$val',
6644
+ }
6613
6645
  },
6614
6646
  0x50 => {
6615
6647
  Name => 'ShootingMenuOffset',
6616
- DataMember => 'ShootingMenuOffset',
6617
6648
  Format => 'int32u',
6618
- Writable => 0,
6619
- Hidden => 1,
6620
- RawConv => '$$self{ShootingMenuOffset} = $val || 0x10000000; undef', # (ignore if 0)
6649
+ SubDirectory => {
6650
+ TagTable => 'Image::ExifTool::Nikon::ShootingMenuD500',
6651
+ Start => '$val',
6652
+ }
6621
6653
  },
6622
6654
  0x58 => {
6623
6655
  Name => 'CustomSettingsOffset',
6624
- DataMember => 'CustomSettingsOffset',
6625
6656
  Format => 'int32u',
6626
- Writable => 0,
6627
- Hidden => 1,
6628
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef', # (ignore if 0)
6657
+ SubDirectory => {
6658
+ TagTable => 'Image::ExifTool::Nikon::CustomSettingsD500',
6659
+ Start => '$val',
6660
+ }
6629
6661
  },
6630
6662
  0xa0 => {
6631
6663
  Name => 'OrientationOffset',
6632
- DataMember => 'OrientationOffset',
6633
6664
  Format => 'int32u',
6634
- Writable => 0,
6635
- Hidden => 1,
6636
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
6665
+ SubDirectory => {
6666
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
6667
+ Start => '$val',
6668
+ }
6637
6669
  },
6638
6670
  0xa8 => {
6639
6671
  Name => 'OtherOffset',
6640
- DataMember => 'OtherOffset',
6641
6672
  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',
6673
+ SubDirectory => {
6674
+ TagTable => 'Image::ExifTool::Nikon::OtherInfoD500',
6675
+ Start => '$val',
6676
+ }
6657
6677
  },
6658
- 0xca => {
6678
+ );
6679
+
6680
+ %Image::ExifTool::Nikon::RotationInfoD500 = (
6681
+ %binaryDataAttrs,
6682
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6683
+ 0x1a => {
6659
6684
  Name => 'Rotation',
6660
6685
  Mask => 0x03,
6661
6686
  PrintConv => {
@@ -6665,32 +6690,29 @@ my %nikonFocalConversions = (
6665
6690
  3 => 'Rotate 180',
6666
6691
  },
6667
6692
  },
6668
- 0x0d0 => {
6693
+ 0x20 => {
6669
6694
  Name => 'Interval',
6670
6695
  # prior version of the d% firmware do not support this tag, nor does the D500 (at least thru firmware 1.3)
6671
6696
  Condition => '$$self{Model} eq "NIKON D5" and $$self{FirmwareVersion} ge "1.40"',
6672
6697
  PrintConv => '$val > 0 ? sprintf("%.0f", $val) : ""',
6673
6698
  },
6674
- 0x0d4 => {
6699
+ 0x24 => {
6675
6700
  Name => 'IntervalFrame',
6676
6701
  # prior version of the d% firmware do not support this tag, nor does the D500 (at least thru firmware 1.3)
6677
6702
  Condition => '$$self{Model} eq "NIKON D5" and $$self{FirmwareVersion} ge "1.40"',
6678
6703
  PrintConv => '$val > 0 ? sprintf("%.0f", $val) : ""',
6679
6704
  },
6680
- 0x05e2 => {
6705
+ 0x0532 => {
6681
6706
  Name => 'FlickerReductionIndicator',
6682
6707
  Mask => 0x01,
6683
6708
  PrintConv => { 0 => 'On', 1 => 'Off' },
6684
6709
  },
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 => {
6710
+ );
6711
+
6712
+ %Image::ExifTool::Nikon::JPGInfoD500 = (
6713
+ %binaryDataAttrs,
6714
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6715
+ 0x24 => {
6694
6716
  Name => 'JPGCompression',
6695
6717
  Mask => 0x01,
6696
6718
  PrintConv => {
@@ -6698,16 +6720,12 @@ my %nikonFocalConversions = (
6698
6720
  1 => 'Optimal Quality',
6699
6721
  },
6700
6722
  },
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 => {
6723
+ );
6724
+
6725
+ %Image::ExifTool::Nikon::BracketingInfoD500 = (
6726
+ %binaryDataAttrs,
6727
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6728
+ 0x0f => {
6711
6729
  Name => 'AEBracketingSteps',
6712
6730
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
6713
6731
  Mask => 0xff,
@@ -6765,7 +6783,7 @@ my %nikonFocalConversions = (
6765
6783
  0xd6 => '5F3',
6766
6784
  },
6767
6785
  },
6768
- 0x087c => {
6786
+ 0x10 => {
6769
6787
  Name => 'WBBracketingSteps',
6770
6788
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
6771
6789
  Mask => 0xff,
@@ -6808,7 +6826,7 @@ my %nikonFocalConversions = (
6808
6826
  0x28 => '9F 3',
6809
6827
  },
6810
6828
  },
6811
- 0x0883 => {
6829
+ 0x17 => {
6812
6830
  Name => 'ADLBracketingStep',
6813
6831
  Mask => 0xf0,
6814
6832
  PrintConv => {
@@ -6820,7 +6838,7 @@ my %nikonFocalConversions = (
6820
6838
  8 => 'Auto',
6821
6839
  },
6822
6840
  },
6823
- 0x0884 => {
6841
+ 0x18 => {
6824
6842
  Name => 'ADLBracketingType',
6825
6843
  Mask => 0x0f,
6826
6844
  PrintConv => {
@@ -6831,23 +6849,12 @@ my %nikonFocalConversions = (
6831
6849
  4 => '5 Shots',
6832
6850
  },
6833
6851
  },
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 => {
6852
+ );
6853
+
6854
+ %Image::ExifTool::Nikon::ShootingMenuD500 = (
6855
+ %binaryDataAttrs,
6856
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6857
+ 0x00 => {
6851
6858
  Name => 'PhotoShootingMenuBank',
6852
6859
  Mask => 0x03,
6853
6860
  PrintConv => {
@@ -6857,7 +6864,7 @@ my %nikonFocalConversions = (
6857
6864
  3 => 'D',
6858
6865
  },
6859
6866
  },
6860
- 0x0e7f => {
6867
+ 0x02 => {
6861
6868
  Name => 'PrimarySlot',
6862
6869
  Condition => '$$self{Model} =~ /\bD500\b/',
6863
6870
  Notes => 'D500 only',
@@ -6867,7 +6874,7 @@ my %nikonFocalConversions = (
6867
6874
  1 => 'SD Card',
6868
6875
  },
6869
6876
  },
6870
- 0x0e81 => {
6877
+ 0x04 => {
6871
6878
  Name => 'ISOAutoShutterTime',
6872
6879
  Mask => 0x3f,
6873
6880
  PrintConv => {
@@ -6910,7 +6917,7 @@ my %nikonFocalConversions = (
6910
6917
  36 => 'Auto (Fastest)',
6911
6918
  },
6912
6919
  },
6913
- 0x0e82 => {
6920
+ 0x05 => {
6914
6921
  Name => 'ISOAutoHiLimit',
6915
6922
  Mask => 0xff,
6916
6923
  PrintHex => 1,
@@ -6958,7 +6965,7 @@ my %nikonFocalConversions = (
6958
6965
  0x72 => 'ISO Hi 5.0',
6959
6966
  },
6960
6967
  },
6961
- 0x0e84 => {
6968
+ 0x07 => {
6962
6969
  Name => 'FlickerReduction',
6963
6970
  Mask => 0x20,
6964
6971
  PrintConv => {
@@ -6966,7 +6973,7 @@ my %nikonFocalConversions = (
6966
6973
  1 => 'Disable',
6967
6974
  },
6968
6975
  },
6969
- 3716.1 => { # (0x0e84)
6976
+ 7.1 => {
6970
6977
  Name => 'PhotoShootingMenuBankImageArea',
6971
6978
  Mask => 0x07,
6972
6979
  PrintConv => {
@@ -6977,16 +6984,14 @@ my %nikonFocalConversions = (
6977
6984
  4 => '1.3x (18x12)',
6978
6985
  },
6979
6986
  },
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 => [{
6987
+ );
6988
+
6989
+ %Image::ExifTool::Nikon::CustomSettingsD500 = (
6990
+ %binaryDataAttrs,
6991
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6992
+ IS_SUBDIR => [ 0x00 ],
6993
+ VARS => { ALLOW_REPROCESS => 1 }, # (necessary because subdirectory is at offset 0)
6994
+ 0x00 => [{
6990
6995
  Name => 'CustomSettingsD5',
6991
6996
  Condition => '$$self{Model} =~ /\bD5\b/',
6992
6997
  Format => 'undef[90]',
@@ -7000,7 +7005,7 @@ my %nikonFocalConversions = (
7000
7005
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD500',
7001
7006
  },
7002
7007
  }],
7003
- # 0x0f68 => { #this decode works, but involves more bits than should be necessary
7008
+ # 0x7d => { #this decode works, but involves more bits than should be necessary
7004
7009
  # Name => 'ShutterTrigger',
7005
7010
  # Mask => 0xff,
7006
7011
  # PrintConv => {
@@ -7009,51 +7014,13 @@ my %nikonFocalConversions = (
7009
7014
  # 195 => 'Shutter Button',
7010
7015
  # },
7011
7016
  # },
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
- },
7017
+ );
7018
+
7019
+ %Image::ExifTool::Nikon::OtherInfoD500 = (
7020
+ %binaryDataAttrs,
7021
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7055
7022
  # (needs testing)
7056
- #0x2cb2 => {
7023
+ #0x22 => {
7057
7024
  # Name => 'ExtendedPhotoShootingBanks',
7058
7025
  # Mask => 0x01,
7059
7026
  # PrintConv => {
@@ -7062,7 +7029,7 @@ my %nikonFocalConversions = (
7062
7029
  # },
7063
7030
  #},
7064
7031
  # (may not be reliable and is found elsewhere)
7065
- #0x2ea2 => {
7032
+ #0x212 => {
7066
7033
  # Name => 'Rotation',
7067
7034
  # Condition => '$$self{Model} =~ /\bD500\b/',
7068
7035
  # Notes => 'D500 firmware 1.1x',
@@ -7074,7 +7041,7 @@ my %nikonFocalConversions = (
7074
7041
  # 3 => 'Rotate 180',
7075
7042
  # },
7076
7043
  #},
7077
- 0x2ea4 => { #PH
7044
+ 0x214 => { #PH
7078
7045
  Name => 'NikonMeteringMode',
7079
7046
  Condition => '$$self{Model} =~ /\bD500\b/', # (didn't seem to work for D5, but I need more samples)
7080
7047
  Notes => 'D500 only',
@@ -7086,18 +7053,16 @@ my %nikonFocalConversions = (
7086
7053
  3 => 'Highlight'
7087
7054
  },
7088
7055
  },
7089
- # note: DecryptLen currently set to OtherOffset + 0x2ea5 - 0x2c90
7090
7056
  );
7091
7057
 
7092
7058
  # shot information for the D6 firmware 1.00 (encrypted) - ref 28
7093
7059
  %Image::ExifTool::Nikon::ShotInfoD6 = (
7094
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7095
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7060
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7061
+ WRITE_PROC => \&ProcessNikonEncrypted,
7096
7062
  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 ],
7063
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
7064
+ IS_SUBDIR => [ 0x30, 0x9c, 0xa4 ],
7099
7065
  WRITABLE => 1,
7100
- FIRST_ENTRY => 0,
7101
7066
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7102
7067
  NOTES => 'These tags are extracted from encrypted data in images from the D6.',
7103
7068
  0x00 => {
@@ -7112,159 +7077,111 @@ my %nikonFocalConversions = (
7112
7077
  },
7113
7078
  0x24 => {
7114
7079
  Name => 'NumberOffsets', # (number of entries in offset table. offsets are from start of ShotInfo data)
7115
- DataMember => 'NumberOffsets',
7116
7080
  Format => 'int32u',
7117
7081
  Writable => 0,
7118
7082
  Hidden => 1,
7119
7083
  },
7120
7084
  0x30 => {
7121
- Name => 'Offset3',
7122
- DataMember => 'Offset3',
7085
+ Name => 'SequenceOffset',
7123
7086
  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)
7087
+ SubDirectory => {
7088
+ TagTable => 'Image::ExifTool::Nikon::SeqInfoD6',
7089
+ Start => '$val',
7090
+ },
7135
7091
  },
7136
7092
  0x9c => {
7137
7093
  Name => 'OrientationOffset',
7138
- DataMember => 'OrientationOffset',
7139
7094
  Format => 'int32u',
7140
- Writable => 0,
7141
- Hidden => 1,
7142
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
7095
+ SubDirectory => {
7096
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7097
+ Start => '$val',
7098
+ },
7143
7099
  },
7144
7100
  0xa4 => {
7145
- Name => 'Offset32',
7146
- DataMember => 'Offset32',
7101
+ Name => 'IntervalOffset',
7147
7102
  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',
7103
+ SubDirectory => {
7104
+ TagTable => 'Image::ExifTool::Nikon::IntervalInfoD6',
7105
+ Start => '$val',
7106
+ }
7159
7107
  },
7160
- 0x760c => {
7108
+ );
7109
+
7110
+ %Image::ExifTool::Nikon::SeqInfoD6 = (
7111
+ %binaryDataAttrs,
7112
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7113
+ DATAMEMBER => [ 0x24, 0x28 ],
7114
+ 0x24 => {
7161
7115
  Name => 'IntervalShooting',
7162
7116
  RawConv => '$$self{IntervalShooting} = $val',
7163
7117
  Format => 'int16u',
7164
7118
  PrintConv => q{
7165
7119
  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
7120
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); #something like "Interval 1 of 3"
7121
+ 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
7122
  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}),
7123
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
7170
7124
  },
7171
7125
  },
7172
- 0x7610 => {
7126
+ 0x28 => {
7173
7127
  Name => 'IntervalFrame',
7174
7128
  RawConv => '$$self{IntervalFrame} = $val',
7175
7129
  Condition => '$$self{IntervalShooting} > 0',
7176
7130
  Format => 'int16u',
7177
7131
  Hidden => 1,
7178
7132
  },
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 => {
7133
+ );
7134
+
7135
+ %Image::ExifTool::Nikon::IntervalInfoD6 = (
7136
+ %binaryDataAttrs,
7137
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7138
+ DATAMEMBER => [ 0x17c, 0x180, 0x214, 0x22c ],
7139
+ 0x17c => {
7223
7140
  Name => 'Intervals',
7224
7141
  Format => 'int32u',
7225
7142
  RawConv => '$$self{IntervalShootingIntervals} = $val',
7226
7143
  Condition => '$$self{IntervalShooting} > 0',
7227
7144
  },
7228
- 0xc412 => {
7145
+ 0x180 => {
7229
7146
  Name => 'ShotsPerInterval',
7230
7147
  Format => 'int32u',
7231
7148
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
7232
7149
  Condition => '$$self{IntervalShooting} > 0',
7233
7150
  },
7234
- 0xc416 => {
7151
+ 0x184 => {
7235
7152
  Name => 'IntervalExposureSmoothing',
7236
7153
  Condition => '$$self{IntervalShooting} > 0',
7237
7154
  Format => 'int8u',
7238
7155
  PrintConv => \%offOn,
7239
7156
  },
7240
- 0xc418 => {
7157
+ 0x186 => {
7241
7158
  Name => 'IntervalPriority',
7242
7159
  Condition => '$$self{IntervalShooting} > 0',
7243
7160
  Format => 'int8u',
7244
7161
  PrintConv => \%offOn,
7245
7162
  },
7246
- 0xc43a => {
7163
+ 0x1a8 => {
7247
7164
  Name => 'FocusShiftNumberShots',
7248
7165
  },
7249
- 0xc43e => {
7166
+ 0x1ac => {
7250
7167
  Name => 'FocusShiftStepWidth',
7251
7168
  },
7252
- 0xc442 => {
7169
+ 0x1b0 => {
7253
7170
  Name => 'FocusShiftInterval',
7254
7171
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
7255
7172
  },
7256
- 0xc446 => {
7173
+ 0x1b4 => {
7257
7174
  Name => 'FocusShiftExposureLock',
7258
7175
  PrintConv => \%offOn,
7259
7176
  },
7260
- #0xc49c => HighISONoiseReduction
7261
- 0xc4a0 => {
7177
+ #0x20a => HighISONoiseReduction
7178
+ 0x20e => {
7262
7179
  Name => 'DiffractionCompensation',
7263
7180
  Format => 'int8u',
7264
7181
  PrintConv => \%offOn,
7265
7182
  },
7266
- #0xc4a1 => {Name => 'FlickerReductionShooting',}, #redundant with tag in NikonSettings
7267
- 0xc4a6 => {
7183
+ #0x20f => {Name => 'FlickerReductionShooting',}, #redundant with tag in NikonSettings
7184
+ 0x214 => {
7268
7185
  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
7186
  RawConv => '$$self{FlashControlMode} = $val',
7270
7187
  PrintConv => {
@@ -7275,14 +7192,14 @@ my %nikonFocalConversions = (
7275
7192
  4 => 'Repeating Flash',
7276
7193
  },
7277
7194
  },
7278
- 0xc4ac => {
7195
+ 0x21a => {
7279
7196
  Name => 'FlashGNDistance',
7280
7197
  Condition => '$$self{FlashControlMode} == 2',
7281
7198
  Unknown => 1,
7282
7199
  ValueConv => '$val + 3',
7283
7200
  PrintConv => \%flashGNDistance,
7284
7201
  },
7285
- 0xc4b0 => {
7202
+ 0x21e => {
7286
7203
  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
7204
  Condition => '$$self{FlashControlMode} >= 3',
7288
7205
  Unknown => 1,
@@ -7291,7 +7208,7 @@ my %nikonFocalConversions = (
7291
7208
  PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
7292
7209
  PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
7293
7210
  },
7294
- 0xc4ba => {
7211
+ 0x228 => {
7295
7212
  Name => 'FlashRemoteControl',
7296
7213
  Unknown => 1,
7297
7214
  PrintConv => {
@@ -7300,12 +7217,12 @@ my %nikonFocalConversions = (
7300
7217
  2 => 'Remote Repeating',
7301
7218
  },
7302
7219
  },
7303
- 0xc4be => {
7220
+ 0x22c => {
7304
7221
  Name => 'FlashMasterControlMode', #tag name chosen for compatibility with those found in FlashInfo0102 & FlashInfo0103
7305
7222
  RawConv => '$$self{FlashGroupOptionsMasterMode} = $val',
7306
7223
  PrintConv => \%flashGroupOptionsMode,
7307
7224
  },
7308
- 0xc4c0 => {
7225
+ 0x22e => {
7309
7226
  Name => 'FlashMasterCompensation',
7310
7227
  Unknown => 1,
7311
7228
  Format => 'int8s',
@@ -7315,7 +7232,7 @@ my %nikonFocalConversions = (
7315
7232
  PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
7316
7233
  PrintConvInv => '$val',
7317
7234
  },
7318
- 0xc4c4 => {
7235
+ 0x232 => {
7319
7236
  Name => 'FlashMasterOutput',
7320
7237
  Unknown => 1,
7321
7238
  Condition => '$$self{FlashGroupOptionsMasterMode} == 1', #only for Mode=M
@@ -7324,7 +7241,7 @@ my %nikonFocalConversions = (
7324
7241
  PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
7325
7242
  PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
7326
7243
  },
7327
- 0xc4c6 => {
7244
+ 0x234 => {
7328
7245
  Name => 'FlashWirelessOption',
7329
7246
  Unknown => 1,
7330
7247
  PrintConv => {
@@ -7332,7 +7249,7 @@ my %nikonFocalConversions = (
7332
7249
  1 => 'Off',
7333
7250
  },
7334
7251
  },
7335
- 0xc55c => {
7252
+ 0x2ca => {
7336
7253
  Name => 'MovieType',
7337
7254
  Unknown => 1,
7338
7255
  PrintConv => {
@@ -7340,13 +7257,12 @@ my %nikonFocalConversions = (
7340
7257
  1 => 'MP4',
7341
7258
  },
7342
7259
  },
7343
- # note: DecryptLen currently set to 0xc9c6 + 720
7344
7260
  );
7345
7261
 
7346
7262
  # shot information for the D610 firmware 1.00 (encrypted) - ref PH
7347
7263
  %Image::ExifTool::Nikon::ShotInfoD610 = (
7348
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7349
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7264
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7265
+ WRITE_PROC => \&ProcessNikonEncrypted,
7350
7266
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7351
7267
  VARS => { ID_LABEL => 'Index' },
7352
7268
  IS_SUBDIR => [ 0x07cf ],
@@ -7371,25 +7287,19 @@ my %nikonFocalConversions = (
7371
7287
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD610',
7372
7288
  },
7373
7289
  },
7374
- # note: DecryptLen currently set to 0x7ff
7375
7290
  );
7376
7291
 
7377
7292
  # shot information for the D810 firmware 1.00(PH)/1.01 (encrypted) - ref 28
7378
7293
  %Image::ExifTool::Nikon::ShotInfoD810 = (
7379
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7380
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7294
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7295
+ WRITE_PROC => \&ProcessNikonEncrypted,
7381
7296
  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 ],
7297
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
7298
+ DATAMEMBER => [ 0x04 ],
7299
+ IS_SUBDIR => [ 0x10, 0x24, 0x38, 0x40, 0x84 ],
7385
7300
  WRITABLE => 1,
7386
- FIRST_ENTRY => 0,
7387
7301
  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
- },
7302
+ NOTES => 'These tags are extracted from encrypted data in images from the D810.',
7393
7303
  0x00 => {
7394
7304
  Name => 'ShotInfoVersion',
7395
7305
  Format => 'string[4]',
@@ -7404,39 +7314,64 @@ my %nikonFocalConversions = (
7404
7314
  },
7405
7315
  # 0x0c - number of entries in offset table (= 0x21)
7406
7316
  # 0x10 - int32u[val 0x0c]: offset table
7317
+ 0x10 => {
7318
+ Name => 'SettingsOffset',
7319
+ Format => 'int32u',
7320
+ SubDirectory => {
7321
+ TagTable => 'Image::ExifTool::Nikon::SettingsInfoD810',
7322
+ Start => '$val',
7323
+ },
7324
+ },
7407
7325
  0x24 => {
7408
7326
  Name => 'BracketingOffset',
7409
- DataMember => 'BracketingOffset',
7410
7327
  Format => 'int32u',
7411
- Writable => 0,
7412
- Hidden => 1,
7413
- RawConv => '$$self{BracketingOffset} = $val || 0x10000000; undef',
7328
+ SubDirectory => {
7329
+ TagTable => 'Image::ExifTool::Nikon::BracketingInfoD810',
7330
+ Start => '$val',
7331
+ },
7414
7332
  },
7415
7333
  0x38 => {
7416
7334
  Name => 'ISOAutoOffset',
7417
- DataMember => 'ISOAutoOffset',
7418
7335
  Format => 'int32u',
7419
- Writable => 0,
7420
- Hidden => 1,
7421
- RawConv => '$$self{ISOAutoOffset} = $val || 0x10000000; undef',
7336
+ SubDirectory => {
7337
+ TagTable => 'Image::ExifTool::Nikon::ISOAutoInfoD810',
7338
+ Start => '$val',
7339
+ },
7422
7340
  },
7423
7341
  0x40 => {
7424
7342
  Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
7425
- DataMember => 'CustomSettingsOffset',
7426
7343
  Format => 'int32u',
7427
- Writable => 0,
7428
- Hidden => 1,
7429
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
7344
+ SubDirectory => {
7345
+ TagTable => 'Image::ExifTool::NikonCustom::SettingsD810',
7346
+ Start => '$val',
7347
+ },
7430
7348
  },
7431
7349
  0x84 => {
7432
7350
  Name => 'OrientationOffset',
7433
- DataMember => 'OrientationOffset',
7434
7351
  Format => 'int32u',
7435
- Writable => 0,
7436
- Hidden => 1,
7437
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
7352
+ SubDirectory => {
7353
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7354
+ Start => '$val',
7355
+ }
7438
7356
  },
7439
- 0x01d0 => {
7357
+ # (moves around too much and doesn't fit cleanly in the offset table)
7358
+ #0x38be => {
7359
+ # Name => 'Rotation',
7360
+ # Condition => '$$self{FirmwareVersion} =~ /^1\.0/',
7361
+ # Mask => 0x30,
7362
+ # PrintConv => {
7363
+ # 0 => 'Horizontal',
7364
+ # 1 => 'Rotate 270 CW',
7365
+ # 2 => 'Rotate 90 CW',
7366
+ # 3 => 'Rotate 180',
7367
+ # },
7368
+ #},
7369
+ );
7370
+
7371
+ %Image::ExifTool::Nikon::SettingsInfoD810 = (
7372
+ %binaryDataAttrs,
7373
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7374
+ 0x13c => {
7440
7375
  Name => 'SecondarySlotFunction',
7441
7376
  Mask => 0x03,
7442
7377
  PrintConv => {
@@ -7444,9 +7379,13 @@ my %nikonFocalConversions = (
7444
7379
  2 => 'Backup',
7445
7380
  3 => 'NEF Primary + JPG Secondary',
7446
7381
  },
7447
- Hook => '$varSize = $$self{BracketingOffset} - 0x1747',
7448
7382
  },
7449
- 0x1756 => {
7383
+ );
7384
+
7385
+ %Image::ExifTool::Nikon::BracketingInfoD810 = (
7386
+ %binaryDataAttrs,
7387
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7388
+ 0x0f => {
7450
7389
  Name => 'AEBracketingSteps',
7451
7390
  Mask => 0xff,
7452
7391
  PrintHex => 1,
@@ -7503,7 +7442,7 @@ my %nikonFocalConversions = (
7503
7442
  0xd6 => '5F3',
7504
7443
  },
7505
7444
  },
7506
- 0x1757 => {
7445
+ 0x10 => {
7507
7446
  Name => 'WBBracketingSteps',
7508
7447
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
7509
7448
  Mask => 0xff,
@@ -7546,7 +7485,7 @@ my %nikonFocalConversions = (
7546
7485
  0x28 => '9F 3',
7547
7486
  },
7548
7487
  },
7549
- 0x175e => {
7488
+ 0x17 => {
7550
7489
  Name => 'NikonMeteringMode',
7551
7490
  Mask => 0x03,
7552
7491
  PrintConv => {
@@ -7555,9 +7494,13 @@ my %nikonFocalConversions = (
7555
7494
  2 => 'Spot',
7556
7495
  3 => 'Highlight'
7557
7496
  },
7558
- Hook => '$varSize = $$self{ISOAutoOffset} - 0x1858',
7559
7497
  },
7560
- 0x185c => {
7498
+ );
7499
+
7500
+ %Image::ExifTool::Nikon::ISOAutoInfoD810 = (
7501
+ %binaryDataAttrs,
7502
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7503
+ 0x04 => {
7561
7504
  Name => 'ISOAutoShutterTime',
7562
7505
  Mask => 0x3f,
7563
7506
  PrintConv => {
@@ -7600,7 +7543,7 @@ my %nikonFocalConversions = (
7600
7543
  36 => 'Auto (Fastest)',
7601
7544
  },
7602
7545
  },
7603
- 0x185d => {
7546
+ 0x05 => {
7604
7547
  Name => 'ISOAutoHiLimit',
7605
7548
  Mask => 0xff,
7606
7549
  PrintHex => 1,
@@ -7647,69 +7590,18 @@ my %nikonFocalConversions = (
7647
7590
  0x6c => 'ISO Hi 4.0',
7648
7591
  0x72 => 'ISO Hi 5.0',
7649
7592
  },
7650
- Hook => '$varSize = $$self{CustomSettingsOffset} - 0x18ab',
7651
7593
  },
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
7594
  );
7702
7595
 
7703
7596
  # shot information for the D850 firmware 1.00b (encrypted) - ref 28
7704
7597
  %Image::ExifTool::Nikon::ShotInfoD850 = (
7705
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7706
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7598
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7599
+ WRITE_PROC => \&ProcessNikonEncrypted,
7707
7600
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7708
- VARS => { ID_LABEL => 'Index' },
7709
- DATAMEMBER => [ 0x04, 0x58, 0xa0, 0x0fbf, 0x2efa ],
7710
- IS_SUBDIR => [ 0x1038 ],
7601
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
7602
+ DATAMEMBER => [ 0x04 ],
7603
+ IS_SUBDIR => [ 0x10, 0x4c, 0x58, 0xa0 ],
7711
7604
  WRITABLE => 1,
7712
- FIRST_ENTRY => 0,
7713
7605
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7714
7606
  NOTES => 'These tags are extracted from encrypted data in images from the D850.',
7715
7607
  0x00 => {
@@ -7724,23 +7616,44 @@ my %nikonFocalConversions = (
7724
7616
  Writable => 0,
7725
7617
  RawConv => '$$self{FirmwareVersion} = $val',
7726
7618
  },
7619
+ 0x10 => {
7620
+ Name => 'MenuSettingsOffset',
7621
+ Format => 'int32u',
7622
+ SubDirectory => {
7623
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsD850',
7624
+ Start => '$val',
7625
+ },
7626
+ },
7627
+ 0x4c => {
7628
+ Name => 'MoreSettingsOffset',
7629
+ Format => 'int32u',
7630
+ SubDirectory => {
7631
+ TagTable => 'Image::ExifTool::Nikon::MoreSettingsD850',
7632
+ Start => '$val',
7633
+ },
7634
+ },
7727
7635
  0x58 => {
7728
- Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
7729
- DataMember => 'CustomSettingsOffset',
7636
+ Name => 'CustomSettingsOffset',
7730
7637
  Format => 'int32u',
7731
- Writable => 0,
7732
- Hidden => 1,
7733
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
7638
+ SubDirectory => {
7639
+ TagTable => 'Image::ExifTool::NikonCustom::SettingsD850',
7640
+ Start => '$val',
7641
+ },
7734
7642
  },
7735
7643
  0xa0 => {
7736
7644
  Name => 'OrientationOffset',
7737
- DataMember => 'OrientationOffset',
7738
7645
  Format => 'int32u',
7739
- Writable => 0,
7740
- Hidden => 1,
7741
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
7646
+ SubDirectory => {
7647
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7648
+ Start => '$val',
7649
+ },
7742
7650
  },
7743
- 0x0791 => {
7651
+ );
7652
+
7653
+ %Image::ExifTool::Nikon::MenuSettingsD850 = (
7654
+ %binaryDataAttrs,
7655
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7656
+ 0x06dd => {
7744
7657
  Name => 'PhotoShootingMenuBankImageArea',
7745
7658
  Mask => 0x07,
7746
7659
  PrintConv => {
@@ -7751,7 +7664,12 @@ my %nikonFocalConversions = (
7751
7664
  4 => '1:1 (24x24)',
7752
7665
  },
7753
7666
  },
7754
- 0x0fbd => {
7667
+ );
7668
+
7669
+ %Image::ExifTool::Nikon::MoreSettingsD850 = (
7670
+ %binaryDataAttrs,
7671
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7672
+ 0x24 => {
7755
7673
  Name => 'PhotoShootingMenuBank',
7756
7674
  Condition => '$$self{FILE_TYPE} eq "JPEG"',
7757
7675
  Notes => 'valid for JPEG images only',
@@ -7763,63 +7681,20 @@ my %nikonFocalConversions = (
7763
7681
  3 => 'D',
7764
7682
  },
7765
7683
  },
7766
- 0x0fbf => {
7684
+ 0x25 => {
7767
7685
  Name => 'PrimarySlot',
7768
7686
  Mask => 0x80,
7769
7687
  PrintConv => {
7770
7688
  0 => 'XQD Card',
7771
7689
  1 => 'SD Card',
7772
7690
  },
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
7691
  },
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
7692
  );
7693
+
7819
7694
  # shot information for the D4 firmware 1.00g (ref PH)
7820
7695
  %Image::ExifTool::Nikon::ShotInfoD4 = (
7821
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7822
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7696
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7697
+ WRITE_PROC => \&ProcessNikonEncrypted,
7823
7698
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7824
7699
  VARS => { ID_LABEL => 'Index' },
7825
7700
  IS_SUBDIR => [ 0x0751 ],
@@ -7845,17 +7720,16 @@ my %nikonFocalConversions = (
7845
7720
  Format => 'undef[56]',
7846
7721
  SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsD4' },
7847
7722
  },
7848
- # note: DecryptLen currently set to 0x789
7849
7723
  );
7850
7724
 
7851
7725
  # shot information for the D4S firmware 1.01a (ref 28, encrypted)
7852
7726
  %Image::ExifTool::Nikon::ShotInfoD4S = (
7853
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7854
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7727
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7728
+ WRITE_PROC => \&ProcessNikonEncrypted,
7855
7729
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7856
7730
  VARS => { ID_LABEL => 'Index' },
7857
7731
  DATAMEMBER => [ 4 ],
7858
- IS_SUBDIR => [ 0x189d, 0x193d ],
7732
+ IS_SUBDIR => [ 0x189d, 0x193d, 0x350b ],
7859
7733
  WRITABLE => 1,
7860
7734
  FIRST_ENTRY => 0,
7861
7735
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
@@ -8119,31 +7993,13 @@ my %nikonFocalConversions = (
8119
7993
  # },
8120
7994
  # },
8121
7995
  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',
7996
+ Name => 'OrientationInfo',
7997
+ Format => 'undef[12]',
7998
+ SubDirectory => {
7999
+ # Note: pitch angle may be wrong sign for this model?
8000
+ # (pitch sign was changed without verification to use same decoding as other models)
8001
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8002
+ },
8147
8003
  },
8148
8004
  0x3693 => {
8149
8005
  Name => 'Rotation',
@@ -8155,20 +8011,17 @@ my %nikonFocalConversions = (
8155
8011
  3 => 'Rotate 180',
8156
8012
  },
8157
8013
  },
8158
- # note: DecryptLen currently set to 0x3697
8159
8014
  );
8160
8015
 
8161
8016
  # shot information for the Z7II firmware 1.00 (encrypted) - ref 28
8162
8017
  %Image::ExifTool::Nikon::ShotInfoZ7II = (
8163
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8164
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8018
+ PROCESS_PROC => \&ProcessNikonEncrypted,
8019
+ WRITE_PROC => \&ProcessNikonEncrypted,
8165
8020
  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 ],
8021
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
8022
+ DATAMEMBER => [ 0x04 ],
8023
+ IS_SUBDIR => [ 0x30, 0x38, 0x98, 0xa0 ],
8170
8024
  WRITABLE => 1,
8171
- FIRST_ENTRY => 0,
8172
8025
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8173
8026
  NOTES => 'These tags are extracted from encrypted data in images from the Z7II.',
8174
8027
  0x00 => {
@@ -8197,79 +8050,73 @@ my %nikonFocalConversions = (
8197
8050
  },
8198
8051
  0x24 => {
8199
8052
  Name => 'NumberOffsets', # number of entries in offset table. offsets are from start of ShotInfo data.
8200
- DataMember => 'NumberOffsets',
8201
8053
  Format => 'int32u',
8202
8054
  Writable => 0,
8203
8055
  Hidden => 1,
8204
8056
  },
8205
8057
  0x30 => {
8206
- Name => 'Offset3',
8207
- DataMember => 'Offset3',
8058
+ Name => 'IntervalOffset',
8208
8059
  Format => 'int32u',
8209
- Writable => 0,
8210
- Hidden => 1,
8211
- RawConv => '$$self{Offset3} = $val || 0x10000000; undef', # (ignore if 0)
8060
+ SubDirectory => {
8061
+ TagTable => 'Image::ExifTool::Nikon::IntervalInfoZ7II',
8062
+ Start => '$val',
8063
+ }
8212
8064
  },
8213
8065
  0x38 => {
8214
- Name => 'Offset5',
8215
- DataMember => 'Offset5',
8066
+ Name => 'PortraitOffset',
8216
8067
  Format => 'int32u',
8217
- Writable => 0,
8218
- Hidden => 1,
8219
- RawConv => '$$self{Offset5} = $val || 0x10000000; undef', # (ignore if 0)
8068
+ SubDirectory => {
8069
+ TagTable => 'Image::ExifTool::Nikon::PortraitInfoZ7II',
8070
+ Start => '$val',
8071
+ }
8220
8072
  },
8221
8073
  0x98 => {
8222
8074
  Name => 'OrientationOffset',
8223
- DataMember => 'OrientationOffset',
8224
8075
  Format => 'int32u',
8225
- Writable => 0,
8226
- Hidden => 1,
8227
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
8076
+ SubDirectory => {
8077
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8078
+ Start => '$val',
8079
+ }
8228
8080
  },
8229
8081
  0xa0 => {
8230
- Name => 'Offset31',
8231
- DataMember => 'Offset31',
8082
+ Name => 'MenuOffset',
8232
8083
  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',
8084
+ SubDirectory => {
8085
+ TagTable => 'Image::ExifTool::Nikon::MenuInfoZ7II',
8086
+ Start => '$val',
8087
+ },
8244
8088
  },
8245
- 0x760c => {
8089
+ );
8090
+
8091
+ %Image::ExifTool::Nikon::IntervalInfoZ7II = (
8092
+ %binaryDataAttrs,
8093
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8094
+ DATAMEMBER => [ 0x24, 0x28 ],
8095
+ 0x24 => {
8246
8096
  Name => 'IntervalShooting',
8247
8097
  RawConv => '$$self{IntervalShooting} = $val',
8248
8098
  Format => 'int16u',
8249
8099
  PrintConv => q{
8250
8100
  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
8101
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); # something like "Interval 1 of 3"
8102
+ 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
8103
  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}),
8104
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
8255
8105
  },
8256
8106
  },
8257
- 0x7610 => {
8107
+ 0x28 => {
8258
8108
  Name => 'IntervalFrame',
8259
8109
  RawConv => '$$self{IntervalFrame} = $val',
8260
8110
  Condition => '$$self{IntervalShooting} > 0',
8261
8111
  Format => 'int16u',
8262
8112
  Hidden => 1,
8263
8113
  },
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
8114
+ );
8115
+
8116
+ %Image::ExifTool::Nikon::PortraitInfoZ7II = (
8117
+ %binaryDataAttrs,
8118
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8119
+ 0xa0 => { #28
8273
8120
  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
8121
  # offset5+160; 128 is neutral; >128 increases Yellow; <128 increases Magenta; increments of 4 result from 1 full unit adjustment on the camera
8275
8122
  # offset5+161 128 is neutral; >128 increases Brightness; <128 decreases Brightness
@@ -8285,83 +8132,31 @@ my %nikonFocalConversions = (
8285
8132
  return "$color $brightness"
8286
8133
  },
8287
8134
  },
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
- },
8135
+ );
8296
8136
 
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]',
8137
+ %Image::ExifTool::Nikon::MenuInfoZ7II = (
8138
+ %binaryDataAttrs,
8139
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8140
+ IS_SUBDIR => [ 0x10 ],
8141
+ 0x10 => {
8142
+ Name => 'MenuSettingsOffsetZ7II',
8143
+ Format => 'int32u',
8347
8144
  SubDirectory => {
8348
8145
  TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ7II',
8146
+ Start => '$dirStart + $val',
8349
8147
  },
8350
- }
8351
- # note: DecryptLen currently set to 0xd04e + 860 (offset for Z50 is 0xd04e)
8148
+ },
8352
8149
  );
8353
8150
 
8354
8151
  # shot information for the Z9 firmware 1.00 (encrypted) - ref 28
8355
8152
  %Image::ExifTool::Nikon::ShotInfoZ9 = (
8356
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8357
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8153
+ PROCESS_PROC => \&ProcessNikonEncrypted,
8154
+ WRITE_PROC => \&ProcessNikonEncrypted,
8358
8155
  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 ],
8156
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
8157
+ DATAMEMBER => [ 0x04 ],
8158
+ IS_SUBDIR => [ 0x30, 0x58, 0x84, 0x8c ],
8363
8159
  WRITABLE => 1,
8364
- FIRST_ENTRY => 0,
8365
8160
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8366
8161
  NOTES => 'These tags are extracted from encrypted data in images from the Z9.',
8367
8162
  0x00 => {
@@ -8390,47 +8185,55 @@ my %nikonFocalConversions = (
8390
8185
  },
8391
8186
  0x24 => {
8392
8187
  Name => 'NumberOffsets', # number of entries in offset table. offsets are from start of ShotInfo data.
8393
- DataMember => 'NumberOffsets',
8394
8188
  Format => 'int32u',
8395
8189
  Writable => 0,
8396
8190
  Hidden => 1,
8397
8191
  },
8192
+ # subdirectories, referenced by offsets (not processed if offset is zero)
8398
8193
  0x30 => {
8399
- Name => 'SequenceOffset', #offset3 - length 2528 (Z9 firmware 1.0)
8400
- DataMember => 'SequenceOffset',
8194
+ Name => 'SequenceOffset',
8401
8195
  Format => 'int32u',
8402
- Writable => 0,
8403
- Hidden => 1,
8404
- RawConv => '$$self{SequenceOffset} = $val || 0x10000000; undef', # (ignore if 0)
8196
+ SubDirectory => {
8197
+ TagTable => 'Image::ExifTool::Nikon::SeqInfoZ9',
8198
+ Start => '$val',
8199
+ },
8200
+ },
8201
+ 0x58 => {
8202
+ 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.
8203
+ Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} ge "03.01"',
8204
+ Format => 'int32u',
8205
+ SubDirectory => {
8206
+ TagTable => 'Image::ExifTool::Nikon::Offset13InfoZ9',
8207
+ Start => '$val',
8208
+ },
8405
8209
  },
8406
8210
  0x84 => {
8407
- Name => 'OrientationOffset', #offset24 - length 108 (Z9 firmware 1.0)
8408
- DataMember => 'OrientationOffset',
8211
+ Name => 'OrientOffset',
8212
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8409
8213
  Format => 'int32u',
8410
- Writable => 0,
8411
- Hidden => 1,
8412
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
8214
+ SubDirectory => {
8215
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8216
+ Start => '$val',
8217
+ },
8413
8218
  },
8414
8219
  0x8c => {
8415
- Name => 'MenuOffset', #offset26 - length 1895 (Z9 firmware 1.0)
8416
- DataMember => 'MenuOffset6',
8220
+ Name => 'MenuOffset',
8417
8221
  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',
8222
+ SubDirectory => {
8223
+ TagTable => 'Image::ExifTool::Nikon::MenuInfoZ9',
8224
+ Start => '$val',
8225
+ },
8430
8226
  },
8431
- 0x00b4 => {
8227
+ );
8228
+
8229
+ # ref 28
8230
+ %Image::ExifTool::Nikon::SeqInfoZ9 = (
8231
+ %binaryDataAttrs,
8232
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8233
+ DATAMEMBER => [ 0x20, 0x28, 0x2a ],
8234
+ 0x0020 => {
8432
8235
  Name => 'FocusShiftShooting',
8433
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8236
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8434
8237
  RawConv => '$$self{FocusShiftShooting} = $val',
8435
8238
  PrintConv => q{
8436
8239
  return 'Off' if $val == 0 ;
@@ -8438,86 +8241,215 @@ my %nikonFocalConversions = (
8438
8241
  return "On: $i"
8439
8242
  },
8440
8243
  },
8441
- 0x00bc => {
8244
+ 0x0028 => {
8442
8245
  Name => 'IntervalShooting',
8443
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8246
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8444
8247
  RawConv => '$$self{IntervalShooting} = $val',
8445
8248
  Format => 'int16u',
8446
8249
  PrintConv => q{
8447
8250
  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
8251
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); # something like "Interval 1 of 3"
8252
+ 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
8253
  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}),
8254
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
8452
8255
  },
8453
8256
  },
8454
- 0x00be => {
8455
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8257
+ 0x002a => {
8456
8258
  Name => 'IntervalFrame',
8457
8259
  RawConv => '$$self{IntervalFrame} = $val',
8458
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8260
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8459
8261
  Format => 'int16u',
8460
8262
  Hidden => 1,
8461
8263
  },
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)
8264
+ );
8265
+
8266
+ # ref 28
8267
+ %Image::ExifTool::Nikon::Offset13InfoZ9 = (
8268
+ %binaryDataAttrs,
8269
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8270
+ DATAMEMBER => [ 0x0bea, 0x0beb ],
8271
+ 0x0be8 => {
8272
+ 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)
8273
+ Condition => '$$self{ShutterMode} ne 96 and $$self{AFAreaMode} < 2 ', #not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19
8274
+ Format => 'int8s',
8275
+ PrintConv => q{
8276
+ #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.
8277
+ #in FX mode and Dynamic(L), the 27 horizontal focus points are spaced 259 pixels apart starting at pixel 761 and ending at 7495
8278
+ #in FX mode and Dynamic(M), the 29 horizontal focus points are spaced 259 pixels apart starting at pixel 502 and ending at 7754
8279
+ #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].
8280
+ #in DX mode and Wide(S), the 17 horizontal focus points are spaced 393 pixels apart starting at pixel 591 and ending at 7272.
8281
+ #in DX mode and Dynamic(L), the 17 horizontal focus points are spaced 388 pixels apart starting at pixel 1024 and ending at 7232
8282
+ #in DX mode and Dynamic(M), the 19 horizontal focus points are spaced 388 pixels apart starting at pixel 636 and ending at 7620
8283
+
8284
+ my $areaMode = $$self{VALUE}{PhotoShootingMenuBankImageArea};
8285
+ my $afAreaMode = $$self{VALUE}{AFAreaMode};
8286
+ my $dynamicAFAreaSize = $$self{VALUE}{DynamicAFAreaSize};
8287
+
8288
+ my $FX = 0;
8289
+ my $DX = 1;
8290
+
8291
+ my $Single = 1;
8292
+ my $Dynamic = 2;
8293
+ my $WideS = 3;
8294
+ my $WideL = 4;
8295
+ my $ThreeD = 5;
8296
+ my $Auto = 6;
8297
+ my $WideC1 = 12;
8298
+
8299
+ my $DynamicS = 0;
8300
+ my $DynamicM = 1;
8301
+ my $DynamicL = 2;
8302
+
8303
+ my $start = 502; #FX - all flavors
8304
+ $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
8305
+ $start = 591 if $areaMode == $DX and $afAreaMode == $WideS ; #DX Wide(S)
8306
+
8307
+ my $increment = 259; #FX - all flavors
8308
+ $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
8309
+ $increment = 393 if $areaMode == $DX and $afAreaMode == $WideS ; #DX Wide(S)
8310
+
8311
+ my $divisor = 4;
8312
+ $divisor = 6 if $areaMode == $DX ;
8313
+
8314
+ my $offsetVal = 0;
8315
+ $offsetVal = 12 if $areaMode == $FX and $afAreaMode == $Dynamic ; #FX Dynamic (L/M) - force positive values so perl rounding toward zero isn't an issue
8316
+ $offsetVal = 18 if $areaMode == $DX and $afAreaMode == $Dynamic ; #DX Dynamic (L/M)
8317
+
8318
+ my $offsetSum = -1;
8319
+ $offsetSum = -4 if $afAreaMode == $Dynamic ; # Dynamic (L/M)
8320
+
8321
+ my $ncol = $$self{AFAreaInitialWidth};
8322
+ $ncol = int($ncol * 2 / 3) if $areaMode == $DX ; #DX
8323
+
8324
+ #some sample mappings:
8325
+ #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]
8326
+ #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]
8327
+ #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]
8328
+ #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]
8329
+
8330
+ 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
8331
+ },
8332
+ },
8333
+ 0x0be9 => {
8334
+ 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)
8335
+ Condition => '$$self{ShutterMode} ne 96 and $$self{AFAreaMode} < 2', #not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19
8336
+ Format => 'int8s',
8337
+ PrintConv => q{
8338
+ #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)
8339
+ #in FX mode and Dynamic(L), the 15 vertical focus points are spaced 291 pixels apart starting at pixel 715 and ending at 4789
8340
+ #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
8341
+ #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].
8342
+ #in DX Mode and Wide(S) the 9 vertical focus points are spaced 442 pixels apart starting at pixel 542 and ending at 4520
8343
+ #in DX mode and Dynamic(L), the 9 vertical focus points are spaced 436 pixels apart starting at pixel 1008 and ending at 4496
8344
+
8345
+ my $areaMode = $$self{VALUE}{PhotoShootingMenuBankImageArea};
8346
+ my $afAreaMode = $$self{VALUE}{AFAreaMode};
8347
+ my $dynamicAFAreaSize = $$self{VALUE}{DynamicAFAreaSize};
8348
+
8349
+ my $FX = 0;
8350
+ my $DX = 1;
8351
+
8352
+ my $Single = 1;
8353
+ my $Dynamic = 2;
8354
+ my $WideS = 3;
8355
+ my $WideL = 4;
8356
+ my $ThreeD = 5;
8357
+ my $Auto = 6;
8358
+ my $WideC1 = 12;
8359
+
8360
+ my $DynamicS = 0;
8361
+ my $DynamicM = 1;
8362
+ my $DynamicL = 2;
8363
+
8364
+ my $start = 424; #FX - all flavors
8365
+ $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
8366
+ $start = 542 if $areaMode == $DX and $afAreaMode == 3 ; #DX Wide(S)
8367
+
8368
+ my $increment = 291; #FX - all flavors
8369
+ $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
8370
+ $increment = 442 if $areaMode == $DX and $afAreaMode == 3 ; #DX Wide(S)
8371
+
8372
+ my $divisor = 7;
8373
+ $divisor = 10 if $areaMode == $DX ; #DX
8374
+
8375
+ my $offsetVal = -1;
8376
+ $offsetVal = 39 if $afAreaMode == $Dynamic and ( $dynamicAFAreaSize == $DynamicL ) ; #Dynamic (L) - force positive values so perl rounding toward zero isn't an issue
8377
+ $offsetVal = 40 if $afAreaMode == $Dynamic and $dynamicAFAreaSize == $DynamicM ; #Dynamic (M)
8378
+ $offsetVal = 40 if $areaMode == $FX and (($afAreaMode == $Dynamic and $dynamicAFAreaSize == $DynamicS) or $afAreaMode == $ThreeD) ; #FX Dynamic (S) or 3D
8379
+ $offsetVal = 38 if $areaMode == $DX and ($afAreaMode == $Dynamic and $dynamicAFAreaSize == $DynamicS ) ; #DX Dynamic (S)or 3D
8380
+
8381
+ my $offsetSum = 0;
8382
+ $offsetSum = -6 if $areaMode == $FX and ($afAreaMode == $Dynamic or $afAreaMode == $ThreeD); #FX Dynamic (L/M/S) or 3D
8383
+ $offsetSum = -4 if $areaMode == $DX and ($afAreaMode == $Dynamic or $afAreaMode == $ThreeD ); #DX Dynamic (L/M/S) or 3D
8384
+
8385
+ my $nrow = $$self{AFAreaInitialHeight};
8386
+ $nrow = int($nrow * 2 / 3) if $areaMode == $DX; #DX
8387
+
8388
+ #some sample mappings:
8389
+ #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]
8390
+ #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]
8391
+ #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]
8392
+ #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]
8393
+
8394
+ return $start + $increment * (int(($val + $offsetVal) / $divisor) + int($nrow / 2) + $offsetSum) ;;
8395
+ },
8396
+ },
8397
+ 0x0bea => {
8398
+ Name => 'AFAreaInitialWidth',
8399
+ Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8400
+ 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
8401
+ 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
8402
  },
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',
8403
+ 0x0beb => {
8404
+ Name => 'AFAreaInitialHeight',
8405
+ Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8406
+ 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
8407
+ 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
8408
  },
8479
- 0x44ec => [
8409
+ );
8410
+
8411
+ %Image::ExifTool::Nikon::MenuInfoZ9 = (
8412
+ %binaryDataAttrs,
8413
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8414
+ IS_SUBDIR => [ 0x10 ],
8415
+ # 0x00 - int32u size of this directory
8416
+ 0x10 => [
8480
8417
  {
8481
- Name => 'MenuSettingsZ9',
8482
- Condition => '$$self{ShutterMode} eq 96 and $$self{FirmwareVersion} lt "03.00"', # C30/C60/C120 jpgs only
8483
- Format => 'undef[1646]',
8418
+ Name => 'MenuSettingsOffsetZ9',
8419
+ Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} lt "03.00"',
8420
+ Format => 'int32u',
8484
8421
  Notes => 'Firmware versions 2.11 and earlier',
8485
8422
  SubDirectory => {
8486
8423
  TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9',
8424
+ Start => '$dirStart + $val',
8487
8425
  },
8488
8426
  },
8489
8427
  {
8490
- Name => 'MenuSettingsZ9',
8428
+ Name => 'MenuSettingsOffsetZ9v3',
8491
8429
  Notes => 'Firmware versions 3.0 and later',
8492
- Condition => '$$self{ShutterMode} eq 96', # C30/C60/C120 jpgs only
8493
- Format => 'undef[1948]',
8430
+ Format => 'int32u',
8494
8431
  SubDirectory => {
8495
- TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9Firmware3',
8432
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9v3',
8433
+ Start => '$dirStart + $val',
8496
8434
  },
8497
8435
  },
8498
8436
  ],
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 => {
8437
+ );
8438
+
8439
+ %Image::ExifTool::Nikon::OrientationInfo = (
8440
+ %binaryDataAttrs,
8441
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8442
+ 0 => {
8509
8443
  Name => 'RollAngle',
8510
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8511
- Format => 'fixed32u',
8444
+ Format => 'fixed32u',
8512
8445
  Notes => 'converted to degrees of clockwise camera roll',
8513
8446
  ValueConv => '$val <= 180 ? $val : $val - 360',
8514
8447
  ValueConvInv => '$val >= 0 ? $val : $val + 360',
8515
8448
  PrintConv => 'sprintf("%.1f", $val)',
8516
8449
  PrintConvInv => '$val',
8517
8450
  },
8518
- 0x80c9 => {
8451
+ 4 => {
8519
8452
  Name => 'PitchAngle',
8520
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8521
8453
  Format => 'fixed32u',
8522
8454
  Notes => 'converted to degrees of upward camera tilt',
8523
8455
  ValueConv => '$val <= 180 ? $val : $val - 360',
@@ -8525,9 +8457,8 @@ my %nikonFocalConversions = (
8525
8457
  PrintConv => 'sprintf("%.1f", $val)',
8526
8458
  PrintConvInv => '$val',
8527
8459
  },
8528
- 0x80cd => {
8460
+ 8 => {
8529
8461
  Name => 'YawAngle',
8530
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8531
8462
  Format => 'fixed32u',
8532
8463
  Notes => 'the camera yaw angle when shooting in portrait orientation',
8533
8464
  ValueConv => '$val <= 180 ? $val : $val - 360',
@@ -8535,51 +8466,25 @@ my %nikonFocalConversions = (
8535
8466
  PrintConv => 'sprintf("%.1f", $val)',
8536
8467
  PrintConvInv => '$val',
8537
8468
  },
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
8469
  );
8577
8470
 
8578
8471
  %Image::ExifTool::Nikon::MenuSettingsZ7II = (
8579
8472
  %binaryDataAttrs,
8580
8473
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8581
- DATAMEMBER => [ 176, 180, 328, 352, 858 ],
8474
+ DATAMEMBER => [ 90, 176, 180, 328, 352, 858 ],
8582
8475
  NOTES => 'These tags are used by the Z5, Z6, Z7, Z6II, Z7II, Z50 and Zfc.',
8476
+ #48 SelfTimer' #0=> no 1=> yes works for Z7II firmware 1.40, but not 1.30. Follow-up required.
8477
+ 90 => {
8478
+ Name => 'SingleFrame', #0=> Single Frame 1=> one of the continuous modes
8479
+ Hidden => 1,
8480
+ RawConv => '$$self{SingleFrame} = $val',
8481
+ },
8482
+ 92 => {
8483
+ Name => 'ReleaseMode',
8484
+ #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
8485
+ ValueConv => '$$self{SingleFrame} == 0 ? 5 : $val', #map single frame to a unique value for PrintConv
8486
+ PrintConv => \%releaseModeZ7,
8487
+ },
8583
8488
  160 => {
8584
8489
  Name => 'IntervalDurationHours',
8585
8490
  Format => 'int32u',
@@ -8800,7 +8705,7 @@ my %nikonFocalConversions = (
8800
8705
  %Image::ExifTool::Nikon::MenuSettingsZ9 = (
8801
8706
  %binaryDataAttrs,
8802
8707
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8803
- DATAMEMBER => [ 140, 188, 192, 232, 424, 534 ],
8708
+ DATAMEMBER => [ 140, 188, 192, 232, 424, 534, 576 ],
8804
8709
  IS_SUBDIR => [ 799 ],
8805
8710
  NOTES => 'These tags are used by the Z9.',
8806
8711
  #90 ISO
@@ -8814,34 +8719,34 @@ my %nikonFocalConversions = (
8814
8719
  Name => 'Intervals',
8815
8720
  Format => 'int32u',
8816
8721
  RawConv => '$$self{IntervalShootingIntervals} = $val',
8817
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8722
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8818
8723
  },
8819
8724
  192 => {
8820
8725
  Name => 'ShotsPerInterval',
8821
8726
  Format => 'int32u',
8822
8727
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
8823
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8728
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8824
8729
  },
8825
8730
  #220 NEFCompression 0=> 'Lossless' 1=> 'High Efficiency*' 4=> 'High Efficientcy'
8826
8731
  232 => {
8827
8732
  Name => 'FocusShiftNumberShots', #1-300
8828
8733
  RawConv => '$$self{FocusShiftNumberShots} = $val',
8829
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8734
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8830
8735
  },
8831
8736
  236 => {
8832
8737
  Name => 'FocusShiftStepWidth', #1(Narrow) to 10 (Wide)
8833
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8738
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8834
8739
  },
8835
8740
  240 => {
8836
8741
  Name => 'FocusShiftInterval',
8837
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8742
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8838
8743
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
8839
8744
  },
8840
8745
  244 => {
8841
8746
  Name => 'FocusShiftExposureLock',
8842
8747
  Unknown => 1,
8843
8748
  PrintConv => \%offOn,
8844
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8749
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8845
8750
  },
8846
8751
  274 => { Name => 'PhotoShootingMenuBank', PrintConv => \%banksZ9 },
8847
8752
  276 => { Name => 'ExtendedMenuBanks', PrintConv => \%offOn }, #single tag from both Photo & Video menus
@@ -8940,6 +8845,12 @@ my %nikonFocalConversions = (
8940
8845
  556 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFunctionZ9 },
8941
8846
  572 => { Name => 'DXCropAlert', PrintConv => \%offOn },
8942
8847
  574 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 },
8848
+ 576 => {
8849
+ Name => 'DynamicAFAreaSize',
8850
+ Condition => '$$self{AFAraMode} = 2',
8851
+ RawConv => '$$self{DynamicAFAreaSize} = $val',
8852
+ PrintConv => \%dynamicAfAreaModesZ9,
8853
+ },
8943
8854
  604 => {
8944
8855
  Name => 'MovieImageArea',
8945
8856
  Unknown => 1,
@@ -8996,16 +8907,16 @@ my %nikonFocalConversions = (
8996
8907
  1565 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
8997
8908
  1572 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
8998
8909
  1573 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
8999
- 1608 => { Name => 'EnergySavingMode', PrintConv =>\%offOn, Unknown => 1 },
8910
+ 1608 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
9000
8911
  1632 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
9001
8912
  1636 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
9002
8913
  1645 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
9003
8914
  );
9004
8915
 
9005
- %Image::ExifTool::Nikon::MenuSettingsZ9Firmware3 = ( #starts at Offset26 + 248
8916
+ %Image::ExifTool::Nikon::MenuSettingsZ9v3 = (
9006
8917
  %binaryDataAttrs,
9007
8918
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
9008
- DATAMEMBER => [ 154, 204, 208, 248, 444, 554 ],
8919
+ DATAMEMBER => [ 154, 204, 208, 248, 444, 554, 596 ],
9009
8920
  IS_SUBDIR => [ 847 ],
9010
8921
  NOTES => 'These tags are used by the Z9 firmware 3.00.',
9011
8922
  72 => {
@@ -9022,33 +8933,33 @@ my %nikonFocalConversions = (
9022
8933
  Name => 'Intervals',
9023
8934
  Format => 'int32u',
9024
8935
  RawConv => '$$self{IntervalShootingIntervals} = $val',
9025
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8936
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9026
8937
  },
9027
8938
  208 => {
9028
8939
  Name => 'ShotsPerInterval',
9029
8940
  Format => 'int32u',
9030
8941
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
9031
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8942
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9032
8943
  },
9033
8944
  248 => {
9034
8945
  Name => 'FocusShiftNumberShots', #1-300
9035
8946
  RawConv => '$$self{FocusShiftNumberShots} = $val',
9036
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8947
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9037
8948
  },
9038
8949
  252 => {
9039
8950
  Name => 'FocusShiftStepWidth', #1(Narrow) to 10 (Wide)
9040
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8951
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9041
8952
  },
9042
8953
  256 => {
9043
8954
  Name => 'FocusShiftInterval',
9044
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8955
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9045
8956
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
9046
8957
  },
9047
8958
  260 => {
9048
8959
  Name => 'FocusShiftExposureLock',
9049
8960
  Unknown => 1,
9050
8961
  PrintConv => \%offOn,
9051
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8962
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9052
8963
  },
9053
8964
  290 => { Name => 'PhotoShootingMenuBank', PrintConv => \%banksZ9 },
9054
8965
  292 => { Name => 'ExtendedMenuBanks', PrintConv => \%offOn }, # single tag from both Photo & Video menus
@@ -9134,6 +9045,12 @@ my %nikonFocalConversions = (
9134
9045
  576 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFunctionZ9 },
9135
9046
  592 => { Name => 'DXCropAlert', PrintConv => \%offOn },
9136
9047
  594 => { Name => 'SubjectDetection', PrintConv => \%subjectDetectionZ9 },
9048
+ 596 => {
9049
+ Name => 'DynamicAFAreaSize',
9050
+ Condition => '$$self{AFAraMode} = 2',
9051
+ RawConv => '$$self{DynamicAFAreaSize} = $val',
9052
+ PrintConv => \%dynamicAfAreaModesZ9,
9053
+ },
9137
9054
  636 => { Name => 'HighFrequencyFlickerReductionShooting', PrintConv => \%offOn, Unknown => 1 }, # new with firmware 3.0
9138
9055
  646 => {
9139
9056
  Name => 'MovieImageArea',
@@ -9192,7 +9109,7 @@ my %nikonFocalConversions = (
9192
9109
  1613 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
9193
9110
  1620 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
9194
9111
  1621 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
9195
- 1656 => { Name => 'EnergySavingMode', PrintConv =>\%offOn, Unknown => 1 },
9112
+ 1656 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
9196
9113
  1680 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
9197
9114
  1684 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
9198
9115
  1693 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
@@ -9200,7 +9117,7 @@ my %nikonFocalConversions = (
9200
9117
  Name => 'FocusShiftAutoReset',
9201
9118
  Unknown => 1,
9202
9119
  PrintConv => \%offOn,
9203
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9120
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9204
9121
  },
9205
9122
  1810 => { #CSd4-a
9206
9123
  Name => 'PreReleaseBurstLength',
@@ -11258,8 +11175,8 @@ my %nikonFocalConversions = (
11258
11175
  Name => 'LensData0201',
11259
11176
  SubDirectory => {
11260
11177
  TagTable => 'Image::ExifTool::Nikon::LensData01',
11261
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11262
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11178
+ ProcessProc => \&ProcessNikonEncrypted,
11179
+ WriteProc => \&ProcessNikonEncrypted,
11263
11180
  DecryptStart => 4,
11264
11181
  },
11265
11182
  },
@@ -11268,8 +11185,8 @@ my %nikonFocalConversions = (
11268
11185
  Name => 'LensData0204',
11269
11186
  SubDirectory => {
11270
11187
  TagTable => 'Image::ExifTool::Nikon::LensData0204',
11271
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11272
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11188
+ ProcessProc => \&ProcessNikonEncrypted,
11189
+ WriteProc => \&ProcessNikonEncrypted,
11273
11190
  DecryptStart => 4,
11274
11191
  },
11275
11192
  },
@@ -11278,8 +11195,8 @@ my %nikonFocalConversions = (
11278
11195
  Name => 'LensData0400',
11279
11196
  SubDirectory => {
11280
11197
  TagTable => 'Image::ExifTool::Nikon::LensData0400',
11281
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11282
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11198
+ ProcessProc => \&ProcessNikonEncrypted,
11199
+ WriteProc => \&ProcessNikonEncrypted,
11283
11200
  DecryptStart => 4,
11284
11201
  },
11285
11202
  },
@@ -11288,8 +11205,8 @@ my %nikonFocalConversions = (
11288
11205
  Name => 'LensData0402',
11289
11206
  SubDirectory => {
11290
11207
  TagTable => 'Image::ExifTool::Nikon::LensData0402',
11291
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11292
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11208
+ ProcessProc => \&ProcessNikonEncrypted,
11209
+ WriteProc => \&ProcessNikonEncrypted,
11293
11210
  DecryptStart => 4,
11294
11211
  },
11295
11212
  },
@@ -11298,8 +11215,8 @@ my %nikonFocalConversions = (
11298
11215
  Name => 'LensData0403',
11299
11216
  SubDirectory => {
11300
11217
  TagTable => 'Image::ExifTool::Nikon::LensData0403',
11301
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11302
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11218
+ ProcessProc => \&ProcessNikonEncrypted,
11219
+ WriteProc => \&ProcessNikonEncrypted,
11303
11220
  DecryptStart => 4,
11304
11221
  },
11305
11222
  },
@@ -11308,8 +11225,8 @@ my %nikonFocalConversions = (
11308
11225
  Name => 'LensData0800',
11309
11226
  SubDirectory => {
11310
11227
  TagTable => 'Image::ExifTool::Nikon::LensData0800',
11311
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11312
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11228
+ ProcessProc => \&ProcessNikonEncrypted,
11229
+ WriteProc => \&ProcessNikonEncrypted,
11313
11230
  DecryptStart => 4,
11314
11231
  ByteOrder => 'LittleEndian',
11315
11232
  # 0x5a0c - NikonMeteringMode for some Z6 ver1.00 samples (ref PH)
@@ -11319,8 +11236,8 @@ my %nikonFocalConversions = (
11319
11236
  Name => 'LensDataUnknown',
11320
11237
  SubDirectory => {
11321
11238
  TagTable => 'Image::ExifTool::Nikon::LensDataUnknown',
11322
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11323
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11239
+ ProcessProc => \&ProcessNikonEncrypted,
11240
+ WriteProc => \&ProcessNikonEncrypted,
11324
11241
  DecryptStart => 4,
11325
11242
  },
11326
11243
  },
@@ -11512,6 +11429,7 @@ my %nikonFocalConversions = (
11512
11429
  # construct lens ID string as per ref 11
11513
11430
  ValueConv => 'sprintf("%.2X"." %.2X"x7, @raw)',
11514
11431
  PrintConv => \%nikonLensIDs,
11432
+ PrintInt => 1,
11515
11433
  },
11516
11434
  AutoFocus => {
11517
11435
  Require => {
@@ -11835,37 +11753,54 @@ my @xlat = (
11835
11753
  0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f ]
11836
11754
  );
11837
11755
 
11756
+ my ($ci0, $cj0, $ck0, $decryptStart); # decryption parameters
11757
+
11838
11758
  # 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)
11759
+ # Inputs: 0) reference to data block, 1) optional start offset (default 0)
11760
+ # 2) optional number of bytes to decode (default to the end of the data)
11761
+ # 3) optional serial number key (undef to continue previous decryption)
11762
+ # 4) optional shutter count key
11842
11763
  # Returns: data block with specified data decrypted
11843
- sub Decrypt($$$;$$)
11764
+ # Notes: The first time this is called for a given encrypted data block the serial/count
11765
+ # keys must be defined, and $start must be the offset for initialization of the
11766
+ # decryption parameters (ie. the beginning of the encrypted data, which isn't
11767
+ # necessarily inside the data block if $len is zero). Subsequent calls for
11768
+ # the same data block do not specify the serial/count keys, and may be used
11769
+ # to decrypt data at any start point within the full data block.
11770
+ sub Decrypt($;$$$$)
11844
11771
  {
11845
- my ($dataPt, $serial, $count, $start, $len) = @_;
11846
- my ($i, $dat);
11772
+ my ($dataPt, $start, $len, $serial, $count) = @_;
11773
+ my ($ch, $cj, $ck);
11847
11774
 
11848
11775
  $start or $start = 0;
11849
11776
  my $maxLen = length($$dataPt) - $start;
11850
11777
  $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;
11778
+ if (defined $serial and defined $count) {
11779
+ # initialize decryption parameters
11780
+ my $key = 0;
11781
+ $key ^= ($count >> ($_*8)) & 0xff foreach 0..3;
11782
+ $ci0 = $xlat[0][$serial & 0xff];
11783
+ $cj0 = $xlat[1][$key];
11784
+ $ck0 = 0x60;
11785
+ undef $decryptStart;
11855
11786
  }
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;
11787
+ if (defined $decryptStart) {
11788
+ # initialize decryption parameters for this start position
11789
+ my $n = $start - $decryptStart;
11790
+ $cj = ($cj0 + $ci0 * ($n * $ck0 + ($n * ($n - 1))/2)) & 0xff;
11791
+ $ck = ($ck0 + $n) & 0xff;
11792
+ } else {
11793
+ $decryptStart = $start;
11794
+ ($cj, $ck) = ($cj0, $ck0);
11795
+ }
11796
+ return $$dataPt if $len <= 0;
11797
+ my @data = unpack('C*', substr($$dataPt, $start, $len));
11798
+ foreach $ch (@data) {
11799
+ $cj = ($cj + $ci0 * $ck) & 0xff;
11862
11800
  $ck = ($ck + 1) & 0xff;
11863
- $dat ^= $cj;
11801
+ $ch ^= $cj;
11864
11802
  }
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;
11803
+ return substr($$dataPt, 0, $start) . pack('C*', @data) . substr($$dataPt, $start+$len);
11869
11804
  }
11870
11805
 
11871
11806
  #------------------------------------------------------------------------------
@@ -12001,6 +11936,166 @@ sub ProcessNikonMOV($$$)
12001
11936
  return 1;
12002
11937
  }
12003
11938
 
11939
+ #------------------------------------------------------------------------------
11940
+ # Get offset of end-of-data for a tag
11941
+ # Inputs: 0) tag table ref, 1) tag ID, 2) true to not calculate end for a SubDirectory
11942
+ # Returns: offset of tag value end, undef if it can't be determined
11943
+ sub GetTagEnd($$;$)
11944
+ {
11945
+ my ($tagTablePtr, $tagID, $ignoreSubdir) = @_;
11946
+ my $tagInfo = $$tagTablePtr{$tagID};
11947
+ $tagInfo = $$tagInfo[0] if ref $tagInfo eq 'ARRAY';
11948
+ # (can't pre-determine position of offset-based subdirectories)
11949
+ return undef if $ignoreSubdir and $$tagInfo{SubDirectory};
11950
+ my $fmt = $$tagInfo{Format} || $$tagTablePtr{FORMAT} || 'int8u';
11951
+ my $nm = $fmt =~ s/\[(\d+)\]$// ? $1 : 1;
11952
+ my $sz = Image::ExifTool::FormatSize($fmt) or return undef;
11953
+ return int($tagID) + $sz * $nm;
11954
+ }
11955
+
11956
+ #------------------------------------------------------------------------------
11957
+ # Initialize SubDirectory KnownStart/KnownEnd limits of known tags (used in decryption)
11958
+ # Inputs: 0) tagInfo ref containing this SubDirectory, 2) tag table ref for encrypted subdir
11959
+ # Notes: KnownStart/KnownEnd are relative to the SubDirectory Start. If KnownStart/KnownEnd
11960
+ # aren't set then the entire data is decrypted, so all of this effort is just for speed.
11961
+ sub InitEncryptedSubdir($$)
11962
+ {
11963
+ my ($tagInfo, $tagTablePtr) = @_;
11964
+ #
11965
+ # for encrypted NIKON_OFFSETS tables we loop through all SubDirectory tags in this table
11966
+ # and set the KnownEnd for each of these according to the last tag in the child tables
11967
+ #
11968
+ my $vars = $$tagTablePtr{VARS};
11969
+ $vars or $vars = $$tagTablePtr{VARS} = { };
11970
+ if ($$vars{NIKON_OFFSETS} and not $$vars{NIKON_INITIALIZED}) {
11971
+ $$vars{NIKON_INITIALIZED} = 1;
11972
+ my $tagID;
11973
+ foreach $tagID (TagTableKeys($tagTablePtr)) {
11974
+ my $tagInfo = $$tagTablePtr{$tagID};
11975
+ next unless ref $tagInfo eq 'HASH';
11976
+ my $subdir = $$tagInfo{SubDirectory} or next;
11977
+ my $tbl = GetTagTable($$subdir{TagTable});
11978
+ my ($last) = sort { $b <=> $a } TagTableKeys($tbl); # (reverse sort)
11979
+ $$subdir{KnownEnd} = GetTagEnd($tbl, $last, 1);
11980
+ }
11981
+ }
11982
+ #
11983
+ # for other encrypted Nikon tables we set the KnownStart/KnownEnd entries in the
11984
+ # SubDirectory of the parent tag
11985
+ #
11986
+ unless ($$tagInfo{NikonInitialized}) {
11987
+ $$tagInfo{NikonInitialized} = 1;
11988
+ my $subdir = $$tagInfo{SubDirectory};
11989
+ my $start = $$subdir{DecryptStart} || 0;
11990
+ my $off = $$subdir{DirOffset};
11991
+ my @tagIDs = sort { $a <=> $b } TagTableKeys($tagTablePtr);
11992
+ if (defined $off) {
11993
+ $off += $start; # (DirOffset, if specified, is relative to DecryptStart)
11994
+ } else {
11995
+ # ignore tags that come before the start of encryption
11996
+ shift @tagIDs while @tagIDs and $tagIDs[0] < $start;
11997
+ $off = 0;
11998
+ }
11999
+ if (@tagIDs) {
12000
+ my ($first, $last) = @tagIDs[0,-1];
12001
+ my $lastInfo = $$tagTablePtr{$last};
12002
+ $lastInfo = $$lastInfo[0] if ref $lastInfo eq 'ARRAY';
12003
+ $$subdir{KnownStart} = int($first) + $off if $first + $off > $start;
12004
+ $$subdir{KnownEnd} = GetTagEnd($tagTablePtr, $last);
12005
+ if (defined $$subdir{KnownEnd}) {
12006
+ $$subdir{KnownEnd} += $off;
12007
+ } else {
12008
+ warn "Internal error setting KnownEnd for $$tagTablePtr{SHORT_NAME}\n";
12009
+ }
12010
+ } else {
12011
+ $$subdir{KnownStart} = $$subdir{KnownEnd} = $start;
12012
+ }
12013
+ }
12014
+ }
12015
+
12016
+ #------------------------------------------------------------------------------
12017
+ # Prepare to process NIKON_OFFSETS directory and decrypt necessary data
12018
+ # Inputs: 0) ExifTool ref, 1) data ref, 2) tag table ref, 3) decrypt start,
12019
+ # 4) decrypt mode (0=piecewise, 1=continuous to end of last known section, 2=all)
12020
+ # Returns: end of decrypted data (or undef for piecewise decryption)
12021
+ sub PrepareNikonOffsets($$$$$)
12022
+ {
12023
+ my ($et, $dataPt, $tagTablePtr, $start, $decryptMode) = @_;
12024
+ my $offset = $$tagTablePtr{VARS}{NIKON_OFFSETS};
12025
+ my $dataLen = length $$dataPt;
12026
+ return undef if $offset + 4 > $dataLen or $offset < $start;
12027
+ my $serial = $$et{NikonSerialKey};
12028
+ my $count = $$et{NikonCountKey};
12029
+ my $dpos = $offset + 4; # decrypt up to NumberOffsets
12030
+ $$dataPt = Decrypt($dataPt, $start, $dpos - $start, $serial, $count);
12031
+ my $numOffsets = Get32u($dataPt, $offset);
12032
+ my $more = $numOffsets * 4; # more bytes to decrypt entire offsets table
12033
+ return undef if $offset + 4 + $more > $dataLen;
12034
+ $$dataPt = Decrypt($dataPt, $dpos, $more);
12035
+ $dpos += $more;
12036
+ my $unknown = $et->Options('Unknown');
12037
+ my ($i, @offInfo, $end);
12038
+ # extract non-zero offsets and create unknown subdirectories if Unknown > 1
12039
+ for ($i=0; $i<$numOffsets; ++$i) {
12040
+ my $pos = $offset + 4 + 4 * $i;
12041
+ my $off = Get32u($dataPt, $pos) or next;
12042
+ my $tagInfo = $$tagTablePtr{$pos};
12043
+ my $known = 0;
12044
+ if ($tagInfo) {
12045
+ $known = 1 if ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown};
12046
+ } elsif ($unknown > 1) {
12047
+ # create new table for unknown information
12048
+ my $tbl = sprintf('Image::ExifTool::Nikon::UnknownInfo%.2x', $pos);
12049
+ no strict 'refs';
12050
+ unless (%$tbl) {
12051
+ %$tbl = ( %binaryDataAttrs, GROUPS => { 0=>'MakerNotes', 2=>'Unknown' } );
12052
+ GetTagTable($tbl);
12053
+ }
12054
+ # add unknown entry in offset table for this subdirectory
12055
+ $tagInfo = AddTagToTable($tagTablePtr, $pos, {
12056
+ Name => sprintf('UnknownOffset%.2x', $pos),
12057
+ Format => 'int32u',
12058
+ SubDirectory => { TagTable => $tbl },
12059
+ Unknown => 2,
12060
+ });
12061
+ }
12062
+ push @offInfo, [ $pos, $off, $known ]; # save parameters for non-zero offsets
12063
+ }
12064
+ # sort offsets in ascending order, and use the differences to calculate
12065
+ # directory lengths and update the SubDirectory DirLen's accordingly
12066
+ my @sorted = sort { $$a[1] <=> $$b[1] or $$a[0] <=> $$b[0] } @offInfo;
12067
+ push @sorted, [ 0, length($$dataPt), 0 ];
12068
+ for ($i=0; $i<@sorted-1; ++$i) {
12069
+ my $pos = $sorted[$i][0];
12070
+ my $len = $sorted[$i+1][1] - $sorted[$i][1];
12071
+ # set DirLen in SubDirectory entry
12072
+ my $tagInfo = $$tagTablePtr{$pos};
12073
+ my $subdir;
12074
+ $$subdir{DirLen} = $len if ref $tagInfo eq 'HASH' and defined($subdir=$$tagInfo{SubDirectory});
12075
+ if ($decryptMode) {
12076
+ # keep track of end of last known directory
12077
+ $end = $sorted[$i+1][1] if $sorted[$i][2];
12078
+ } elsif ($tagInfo and (ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown})) {
12079
+ # decrypt data piecewise as necessary
12080
+ my $n = $len;
12081
+ if ($subdir and $$subdir{KnownEnd}) {
12082
+ $n = $$subdir{KnownEnd};
12083
+ if ($n > $len) {
12084
+ $et->Warn("Data too short for $$tagInfo{Name}",1);
12085
+ $n = $len;
12086
+ }
12087
+ }
12088
+ $$dataPt = Decrypt($dataPt, $sorted[$i][1], $n);
12089
+ }
12090
+ }
12091
+ if ($decryptMode) {
12092
+ # decrypt the remaining required data
12093
+ $end = length $$dataPt if $decryptMode == 2 or not $end or $end < $dpos;
12094
+ $$dataPt = Decrypt($dataPt, $dpos, $end - $dpos);
12095
+ }
12096
+ return $end;
12097
+ }
12098
+
12004
12099
  #------------------------------------------------------------------------------
12005
12100
  # Read/Write Nikon Encrypted data block
12006
12101
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -12025,15 +12120,17 @@ sub ProcessNikonEncrypted($$$)
12025
12120
  delete $$et{NikonCountKey};
12026
12121
  return 0;
12027
12122
  }
12028
- my $verbose = $$dirInfo{IsWriting} ? 0 : $et->Options('Verbose');
12123
+ my $oldOrder = GetByteOrder();
12124
+ my $isWriting = $$dirInfo{IsWriting};
12125
+ my $verbose = $isWriting ? 0 : $et->Options('Verbose');
12029
12126
  my $tagInfo = $$dirInfo{TagInfo};
12030
12127
  my $dirStart = $$dirInfo{DirStart};
12031
12128
  my $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen});
12032
12129
 
12033
- my ($start, $len, $more, $offset, $byteOrder, $recrypt, $newSerial, $newCount);
12130
+ my ($start, $len, $offset, $recrypt, $newSerial, $newCount, $didDecrypt);
12034
12131
 
12035
12132
  # must re-encrypt when writing if serial number or shutter count changes
12036
- if ($$dirInfo{IsWriting}) {
12133
+ if ($isWriting) {
12037
12134
  if ($$et{NewNikonSerialKey}) {
12038
12135
  $newSerial = $$et{NewNikonSerialKey};
12039
12136
  $recrypt = 1;
@@ -12044,46 +12141,43 @@ sub ProcessNikonEncrypted($$$)
12044
12141
  }
12045
12142
  }
12046
12143
  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};
12144
+ # initialize SubDirectory entries used in encryption (KnownStart, KnownEnd)
12145
+ InitEncryptedSubdir($tagInfo, $tagTablePtr);
12146
+ my $subdir = $$tagInfo{SubDirectory};
12147
+ $start = $$subdir{DecryptStart} || 0;
12148
+ # DirOffset, if specified, is the offset to the start of the
12149
+ # directory relative to start of encrypted data
12150
+ $offset = defined $$subdir{DirOffset} ? $$subdir{DirOffset} + $start : 0;
12151
+ # must set byte ordering before calling PrepareNikonOffsets()
12152
+ SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
12153
+ # prepare for processing NIKON_OFFSETS directory if necessary
12154
+ my $unknown = $verbose > 2 || $et->Options('Unknown') > 1;
12155
+ # decrypt mode: 0=piecewise, 1=continuous to end of last known section, 2=all
12156
+ my $dMode = $isWriting ? ($recrypt ? 2 : 1) : ($unknown ? 2 : 0);
12157
+ if ($$tagTablePtr{VARS}{NIKON_OFFSETS}) {
12158
+ $len = PrepareNikonOffsets($et, \$data, $tagTablePtr, $start, $dMode);
12159
+ $didDecrypt = 1;
12160
+ } elsif ($dMode < 2) {
12161
+ if ($dMode == 0 and $$subdir{KnownStart}) {
12162
+ # initialize decryption parameters for address DecryptStart address
12163
+ Decrypt(\$data, $start, 0, $serial, $count);
12164
+ # reset serial/count keys so we don't re-initialize below
12165
+ undef $serial;
12166
+ undef $count;
12167
+ # change decryption start to skip unnecessary data
12168
+ $start = $$subdir{KnownStart};
12169
+ }
12170
+ $len = $$subdir{KnownEnd} - $start if $$subdir{KnownEnd};
12052
12171
  }
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
12172
  } else {
12061
- $offset = 0;
12173
+ $start = $offset = 0;
12062
12174
  }
12063
12175
  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
- }
12176
+ # decrypt all the data unless the length was specified
12177
+ $len = $maxLen unless $len and $len < $maxLen;
12069
12178
 
12070
- $data = Decrypt(\$data, $serial, $count, $start, $len);
12179
+ $data = Decrypt(\$data, $start, $len, $serial, $count) unless $didDecrypt;
12071
12180
 
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
12181
  if ($verbose > 2) {
12088
12182
  $et->VerboseDir("Decrypted $$tagInfo{Name}");
12089
12183
  $et->VerboseDump(\$data,
@@ -12102,7 +12196,7 @@ sub ProcessNikonEncrypted($$$)
12102
12196
  Base => $$dirInfo{Base},
12103
12197
  );
12104
12198
  my $rtnVal;
12105
- if ($$dirInfo{IsWriting}) {
12199
+ if ($isWriting) {
12106
12200
  my $changed = $$et{CHANGED};
12107
12201
  $rtnVal = $et->WriteBinaryData(\%subdirInfo, $tagTablePtr);
12108
12202
  # must re-encrypt if serial number or shutter count changes
@@ -12117,7 +12211,8 @@ sub ProcessNikonEncrypted($$$)
12117
12211
  # add back any un-encrypted data at start
12118
12212
  $rtnVal = substr($data, 0, $offset) . $rtnVal if $offset;
12119
12213
  # re-encrypt data (symmetrical algorithm)
12120
- $rtnVal = Decrypt(\$rtnVal, $serial, $count, $start, $len);
12214
+ $rtnVal = Decrypt(\$rtnVal, $start, $len, $serial, $count);
12215
+ $et->VPrint(2, $$et{INDENT}, " [recrypted $$tagInfo{Name}]");
12121
12216
  }
12122
12217
  } else {
12123
12218
  $rtnVal = $et->ProcessBinaryData(\%subdirInfo, $tagTablePtr);