exiftool_vendored 12.56.0 → 12.57.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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);