exiftool_vendored 13.30.0 → 13.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +57 -1
  3. data/bin/MANIFEST +5 -0
  4. data/bin/META.json +4 -3
  5. data/bin/META.yml +3 -2
  6. data/bin/README +47 -46
  7. data/bin/exiftool +88 -60
  8. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +7 -5
  9. data/bin/lib/Image/ExifTool/Canon.pm +16 -5
  10. data/bin/lib/Image/ExifTool/Exif.pm +7 -4
  11. data/bin/lib/Image/ExifTool/FlashPix.pm +4 -159
  12. data/bin/lib/Image/ExifTool/FujiFilm.pm +13 -3
  13. data/bin/lib/Image/ExifTool/Geotag.pm +5 -3
  14. data/bin/lib/Image/ExifTool/GoPro.pm +23 -4
  15. data/bin/lib/Image/ExifTool/LNK.pm +24 -3
  16. data/bin/lib/Image/ExifTool/Lang/cs.pm +0 -1
  17. data/bin/lib/Image/ExifTool/Lang/de.pm +2 -2
  18. data/bin/lib/Image/ExifTool/Lang/fr.pm +2 -2
  19. data/bin/lib/Image/ExifTool/Lang/it.pm +0 -1
  20. data/bin/lib/Image/ExifTool/Lang/ja.pm +0 -1
  21. data/bin/lib/Image/ExifTool/Lang/nl.pm +0 -1
  22. data/bin/lib/Image/ExifTool/Lang/pl.pm +0 -1
  23. data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +0 -1
  24. data/bin/lib/Image/ExifTool/LigoGPS.pm +14 -6
  25. data/bin/lib/Image/ExifTool/Microsoft.pm +158 -1
  26. data/bin/lib/Image/ExifTool/Minolta.pm +1 -1
  27. data/bin/lib/Image/ExifTool/Nikon.pm +80 -39
  28. data/bin/lib/Image/ExifTool/NikonCustom.pm +40 -10
  29. data/bin/lib/Image/ExifTool/Olympus.pm +240 -35
  30. data/bin/lib/Image/ExifTool/PDF.pm +1 -0
  31. data/bin/lib/Image/ExifTool/Panasonic.pm +4 -4
  32. data/bin/lib/Image/ExifTool/Parrot.pm +1 -1
  33. data/bin/lib/Image/ExifTool/Pentax.pm +276 -56
  34. data/bin/lib/Image/ExifTool/Plot.pm +2 -3
  35. data/bin/lib/Image/ExifTool/QuickTime.pm +13 -5
  36. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +41 -17
  37. data/bin/lib/Image/ExifTool/Sigma.pm +19 -1
  38. data/bin/lib/Image/ExifTool/Sony.pm +5 -2
  39. data/bin/lib/Image/ExifTool/TNEF.pm +487 -0
  40. data/bin/lib/Image/ExifTool/TagLookup.pm +4374 -4262
  41. data/bin/lib/Image/ExifTool/TagNames.pod +259 -22
  42. data/bin/lib/Image/ExifTool/WriteExif.pl +14 -12
  43. data/bin/lib/Image/ExifTool/WritePDF.pl +1 -0
  44. data/bin/lib/Image/ExifTool/Writer.pl +142 -139
  45. data/bin/lib/Image/ExifTool/XMPStruct.pl +1 -1
  46. data/bin/lib/Image/ExifTool.pm +16 -7
  47. data/bin/lib/Image/ExifTool.pod +45 -44
  48. data/bin/perl-Image-ExifTool.spec +46 -45
  49. data/lib/exiftool_vendored/version.rb +1 -1
  50. metadata +3 -2
@@ -11,7 +11,7 @@ use strict;
11
11
  use vars qw($VERSION);
12
12
  use Image::ExifTool;
13
13
 
14
- $VERSION = '1.05';
14
+ $VERSION = '1.06';
15
15
 
16
16
  sub ProcessLigoGPS($$$;$);
17
17
  sub ProcessLigoJSON($$$);
@@ -223,11 +223,12 @@ sub DecipherLigoGPS($$$;$)
223
223
  #------------------------------------------------------------------------------
224
224
  # Parse decrypted/deciphered (but not defuzzed) LIGOGPSINFO record
225
225
  # (record starts with 4-byte int32u counter followed by date/time, etc)
226
- # Inputs: 0) ExifTool ref, 1) GPS string, 2) tag table ref, 3) not fuzzed
226
+ # Inputs: 0) ExifTool ref, 1) GPS string, 2) tag table ref,
227
+ # 3) flags: 0x01=not fuzzed, 0x02=spd in km/h
227
228
  # Returns: nothing
228
229
  sub ParseLigoGPS($$$;$)
229
230
  {
230
- my ($et, $str, $tagTbl, $noFuzz) = @_;
231
+ my ($et, $str, $tagTbl, $flags) = @_;
231
232
 
232
233
  # example string input
233
234
  # "....2022/09/19 12:45:24 N:31.285065 W:124.759483 46.93 km/h x:-0.000 y:-0.000 z:-0.000"
@@ -235,15 +236,16 @@ sub ParseLigoGPS($$$;$)
235
236
  $et->Warn('LIGOGPSINFO format error');
236
237
  return;
237
238
  }
239
+ $flags or $flags = 0;
238
240
  my ($time,$latRef,$latNeg,$lat,$lonRef,$lonNeg,$lon,$spd) = ($1,$2,$3,$4,$5,$6,$7,$8);
239
241
  my %gpsScl = ( 1 => 1.524855137, 2 => 1.456027985, 3 => 1.15368 );
