exiftool_vendored 12.56.0 → 12.57.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.
@@ -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.19';
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($$);
@@ -1112,6 +1113,14 @@ my %offLowNormalHighZ7 = (
1112
1113
  3 => 'High',
1113
1114
  );
1114
1115
 
1116
+ my %releaseModeZ7 = (
1117
+ 0 => 'Continuous Low',
1118
+ 1 => 'Continuous High',
1119
+ 2 => 'Continuous High (Extended)',
1120
+ 4 => 'Timer',
1121
+ 5 => 'Single Frame',
1122
+ );
1123
+
1115
1124
  my %secondarySlotFunctionZ9 = (
1116
1125
  0 => 'Overflow',
1117
1126
  1 => 'Backup',
@@ -1509,9 +1518,7 @@ my %base64coord = (
1509
1518
  0x0006 => { Name => 'Sharpness', Writable => 'string' },
1510
1519
  0x0007 => {
1511
1520
  Name => 'FocusMode',
1512
- DataMember => 'FocusMode',
1513
1521
  Writable => 'string',
1514
- RawConv => '$$self{FocusMode} = $val',
1515
1522
  },
1516
1523
  # FlashSetting (better named FlashSyncMode, ref 28) values:
1517
1524
  # "Normal", "Slow", "Rear Slow", "RED-EYE", "RED-EYE SLOW"
@@ -1812,6 +1819,7 @@ my %base64coord = (
1812
1819
  Name => 'ShutterMode',
1813
1820
  Writable => 'int16u',
1814
1821
  RawConv => '$$self{ShutterMode} = $val',
1822
+ DataMember => 'ShutterMode',
1815
1823
  PrintConv => {
1816
1824
  0 => 'Mechanical',
1817
1825
  16 => 'Electronic',
@@ -2184,8 +2192,6 @@ my %base64coord = (
2184
2192
  SubDirectory => {
2185
2193
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD810',
2186
2194
  DecryptStart => 4,
2187
- DecryptLen => 0x36f4 + 12,
2188
- DecryptMore => 'Get32u(\$data, 0x84) + 12',
2189
2195
  ByteOrder => 'LittleEndian',
2190
2196
  },
2191
2197
  },
@@ -2195,8 +2201,6 @@ my %base64coord = (
2195
2201
  SubDirectory => {
2196
2202
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD850',
2197
2203
  DecryptStart => 4,
2198
- DecryptLen => 0x2efb + 12,
2199
- DecryptMore => 'Get32u(\$data, 0xa0) + 12',
2200
2204
  ByteOrder => 'LittleEndian',
2201
2205
  },
2202
2206
  },
@@ -2263,25 +2267,12 @@ my %base64coord = (
2263
2267
  ByteOrder => 'LittleEndian',
2264
2268
  },
2265
2269
  },
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
- ByteOrder => 'LittleEndian',
2275
- },
2276
- },
2277
- { # (D500 firmware version 1.00)
2278
- Condition => '$$valPt =~ /^0239/',
2270
+ { #28 (D500 firmware version 1.00 and D5 firmware version 1.10a)
2271
+ Condition => '$$valPt =~ /^023[89]/',
2279
2272
  Name => 'ShotInfoD500',
2280
2273
  SubDirectory => {
2281
2274
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD500',
2282
2275
  DecryptStart => 4,
2283
- DecryptLen => 0x2cb2 + 4,
2284
- DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90',
2285
2276
  ByteOrder => 'LittleEndian',
2286
2277
  },
2287
2278
  },
@@ -2291,7 +2282,6 @@ my %base64coord = (
2291
2282
  SubDirectory => {
2292
2283
  TagTable => 'Image::ExifTool::Nikon::ShotInfoD6',
2293
2284
  DecryptStart => 4,
2294
- DecryptLen => 0xc292 + 720, # thru decoded parts of Offset 32
2295
2285
  ByteOrder => 'LittleEndian',
2296
2286
  },
2297
2287
  },
@@ -2312,8 +2302,6 @@ my %base64coord = (
2312
2302
  SubDirectory => {
2313
2303
  TagTable => 'Image::ExifTool::Nikon::ShotInfoZ7II',
2314
2304
  DecryptStart => 4,
2315
- # TODO: eventually set the length dynamically according to actual offsets!
2316
- DecryptLen => 0xd04e + 860, # thru decoded MenuSettingsZ7II
2317
2305
  ByteOrder => 'LittleEndian',
2318
2306
  },
2319
2307
  },
@@ -2323,8 +2311,6 @@ my %base64coord = (
2323
2311
  SubDirectory => {
2324
2312
  TagTable => 'Image::ExifTool::Nikon::ShotInfoZ9',
2325
2313
  DecryptStart => 4,
2326
- # TODO: eventually set the length dynamically according to actual offsets!
2327
- DecryptLen => 0xec4b + 2196, # decoded thru end of Offset26
2328
2314
  ByteOrder => 'LittleEndian',
2329
2315
  },
2330
2316
  },
@@ -2333,8 +2319,8 @@ my %base64coord = (
2333
2319
  Name => 'ShotInfo02xx',
2334
2320
  SubDirectory => {
2335
2321
  TagTable => 'Image::ExifTool::Nikon::ShotInfo',
2336
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2337
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2322
+ ProcessProc => \&ProcessNikonEncrypted,
2323
+ WriteProc => \&ProcessNikonEncrypted,
2338
2324
  DecryptStart => 4,
2339
2325
  DecryptLen => 0x251,
2340
2326
  ByteOrder => 'BigEndian',
@@ -2400,8 +2386,8 @@ my %base64coord = (
2400
2386
  Name => 'ColorBalance0205',
2401
2387
  SubDirectory => {
2402
2388
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2403
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2404
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2389
+ ProcessProc => \&ProcessNikonEncrypted,
2390
+ WriteProc => \&ProcessNikonEncrypted,
2405
2391
  DecryptStart => 4,
2406
2392
  DecryptLen => 22, # 284 bytes encrypted, but don't need to decrypt it all
2407
2393
  DirOffset => 14,
@@ -2412,8 +2398,8 @@ my %base64coord = (
2412
2398
  Name => 'ColorBalance0209',
2413
2399
  SubDirectory => {
2414
2400
  TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
2415
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2416
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2401
+ ProcessProc => \&ProcessNikonEncrypted,
2402
+ WriteProc => \&ProcessNikonEncrypted,
2417
2403
  DecryptStart => 284,
2418
2404
  DecryptLen => 18, # 324 bytes encrypted, but don't need to decrypt it all
2419
2405
  DirOffset => 10,
@@ -2424,8 +2410,8 @@ my %base64coord = (
2424
2410
  Name => 'ColorBalance02',
2425
2411
  SubDirectory => {
2426
2412
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2427
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2428
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2413
+ ProcessProc => \&ProcessNikonEncrypted,
2414
+ WriteProc => \&ProcessNikonEncrypted,
2429
2415
  DecryptStart => 284,
2430
2416
  DecryptLen => 14, # don't need to decrypt it all
2431
2417
  DirOffset => 6,
@@ -2436,8 +2422,8 @@ 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
2428
  DecryptLen => 24, # don't need to decrypt it all
2443
2429
  DirOffset => 16,
@@ -2448,8 +2434,8 @@ my %base64coord = (
2448
2434
  Name => 'ColorBalance0213',
2449
2435
  SubDirectory => {
2450
2436
  TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2451
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2452
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2437
+ ProcessProc => \&ProcessNikonEncrypted,
2438
+ WriteProc => \&ProcessNikonEncrypted,
2453
2439
  DecryptStart => 284,
2454
2440
  DecryptLen => 18, # don't need to decrypt it all
2455
2441
  DirOffset => 10,
@@ -2460,8 +2446,8 @@ my %base64coord = (
2460
2446
  Name => 'ColorBalance0215',
2461
2447
  SubDirectory => {
2462
2448
  TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
2463
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2464
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2449
+ ProcessProc => \&ProcessNikonEncrypted,
2450
+ WriteProc => \&ProcessNikonEncrypted,
2465
2451
  DecryptStart => 284,
2466
2452
  DecryptLen => 12, # don't need to decrypt it all
2467
2453
  DirOffset => 4,
@@ -2472,7 +2458,8 @@ my %base64coord = (
2472
2458
  Condition => '$$valPt =~ /^0[26]/',
2473
2459
  SubDirectory => {
2474
2460
  TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
2475
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2461
+ ProcessProc => \&ProcessNikonEncrypted,
2462
+ WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt this if serial number changed)
2476
2463
  DecryptStart => 284,
2477
2464
  DecryptLen => 10, # (arbitrary)
2478
2465
  },
@@ -2482,7 +2469,8 @@ my %base64coord = (
2482
2469
  Condition => '$$valPt =~ /^0[48]/',
2483
2470
  SubDirectory => {
2484
2471
  TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
2485
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2472
+ ProcessProc => \&ProcessNikonEncrypted,
2473
+ WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt this if serial number changed)
2486
2474
  DecryptStart => 4,
2487
2475
  DecryptLen => 10, # (arbitrary)
2488
2476
  },
@@ -2513,8 +2501,8 @@ my %base64coord = (
2513
2501
  Name => 'LensData0201',
2514
2502
  SubDirectory => {
2515
2503
  TagTable => 'Image::ExifTool::Nikon::LensData01',
2516
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2517
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2504
+ ProcessProc => \&ProcessNikonEncrypted,
2505
+ WriteProc => \&ProcessNikonEncrypted,
2518
2506
  DecryptStart => 4,
2519
2507
  },
2520
2508
  },
@@ -2523,8 +2511,8 @@ my %base64coord = (
2523
2511
  Name => 'LensData0204',
2524
2512
  SubDirectory => {
2525
2513
  TagTable => 'Image::ExifTool::Nikon::LensData0204',
2526
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2527
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2514
+ ProcessProc => \&ProcessNikonEncrypted,
2515
+ WriteProc => \&ProcessNikonEncrypted,
2528
2516
  DecryptStart => 4,
2529
2517
  },
2530
2518
  },
@@ -2533,8 +2521,8 @@ my %base64coord = (
2533
2521
  Name => 'LensData0400',
2534
2522
  SubDirectory => {
2535
2523
  TagTable => 'Image::ExifTool::Nikon::LensData0400',
2536
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2537
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2524
+ ProcessProc => \&ProcessNikonEncrypted,
2525
+ WriteProc => \&ProcessNikonEncrypted,
2538
2526
  DecryptStart => 4,
2539
2527
  },
2540
2528
  },
@@ -2543,8 +2531,8 @@ my %base64coord = (
2543
2531
  Name => 'LensData0402',
2544
2532
  SubDirectory => {
2545
2533
  TagTable => 'Image::ExifTool::Nikon::LensData0402',
2546
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2547
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2534
+ ProcessProc => \&ProcessNikonEncrypted,
2535
+ WriteProc => \&ProcessNikonEncrypted,
2548
2536
  DecryptStart => 4,
2549
2537
  },
2550
2538
  },
@@ -2553,8 +2541,8 @@ my %base64coord = (
2553
2541
  Name => 'LensData0403',
2554
2542
  SubDirectory => {
2555
2543
  TagTable => 'Image::ExifTool::Nikon::LensData0403',
2556
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2557
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2544
+ ProcessProc => \&ProcessNikonEncrypted,
2545
+ WriteProc => \&ProcessNikonEncrypted,
2558
2546
  DecryptStart => 4,
2559
2547
  },
2560
2548
  },
@@ -2563,8 +2551,8 @@ my %base64coord = (
2563
2551
  Name => 'LensData0800',
2564
2552
  SubDirectory => {
2565
2553
  TagTable => 'Image::ExifTool::Nikon::LensData0800',
2566
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2567
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2554
+ ProcessProc => \&ProcessNikonEncrypted,
2555
+ WriteProc => \&ProcessNikonEncrypted,
2568
2556
  DecryptStart => 4,
2569
2557
  ByteOrder => 'LittleEndian',
2570
2558
  },
@@ -2573,8 +2561,8 @@ my %base64coord = (
2573
2561
  Name => 'LensDataUnknown',
2574
2562
  SubDirectory => {
2575
2563
  TagTable => 'Image::ExifTool::Nikon::LensDataUnknown',
2576
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2577
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
2564
+ ProcessProc => \&ProcessNikonEncrypted,
2565
+ WriteProc => \&ProcessNikonEncrypted,
2578
2566
  DecryptStart => 4,
2579
2567
  },
2580
2568
  },
@@ -5305,12 +5293,14 @@ my %nikonFocalConversions = (
5305
5293
  23 => 'Nikkor Z 14-24mm f/2.8 S', #IB
5306
5294
  24 => 'Nikkor Z MC 105mm f/2.8 VR S', #IB
5307
5295
  25 => 'Nikkor Z 40mm f/2', #28
5296
+ 26 => 'Nikkor Z DX 18-140mm f/3.5-6.3 VR', #IB
5308
5297
  27 => 'Nikkor Z MC 50mm f/2.8', #IB
5309
5298
  28 => 'Nikkor Z 100-400mm f/4.5-5.6 VR S', #28
5310
5299
  29 => 'Nikkor Z 28mm f/2.8', #IB
5311
5300
  30 => 'Nikkor Z 400mm f/2.8 TC VR S', #28
5312
5301
  31 => 'Nikkor Z 24-120 f/4', #28
5313
5302
  32 => 'Nikkor Z 800mm f/6.3 VR S', #28
5303
+ 35 => 'Nikkor Z 28-75mm f/2.8', #IB
5314
5304
  36 => 'Nikkor Z 400mm f/4.5 VR S', #IB
5315
5305
  37 => 'Nikkor Z 600mm f/4 TC VR S', #28
5316
5306
  39 => 'Nikkor Z 17-28mm f/2.8', #IB
@@ -5521,8 +5511,8 @@ my %nikonFocalConversions = (
5521
5511
 
5522
5512
  # shot information for D40 and D40X (encrypted) - ref PH
5523
5513
  %Image::ExifTool::Nikon::ShotInfoD40 = (
5524
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5525
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5514
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5515
+ WRITE_PROC => \&ProcessNikonEncrypted,
5526
5516
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5527
5517
  VARS => { ID_LABEL => 'Index' },
5528
5518
  IS_SUBDIR => [ 729 ],
@@ -5557,8 +5547,8 @@ my %nikonFocalConversions = (
5557
5547
 
5558
5548
  # shot information for D80 (encrypted) - ref JD
5559
5549
  %Image::ExifTool::Nikon::ShotInfoD80 = (
5560
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5561
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5550
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5551
+ WRITE_PROC => \&ProcessNikonEncrypted,
5562
5552
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5563
5553
  VARS => { ID_LABEL => 'Index' },
5564
5554
  IS_SUBDIR => [ 748 ],
@@ -5637,8 +5627,8 @@ my %nikonFocalConversions = (
5637
5627
 
5638
5628
  # shot information for D90 (encrypted) - ref PH
5639
5629
  %Image::ExifTool::Nikon::ShotInfoD90 = (
5640
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5641
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5630
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5631
+ WRITE_PROC => \&ProcessNikonEncrypted,
5642
5632
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5643
5633
  VARS => { ID_LABEL => 'Index' },
5644
5634
  IS_SUBDIR => [ 0x374 ],
@@ -5683,8 +5673,8 @@ my %nikonFocalConversions = (
5683
5673
 
5684
5674
  # shot information for the D3 firmware 0.37 and 1.00 (encrypted) - ref PH
5685
5675
  %Image::ExifTool::Nikon::ShotInfoD3a = (
5686
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5687
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5676
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5677
+ WRITE_PROC => \&ProcessNikonEncrypted,
5688
5678
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5689
5679
  VARS => { ID_LABEL => 'Index' },
5690
5680
  IS_SUBDIR => [ 0x301 ],
@@ -5747,8 +5737,8 @@ my %nikonFocalConversions = (
5747
5737
 
5748
5738
  # shot information for the D3 firmware 1.10, 2.00 and 2.01 (encrypted) - ref PH
5749
5739
  %Image::ExifTool::Nikon::ShotInfoD3b = (
5750
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5751
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5740
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5741
+ WRITE_PROC => \&ProcessNikonEncrypted,
5752
5742
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5753
5743
  VARS => { ID_LABEL => 'Index' },
5754
5744
  IS_SUBDIR => [ 0x30a ],
@@ -5842,8 +5832,8 @@ my %nikonFocalConversions = (
5842
5832
 
5843
5833
  # shot information for the D3X firmware 1.00 (encrypted) - ref PH
5844
5834
  %Image::ExifTool::Nikon::ShotInfoD3X = (
5845
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5846
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5835
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5836
+ WRITE_PROC => \&ProcessNikonEncrypted,
5847
5837
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5848
5838
  VARS => { ID_LABEL => 'Index' },
5849
5839
  IS_SUBDIR => [ 0x30b ],
@@ -5888,8 +5878,8 @@ my %nikonFocalConversions = (
5888
5878
 
5889
5879
  # shot information for the D3S firmware 0.16 and 1.00 (encrypted) - ref PH
5890
5880
  %Image::ExifTool::Nikon::ShotInfoD3S = (
5891
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5892
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5881
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5882
+ WRITE_PROC => \&ProcessNikonEncrypted,
5893
5883
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5894
5884
  VARS => { ID_LABEL => 'Index' },
5895
5885
  IS_SUBDIR => [ 0x2ce ],
@@ -5943,8 +5933,8 @@ my %nikonFocalConversions = (
5943
5933
 
5944
5934
  # shot information for the D300 firmware 1.00 (encrypted) - ref JD
5945
5935
  %Image::ExifTool::Nikon::ShotInfoD300a = (
5946
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5947
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
5936
+ PROCESS_PROC => \&ProcessNikonEncrypted,
5937
+ WRITE_PROC => \&ProcessNikonEncrypted,
5948
5938
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
5949
5939
  VARS => { ID_LABEL => 'Index' },
5950
5940
  IS_SUBDIR => [ 790 ],
@@ -6036,8 +6026,8 @@ my %nikonFocalConversions = (
6036
6026
 
6037
6027
  # shot information for the D300 firmware 1.10 (encrypted) - ref PH
6038
6028
  %Image::ExifTool::Nikon::ShotInfoD300b = (
6039
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6040
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6029
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6030
+ WRITE_PROC => \&ProcessNikonEncrypted,
6041
6031
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6042
6032
  VARS => { ID_LABEL => 'Index' },
6043
6033
  DATAMEMBER => [ 4 ],
@@ -6187,8 +6177,8 @@ my %nikonFocalConversions = (
6187
6177
 
6188
6178
  # shot information for the D300S firmware 1.00 (encrypted) - ref PH
6189
6179
  %Image::ExifTool::Nikon::ShotInfoD300S = (
6190
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6191
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6180
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6181
+ WRITE_PROC => \&ProcessNikonEncrypted,
6192
6182
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6193
6183
  VARS => { ID_LABEL => 'Index' },
6194
6184
  IS_SUBDIR => [ 804 ],
@@ -6233,8 +6223,8 @@ my %nikonFocalConversions = (
6233
6223
 
6234
6224
  # shot information for the D700 firmware 1.02f (encrypted) - ref 29
6235
6225
  %Image::ExifTool::Nikon::ShotInfoD700 = (
6236
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6237
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6226
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6227
+ WRITE_PROC => \&ProcessNikonEncrypted,
6238
6228
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6239
6229
  VARS => { ID_LABEL => 'Index' },
6240
6230
  IS_SUBDIR => [ 804 ],
@@ -6279,8 +6269,8 @@ my %nikonFocalConversions = (
6279
6269
 
6280
6270
  # shot information for the D5000 firmware 1.00 (encrypted) - ref PH
6281
6271
  %Image::ExifTool::Nikon::ShotInfoD5000 = (
6282
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6283
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6272
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6273
+ WRITE_PROC => \&ProcessNikonEncrypted,
6284
6274
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6285
6275
  VARS => { ID_LABEL => 'Index' },
6286
6276
  IS_SUBDIR => [ 0x378 ],
@@ -6325,8 +6315,8 @@ my %nikonFocalConversions = (
6325
6315
 
6326
6316
  # shot information for the D5100 firmware 1.00f (encrypted) - ref PH
6327
6317
  %Image::ExifTool::Nikon::ShotInfoD5100 = (
6328
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6329
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6318
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6319
+ WRITE_PROC => \&ProcessNikonEncrypted,
6330
6320
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6331
6321
  VARS => { ID_LABEL => 'Index' },
6332
6322
  IS_SUBDIR => [ 0x407 ],
@@ -6360,8 +6350,8 @@ my %nikonFocalConversions = (
6360
6350
 
6361
6351
  # shot information for the D5200 firmware 1.00 (encrypted) - ref PH
6362
6352
  %Image::ExifTool::Nikon::ShotInfoD5200 = (
6363
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6364
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6353
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6354
+ WRITE_PROC => \&ProcessNikonEncrypted,
6365
6355
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6366
6356
  VARS => { ID_LABEL => 'Index' },
6367
6357
  IS_SUBDIR => [ 0xcd5 ],
@@ -6398,8 +6388,8 @@ my %nikonFocalConversions = (
6398
6388
 
6399
6389
  # shot information for the D7000 firmware 1.01d (encrypted) - ref 29
6400
6390
  %Image::ExifTool::Nikon::ShotInfoD7000 = (
6401
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6402
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6391
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6392
+ WRITE_PROC => \&ProcessNikonEncrypted,
6403
6393
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6404
6394
  VARS => { ID_LABEL => 'Index' },
6405
6395
  IS_SUBDIR => [ 1028 ],
@@ -6443,8 +6433,8 @@ my %nikonFocalConversions = (
6443
6433
 
6444
6434
  # shot information for the D800 firmware 1.01a (encrypted) - ref PH
6445
6435
  %Image::ExifTool::Nikon::ShotInfoD800 = (
6446
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6447
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6436
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6437
+ WRITE_PROC => \&ProcessNikonEncrypted,
6448
6438
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
6449
6439
  VARS => { ID_LABEL => 'Index' },
6450
6440
  IS_SUBDIR => [ 0x6ec ],
@@ -6564,15 +6554,13 @@ my %nikonFocalConversions = (
6564
6554
 
6565
6555
  # shot information for the D5 firmware 1.10a and D500 firmware 1.01 (encrypted) - ref 28
6566
6556
  %Image::ExifTool::Nikon::ShotInfoD500 = (
6567
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6568
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
6557
+ PROCESS_PROC => \&ProcessNikonEncrypted,
6558
+ WRITE_PROC => \&ProcessNikonEncrypted,
6569
6559
  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 ],
6560
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
6561
+ DATAMEMBER => [ 0x04 ],
6562
+ IS_SUBDIR => [ 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8 ],
6574
6563
  WRITABLE => 1,
6575
- FIRST_ENTRY => 0,
6576
6564
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6577
6565
  NOTES => 'These tags are extracted from encrypted data in images from the D5 and D500.',
6578
6566
  0x00 => {
@@ -6589,73 +6577,66 @@ my %nikonFocalConversions = (
6589
6577
  },
6590
6578
  0x10 => {
6591
6579
  Name => 'RotationInfoOffset',
6592
- DataMember => 'RotationInfoOffset',
6593
6580
  Format => 'int32u',
6594
- Writable => 0,
6595
- Hidden => 1,
6596
- RawConv => '$$self{RotationInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6581
+ SubDirectory => {
6582
+ TagTable => 'Image::ExifTool::Nikon::RotationInfoD500',
6583
+ Start => '$val',
6584
+ }
6597
6585
  },
6598
6586
  0x14 => {
6599
6587
  Name => 'JPGInfoOffset',
6600
- DataMember => 'JPGInfoOffset',
6601
6588
  Format => 'int32u',
6602
- Writable => 0,
6603
- Hidden => 1,
6604
- RawConv => '$$self{JPGInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6589
+ SubDirectory => {
6590
+ TagTable => 'Image::ExifTool::Nikon::JPGInfoD500',
6591
+ Start => '$val',
6592
+ }
6605
6593
  },
6606
6594
  0x2c => {
6607
- Name => 'BracketingInfoOffset',
6608
- DataMember => 'BracketingInfoOffset',
6595
+ Name => 'BracketingOffset',
6609
6596
  Format => 'int32u',
6610
- Writable => 0,
6611
- Hidden => 1,
6612
- RawConv => '$$self{BracketingInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
6597
+ SubDirectory => {
6598
+ TagTable => 'Image::ExifTool::Nikon::BracketingInfoD500',
6599
+ Start => '$val',
6600
+ }
6613
6601
  },
6614
6602
  0x50 => {
6615
6603
  Name => 'ShootingMenuOffset',
6616
- DataMember => 'ShootingMenuOffset',
6617
6604
  Format => 'int32u',
6618
- Writable => 0,
6619
- Hidden => 1,
6620
- RawConv => '$$self{ShootingMenuOffset} = $val || 0x10000000; undef', # (ignore if 0)
6605
+ SubDirectory => {
6606
+ TagTable => 'Image::ExifTool::Nikon::ShootingMenuD500',
6607
+ Start => '$val',
6608
+ }
6621
6609
  },
6622
6610
  0x58 => {
6623
6611
  Name => 'CustomSettingsOffset',
6624
- DataMember => 'CustomSettingsOffset',
6625
6612
  Format => 'int32u',
6626
- Writable => 0,
6627
- Hidden => 1,
6628
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef', # (ignore if 0)
6613
+ SubDirectory => {
6614
+ TagTable => 'Image::ExifTool::Nikon::CustomSettingsD500',
6615
+ Start => '$val',
6616
+ }
6629
6617
  },
6630
6618
  0xa0 => {
6631
6619
  Name => 'OrientationOffset',
6632
- DataMember => 'OrientationOffset',
6633
6620
  Format => 'int32u',
6634
- Writable => 0,
6635
- Hidden => 1,
6636
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
6621
+ SubDirectory => {
6622
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
6623
+ Start => '$val',
6624
+ }
6637
6625
  },
6638
6626
  0xa8 => {
6639
6627
  Name => 'OtherOffset',
6640
- DataMember => 'OtherOffset',
6641
6628
  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',
6629
+ SubDirectory => {
6630
+ TagTable => 'Image::ExifTool::Nikon::OtherInfoD500',
6631
+ Start => '$val',
6632
+ }
6657
6633
  },
6658
- 0xca => {
6634
+ );
6635
+
6636
+ %Image::ExifTool::Nikon::RotationInfoD500 = (
6637
+ %binaryDataAttrs,
6638
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6639
+ 0x1a => {
6659
6640
  Name => 'Rotation',
6660
6641
  Mask => 0x03,
6661
6642
  PrintConv => {
@@ -6665,32 +6646,29 @@ my %nikonFocalConversions = (
6665
6646
  3 => 'Rotate 180',
6666
6647
  },
6667
6648
  },
6668
- 0x0d0 => {
6649
+ 0x20 => {
6669
6650
  Name => 'Interval',
6670
6651
  # prior version of the d% firmware do not support this tag, nor does the D500 (at least thru firmware 1.3)
6671
6652
  Condition => '$$self{Model} eq "NIKON D5" and $$self{FirmwareVersion} ge "1.40"',
6672
6653
  PrintConv => '$val > 0 ? sprintf("%.0f", $val) : ""',
6673
6654
  },
6674
- 0x0d4 => {
6655
+ 0x24 => {
6675
6656
  Name => 'IntervalFrame',
6676
6657
  # prior version of the d% firmware do not support this tag, nor does the D500 (at least thru firmware 1.3)
6677
6658
  Condition => '$$self{Model} eq "NIKON D5" and $$self{FirmwareVersion} ge "1.40"',
6678
6659
  PrintConv => '$val > 0 ? sprintf("%.0f", $val) : ""',
6679
6660
  },
6680
- 0x05e2 => {
6661
+ 0x0532 => {
6681
6662
  Name => 'FlickerReductionIndicator',
6682
6663
  Mask => 0x01,
6683
6664
  PrintConv => { 0 => 'On', 1 => 'Off' },
6684
6665
  },
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 => {
6666
+ );
6667
+
6668
+ %Image::ExifTool::Nikon::JPGInfoD500 = (
6669
+ %binaryDataAttrs,
6670
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6671
+ 0x24 => {
6694
6672
  Name => 'JPGCompression',
6695
6673
  Mask => 0x01,
6696
6674
  PrintConv => {
@@ -6698,16 +6676,12 @@ my %nikonFocalConversions = (
6698
6676
  1 => 'Optimal Quality',
6699
6677
  },
6700
6678
  },
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 => {
6679
+ );
6680
+
6681
+ %Image::ExifTool::Nikon::BracketingInfoD500 = (
6682
+ %binaryDataAttrs,
6683
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6684
+ 0x0f => {
6711
6685
  Name => 'AEBracketingSteps',
6712
6686
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
6713
6687
  Mask => 0xff,
@@ -6765,7 +6739,7 @@ my %nikonFocalConversions = (
6765
6739
  0xd6 => '5F3',
6766
6740
  },
6767
6741
  },
6768
- 0x087c => {
6742
+ 0x10 => {
6769
6743
  Name => 'WBBracketingSteps',
6770
6744
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
6771
6745
  Mask => 0xff,
@@ -6808,7 +6782,7 @@ my %nikonFocalConversions = (
6808
6782
  0x28 => '9F 3',
6809
6783
  },
6810
6784
  },
6811
- 0x0883 => {
6785
+ 0x17 => {
6812
6786
  Name => 'ADLBracketingStep',
6813
6787
  Mask => 0xf0,
6814
6788
  PrintConv => {
@@ -6820,7 +6794,7 @@ my %nikonFocalConversions = (
6820
6794
  8 => 'Auto',
6821
6795
  },
6822
6796
  },
6823
- 0x0884 => {
6797
+ 0x18 => {
6824
6798
  Name => 'ADLBracketingType',
6825
6799
  Mask => 0x0f,
6826
6800
  PrintConv => {
@@ -6831,23 +6805,12 @@ my %nikonFocalConversions = (
6831
6805
  4 => '5 Shots',
6832
6806
  },
6833
6807
  },
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 => {
6808
+ );
6809
+
6810
+ %Image::ExifTool::Nikon::ShootingMenuD500 = (
6811
+ %binaryDataAttrs,
6812
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6813
+ 0x00 => {
6851
6814
  Name => 'PhotoShootingMenuBank',
6852
6815
  Mask => 0x03,
6853
6816
  PrintConv => {
@@ -6857,7 +6820,7 @@ my %nikonFocalConversions = (
6857
6820
  3 => 'D',
6858
6821
  },
6859
6822
  },
6860
- 0x0e7f => {
6823
+ 0x02 => {
6861
6824
  Name => 'PrimarySlot',
6862
6825
  Condition => '$$self{Model} =~ /\bD500\b/',
6863
6826
  Notes => 'D500 only',
@@ -6867,7 +6830,7 @@ my %nikonFocalConversions = (
6867
6830
  1 => 'SD Card',
6868
6831
  },
6869
6832
  },
6870
- 0x0e81 => {
6833
+ 0x04 => {
6871
6834
  Name => 'ISOAutoShutterTime',
6872
6835
  Mask => 0x3f,
6873
6836
  PrintConv => {
@@ -6910,7 +6873,7 @@ my %nikonFocalConversions = (
6910
6873
  36 => 'Auto (Fastest)',
6911
6874
  },
6912
6875
  },
6913
- 0x0e82 => {
6876
+ 0x05 => {
6914
6877
  Name => 'ISOAutoHiLimit',
6915
6878
  Mask => 0xff,
6916
6879
  PrintHex => 1,
@@ -6958,7 +6921,7 @@ my %nikonFocalConversions = (
6958
6921
  0x72 => 'ISO Hi 5.0',
6959
6922
  },
6960
6923
  },
6961
- 0x0e84 => {
6924
+ 0x07 => {
6962
6925
  Name => 'FlickerReduction',
6963
6926
  Mask => 0x20,
6964
6927
  PrintConv => {
@@ -6966,7 +6929,7 @@ my %nikonFocalConversions = (
6966
6929
  1 => 'Disable',
6967
6930
  },
6968
6931
  },
6969
- 3716.1 => { # (0x0e84)
6932
+ 7.1 => {
6970
6933
  Name => 'PhotoShootingMenuBankImageArea',
6971
6934
  Mask => 0x07,
6972
6935
  PrintConv => {
@@ -6977,16 +6940,14 @@ my %nikonFocalConversions = (
6977
6940
  4 => '1.3x (18x12)',
6978
6941
  },
6979
6942
  },
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 => [{
6943
+ );
6944
+
6945
+ %Image::ExifTool::Nikon::CustomSettingsD500 = (
6946
+ %binaryDataAttrs,
6947
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
6948
+ IS_SUBDIR => [ 0x00 ],
6949
+ VARS => { ALLOW_REPROCESS => 1 }, # (necessary because subdirectory is at offset 0)
6950
+ 0x00 => [{
6990
6951
  Name => 'CustomSettingsD5',
6991
6952
  Condition => '$$self{Model} =~ /\bD5\b/',
6992
6953
  Format => 'undef[90]',
@@ -7000,7 +6961,7 @@ my %nikonFocalConversions = (
7000
6961
  TagTable => 'Image::ExifTool::NikonCustom::SettingsD500',
7001
6962
  },
7002
6963
  }],
7003
- # 0x0f68 => { #this decode works, but involves more bits than should be necessary
6964
+ # 0x7d => { #this decode works, but involves more bits than should be necessary
7004
6965
  # Name => 'ShutterTrigger',
7005
6966
  # Mask => 0xff,
7006
6967
  # PrintConv => {
@@ -7009,51 +6970,13 @@ my %nikonFocalConversions = (
7009
6970
  # 195 => 'Shutter Button',
7010
6971
  # },
7011
6972
  # },
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
- },
6973
+ );
6974
+
6975
+ %Image::ExifTool::Nikon::OtherInfoD500 = (
6976
+ %binaryDataAttrs,
6977
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7055
6978
  # (needs testing)
7056
- #0x2cb2 => {
6979
+ #0x22 => {
7057
6980
  # Name => 'ExtendedPhotoShootingBanks',
7058
6981
  # Mask => 0x01,
7059
6982
  # PrintConv => {
@@ -7062,7 +6985,7 @@ my %nikonFocalConversions = (
7062
6985
  # },
7063
6986
  #},
7064
6987
  # (may not be reliable and is found elsewhere)
7065
- #0x2ea2 => {
6988
+ #0x212 => {
7066
6989
  # Name => 'Rotation',
7067
6990
  # Condition => '$$self{Model} =~ /\bD500\b/',
7068
6991
  # Notes => 'D500 firmware 1.1x',
@@ -7074,7 +6997,7 @@ my %nikonFocalConversions = (
7074
6997
  # 3 => 'Rotate 180',
7075
6998
  # },
7076
6999
  #},
7077
- 0x2ea4 => { #PH
7000
+ 0x214 => { #PH
7078
7001
  Name => 'NikonMeteringMode',
7079
7002
  Condition => '$$self{Model} =~ /\bD500\b/', # (didn't seem to work for D5, but I need more samples)
7080
7003
  Notes => 'D500 only',
@@ -7091,13 +7014,12 @@ my %nikonFocalConversions = (
7091
7014
 
7092
7015
  # shot information for the D6 firmware 1.00 (encrypted) - ref 28
7093
7016
  %Image::ExifTool::Nikon::ShotInfoD6 = (
7094
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7095
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7017
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7018
+ WRITE_PROC => \&ProcessNikonEncrypted,
7096
7019
  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 ],
7020
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
7021
+ IS_SUBDIR => [ 0x30, 0x9c, 0xa4 ],
7099
7022
  WRITABLE => 1,
7100
- FIRST_ENTRY => 0,
7101
7023
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7102
7024
  NOTES => 'These tags are extracted from encrypted data in images from the D6.',
7103
7025
  0x00 => {
@@ -7112,159 +7034,111 @@ my %nikonFocalConversions = (
7112
7034
  },
7113
7035
  0x24 => {
7114
7036
  Name => 'NumberOffsets', # (number of entries in offset table. offsets are from start of ShotInfo data)
7115
- DataMember => 'NumberOffsets',
7116
7037
  Format => 'int32u',
7117
7038
  Writable => 0,
7118
7039
  Hidden => 1,
7119
7040
  },
7120
7041
  0x30 => {
7121
- Name => 'Offset3',
7122
- DataMember => 'Offset3',
7123
- 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',
7042
+ Name => 'SequenceOffset',
7131
7043
  Format => 'int32u',
7132
- Writable => 0,
7133
- Hidden => 1,
7134
- RawConv => '$$self{Offset15} = $val || 0x10000000; undef', # (ignore if 0)
7044
+ SubDirectory => {
7045
+ TagTable => 'Image::ExifTool::Nikon::SeqInfoD6',
7046
+ Start => '$val',
7047
+ },
7135
7048
  },
7136
7049
  0x9c => {
7137
7050
  Name => 'OrientationOffset',
7138
- DataMember => 'OrientationOffset',
7139
7051
  Format => 'int32u',
7140
- Writable => 0,
7141
- Hidden => 1,
7142
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
7052
+ SubDirectory => {
7053
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7054
+ Start => '$val',
7055
+ },
7143
7056
  },
7144
7057
  0xa4 => {
7145
- Name => 'Offset32',
7146
- DataMember => 'Offset32',
7058
+ Name => 'IntervalOffset',
7147
7059
  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',
7060
+ SubDirectory => {
7061
+ TagTable => 'Image::ExifTool::Nikon::IntervalInfoD6',
7062
+ Start => '$val',
7063
+ }
7159
7064
  },
7160
- 0x760c => {
7065
+ );
7066
+
7067
+ %Image::ExifTool::Nikon::SeqInfoD6 = (
7068
+ %binaryDataAttrs,
7069
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7070
+ DATAMEMBER => [ 0x24, 0x28 ],
7071
+ 0x24 => {
7161
7072
  Name => 'IntervalShooting',
7162
7073
  RawConv => '$$self{IntervalShooting} = $val',
7163
7074
  Format => 'int16u',
7164
7075
  PrintConv => q{
7165
7076
  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
7077
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); #something like "Interval 1 of 3"
7078
+ 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
7079
  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}),
7080
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
7170
7081
  },
7171
7082
  },
7172
- 0x7610 => {
7083
+ 0x28 => {
7173
7084
  Name => 'IntervalFrame',
7174
7085
  RawConv => '$$self{IntervalFrame} = $val',
7175
7086
  Condition => '$$self{IntervalShooting} > 0',
7176
7087
  Format => 'int16u',
7177
7088
  Hidden => 1,
7178
7089
  },
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 => {
7090
+ );
7091
+
7092
+ %Image::ExifTool::Nikon::IntervalInfoD6 = (
7093
+ %binaryDataAttrs,
7094
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7095
+ DATAMEMBER => [ 0x17c, 0x180, 0x214, 0x22c ],
7096
+ 0x17c => {
7223
7097
  Name => 'Intervals',
7224
7098
  Format => 'int32u',
7225
7099
  RawConv => '$$self{IntervalShootingIntervals} = $val',
7226
7100
  Condition => '$$self{IntervalShooting} > 0',
7227
7101
  },
7228
- 0xc412 => {
7102
+ 0x180 => {
7229
7103
  Name => 'ShotsPerInterval',
7230
7104
  Format => 'int32u',
7231
7105
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
7232
7106
  Condition => '$$self{IntervalShooting} > 0',
7233
7107
  },
7234
- 0xc416 => {
7108
+ 0x184 => {
7235
7109
  Name => 'IntervalExposureSmoothing',
7236
7110
  Condition => '$$self{IntervalShooting} > 0',
7237
7111
  Format => 'int8u',
7238
7112
  PrintConv => \%offOn,
7239
7113
  },
7240
- 0xc418 => {
7114
+ 0x186 => {
7241
7115
  Name => 'IntervalPriority',
7242
7116
  Condition => '$$self{IntervalShooting} > 0',
7243
7117
  Format => 'int8u',
7244
7118
  PrintConv => \%offOn,
7245
7119
  },
7246
- 0xc43a => {
7120
+ 0x1a8 => {
7247
7121
  Name => 'FocusShiftNumberShots',
7248
7122
  },
7249
- 0xc43e => {
7123
+ 0x1ac => {
7250
7124
  Name => 'FocusShiftStepWidth',
7251
7125
  },
7252
- 0xc442 => {
7126
+ 0x1b0 => {
7253
7127
  Name => 'FocusShiftInterval',
7254
7128
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
7255
7129
  },
7256
- 0xc446 => {
7130
+ 0x1b4 => {
7257
7131
  Name => 'FocusShiftExposureLock',
7258
7132
  PrintConv => \%offOn,
7259
7133
  },
7260
- #0xc49c => HighISONoiseReduction
7261
- 0xc4a0 => {
7134
+ #0x20a => HighISONoiseReduction
7135
+ 0x20e => {
7262
7136
  Name => 'DiffractionCompensation',
7263
7137
  Format => 'int8u',
7264
7138
  PrintConv => \%offOn,
7265
7139
  },
7266
- #0xc4a1 => {Name => 'FlickerReductionShooting',}, #redundant with tag in NikonSettings
7267
- 0xc4a6 => {
7140
+ #0x20f => {Name => 'FlickerReductionShooting',}, #redundant with tag in NikonSettings
7141
+ 0x214 => {
7268
7142
  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
7143
  RawConv => '$$self{FlashControlMode} = $val',
7270
7144
  PrintConv => {
@@ -7275,14 +7149,14 @@ my %nikonFocalConversions = (
7275
7149
  4 => 'Repeating Flash',
7276
7150
  },
7277
7151
  },
7278
- 0xc4ac => {
7152
+ 0x21a => {
7279
7153
  Name => 'FlashGNDistance',
7280
7154
  Condition => '$$self{FlashControlMode} == 2',
7281
7155
  Unknown => 1,
7282
7156
  ValueConv => '$val + 3',
7283
7157
  PrintConv => \%flashGNDistance,
7284
7158
  },
7285
- 0xc4b0 => {
7159
+ 0x21e => {
7286
7160
  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
7161
  Condition => '$$self{FlashControlMode} >= 3',
7288
7162
  Unknown => 1,
@@ -7291,7 +7165,7 @@ my %nikonFocalConversions = (
7291
7165
  PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
7292
7166
  PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
7293
7167
  },
7294
- 0xc4ba => {
7168
+ 0x228 => {
7295
7169
  Name => 'FlashRemoteControl',
7296
7170
  Unknown => 1,
7297
7171
  PrintConv => {
@@ -7300,12 +7174,12 @@ my %nikonFocalConversions = (
7300
7174
  2 => 'Remote Repeating',
7301
7175
  },
7302
7176
  },
7303
- 0xc4be => {
7177
+ 0x22c => {
7304
7178
  Name => 'FlashMasterControlMode', #tag name chosen for compatibility with those found in FlashInfo0102 & FlashInfo0103
7305
7179
  RawConv => '$$self{FlashGroupOptionsMasterMode} = $val',
7306
7180
  PrintConv => \%flashGroupOptionsMode,
7307
7181
  },
7308
- 0xc4c0 => {
7182
+ 0x22e => {
7309
7183
  Name => 'FlashMasterCompensation',
7310
7184
  Unknown => 1,
7311
7185
  Format => 'int8s',
@@ -7315,7 +7189,7 @@ my %nikonFocalConversions = (
7315
7189
  PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
7316
7190
  PrintConvInv => '$val',
7317
7191
  },
7318
- 0xc4c4 => {
7192
+ 0x232 => {
7319
7193
  Name => 'FlashMasterOutput',
7320
7194
  Unknown => 1,
7321
7195
  Condition => '$$self{FlashGroupOptionsMasterMode} == 1', #only for Mode=M
@@ -7324,7 +7198,7 @@ my %nikonFocalConversions = (
7324
7198
  PrintConv => '$val>0.99 ? "Full" : sprintf("%.1f%%",$val*100)',
7325
7199
  PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
7326
7200
  },
7327
- 0xc4c6 => {
7201
+ 0x234 => {
7328
7202
  Name => 'FlashWirelessOption',
7329
7203
  Unknown => 1,
7330
7204
  PrintConv => {
@@ -7332,7 +7206,7 @@ my %nikonFocalConversions = (
7332
7206
  1 => 'Off',
7333
7207
  },
7334
7208
  },
7335
- 0xc55c => {
7209
+ 0x2ca => {
7336
7210
  Name => 'MovieType',
7337
7211
  Unknown => 1,
7338
7212
  PrintConv => {
@@ -7340,13 +7214,12 @@ my %nikonFocalConversions = (
7340
7214
  1 => 'MP4',
7341
7215
  },
7342
7216
  },
7343
- # note: DecryptLen currently set to 0xc9c6 + 720
7344
7217
  );
7345
7218
 
7346
7219
  # shot information for the D610 firmware 1.00 (encrypted) - ref PH
7347
7220
  %Image::ExifTool::Nikon::ShotInfoD610 = (
7348
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7349
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7221
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7222
+ WRITE_PROC => \&ProcessNikonEncrypted,
7350
7223
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7351
7224
  VARS => { ID_LABEL => 'Index' },
7352
7225
  IS_SUBDIR => [ 0x07cf ],
@@ -7376,20 +7249,15 @@ my %nikonFocalConversions = (
7376
7249
 
7377
7250
  # shot information for the D810 firmware 1.00(PH)/1.01 (encrypted) - ref 28
7378
7251
  %Image::ExifTool::Nikon::ShotInfoD810 = (
7379
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7380
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7252
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7253
+ WRITE_PROC => \&ProcessNikonEncrypted,
7381
7254
  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 ],
7255
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
7256
+ DATAMEMBER => [ 0x04 ],
7257
+ IS_SUBDIR => [ 0x10, 0x24, 0x38, 0x40, 0x84 ],
7385
7258
  WRITABLE => 1,
7386
- FIRST_ENTRY => 0,
7387
7259
  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
- },
7260
+ NOTES => 'These tags are extracted from encrypted data in images from the D810.',
7393
7261
  0x00 => {
7394
7262
  Name => 'ShotInfoVersion',
7395
7263
  Format => 'string[4]',
@@ -7404,39 +7272,64 @@ my %nikonFocalConversions = (
7404
7272
  },
7405
7273
  # 0x0c - number of entries in offset table (= 0x21)
7406
7274
  # 0x10 - int32u[val 0x0c]: offset table
7275
+ 0x10 => {
7276
+ Name => 'SettingsOffset',
7277
+ Format => 'int32u',
7278
+ SubDirectory => {
7279
+ TagTable => 'Image::ExifTool::Nikon::SettingsInfoD810',
7280
+ Start => '$val',
7281
+ },
7282
+ },
7407
7283
  0x24 => {
7408
7284
  Name => 'BracketingOffset',
7409
- DataMember => 'BracketingOffset',
7410
7285
  Format => 'int32u',
7411
- Writable => 0,
7412
- Hidden => 1,
7413
- RawConv => '$$self{BracketingOffset} = $val || 0x10000000; undef',
7286
+ SubDirectory => {
7287
+ TagTable => 'Image::ExifTool::Nikon::BracketingInfoD810',
7288
+ Start => '$val',
7289
+ },
7414
7290
  },
7415
7291
  0x38 => {
7416
7292
  Name => 'ISOAutoOffset',
7417
- DataMember => 'ISOAutoOffset',
7418
7293
  Format => 'int32u',
7419
- Writable => 0,
7420
- Hidden => 1,
7421
- RawConv => '$$self{ISOAutoOffset} = $val || 0x10000000; undef',
7294
+ SubDirectory => {
7295
+ TagTable => 'Image::ExifTool::Nikon::ISOAutoInfoD810',
7296
+ Start => '$val',
7297
+ },
7422
7298
  },
7423
7299
  0x40 => {
7424
7300
  Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
7425
- DataMember => 'CustomSettingsOffset',
7426
7301
  Format => 'int32u',
7427
- Writable => 0,
7428
- Hidden => 1,
7429
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
7302
+ SubDirectory => {
7303
+ TagTable => 'Image::ExifTool::NikonCustom::SettingsD810',
7304
+ Start => '$val',
7305
+ },
7430
7306
  },
7431
7307
  0x84 => {
7432
7308
  Name => 'OrientationOffset',
7433
- DataMember => 'OrientationOffset',
7434
7309
  Format => 'int32u',
7435
- Writable => 0,
7436
- Hidden => 1,
7437
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
7310
+ SubDirectory => {
7311
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7312
+ Start => '$val',
7313
+ }
7438
7314
  },
7439
- 0x01d0 => {
7315
+ # (moves around too much and doesn't fit cleanly in the offset table)
7316
+ #0x38be => {
7317
+ # Name => 'Rotation',
7318
+ # Condition => '$$self{FirmwareVersion} =~ /^1\.0/',
7319
+ # Mask => 0x30,
7320
+ # PrintConv => {
7321
+ # 0 => 'Horizontal',
7322
+ # 1 => 'Rotate 270 CW',
7323
+ # 2 => 'Rotate 90 CW',
7324
+ # 3 => 'Rotate 180',
7325
+ # },
7326
+ #},
7327
+ );
7328
+
7329
+ %Image::ExifTool::Nikon::SettingsInfoD810 = (
7330
+ %binaryDataAttrs,
7331
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7332
+ 0x13c => {
7440
7333
  Name => 'SecondarySlotFunction',
7441
7334
  Mask => 0x03,
7442
7335
  PrintConv => {
@@ -7444,9 +7337,13 @@ my %nikonFocalConversions = (
7444
7337
  2 => 'Backup',
7445
7338
  3 => 'NEF Primary + JPG Secondary',
7446
7339
  },
7447
- Hook => '$varSize = $$self{BracketingOffset} - 0x1747',
7448
7340
  },
7449
- 0x1756 => {
7341
+ );
7342
+
7343
+ %Image::ExifTool::Nikon::BracketingInfoD810 = (
7344
+ %binaryDataAttrs,
7345
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7346
+ 0x0f => {
7450
7347
  Name => 'AEBracketingSteps',
7451
7348
  Mask => 0xff,
7452
7349
  PrintHex => 1,
@@ -7503,7 +7400,7 @@ my %nikonFocalConversions = (
7503
7400
  0xd6 => '5F3',
7504
7401
  },
7505
7402
  },
7506
- 0x1757 => {
7403
+ 0x10 => {
7507
7404
  Name => 'WBBracketingSteps',
7508
7405
  Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
7509
7406
  Mask => 0xff,
@@ -7546,7 +7443,7 @@ my %nikonFocalConversions = (
7546
7443
  0x28 => '9F 3',
7547
7444
  },
7548
7445
  },
7549
- 0x175e => {
7446
+ 0x17 => {
7550
7447
  Name => 'NikonMeteringMode',
7551
7448
  Mask => 0x03,
7552
7449
  PrintConv => {
@@ -7555,9 +7452,13 @@ my %nikonFocalConversions = (
7555
7452
  2 => 'Spot',
7556
7453
  3 => 'Highlight'
7557
7454
  },
7558
- Hook => '$varSize = $$self{ISOAutoOffset} - 0x1858',
7559
7455
  },
7560
- 0x185c => {
7456
+ );
7457
+
7458
+ %Image::ExifTool::Nikon::ISOAutoInfoD810 = (
7459
+ %binaryDataAttrs,
7460
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7461
+ 0x04 => {
7561
7462
  Name => 'ISOAutoShutterTime',
7562
7463
  Mask => 0x3f,
7563
7464
  PrintConv => {
@@ -7600,7 +7501,7 @@ my %nikonFocalConversions = (
7600
7501
  36 => 'Auto (Fastest)',
7601
7502
  },
7602
7503
  },
7603
- 0x185d => {
7504
+ 0x05 => {
7604
7505
  Name => 'ISOAutoHiLimit',
7605
7506
  Mask => 0xff,
7606
7507
  PrintHex => 1,
@@ -7647,69 +7548,18 @@ my %nikonFocalConversions = (
7647
7548
  0x6c => 'ISO Hi 4.0',
7648
7549
  0x72 => 'ISO Hi 5.0',
7649
7550
  },
7650
- Hook => '$varSize = $$self{CustomSettingsOffset} - 0x18ab',
7651
- },
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
7551
  },
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
7552
  );
7702
7553
 
7703
7554
  # shot information for the D850 firmware 1.00b (encrypted) - ref 28
7704
7555
  %Image::ExifTool::Nikon::ShotInfoD850 = (
7705
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7706
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7556
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7557
+ WRITE_PROC => \&ProcessNikonEncrypted,
7707
7558
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7708
- VARS => { ID_LABEL => 'Index' },
7709
- DATAMEMBER => [ 0x04, 0x58, 0xa0, 0x0fbf, 0x2efa ],
7710
- IS_SUBDIR => [ 0x1038 ],
7559
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x0c },
7560
+ DATAMEMBER => [ 0x04 ],
7561
+ IS_SUBDIR => [ 0x10, 0x4c, 0x58, 0xa0 ],
7711
7562
  WRITABLE => 1,
7712
- FIRST_ENTRY => 0,
7713
7563
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7714
7564
  NOTES => 'These tags are extracted from encrypted data in images from the D850.',
7715
7565
  0x00 => {
@@ -7724,23 +7574,44 @@ my %nikonFocalConversions = (
7724
7574
  Writable => 0,
7725
7575
  RawConv => '$$self{FirmwareVersion} = $val',
7726
7576
  },
7577
+ 0x10 => {
7578
+ Name => 'MenuSettingsOffset',
7579
+ Format => 'int32u',
7580
+ SubDirectory => {
7581
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsD850',
7582
+ Start => '$val',
7583
+ },
7584
+ },
7585
+ 0x4c => {
7586
+ Name => 'MoreSettingsOffset',
7587
+ Format => 'int32u',
7588
+ SubDirectory => {
7589
+ TagTable => 'Image::ExifTool::Nikon::MoreSettingsD850',
7590
+ Start => '$val',
7591
+ },
7592
+ },
7727
7593
  0x58 => {
7728
- Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
7729
- DataMember => 'CustomSettingsOffset',
7594
+ Name => 'CustomSettingsOffset',
7730
7595
  Format => 'int32u',
7731
- Writable => 0,
7732
- Hidden => 1,
7733
- RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
7596
+ SubDirectory => {
7597
+ TagTable => 'Image::ExifTool::NikonCustom::SettingsD850',
7598
+ Start => '$val',
7599
+ },
7734
7600
  },
7735
7601
  0xa0 => {
7736
7602
  Name => 'OrientationOffset',
7737
- DataMember => 'OrientationOffset',
7738
7603
  Format => 'int32u',
7739
- Writable => 0,
7740
- Hidden => 1,
7741
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
7604
+ SubDirectory => {
7605
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7606
+ Start => '$val',
7607
+ },
7742
7608
  },
7743
- 0x0791 => {
7609
+ );
7610
+
7611
+ %Image::ExifTool::Nikon::MenuSettingsD850 = (
7612
+ %binaryDataAttrs,
7613
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7614
+ 0x06dd => {
7744
7615
  Name => 'PhotoShootingMenuBankImageArea',
7745
7616
  Mask => 0x07,
7746
7617
  PrintConv => {
@@ -7751,7 +7622,12 @@ my %nikonFocalConversions = (
7751
7622
  4 => '1:1 (24x24)',
7752
7623
  },
7753
7624
  },
7754
- 0x0fbd => {
7625
+ );
7626
+
7627
+ %Image::ExifTool::Nikon::MoreSettingsD850 = (
7628
+ %binaryDataAttrs,
7629
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
7630
+ 0x24 => {
7755
7631
  Name => 'PhotoShootingMenuBank',
7756
7632
  Condition => '$$self{FILE_TYPE} eq "JPEG"',
7757
7633
  Notes => 'valid for JPEG images only',
@@ -7763,63 +7639,20 @@ my %nikonFocalConversions = (
7763
7639
  3 => 'D',
7764
7640
  },
7765
7641
  },
7766
- 0x0fbf => {
7642
+ 0x25 => {
7767
7643
  Name => 'PrimarySlot',
7768
7644
  Mask => 0x80,
7769
7645
  PrintConv => {
7770
7646
  0 => 'XQD Card',
7771
7647
  1 => 'SD Card',
7772
7648
  },
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
- },
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
7649
  },
7817
- # note: DecryptLen currently set to 0x2f07
7818
7650
  );
7651
+
7819
7652
  # shot information for the D4 firmware 1.00g (ref PH)
7820
7653
  %Image::ExifTool::Nikon::ShotInfoD4 = (
7821
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7822
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7654
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7655
+ WRITE_PROC => \&ProcessNikonEncrypted,
7823
7656
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7824
7657
  VARS => { ID_LABEL => 'Index' },
7825
7658
  IS_SUBDIR => [ 0x0751 ],
@@ -7850,12 +7683,12 @@ my %nikonFocalConversions = (
7850
7683
 
7851
7684
  # shot information for the D4S firmware 1.01a (ref 28, encrypted)
7852
7685
  %Image::ExifTool::Nikon::ShotInfoD4S = (
7853
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7854
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7686
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7687
+ WRITE_PROC => \&ProcessNikonEncrypted,
7855
7688
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7856
7689
  VARS => { ID_LABEL => 'Index' },
7857
7690
  DATAMEMBER => [ 4 ],
7858
- IS_SUBDIR => [ 0x189d, 0x193d ],
7691
+ IS_SUBDIR => [ 0x189d, 0x193d, 0x350b ],
7859
7692
  WRITABLE => 1,
7860
7693
  FIRST_ENTRY => 0,
7861
7694
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
@@ -8119,31 +7952,13 @@ my %nikonFocalConversions = (
8119
7952
  # },
8120
7953
  # },
8121
7954
  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',
7955
+ Name => 'OrientationInfo',
7956
+ Format => 'undef[12]',
7957
+ SubDirectory => {
7958
+ # Note: pitch angle may be wrong sign for this model?
7959
+ # (pitch sign was changed without verification to use same decoding as other models)
7960
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
7961
+ },
8147
7962
  },
8148
7963
  0x3693 => {
8149
7964
  Name => 'Rotation',
@@ -8160,15 +7975,13 @@ my %nikonFocalConversions = (
8160
7975
 
8161
7976
  # shot information for the Z7II firmware 1.00 (encrypted) - ref 28
8162
7977
  %Image::ExifTool::Nikon::ShotInfoZ7II = (
8163
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8164
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
7978
+ PROCESS_PROC => \&ProcessNikonEncrypted,
7979
+ WRITE_PROC => \&ProcessNikonEncrypted,
8165
7980
  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 ],
7981
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
7982
+ DATAMEMBER => [ 0x04 ],
7983
+ IS_SUBDIR => [ 0x30, 0x38, 0x98, 0xa0 ],
8170
7984
  WRITABLE => 1,
8171
- FIRST_ENTRY => 0,
8172
7985
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8173
7986
  NOTES => 'These tags are extracted from encrypted data in images from the Z7II.',
8174
7987
  0x00 => {
@@ -8197,79 +8010,73 @@ my %nikonFocalConversions = (
8197
8010
  },
8198
8011
  0x24 => {
8199
8012
  Name => 'NumberOffsets', # number of entries in offset table. offsets are from start of ShotInfo data.
8200
- DataMember => 'NumberOffsets',
8201
8013
  Format => 'int32u',
8202
8014
  Writable => 0,
8203
8015
  Hidden => 1,
8204
8016
  },
8205
8017
  0x30 => {
8206
- Name => 'Offset3',
8207
- DataMember => 'Offset3',
8018
+ Name => 'IntervalOffset',
8208
8019
  Format => 'int32u',
8209
- Writable => 0,
8210
- Hidden => 1,
8211
- RawConv => '$$self{Offset3} = $val || 0x10000000; undef', # (ignore if 0)
8020
+ SubDirectory => {
8021
+ TagTable => 'Image::ExifTool::Nikon::IntervalInfoZ7II',
8022
+ Start => '$val',
8023
+ }
8212
8024
  },
8213
8025
  0x38 => {
8214
- Name => 'Offset5',
8215
- DataMember => 'Offset5',
8026
+ Name => 'PortraitOffset',
8216
8027
  Format => 'int32u',
8217
- Writable => 0,
8218
- Hidden => 1,
8219
- RawConv => '$$self{Offset5} = $val || 0x10000000; undef', # (ignore if 0)
8028
+ SubDirectory => {
8029
+ TagTable => 'Image::ExifTool::Nikon::PortraitInfoZ7II',
8030
+ Start => '$val',
8031
+ }
8220
8032
  },
8221
8033
  0x98 => {
8222
8034
  Name => 'OrientationOffset',
8223
- DataMember => 'OrientationOffset',
8224
8035
  Format => 'int32u',
8225
- Writable => 0,
8226
- Hidden => 1,
8227
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
8036
+ SubDirectory => {
8037
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8038
+ Start => '$val',
8039
+ }
8228
8040
  },
8229
8041
  0xa0 => {
8230
- Name => 'Offset31',
8231
- DataMember => 'Offset31',
8042
+ Name => 'MenuOffset',
8232
8043
  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',
8044
+ SubDirectory => {
8045
+ TagTable => 'Image::ExifTool::Nikon::MenuInfoZ7II',
8046
+ Start => '$val',
8047
+ },
8244
8048
  },
8245
- 0x760c => {
8049
+ );
8050
+
8051
+ %Image::ExifTool::Nikon::IntervalInfoZ7II = (
8052
+ %binaryDataAttrs,
8053
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8054
+ DATAMEMBER => [ 0x24, 0x28 ],
8055
+ 0x24 => {
8246
8056
  Name => 'IntervalShooting',
8247
8057
  RawConv => '$$self{IntervalShooting} = $val',
8248
8058
  Format => 'int16u',
8249
8059
  PrintConv => q{
8250
8060
  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
8061
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); # something like "Interval 1 of 3"
8062
+ 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
8063
  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}),
8064
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
8255
8065
  },
8256
8066
  },
8257
- 0x7610 => {
8067
+ 0x28 => {
8258
8068
  Name => 'IntervalFrame',
8259
8069
  RawConv => '$$self{IntervalFrame} = $val',
8260
8070
  Condition => '$$self{IntervalShooting} > 0',
8261
8071
  Format => 'int16u',
8262
8072
  Hidden => 1,
8263
8073
  },
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
8074
+ );
8075
+
8076
+ %Image::ExifTool::Nikon::PortraitInfoZ7II = (
8077
+ %binaryDataAttrs,
8078
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8079
+ 0xa0 => { #28
8273
8080
  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
8081
  # offset5+160; 128 is neutral; >128 increases Yellow; <128 increases Magenta; increments of 4 result from 1 full unit adjustment on the camera
8275
8082
  # offset5+161 128 is neutral; >128 increases Brightness; <128 decreases Brightness
@@ -8285,83 +8092,31 @@ my %nikonFocalConversions = (
8285
8092
  return "$color $brightness"
8286
8093
  },
8287
8094
  },
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
- },
8095
+ );
8296
8096
 
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]',
8097
+ %Image::ExifTool::Nikon::MenuInfoZ7II = (
8098
+ %binaryDataAttrs,
8099
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8100
+ IS_SUBDIR => [ 0x10 ],
8101
+ 0x10 => {
8102
+ Name => 'MenuSettingsOffsetZ7II',
8103
+ Format => 'int32u',
8347
8104
  SubDirectory => {
8348
8105
  TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ7II',
8106
+ Start => '$dirStart + $val',
8349
8107
  },
8350
- }
8351
- # note: DecryptLen currently set to 0xd04e + 860 (offset for Z50 is 0xd04e)
8108
+ },
8352
8109
  );
8353
8110
 
8354
8111
  # shot information for the Z9 firmware 1.00 (encrypted) - ref 28
8355
8112
  %Image::ExifTool::Nikon::ShotInfoZ9 = (
8356
- PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8357
- WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
8113
+ PROCESS_PROC => \&ProcessNikonEncrypted,
8114
+ WRITE_PROC => \&ProcessNikonEncrypted,
8358
8115
  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 ],
8116
+ VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
8117
+ DATAMEMBER => [ 0x04 ],
8118
+ IS_SUBDIR => [ 0x30, 0x84, 0x8c ],
8363
8119
  WRITABLE => 1,
8364
- FIRST_ENTRY => 0,
8365
8120
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8366
8121
  NOTES => 'These tags are extracted from encrypted data in images from the Z9.',
8367
8122
  0x00 => {
@@ -8390,47 +8145,45 @@ my %nikonFocalConversions = (
8390
8145
  },
8391
8146
  0x24 => {
8392
8147
  Name => 'NumberOffsets', # number of entries in offset table. offsets are from start of ShotInfo data.
8393
- DataMember => 'NumberOffsets',
8394
8148
  Format => 'int32u',
8395
8149
  Writable => 0,
8396
8150
  Hidden => 1,
8397
8151
  },
8152
+ # subdirectories, referenced by offsets (not processed if offset is zero)
8398
8153
  0x30 => {
8399
- Name => 'SequenceOffset', #offset3 - length 2528 (Z9 firmware 1.0)
8400
- DataMember => 'SequenceOffset',
8154
+ Name => 'SequenceOffset',
8401
8155
  Format => 'int32u',
8402
- Writable => 0,
8403
- Hidden => 1,
8404
- RawConv => '$$self{SequenceOffset} = $val || 0x10000000; undef', # (ignore if 0)
8156
+ SubDirectory => {
8157
+ TagTable => 'Image::ExifTool::Nikon::SeqInfoZ9',
8158
+ Start => '$val',
8159
+ },
8405
8160
  },
8406
8161
  0x84 => {
8407
- Name => 'OrientationOffset', #offset24 - length 108 (Z9 firmware 1.0)
8408
- DataMember => 'OrientationOffset',
8162
+ Name => 'OrientOffset',
8163
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8409
8164
  Format => 'int32u',
8410
- Writable => 0,
8411
- Hidden => 1,
8412
- RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
8165
+ SubDirectory => {
8166
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8167
+ Start => '$val',
8168
+ },
8413
8169
  },
8414
8170
  0x8c => {
8415
- Name => 'MenuOffset', #offset26 - length 1895 (Z9 firmware 1.0)
8416
- DataMember => 'MenuOffset6',
8171
+ Name => 'MenuOffset',
8417
8172
  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',
8173
+ SubDirectory => {
8174
+ TagTable => 'Image::ExifTool::Nikon::MenuInfoZ9',
8175
+ Start => '$val',
8176
+ },
8430
8177
  },
8431
- 0x00b4 => {
8178
+ );
8179
+
8180
+ %Image::ExifTool::Nikon::SeqInfoZ9 = (
8181
+ %binaryDataAttrs,
8182
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8183
+ DATAMEMBER => [ 0x20, 0x28, 0x2a ],
8184
+ 0x0020 => {
8432
8185
  Name => 'FocusShiftShooting',
8433
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8186
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8434
8187
  RawConv => '$$self{FocusShiftShooting} = $val',
8435
8188
  PrintConv => q{
8436
8189
  return 'Off' if $val == 0 ;
@@ -8438,86 +8191,70 @@ my %nikonFocalConversions = (
8438
8191
  return "On: $i"
8439
8192
  },
8440
8193
  },
8441
- 0x00bc => {
8194
+ 0x0028 => {
8442
8195
  Name => 'IntervalShooting',
8443
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8196
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8444
8197
  RawConv => '$$self{IntervalShooting} = $val',
8445
8198
  Format => 'int16u',
8446
8199
  PrintConv => q{
8447
8200
  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
8201
+ my $i = sprintf("Interval %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0); # something like "Interval 1 of 3"
8202
+ 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
8203
  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}),
8204
+ #$val == 0 ? 'Off' : sprintf("On: Interval %.0f of %.0f Frame %.0f of %.0f",$val, $$self{IntervalShootingIntervals}||0, $$self{IntervalFrame}||0, $$self{IntervalShootingShotsPerInterval}||0),
8452
8205
  },
8453
8206
  },
8454
- 0x00be => {
8455
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8207
+ 0x002a => {
8456
8208
  Name => 'IntervalFrame',
8457
8209
  RawConv => '$$self{IntervalFrame} = $val',
8458
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8210
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8459
8211
  Format => 'int16u',
8460
8212
  Hidden => 1,
8461
8213
  },
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)
8470
- },
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',
8478
- },
8479
- 0x44ec => [
8214
+ );
8215
+
8216
+ %Image::ExifTool::Nikon::MenuInfoZ9 = (
8217
+ %binaryDataAttrs,
8218
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8219
+ IS_SUBDIR => [ 0x10 ],
8220
+ # 0x00 - int32u size of this directory
8221
+ 0x10 => [
8480
8222
  {
8481
- Name => 'MenuSettingsZ9',
8482
- Condition => '$$self{ShutterMode} eq 96 and $$self{FirmwareVersion} lt "03.00"', # C30/C60/C120 jpgs only
8483
- Format => 'undef[1646]',
8223
+ Name => 'MenuSettingsOffsetZ9',
8224
+ Condition => '$$self{FirmwareVersion} and $$self{FirmwareVersion} lt "03.00"',
8225
+ Format => 'int32u',
8484
8226
  Notes => 'Firmware versions 2.11 and earlier',
8485
8227
  SubDirectory => {
8486
8228
  TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9',
8229
+ Start => '$dirStart + $val',
8487
8230
  },
8488
8231
  },
8489
8232
  {
8490
- Name => 'MenuSettingsZ9',
8233
+ Name => 'MenuSettingsOffsetZ9v3',
8491
8234
  Notes => 'Firmware versions 3.0 and later',
8492
- Condition => '$$self{ShutterMode} eq 96', # C30/C60/C120 jpgs only
8493
- Format => 'undef[1948]',
8235
+ Format => 'int32u',
8494
8236
  SubDirectory => {
8495
- TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9Firmware3',
8237
+ TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ9v3',
8238
+ Start => '$dirStart + $val',
8496
8239
  },
8497
8240
  },
8498
8241
  ],
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 => {
8242
+ );
8243
+
8244
+ %Image::ExifTool::Nikon::OrientationInfo = (
8245
+ %binaryDataAttrs,
8246
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8247
+ 0 => {
8509
8248
  Name => 'RollAngle',
8510
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8511
- Format => 'fixed32u',
8249
+ Format => 'fixed32u',
8512
8250
  Notes => 'converted to degrees of clockwise camera roll',
8513
8251
  ValueConv => '$val <= 180 ? $val : $val - 360',
8514
8252
  ValueConvInv => '$val >= 0 ? $val : $val + 360',
8515
8253
  PrintConv => 'sprintf("%.1f", $val)',
8516
8254
  PrintConvInv => '$val',
8517
8255
  },
8518
- 0x80c9 => {
8256
+ 4 => {
8519
8257
  Name => 'PitchAngle',
8520
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8521
8258
  Format => 'fixed32u',
8522
8259
  Notes => 'converted to degrees of upward camera tilt',
8523
8260
  ValueConv => '$val <= 180 ? $val : $val - 360',
@@ -8525,9 +8262,8 @@ my %nikonFocalConversions = (
8525
8262
  PrintConv => 'sprintf("%.1f", $val)',
8526
8263
  PrintConvInv => '$val',
8527
8264
  },
8528
- 0x80cd => {
8265
+ 8 => {
8529
8266
  Name => 'YawAngle',
8530
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8531
8267
  Format => 'fixed32u',
8532
8268
  Notes => 'the camera yaw angle when shooting in portrait orientation',
8533
8269
  ValueConv => '$val <= 180 ? $val : $val - 360',
@@ -8535,51 +8271,25 @@ my %nikonFocalConversions = (
8535
8271
  PrintConv => 'sprintf("%.1f", $val)',
8536
8272
  PrintConvInv => '$val',
8537
8273
  },
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
8274
  );
8577
8275
 
8578
8276
  %Image::ExifTool::Nikon::MenuSettingsZ7II = (
8579
8277
  %binaryDataAttrs,
8580
8278
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8581
- DATAMEMBER => [ 176, 180, 328, 352, 858 ],
8279
+ DATAMEMBER => [ 90, 176, 180, 328, 352, 858 ],
8582
8280
  NOTES => 'These tags are used by the Z5, Z6, Z7, Z6II, Z7II, Z50 and Zfc.',
8281
+ #48 SelfTimer' #0=> no 1=> yes works for Z7II firmware 1.40, but not 1.30. Follow-up required.
8282
+ 90 => {
8283
+ Name => 'SingleFrame', #0=> Single Frame 1=> one of the continuous modes
8284
+ Hidden => 1,
8285
+ RawConv => '$$self{SingleFrame} = $val',
8286
+ },
8287
+ 92 => {
8288
+ Name => 'ReleaseMode',
8289
+ #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
8290
+ ValueConv => '$$self{SingleFrame} == 0 ? 5 : $val', #map single frame to a unique value for PrintConv
8291
+ PrintConv => \%releaseModeZ7,
8292
+ },
8583
8293
  160 => {
8584
8294
  Name => 'IntervalDurationHours',
8585
8295
  Format => 'int32u',
@@ -8814,34 +8524,34 @@ my %nikonFocalConversions = (
8814
8524
  Name => 'Intervals',
8815
8525
  Format => 'int32u',
8816
8526
  RawConv => '$$self{IntervalShootingIntervals} = $val',
8817
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8527
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8818
8528
  },
8819
8529
  192 => {
8820
8530
  Name => 'ShotsPerInterval',
8821
8531
  Format => 'int32u',
8822
8532
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
8823
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8533
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8824
8534
  },
8825
8535
  #220 NEFCompression 0=> 'Lossless' 1=> 'High Efficiency*' 4=> 'High Efficientcy'
8826
8536
  232 => {
8827
8537
  Name => 'FocusShiftNumberShots', #1-300
8828
8538
  RawConv => '$$self{FocusShiftNumberShots} = $val',
8829
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8539
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8830
8540
  },
8831
8541
  236 => {
8832
8542
  Name => 'FocusShiftStepWidth', #1(Narrow) to 10 (Wide)
8833
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8543
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8834
8544
  },
8835
8545
  240 => {
8836
8546
  Name => 'FocusShiftInterval',
8837
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8547
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8838
8548
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
8839
8549
  },
8840
8550
  244 => {
8841
8551
  Name => 'FocusShiftExposureLock',
8842
8552
  Unknown => 1,
8843
8553
  PrintConv => \%offOn,
8844
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8554
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8845
8555
  },
8846
8556
  274 => { Name => 'PhotoShootingMenuBank', PrintConv => \%banksZ9 },
8847
8557
  276 => { Name => 'ExtendedMenuBanks', PrintConv => \%offOn }, #single tag from both Photo & Video menus
@@ -8996,13 +8706,13 @@ my %nikonFocalConversions = (
8996
8706
  1565 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
8997
8707
  1572 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
8998
8708
  1573 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
8999
- 1608 => { Name => 'EnergySavingMode', PrintConv =>\%offOn, Unknown => 1 },
8709
+ 1608 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
9000
8710
  1632 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
9001
8711
  1636 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
9002
8712
  1645 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
9003
8713
  );
9004
8714
 
9005
- %Image::ExifTool::Nikon::MenuSettingsZ9Firmware3 = ( #starts at Offset26 + 248
8715
+ %Image::ExifTool::Nikon::MenuSettingsZ9v3 = (
9006
8716
  %binaryDataAttrs,
9007
8717
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
9008
8718
  DATAMEMBER => [ 154, 204, 208, 248, 444, 554 ],
@@ -9022,33 +8732,33 @@ my %nikonFocalConversions = (
9022
8732
  Name => 'Intervals',
9023
8733
  Format => 'int32u',
9024
8734
  RawConv => '$$self{IntervalShootingIntervals} = $val',
9025
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8735
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9026
8736
  },
9027
8737
  208 => {
9028
8738
  Name => 'ShotsPerInterval',
9029
8739
  Format => 'int32u',
9030
8740
  RawConv => '$$self{IntervalShootingShotsPerInterval} = $val',
9031
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8741
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9032
8742
  },
9033
8743
  248 => {
9034
8744
  Name => 'FocusShiftNumberShots', #1-300
9035
8745
  RawConv => '$$self{FocusShiftNumberShots} = $val',
9036
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8746
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9037
8747
  },
9038
8748
  252 => {
9039
8749
  Name => 'FocusShiftStepWidth', #1(Narrow) to 10 (Wide)
9040
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8750
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9041
8751
  },
9042
8752
  256 => {
9043
8753
  Name => 'FocusShiftInterval',
9044
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8754
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9045
8755
  PrintConv => '$val == 1? "1 Second" : sprintf("%.0f Seconds",$val)',
9046
8756
  },
9047
8757
  260 => {
9048
8758
  Name => 'FocusShiftExposureLock',
9049
8759
  Unknown => 1,
9050
8760
  PrintConv => \%offOn,
9051
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8761
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9052
8762
  },
9053
8763
  290 => { Name => 'PhotoShootingMenuBank', PrintConv => \%banksZ9 },
9054
8764
  292 => { Name => 'ExtendedMenuBanks', PrintConv => \%offOn }, # single tag from both Photo & Video menus
@@ -9192,7 +8902,7 @@ my %nikonFocalConversions = (
9192
8902
  1613 => { Name => 'SetClockFromLocationData', PrintConv => \%offOn, Unknown => 1 },
9193
8903
  1620 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
9194
8904
  1621 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
9195
- 1656 => { Name => 'EnergySavingMode', PrintConv =>\%offOn, Unknown => 1 },
8905
+ 1656 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
9196
8906
  1680 => { Name => 'RecordLocationData', PrintConv => \%offOn, Unknown => 1 },
9197
8907
  1684 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
9198
8908
  1693 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
@@ -9200,7 +8910,7 @@ my %nikonFocalConversions = (
9200
8910
  Name => 'FocusShiftAutoReset',
9201
8911
  Unknown => 1,
9202
8912
  PrintConv => \%offOn,
9203
- Condition => '$$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8913
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
9204
8914
  },
9205
8915
  1810 => { #CSd4-a
9206
8916
  Name => 'PreReleaseBurstLength',
@@ -11258,8 +10968,8 @@ my %nikonFocalConversions = (
11258
10968
  Name => 'LensData0201',
11259
10969
  SubDirectory => {
11260
10970
  TagTable => 'Image::ExifTool::Nikon::LensData01',
11261
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11262
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
10971
+ ProcessProc => \&ProcessNikonEncrypted,
10972
+ WriteProc => \&ProcessNikonEncrypted,
11263
10973
  DecryptStart => 4,
11264
10974
  },
11265
10975
  },
@@ -11268,8 +10978,8 @@ my %nikonFocalConversions = (
11268
10978
  Name => 'LensData0204',
11269
10979
  SubDirectory => {
11270
10980
  TagTable => 'Image::ExifTool::Nikon::LensData0204',
11271
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11272
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
10981
+ ProcessProc => \&ProcessNikonEncrypted,
10982
+ WriteProc => \&ProcessNikonEncrypted,
11273
10983
  DecryptStart => 4,
11274
10984
  },
11275
10985
  },
@@ -11278,8 +10988,8 @@ my %nikonFocalConversions = (
11278
10988
  Name => 'LensData0400',
11279
10989
  SubDirectory => {
11280
10990
  TagTable => 'Image::ExifTool::Nikon::LensData0400',
11281
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11282
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
10991
+ ProcessProc => \&ProcessNikonEncrypted,
10992
+ WriteProc => \&ProcessNikonEncrypted,
11283
10993
  DecryptStart => 4,
11284
10994
  },
11285
10995
  },
@@ -11288,8 +10998,8 @@ my %nikonFocalConversions = (
11288
10998
  Name => 'LensData0402',
11289
10999
  SubDirectory => {
11290
11000
  TagTable => 'Image::ExifTool::Nikon::LensData0402',
11291
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11292
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11001
+ ProcessProc => \&ProcessNikonEncrypted,
11002
+ WriteProc => \&ProcessNikonEncrypted,
11293
11003
  DecryptStart => 4,
11294
11004
  },
11295
11005
  },
@@ -11298,8 +11008,8 @@ my %nikonFocalConversions = (
11298
11008
  Name => 'LensData0403',
11299
11009
  SubDirectory => {
11300
11010
  TagTable => 'Image::ExifTool::Nikon::LensData0403',
11301
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11302
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11011
+ ProcessProc => \&ProcessNikonEncrypted,
11012
+ WriteProc => \&ProcessNikonEncrypted,
11303
11013
  DecryptStart => 4,
11304
11014
  },
11305
11015
  },
@@ -11308,8 +11018,8 @@ my %nikonFocalConversions = (
11308
11018
  Name => 'LensData0800',
11309
11019
  SubDirectory => {
11310
11020
  TagTable => 'Image::ExifTool::Nikon::LensData0800',
11311
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11312
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11021
+ ProcessProc => \&ProcessNikonEncrypted,
11022
+ WriteProc => \&ProcessNikonEncrypted,
11313
11023
  DecryptStart => 4,
11314
11024
  ByteOrder => 'LittleEndian',
11315
11025
  # 0x5a0c - NikonMeteringMode for some Z6 ver1.00 samples (ref PH)
@@ -11319,8 +11029,8 @@ my %nikonFocalConversions = (
11319
11029
  Name => 'LensDataUnknown',
11320
11030
  SubDirectory => {
11321
11031
  TagTable => 'Image::ExifTool::Nikon::LensDataUnknown',
11322
- ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11323
- WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
11032
+ ProcessProc => \&ProcessNikonEncrypted,
11033
+ WriteProc => \&ProcessNikonEncrypted,
11324
11034
  DecryptStart => 4,
11325
11035
  },
11326
11036
  },
@@ -11835,37 +11545,54 @@ my @xlat = (
11835
11545
  0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f ]
11836
11546
  );
11837
11547
 
11548
+ my ($ci0, $cj0, $ck0, $decryptStart); # decryption parameters
11549
+
11838
11550
  # 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)
11551
+ # Inputs: 0) reference to data block, 1) optional start offset (default 0)
11552
+ # 2) optional number of bytes to decode (default to the end of the data)
11553
+ # 3) optional serial number key (undef to continue previous decryption)
11554
+ # 4) optional shutter count key
11842
11555
  # Returns: data block with specified data decrypted
11843
- sub Decrypt($$$;$$)
11556
+ # Notes: The first time this is called for a given encrypted data block the serial/count
11557
+ # keys must be defined, and $start must be the offset for initialization of the
11558
+ # decryption parameters (ie. the beginning of the encrypted data, which isn't
11559
+ # necessarily inside the data block if $len is zero). Subsequent calls for
11560
+ # the same data block do not specify the serial/count keys, and may be used
11561
+ # to decrypt data at any start point within the full data block.
11562
+ sub Decrypt($;$$$$)
11844
11563
  {
11845
- my ($dataPt, $serial, $count, $start, $len) = @_;
11846
- my ($i, $dat);
11564
+ my ($dataPt, $start, $len, $serial, $count) = @_;
11565
+ my ($ch, $cj, $ck);
11847
11566
 
11848
11567
  $start or $start = 0;
11849
11568
  my $maxLen = length($$dataPt) - $start;
11850
11569
  $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;
11570
+ if (defined $serial and defined $count) {
11571
+ # initialize decryption parameters
11572
+ my $key = 0;
11573
+ $key ^= ($count >> ($_*8)) & 0xff foreach 0..3;
11574
+ $ci0 = $xlat[0][$serial & 0xff];
11575
+ $cj0 = $xlat[1][$key];
11576
+ $ck0 = 0x60;
11577
+ undef $decryptStart;
11578
+ }
11579
+ if (defined $decryptStart) {
11580
+ # initialize decryption parameters for this start position
11581
+ my $n = $start - $decryptStart;
11582
+ $cj = ($cj0 + $ci0 * ($n * $ck0 + ($n * ($n - 1))/2)) & 0xff;
11583
+ $ck = ($ck0 + $n) & 0xff;
11584
+ } else {
11585
+ $decryptStart = $start;
11586
+ ($cj, $ck) = ($cj0, $ck0);
11855
11587
  }
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;
11588
+ return $$dataPt if $len <= 0;
11589
+ my @data = unpack('C*', substr($$dataPt, $start, $len));
11590
+ foreach $ch (@data) {
11591
+ $cj = ($cj + $ci0 * $ck) & 0xff;
11862
11592
  $ck = ($ck + 1) & 0xff;
11863
- $dat ^= $cj;
11593
+ $ch ^= $cj;
11864
11594
  }
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;
11595
+ return substr($$dataPt, 0, $start) . pack('C*', @data) . substr($$dataPt, $start+$len);
11869
11596
  }
11870
11597
 
11871
11598
  #------------------------------------------------------------------------------
@@ -12001,6 +11728,110 @@ sub ProcessNikonMOV($$$)
12001
11728
  return 1;
12002
11729
  }
12003
11730
 
11731
+ #------------------------------------------------------------------------------
11732
+ # Prepare to process NIKON_OFFSETS directory and decrypt necessary data
11733
+ # Inputs: 0) ExifTool ref, 1) data ref, 2) tag table ref, 3) decrypt start,
11734
+ # 4) serial key, 5) count key, 6) decrypt mode (0=piecewise,
11735
+ # 1=continuous to end of last known section, 2=all)
11736
+ # Returns: end of decrypted data (or undef for piecewise decryption)
11737
+ sub PrepareNikonOffsets($$$$$$$)
11738
+ {
11739
+ my ($et, $dataPt, $tagTablePtr, $start, $serial, $count, $decryptMode) = @_;
11740
+ my $offset = $$tagTablePtr{VARS}{NIKON_OFFSETS};
11741
+ my $unknown = $et->Options('Unknown');
11742
+ my $dataLen = length $$dataPt;
11743
+ return undef if $offset + 4 > $dataLen or $offset < $start;
11744
+ my $dpos = $offset + 4; # decrypt the first 4 bytes
11745
+ $$dataPt = Decrypt($dataPt, $start, $dpos - $start, $serial, $count);
11746
+ my $numOffsets = Get32u($dataPt, $offset);
11747
+ my $more = $numOffsets * 4;
11748
+ return undef if $offset + 4 + $more > $dataLen;
11749
+ $$dataPt = Decrypt($dataPt, $dpos, $more);
11750
+ $dpos += $more;
11751
+ my $doneAlready = $$tagTablePtr{VARS}{NIKON_OFFSETS_DONE};
11752
+ $$tagTablePtr{VARS}{NIKON_OFFSETS_DONE} = 1;
11753
+ my ($i, @offInfo);
11754
+ for ($i=0; $i<$numOffsets; ++$i) {
11755
+ my $pos = $offset + 4 + 4 * $i;
11756
+ my $off = Get32u($dataPt, $pos) or next;
11757
+ my $tagInfo = $$tagTablePtr{$pos};
11758
+ if ($tagInfo) {
11759
+ if (not $doneAlready and ref $tagInfo eq 'HASH' and
11760
+ not $$tagInfo{Unknown} and $$tagInfo{SubDirectory})
11761
+ {
11762
+ # determine length of subdirectory up to end of last known tag
11763
+ my $subdir = $$tagInfo{SubDirectory};
11764
+ my $tbl = GetTagTable($$subdir{TagTable});
11765
+ my ($last) = sort { $b <=> $a } TagTableKeys($tbl);
11766
+ my $lastInfo = $$tbl{$last};
11767
+ $lastInfo = $$lastInfo[0] if ref $lastInfo eq 'ARRAY';
11768
+ # (can't pre-determine known length of offset-based subdirectories)
11769
+ unless ($$lastInfo{SubDirectory}) {
11770
+ my $fmt = $$lastInfo{Format} || $$tbl{FORMAT} || 'int8u';
11771
+ my $nm = $fmt =~ s/\[(\d+)\]$// ? $1 : 1;
11772
+ my $sz = Image::ExifTool::FormatSize($fmt);
11773
+ $$subdir{KnownLen} = int($last) + $sz * $nm if $sz;
11774
+ }
11775
+ }
11776
+ } elsif ($unknown > 1) {
11777
+ # create new table for unknown information
11778
+ my $tbl = sprintf('Image::ExifTool::Nikon::UnknownInfo%.2x', $pos);
11779
+ no strict 'refs';
11780
+ unless (%$tbl) {
11781
+ %$tbl = ( %binaryDataAttrs, GROUPS => { 0=>'MakerNotes', 2=>'Unknown' } );
11782
+ GetTagTable($tbl);
11783
+ }
11784
+ # add unknown entry in offset table for this subdirectory
11785
+ $tagInfo = AddTagToTable($tagTablePtr, $pos, {
11786
+ Name => sprintf('UnknownOffset%.2x', $pos),
11787
+ Format => 'int32u',
11788
+ SubDirectory => { TagTable => $tbl },
11789
+ Unknown => 2,
11790
+ });
11791
+ }
11792
+ if ($off) {
11793
+ my $known = ($tagInfo and (ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown})) ? 1 : 0;
11794
+ push @offInfo, [ $pos, $off, $known ];
11795
+ }
11796
+ }
11797
+ my $end;
11798
+ # sort offsets in ascending order, and use the differences to calculate
11799
+ # directory lengths and update the SubDirectory DirLen's accordingly
11800
+ my @sorted = sort { $$a[1] <=> $$b[1] or $$a[0] <=> $$b[0] } @offInfo;
11801
+ push @sorted, [ 0, length($$dataPt), 0 ];
11802
+ for ($i=0; $i<@sorted-1; ++$i) {
11803
+ my $pos = $sorted[$i][0];
11804
+ my $len = $sorted[$i+1][1] - $sorted[$i][1];
11805
+ # set DirLen in SubDirectory entry
11806
+ my $tagInfo = $$tagTablePtr{$pos};
11807
+ my $subdir;
11808
+ if (ref $tagInfo eq 'HASH' and defined($subdir=$$tagInfo{SubDirectory})) {
11809
+ $$tagInfo{SubDirectory}{DirLen} = $len;
11810
+ }
11811
+ if ($decryptMode) {
11812
+ # keep track of end of last known directory
11813
+ $end = $sorted[$i+1][1] if $sorted[$i][2];
11814
+ } elsif ($tagInfo and (ref $tagInfo ne 'HASH' or not $$tagInfo{Unknown})) {
11815
+ # decrypt data piecewise as necessary
11816
+ my $n = $len;
11817
+ if ($subdir and $$subdir{KnownLen}) {
11818
+ $n = $$subdir{KnownLen};
11819
+ if ($n > $len) {
11820
+ $et->Warn("Data too short for $$tagInfo{Name}",1);
11821
+ $n = $len;
11822
+ }
11823
+ }
11824
+ $$dataPt = Decrypt($dataPt, $sorted[$i][1], $n);
11825
+ }
11826
+ }
11827
+ if ($decryptMode) {
11828
+ # decrypt the remaining required data
11829
+ $end = length $$dataPt if $decryptMode == 2 or not $end or $end < $dpos;
11830
+ $$dataPt = Decrypt($dataPt, $dpos, $end - $dpos);
11831
+ }
11832
+ return $end;
11833
+ }
11834
+
12004
11835
  #------------------------------------------------------------------------------
12005
11836
  # Read/Write Nikon Encrypted data block
12006
11837
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -12025,15 +11856,17 @@ sub ProcessNikonEncrypted($$$)
12025
11856
  delete $$et{NikonCountKey};
12026
11857
  return 0;
12027
11858
  }
12028
- my $verbose = $$dirInfo{IsWriting} ? 0 : $et->Options('Verbose');
11859
+ my $oldOrder = GetByteOrder();
11860
+ my $isWriting = $$dirInfo{IsWriting};
11861
+ my $verbose = $isWriting ? 0 : $et->Options('Verbose');
12029
11862
  my $tagInfo = $$dirInfo{TagInfo};
12030
11863
  my $dirStart = $$dirInfo{DirStart};
12031
11864
  my $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen});
12032
11865
 
12033
- my ($start, $len, $more, $offset, $byteOrder, $recrypt, $newSerial, $newCount);
11866
+ my ($start, $len, $offset, $byteOrder, $recrypt, $newSerial, $newCount, $didDecrypt);
12034
11867
 
12035
11868
  # must re-encrypt when writing if serial number or shutter count changes
12036
- if ($$dirInfo{IsWriting}) {
11869
+ if ($isWriting) {
12037
11870
  if ($$et{NewNikonSerialKey}) {
12038
11871
  $newSerial = $$et{NewNikonSerialKey};
12039
11872
  $recrypt = 1;
@@ -12044,46 +11877,32 @@ sub ProcessNikonEncrypted($$$)
12044
11877
  }
12045
11878
  }
12046
11879
  if ($tagInfo and $$tagInfo{SubDirectory}) {
12047
- $start = $$tagInfo{SubDirectory}{DecryptStart};
11880
+ my $subdir = $$tagInfo{SubDirectory};
11881
+ $start = $$subdir{DecryptStart} || 0;
11882
+ # DirOffset, if specified, is relative to start of encrypted data
11883
+ $offset = defined $$subdir{DirOffset} ? $$subdir{DirOffset} + $start : 0;
11884
+ $byteOrder = $$subdir{ByteOrder};
11885
+ SetByteOrder($byteOrder) if $byteOrder;
11886
+ # prepare for processing NIKON_OFFSETS directory if necessary
11887
+ if ($$tagTablePtr{VARS} and $$tagTablePtr{VARS}{NIKON_OFFSETS}) {
11888
+ my $unknown = $et->Options('Verbose') > 2 || $et->Options('Unknown') > 1;
11889
+ # decrypt mode: 0=piecewise, 1=continuous to end of last known section, 2=all
11890
+ my $dMode = $isWriting ? ($recrypt ? 2 : 1) : ($unknown ? 2 : 0);
11891
+ $len = PrepareNikonOffsets($et, \$data, $tagTablePtr, $start, $serial, $count, $dMode);
11892
+ $didDecrypt = 1;
12048
11893
  # 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};
11894
+ } elsif ($verbose < 3 and $et->Options('Unknown') < 2 and not $recrypt) {
11895
+ $len = $$subdir{DecryptLen};
12052
11896
  }
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
11897
  } else {
12061
- $offset = 0;
11898
+ $start = $offset = 0;
12062
11899
  }
12063
11900
  my $maxLen = length($data) - $start;
12064
11901
  # 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
- }
11902
+ $len = $maxLen unless $len and $len < $maxLen;
12069
11903
 
12070
- $data = Decrypt(\$data, $serial, $count, $start, $len);
11904
+ $data = Decrypt(\$data, $start, $len, $serial, $count) unless $didDecrypt;
12071
11905
 
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
11906
  if ($verbose > 2) {
12088
11907
  $et->VerboseDir("Decrypted $$tagInfo{Name}");
12089
11908
  $et->VerboseDump(\$data,
@@ -12102,7 +11921,7 @@ sub ProcessNikonEncrypted($$$)
12102
11921
  Base => $$dirInfo{Base},
12103
11922
  );
12104
11923
  my $rtnVal;
12105
- if ($$dirInfo{IsWriting}) {
11924
+ if ($isWriting) {
12106
11925
  my $changed = $$et{CHANGED};
12107
11926
  $rtnVal = $et->WriteBinaryData(\%subdirInfo, $tagTablePtr);
12108
11927
  # must re-encrypt if serial number or shutter count changes
@@ -12117,7 +11936,8 @@ sub ProcessNikonEncrypted($$$)
12117
11936
  # add back any un-encrypted data at start
12118
11937
  $rtnVal = substr($data, 0, $offset) . $rtnVal if $offset;
12119
11938
  # re-encrypt data (symmetrical algorithm)
12120
- $rtnVal = Decrypt(\$rtnVal, $serial, $count, $start, $len);
11939
+ $rtnVal = Decrypt(\$rtnVal, $start, $len, $serial, $count);
11940
+ $et->VPrint(2, $$et{INDENT}, " [recrypted $$tagInfo{Name}]");
12121
11941
  }
12122
11942
  } else {
12123
11943
  $rtnVal = $et->ProcessBinaryData(\%subdirInfo, $tagTablePtr);