240
- my $spdScl = $noFuzz ? $knotsToKph : 1.85407333;
242
+ my $spdScl = $flags & 0x01 ? ($flags & 0x02 ? 1 : $knotsToKph) : 1.85407333;
241
243
  $$et{DOC_NUM} = ++$$et{DOC_COUNT};
242
244
  $time =~ tr(/)(:);
243
245
  # convert from DDMM.MMMMMM to DD.DDDDDD if necessary
244
246
  # (speed wasn't scaled in my 1 sample with this format)
245
247
  $lat =~ /^\d{3}/ and Image::ExifTool::QuickTime::ConvertLatLon($lat,$lon), $spdScl = 1;
246
- unless ($noFuzz) { # unfuzz the coordinates if necessary
248
+ unless ($flags & 0x01) { # unfuzz the coordinates if necessary
247
249
  my $scl = $$et{OPTIONS}{LigoGPSScale} || $$et{LigoGPSScale} || 1;
248
250
  $scl = $gpsScl{$scl} if $gpsScl{$scl};
249
251
  ($lat, $lon) = UnfuzzLigoGPS($lat, $lon, $scl);
@@ -298,7 +300,13 @@ sub ProcessLigoGPS($$$;$)
298
300
  $et->VerboseDir($dirName);
299
301
  for (; $pos + 0x84 <= length($$dataPt); $pos+=0x84) {
300
302
  my $dat = substr($$dataPt, $pos, 0x84);
301
- $dat =~ /^####/ or next; # (have seen blank records filled with zeros, so keep trying)
303
+ unless ($dat =~ /^####/) {
304
+ next unless $dat =~ m(^.{4}\d{4}/\d{2}/\d{2} )s; # (have seen blank records filled with zeros, so keep trying)
305
+ # non-encrypted format written by Redtiger F9 4K
306
+ $dat =~ s/\0+$//; # remove trailing nulls
307
+ ParseLigoGPS($et, $dat, $tagTbl, 0x03);
308
+ next;
309
+ }
302
310
  # decipher if we already know the encryption
303
311
  $cipherInfo and $$cipherInfo{decipher} and DecipherLigoGPS($et, $dat, $tagTbl, $noFuzz) and next;
304
312
  my $str = DecryptLigoGPS($dat);
@@ -13,7 +13,7 @@
13
13
  package Image::ExifTool::Microsoft;
14
14
 
15
15
  use strict;
16
- use vars qw($VERSION);
16
+ use vars qw($VERSION %codePage);
17
17
  use Image::ExifTool qw(:DataAccess :Utils);
18
18
  use Image::ExifTool::XMP;
19
19
 
@@ -23,6 +23,163 @@ sub ProcessXtra($$$);
23
23
  sub WriteXtra($$$);
24
24
  sub CheckXtra($$$);
25
25
 
26
+ # list of code pages used by Microsoft
27
+ # (ref http://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx)
28
+ %codePage = (
29
+ 37 => 'IBM EBCDIC US-Canada',
30
+ 437 => 'DOS United States',
31
+ 500 => 'IBM EBCDIC International',
32
+ 708 => 'Arabic (ASMO 708)',
33
+ 709 => 'Arabic (ASMO-449+, BCON V4)',
34
+ 710 => 'Arabic - Transparent Arabic',
35
+ 720 => 'DOS Arabic (Transparent ASMO)',
36
+ 737 => 'DOS Greek (formerly 437G)',
37
+ 775 => 'DOS Baltic',
38
+ 850 => 'DOS Latin 1 (Western European)',
39
+ 852 => 'DOS Latin 2 (Central European)',
40
+ 855 => 'DOS Cyrillic (primarily Russian)',
41
+ 857 => 'DOS Turkish',
42
+ 858 => 'DOS Multilingual Latin 1 with Euro',
43
+ 860 => 'DOS Portuguese',
44
+ 861 => 'DOS Icelandic',
45
+ 862 => 'DOS Hebrew',
46
+ 863 => 'DOS French Canadian',
47
+ 864 => 'DOS Arabic',
48
+ 865 => 'DOS Nordic',
49
+ 866 => 'DOS Russian (Cyrillic)',
50
+ 869 => 'DOS Modern Greek',
51
+ 870 => 'IBM EBCDIC Multilingual/ROECE (Latin 2)',
52
+ 874 => 'Windows Thai (same as 28605, ISO 8859-15)',
53
+ 875 => 'IBM EBCDIC Greek Modern',
54
+ 932 => 'Windows Japanese (Shift-JIS)',
55
+ 936 => 'Windows Simplified Chinese (PRC, Singapore)',
56
+ 949 => 'Windows Korean (Unified Hangul Code)',
57
+ 950 => 'Windows Traditional Chinese (Taiwan)',
58
+ 1026 => 'IBM EBCDIC Turkish (Latin 5)',
59
+ 1047 => 'IBM EBCDIC Latin 1/Open System',
60
+ 1140 => 'IBM EBCDIC US-Canada with Euro',
61
+ 1141 => 'IBM EBCDIC Germany with Euro',
62
+ 1142 => 'IBM EBCDIC Denmark-Norway with Euro',
63
+ 1143 => 'IBM EBCDIC Finland-Sweden with Euro',
64
+ 1144 => 'IBM EBCDIC Italy with Euro',
65
+ 1145 => 'IBM EBCDIC Latin America-Spain with Euro',
66
+ 1146 => 'IBM EBCDIC United Kingdom with Euro',
67
+ 1147 => 'IBM EBCDIC France with Euro',
68
+ 1148 => 'IBM EBCDIC International with Euro',
69
+ 1149 => 'IBM EBCDIC Icelandic with Euro',
70
+ 1200 => 'Unicode UTF-16, little endian',
71
+ 1201 => 'Unicode UTF-16, big endian',
72
+ 1250 => 'Windows Latin 2 (Central European)',
73
+ 1251 => 'Windows Cyrillic',
74
+ 1252 => 'Windows Latin 1 (Western European)',
75
+ 1253 => 'Windows Greek',
76
+ 1254 => 'Windows Turkish',
77
+ 1255 => 'Windows Hebrew',
78
+ 1256 => 'Windows Arabic',
79
+ 1257 => 'Windows Baltic',
80
+ 1258 => 'Windows Vietnamese',
81
+ 1361 => 'Korean (Johab)',
82
+ 10000 => 'Mac Roman (Western European)',
83
+ 10001 => 'Mac Japanese',
84
+ 10002 => 'Mac Traditional Chinese',
85
+ 10003 => 'Mac Korean',
86
+ 10004 => 'Mac Arabic',
87
+ 10005 => 'Mac Hebrew',
88
+ 10006 => 'Mac Greek',
89
+ 10007 => 'Mac Cyrillic',
90
+ 10008 => 'Mac Simplified Chinese',
91
+ 10010 => 'Mac Romanian',
92
+ 10017 => 'Mac Ukrainian',
93
+ 10021 => 'Mac Thai',
94
+ 10029 => 'Mac Latin 2 (Central European)',
95
+ 10079 => 'Mac Icelandic',
96
+ 10081 => 'Mac Turkish',
97
+ 10082 => 'Mac Croatian',
98
+ 12000 => 'Unicode UTF-32, little endian',
99
+ 12001 => 'Unicode UTF-32, big endian',
100
+ 20000 => 'CNS Taiwan',
101
+ 20001 => 'TCA Taiwan',
102
+ 20002 => 'Eten Taiwan',
103
+ 20003 => 'IBM5550 Taiwan',
104
+ 20004 => 'TeleText Taiwan',
105
+ 20005 => 'Wang Taiwan',
106
+ 20105 => 'IA5 (IRV International Alphabet No. 5, 7-bit)',
107
+ 20106 => 'IA5 German (7-bit)',
108
+ 20107 => 'IA5 Swedish (7-bit)',
109
+ 20108 => 'IA5 Norwegian (7-bit)',
110
+ 20127 => 'US-ASCII (7-bit)',
111
+ 20261 => 'T.61',
112
+ 20269 => 'ISO 6937 Non-Spacing Accent',
113
+ 20273 => 'IBM EBCDIC Germany',
114
+ 20277 => 'IBM EBCDIC Denmark-Norway',
115
+ 20278 => 'IBM EBCDIC Finland-Sweden',
116
+ 20280 => 'IBM EBCDIC Italy',
117
+ 20284 => 'IBM EBCDIC Latin America-Spain',
118
+ 20285 => 'IBM EBCDIC United Kingdom',
119
+ 20290 => 'IBM EBCDIC Japanese Katakana Extended',
120
+ 20297 => 'IBM EBCDIC France',
121
+ 20420 => 'IBM EBCDIC Arabic',
122
+ 20423 => 'IBM EBCDIC Greek',
123
+ 20424 => 'IBM EBCDIC Hebrew',
124
+ 20833 => 'IBM EBCDIC Korean Extended',
125
+ 20838 => 'IBM EBCDIC Thai',
126
+ 20866 => 'Russian/Cyrillic (KOI8-R)',
127
+ 20871 => 'IBM EBCDIC Icelandic',
128
+ 20880 => 'IBM EBCDIC Cyrillic Russian',
129
+ 20905 => 'IBM EBCDIC Turkish',
130
+ 20924 => 'IBM EBCDIC Latin 1/Open System with Euro',
131
+ 20932 => 'Japanese (JIS 0208-1990 and 0121-1990)',
132
+ 20936 => 'Simplified Chinese (GB2312)',
133
+ 20949 => 'Korean Wansung',
134
+ 21025 => 'IBM EBCDIC Cyrillic Serbian-Bulgarian',
135
+ 21027 => 'Extended Alpha Lowercase (deprecated)',
136
+ 21866 => 'Ukrainian/Cyrillic (KOI8-U)',
137
+ 28591 => 'ISO 8859-1 Latin 1 (Western European)',
138
+ 28592 => 'ISO 8859-2 (Central European)',
139
+ 28593 => 'ISO 8859-3 Latin 3',
140
+ 28594 => 'ISO 8859-4 Baltic',
141
+ 28595 => 'ISO 8859-5 Cyrillic',
142
+ 28596 => 'ISO 8859-6 Arabic',
143
+ 28597 => 'ISO 8859-7 Greek',
144
+ 28598 => 'ISO 8859-8 Hebrew (Visual)',
145
+ 28599 => 'ISO 8859-9 Turkish',
146
+ 28603 => 'ISO 8859-13 Estonian',
147
+ 28605 => 'ISO 8859-15 Latin 9',
148
+ 29001 => 'Europa 3',
149
+ 38598 => 'ISO 8859-8 Hebrew (Logical)',
150
+ 50220 => 'ISO 2022 Japanese with no halfwidth Katakana (JIS)',
151
+ 50221 => 'ISO 2022 Japanese with halfwidth Katakana (JIS-Allow 1 byte Kana)',
152
+ 50222 => 'ISO 2022 Japanese JIS X 0201-1989 (JIS-Allow 1 byte Kana - SO/SI)',
153
+ 50225 => 'ISO 2022 Korean',
154
+ 50227 => 'ISO 2022 Simplified Chinese',
155
+ 50229 => 'ISO 2022 Traditional Chinese',
156
+ 50930 => 'EBCDIC Japanese (Katakana) Extended',
157
+ 50931 => 'EBCDIC US-Canada and Japanese',
158
+ 50933 => 'EBCDIC Korean Extended and Korean',
159
+ 50935 => 'EBCDIC Simplified Chinese Extended and Simplified Chinese',
160
+ 50936 => 'EBCDIC Simplified Chinese',
161
+ 50937 => 'EBCDIC US-Canada and Traditional Chinese',
162
+ 50939 => 'EBCDIC Japanese (Latin) Extended and Japanese',
163
+ 51932 => 'EUC Japanese',
164
+ 51936 => 'EUC Simplified Chinese',
165
+ 51949 => 'EUC Korean',
166
+ 51950 => 'EUC Traditional Chinese',
167
+ 52936 => 'HZ-GB2312 Simplified Chinese',
168
+ 54936 => 'Windows XP and later: GB18030 Simplified Chinese (4 byte)',
169
+ 57002 => 'ISCII Devanagari',
170
+ 57003 => 'ISCII Bengali',
171
+ 57004 => 'ISCII Tamil',
172
+ 57005 => 'ISCII Telugu',
173
+ 57006 => 'ISCII Assamese',
174
+ 57007 => 'ISCII Oriya',
175
+ 57008 => 'ISCII Kannada',
176
+ 57009 => 'ISCII Malayalam',
177
+ 57010 => 'ISCII Gujarati',
178
+ 57011 => 'ISCII Punjabi',
179
+ 65000 => 'Unicode (UTF-7)',
180
+ 65001 => 'Unicode (UTF-8)',
181
+ );
182
+
26
183
  # tags written by Microsoft HDView (ref 1)
27
184
  %Image::ExifTool::Microsoft::Stitch = (
28
185
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -2411,7 +2411,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
2411
2411
  0x5a => { #15
2412
2412
  Name => 'Rotation',
2413
2413
  PrintConv => {
2414
- 0 => 'Horizontal (Normal)',
2414
+ 0 => 'Horizontal (normal)',
2415
2415
  1 => 'Rotate 270 CW',
2416
2416
  2 => 'Rotate 90 CW',
2417
2417
  },
@@ -60,12 +60,12 @@ package Image::ExifTool::Nikon;
60
60
  use strict;
61
61
  use vars qw($VERSION %nikonLensIDs %nikonTextEncoding);
62
62
  use Image::ExifTool qw(:DataAccess :Utils);
63
- use Image::ExifTool::NikonCustom qw(%buttonsZ9);
63
+ use Image::ExifTool::NikonCustom qw(%buttonsZ8 %buttonsZ9);
64
64
  use Image::ExifTool::Exif;
65
65
  use Image::ExifTool::GPS;
66
66
  use Image::ExifTool::XMP;
67
67
 
68
- $VERSION = '4.46';
68
+ $VERSION = '4.49';
69
69
 
70
70
  sub LensIDConv($$$);
71
71
  sub ProcessNikonAVI($$$);
@@ -1013,7 +1013,7 @@ my %hDMIOutputResolutionZ9 = (
1013
1013
  1 => '4320p',
1014
1014
  2 => '2160p',
1015
1015
  3 => '1080p',
1016
- #4 => '1080i',
1016
+ 4 => '1080i',
1017
1017
  5 => '720p',
1018
1018
  #6 => '576p',
1019
1019
  #7 => '480p',
@@ -1059,8 +1059,8 @@ my %imageAreaZ9b = (
1059
1059
  );
1060
1060
 
1061
1061
  my %infoZSeries = (
1062
- Condition => '$$self{Model} =~ /^NIKON Z (30|5|50|6|6_2|7|7_2|8|f|fc|9)\b/i',
1063
- Notes => 'Z Series cameras thru October 2023',
1062
+ Condition => '$$self{Model} =~ /^NIKON Z (30|5|50|6|6_2|7|7_2|8|f|fc|9)\b/i or $$self{Model} =~ /^NIKON Z(5_2|50_2|6_3)\b/i', #no space after 'Nikon Z' on models from Oct 2023
1063
+ Notes => 'Z Series cameras thru July 2025',
1064
1064
  );
1065
1065
 
1066
1066
  my %iSOAutoHiLimitZ6III = ( #28
@@ -1691,14 +1691,15 @@ my %cropHiSpeed = ( #IB
1691
1691
  4 => '3:2 Crop', # (1.2x, ref 36)
1692
1692
  6 => '16:9 Crop',
1693
1693
  8 => '2.7x Crop', #36 (D4/D500)
1694
- 9 => 'DX Movie Crop', # (DX during movie recording, Large)
1694
+ 9 => 'DX Movie 16:9 Crop', # (DX during movie recording, Large)
1695
1695
  10 => '1.3x Movie Crop', #36 (D4/D500)
1696
1696
  11 => 'FX Uncropped',
1697
1697
  12 => 'DX Uncropped',
1698
1698
  13 => '2.8x Movie Crop', #28 (D5/D6) 5584/1936
1699
1699
  14 => '1.4x Movie Crop', #28 (D5/D6) 5584/3856
1700
1700
  15 => '1.5x Movie Crop', #36 (D4/D500) 5600/3872
1701
- 17 => '1:1 Crop',
1701
+ 17 => 'FX 1:1 Crop',
1702
+ 18 => 'DX 1:1 Crop',
1702
1703
  OTHER => sub {
1703
1704
  my ($val, $inv, $conv) = @_;
1704
1705
  return undef if $inv;
@@ -2597,7 +2598,7 @@ my %base64coord = (
2597
2598
  },
2598
2599
  },
2599
2600
  { # (Z6_3 firmware version 1.00, ref 28)
2600
- Condition => '$$valPt =~ /^0809/',
2601
+ Condition => '$$valPt =~ /^08(09|10|11)/', #0809=Z6iii 0810=Z50ii #0811=Z5ii
2601
2602
  Name => 'ShotInfoZ6III',
2602
2603
  SubDirectory => {
2603
2604
  TagTable => 'Image::ExifTool::Nikon::ShotInfoZ6III',
@@ -4919,7 +4920,7 @@ my %base64coord = (
4919
4920
  DATAMEMBER => [ 0, 4, 5, 7, 66, 68 ],
4920
4921
  NOTES => q{
4921
4922
  AF information for Nikon cameras with the Expeed 7 processor: The Zf, Z6_3,
4922
- Z8, Z9 and Z50_3.
4923
+ Z8, Z9, Z50_2 and Z5_2.
4923
4924
  },
4924
4925
  0 => {
4925
4926
  Name => 'AFInfo2Version',
@@ -4965,8 +4966,8 @@ my %base64coord = (
4965
4966
  PrintConv => sub { PrintAFPoints(shift, \@afPoints405) }, #full-frame sensor, 45MP, auto-area focus point configuration
4966
4967
  PrintConvInv => sub { PrintAFPointsInv(shift, \@afPoints405) },
4967
4968
  },{
4968
- Name => 'AFPointsUsed', # Z6iii and Zf (AFInfo2Version 0401)
4969
- Condition => '$$self{Model} =~ /^NIKON (Z6_3|Z f)\b/i and ($$self{AFAreaModeUsed} == 197 or $$self{AFAreaModeUsed} == 207)',
4969
+ Name => 'AFPointsUsed', # Z6iii & Zf (AFInfo2Version 0401) and Z5ii (AFInfo2Version 0402)
4970
+ Condition => '$$self{Model} =~ /^NIKON (Z6_3|Z f|Z5_2)\b/i and ($$self{AFAreaModeUsed} == 197 or $$self{AFAreaModeUsed} == 207)',
4970
4971
  Format => 'undef[38]',
4971
4972
  ValueConv => 'join(" ", unpack("H2"x38, $val))',
4972
4973
  ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
@@ -5000,17 +5001,17 @@ my %base64coord = (
5000
5001
  0x43 => [
5001
5002
  {
5002
5003
  Name => 'FocusPositionHorizontal', # 209/231 focus point cameras
5003
- Condition => '$$self{Model} =~ /^NIKON Z50_2\b/i and $$self{AFAreaXPosition} != 0', #model Z50ii
5004
+ Condition => '$$self{Model} =~ /^NIKON Z50_2\b/i and $$self{AFAreaXPosition} and $$self{AFAreaXPosition} != 0', #model Z50ii
5004
5005
  ValueConv => 'int($$self{AFAreaXPosition} / 260 )', #divisor is the estimated separation between adjacent points (informed by the measured Z7ii separation)
5005
5006
  PrintConv => sub { my ($val) = @_; PrintAFPointsLeftRight($val, 19 ) },
5006
5007
  },{
5007
5008
  Name => 'FocusPositionHorizontal', #273/299 focus point cameras
5008
- Condition => '$$self{Model} =~ /^NIKON (Z6_3|Z f)\b/i and $$self{AFAreaXPosition} != 0', #models Z6iii and Zf
5009
+ Condition => '$$self{Model} =~ /^NIKON (Z6_3|Z f|Z5_2)\b/i and $$self{AFAreaXPosition} and $$self{AFAreaXPosition} != 0', #models Z6iii, Zf & Z5ii
5009
5010
  ValueConv => 'int($$self{AFAreaXPosition} / 260 )', #divisor is the estimated separation between adjacent points (informed by the measured Z7ii separation)
5010
5011
  PrintConv => sub { my ($val) = @_; PrintAFPointsLeftRight($val, 21 ) },
5011
5012
  },{
5012
5013
  Name => 'FocusPositionHorizontal', #405/493 focus point cameras
5013
- Condition => '$$self{Model} =~ /^NIKON (Z 8|Z 9)\b/i and $$self{AFAreaXPosition} != 0', #models Z8 and Z9
5014
+ Condition => '$$self{Model} =~ /^NIKON (Z 8|Z 9)\b/i and $$self{AFAreaXPosition} and $$self{AFAreaXPosition} != 0', #models Z8 and Z9
5014
5015
  ValueConv => 'int($$self{AFAreaXPosition} / 260 )', #divisor is the measured horizontal pixel separation between adjacent points
5015
5016
  PrintConv => sub { my ($val) = @_; PrintAFPointsLeftRight($val, 29 ) },
5016
5017
  },
@@ -5024,17 +5025,17 @@ my %base64coord = (
5024
5025
  0x45 => [
5025
5026
  {
5026
5027
  Name => 'FocusPositionVertical', # 209/233 focus point cameras
5027
- Condition => '$$self{Model} =~ /^NIKON Z50_2\b/i and $$self{AFAreaYPosition} != 0', #model Z50ii
5028
+ Condition => '$$self{Model} =~ /^NIKON Z50_2\b/i and $$self{AFAreaYPosition} and $$self{AFAreaYPosition} != 0', #model Z50ii
5028
5029
  ValueConv => 'int($$self{AFAreaYPosition} / 286 )', #divisor chosen to cause center point report 'C'
5029
5030
  PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 11 ) },
5030
5031
  },{
5031
5032
  Name => 'FocusPositionVertical', #273/299 focus point cameras
5032
- Condition => '$$self{Model} =~ /^NIKON (Z6_3|Z f)\b/i and $$self{AFAreaYPosition} != 0', #models Z6iii and Zf
5033
+ Condition => '$$self{Model} =~ /^NIKON (Z6_3|Z f|Z5_2)\b/i and $$self{AFAreaYPosition} and $$self{AFAreaYPosition} != 0', #models Z6iii, Zf & Z5ii
5033
5034
  ValueConv => 'int($$self{AFAreaYPosition} / 286 )', #divisor chosen to cause center point report 'C'
5034
5035
  PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 13 ) },
5035
5036
  },{
5036
5037
  Name => 'FocusPositionVertical', #405/493 focus point cameras
5037
- Condition => '$$self{Model} =~ /^NIKON (Z 8|Z 9)\b/i and $$self{AFAreaYPosition} != 0', #models Z8 and Z9
5038
+ Condition => '$$self{Model} =~ /^NIKON (Z 8|Z 9)\b/i and $$self{AFAreaYPosition} and $$self{AFAreaYPosition} != 0', #models Z8 and Z9
5038
5039
  ValueConv => 'int($$self{AFAreaYPosition} / 292 )', #divisor is the measured vertical pixel separation between adjacent points
5039
5040
  PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 17 ) },
5040
5041
  },
@@ -5856,6 +5857,7 @@ my %nikonFocalConversions = (
5856
5857
  46 => 'Nikkor Z 135mm f/1.8 S Plena', #28
5857
5858
  47 => 'Nikkor Z 35mm f/1.2 S', #28
5858
5859
  48 => 'Nikkor Z 28-400mm f/4-8 VR', #30
5860
+ 49 => 'Nikkor Z 28-135mm f/4 PZ', #28
5859
5861
  51 => 'Nikkor Z 35mm f/1.4', #28
5860
5862
  52 => 'Nikkor Z 50mm f/1.4', #28
5861
5863
  2305 => 'Laowa FFII 10mm F2.8 C&D Dreamer', #30
@@ -8667,6 +8669,7 @@ my %nikonFocalConversions = (
8667
8669
  },
8668
8670
  0x90 => {
8669
8671
  Name => 'MenuOffset',
8672
+ Condition => '$$self{Model} =~ /^NIKON Z6_3\b/i',
8670
8673
  Format => 'int32u',
8671
8674
  SubDirectory => {
8672
8675
  TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ6III',
@@ -9005,12 +9008,17 @@ my %nikonFocalConversions = (
9005
9008
  RawConv => '$$self{FocusShiftShooting} = $val',
9006
9009
  PrintConv => q{
9007
9010
  return 'Off' if $val == 0 ;
9008
- my $i = sprintf("Frame %.0f of %.0f",$val, $$self{FocusShiftNumberShots}); # something like Frame 1 of 100"
9011
+ my $i = sprintf("Frame %.0f of %.0f",$val, $$self{FocusShiftNumberShots}); # something like Frame 1 of 100"
9012
+ if ($$self{PixelShiftActive} and $$self{PixelShiftActive} eq 1) {$i = sprintf("Frame %.0f",$val);} #for the Z8 fw3 with PixelShift Enabled, the frame count is correct, but the frame total needs to be multiplied by the number of PixelShift frames (which I cannot find)
9009
9013
  return "On: $i"
9010
9014
  },
9015
+ Hook => '$varSize += 2 if $$self{Model} =~ /^NIKON Z 8/ and $$self{FirmwareVersion} and $$self{FirmwareVersion} ge "03.00"', # 2 bytes were added with Z8 firmware 3.0 support for pixel shift when focus stacking
9011
9016
  },
9017
+ #
9018
+ # Note: Offsets after this are shifted by +2 for Z8 firmware 3.0 (see Hook above)
9019
+ #
9012
9020
  0x0028 => {
9013
- Name => 'IntervalShooting',
9021
+ Name => 'IntervalShooting', #will be 'On' when Interval Shooting is selected via the Photo Shooting Menu and also when a non-zero interval is specified when using Focus Shift and/or Pixel Shift Shooting
9014
9022
  Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
9015
9023
  RawConv => '$$self{IntervalShooting} = $val',
9016
9024
  Format => 'int16u',
@@ -9789,7 +9797,7 @@ my %nikonFocalConversions = (
9789
9797
  %Image::ExifTool::Nikon::MenuSettingsZ8 = (
9790
9798
  %binaryDataAttrs,
9791
9799
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
9792
- DATAMEMBER => [ 72, 152, 200, 204, 244, 440, 548, 554, 570, 596 ],
9800
+ DATAMEMBER => [ 72, 152, 200, 204, 244, 440, 548, 554, 570, 596, 636 ],
9793
9801
  NOTES => 'These tags are common to all Z8 firmware versions.',
9794
9802
  72 => {
9795
9803
  Name => 'HighFrameRate', #CH and C30/C60/C120 but not CL
@@ -9804,7 +9812,7 @@ my %nikonFocalConversions = (
9804
9812
  RawConv => '$$self{MultipleExposureMode} = $val',
9805
9813
  PrintConv => \%multipleExposureModeZ9,
9806
9814
  },
9807
- 154 => {Name => 'MultiExposureShots', Condition => '$$self{MultipleExposureMode} != 0'}, #range 2-9
9815
+ 154 => {Name => 'MultiExposureShots', Condition => '$$self{MultipleExposureMode} != 0'}, #range 2-9 - not present in a NEF, only in the assembled JPG
9808
9816
  184 => {
9809
9817
  Name => 'IntervalDurationHours',
9810
9818
  Format => 'int32u',
@@ -9903,7 +9911,7 @@ my %nikonFocalConversions = (
9903
9911
  Notes => 'AE and/or Flash Bracketing',
9904
9912
  PrintConv => \%bracketIncrementZ9,
9905
9913
  },
9906
- 570 => { Name => 'HDR', RawConv => '$$self{HDR} = $val', PrintConv => \%multipleExposureModeZ9 },
9914
+ 570 => { Name => 'HDR', RawConv => '$$self{HDR} = $val', PrintConv => \%multipleExposureModeZ9 }, #will be 'on' for the tone mapped JPGs, off for the source NEF files
9907
9915
  #572 HDRSaveRaw 0=> No; 1=> Yes
9908
9916
  576 => { Name => 'SecondarySlotFunction', PrintConv => \%secondarySlotFunctionZ9 },
9909
9917
  582 => { Name => 'HDRLevel', Condition => '$$self{HDR} ne 0', PrintConv => \%hdrLevelZ8 },
@@ -9918,7 +9926,15 @@ my %nikonFocalConversions = (
9918
9926
  },
9919
9927
  618 => { Name => 'ToneMap', PrintConv => { 0 => 'SDR', 1 => 'HLG' }, Unknown => 1 },
9920
9928
  622 => { Name => 'PortraitImpressionBalance', PrintConv => \%portraitImpressionBalanceZ8 },
9921
- 636 => { Name => 'HighFrequencyFlickerReduction', PrintConv => \%offOn, Unknown => 1 }, # new with firmware 3.0
9929
+ 636 => {
9930
+ Name => 'HighFrequencyFlickerReduction',
9931
+ PrintConv => \%offOn,
9932
+ Unknown => 1,
9933
+ Hook => '$varSize += 4 if $$self{FirmwareVersion} and $$self{FirmwareVersion} ge "03.00"',
9934
+ },
9935
+ #
9936
+ # firmware 3.00 adds 4 bytes somewhere in the range 638-730 (hence the Hook above)
9937
+ #
9922
9938
  730 => {
9923
9939
  Name => 'MovieImageArea',
9924
9940
  Unknown => 1,
@@ -10027,7 +10043,15 @@ my %nikonFocalConversions = (
10027
10043
  Name => 'MenuSettingsZ8',
10028
10044
  Format => 'undef[943]',
10029
10045
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::MenuSettingsZ8' },
10030
- Hook => '$varSize += 4 if $$self{FirmwareVersion} and $$self{FirmwareVersion} ge "02.10"',
10046
+ Hook => q{
10047
+ if ($$self{FirmwareVersion}) {
10048
+ if ($$self{FirmwareVersion} =~ /^02\.10/) {
10049
+ $varSize += 4;
10050
+ } elsif ($$self{FirmwareVersion} ge "03.0") {
10051
+ $varSize += 8
10052
+ }
10053
+ }
10054
+ },
10031
10055
  },
10032
10056
  943 => {
10033
10057
  Name => 'CustomSettingsZ8',
@@ -10078,22 +10102,26 @@ my %nikonFocalConversions = (
10078
10102
  1880 => { Name => 'NonCPULens18MaxAperture', Format => 'int32u', PrintConv => 'sprintf("%.1fmm",$val/100)', Unknown => 1},
10079
10103
  1884 => { Name => 'NonCPULens19MaxAperture', Format => 'int32u', PrintConv => 'sprintf("%.1fmm",$val/100)', Unknown => 1},
10080
10104
  1888 => { Name => 'NonCPULens20MaxAperture', Format => 'int32u', PrintConv => 'sprintf("%.1fmm",$val/100)', Unknown => 1},
10081
- 1824 => { Name => 'HDMIOutputResolution', PrintConv => \%hDMIOutputResolutionZ9 },
10082
- 1842 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
10083
- 1843 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
10084
- 1878 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
10085
- 1906 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
10086
- 1915 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
10105
+ 1904 => { Name => 'HDMIOutputResolution', PrintConv => \%hDMIOutputResolutionZ9 },
10106
+ 1922 => { Name => 'AirplaneMode', PrintConv => \%offOn, Unknown => 1 },
10107
+ 1923 => { Name => 'EmptySlotRelease', PrintConv => { 0 => 'Disable Release', 1 => 'Enable Release' }, Unknown => 1 },
10108
+ 1958 => { Name => 'EnergySavingMode', PrintConv => \%offOn, Unknown => 1 },
10109
+ 1986 => { Name => 'USBPowerDelivery', PrintConv => \%offOn, Unknown => 1 },
10110
+ 1995 => { Name => 'SensorShield', PrintConv => { 0 => 'Stays Open', 1 => 'Closes' }, Unknown => 1 },
10087
10111
  2046 => { Name => 'PixelShiftShooting', RawConv => '$$self{PixelShiftShooting} = $val', PrintConv => \%multipleExposureModeZ9 }, #off/on/on (series)
10088
10112
  2048 => { Name => 'PixelShiftNumberShots', Condition => '$$self{PixelShiftShooting} > 0', PrintConv => \%pixelShiftNumberShots },
10089
10113
  2050 => { Name => 'PixelShiftDelay', Condition => '$$self{PixelShiftShooting} > 0', PrintConv => \%pixelShiftDelay },
10090
- 2052 => { Name => 'PlaybackButton', %buttonsZ9 }, #CSf2
10091
- 2054 => { Name => 'WBButton', %buttonsZ9}, #CSf2
10092
- 2056 => { Name => 'BracketButton', %buttonsZ9}, #CSf2
10093
- 2058 => { Name => 'LensFunc1ButtonPlaybackMode', %buttonsZ9}, #CSf2
10094
- 2060 => { Name => 'LensFunc2ButtonPlaybackMode', %buttonsZ9}, #CSf2
10095
- 2062 => { Name => 'PlaybackButtonPlaybackMode', %buttonsZ9}, #CSf2
10096
- 2064 => { Name => 'BracketButtonPlaybackMode', %buttonsZ9}, #CSf2
10114
+ 2052 => { Name => 'PlaybackButton', %buttonsZ8 }, #CSf2
10115
+ 2054 => { Name => 'WBButton', %buttonsZ8}, #CSf2
10116
+ 2056 => { Name => 'BracketButton', %buttonsZ8}, #CSf2
10117
+ 2058 => { Name => 'LensFunc1ButtonPlaybackMode', %buttonsZ8}, #CSf3
10118
+ 2060 => { Name => 'LensFunc2ButtonPlaybackMode', %buttonsZ8}, #CSf3
10119
+ 2062 => { Name => 'PlaybackButtonPlaybackMode', %buttonsZ8}, #CSf3
10120
+ 2064 => { Name => 'BracketButtonPlaybackMode', %buttonsZ8}, #CSf3
10121
+ #2088 FlickerFrequencyPreset #Z8 fw 3.0
10122
+ 2206 => { Name => 'MaximumApertureLV', PrintConv => \%offOn, Unknown => 1 }, #CSa14
10123
+ 2208 => { Name => 'ReleaseModeButton', %buttonsZ8}, #CSf2
10124
+ 2216 => { Name => 'ReleaseModeButtonPlaybackMode', %buttonsZ8}, #CSf3
10097
10125
  );
10098
10126
 
10099
10127
  %Image::ExifTool::Nikon::MenuSettingsZ9 = (
@@ -12056,6 +12084,7 @@ my %nikonFocalConversions = (
12056
12084
  %Image::ExifTool::Nikon::MakerNotes0x56 = (
12057
12085
  %binaryDataAttrs,
12058
12086
  GROUPS => { 0 => 'MakerNotes' },
12087
+ DATAMEMBER => [ 12 ],
12059
12088
  0 => {
12060
12089
  Name => 'FirmwareVersion56',
12061
12090
  Format => 'string[4]',
@@ -12066,6 +12095,11 @@ my %nikonFocalConversions = (
12066
12095
  Name => 'BurstGroupID', #all frames shot within a burst (using CL/CH/C30/C60/C120) will share the same BurstGroupID. Value will be > 0 for all images shot in continuous modes (or via Pixel Shift). 0 for single-frame.
12067
12096
  Format => 'int16u'
12068
12097
  },
12098
+ 12 => {
12099
+ Name => 'PixelShiftID', # 1 => Pixel shift enabled (either directly or thru Focus Shift Shooting with Z8 fw 3.0)
12100
+ RawConv => '$$self{PixelShiftActive} = $val',
12101
+ Hidden => 1
12102
+ },
12069
12103
  );
12070
12104
 
12071
12105
  # extra info found in IFD0 of NEF files (ref PH, Z6/Z7)
@@ -12104,6 +12138,7 @@ my %nikonFocalConversions = (
12104
12138
  Name => 'DistortionCorrection', #used by ACR to determine whether the built-in lens profile is applied
12105
12139
  Format => 'int8u',
12106
12140
  PrintConv => {
12141
+ 0 => 'No Lens Attached', #to prevent reporting 'Unknown'
12107
12142
  1 => 'On (Optional)',
12108
12143
  2 => 'Off',
12109
12144
  3 => 'On (Required)',
@@ -12791,7 +12826,7 @@ my %nikonFocalConversions = (
12791
12826
  Name => 'UnknownInfo',
12792
12827
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::UnknownInfo' },
12793
12828
  },
12794
- # 0x200002d - int16u[3]: "512 0 0"
12829
+ # 0x200002d - int16u[3]: "512 0 0", "512 1 14", "512 3 10"
12795
12830
  0x2000032 => {
12796
12831
  Name => 'UnknownInfo2',
12797
12832
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::UnknownInfo2' },
@@ -12804,10 +12839,12 @@ my %nikonFocalConversions = (
12804
12839
  # 0x200003f - rational64s[2]: "0 0"
12805
12840
  # 0x2000042 - undef[6]: "0100\x03\0"
12806
12841
  # 0x2000043 - undef[12]: all zeros
12842
+ # 0x200004d - undef[84]: "0100\0\0\0\0x020100\0\0\0\x010100\0\0\0\x05\0\0\..."
12807
12843
  0x200004e => {
12808
12844
  Name => 'NikonSettings',
12809
12845
  SubDirectory => { TagTable => 'Image::ExifTool::NikonSettings::Main' },
12810
12846
  },
12847
+ # 0x2000055 - undef[8]: "0100\x01\0\0\0"
12811
12848
  0x2000083 => {
12812
12849
  Name => 'LensType',
12813
12850
  # credit to Tom Christiansen (ref 7) for figuring this out...
@@ -13011,7 +13048,11 @@ my %nikonFocalConversions = (
13011
13048
  Condition => '$$valPt =~ /^040[012]/',
13012
13049
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AFInfo2V0400' },
13013
13050
  }],
13014
- # 0x20000c0 - undef[8]
13051
+ # 0x20000c0 - undef[8]:
13052
+ # 34 01 0c 00 90 01 0c 00
13053
+ # 34 01 0c 00 9c 01 0c 00
13054
+ # 3c 01 0c 00 9c 01 0c 00
13055
+ # 3c 01 0c 00 a8 01 0c 00
13015
13056
  0x20000c3 => {
13016
13057
  Name => 'BarometerInfo',
13017
13058
  SubDirectory => {