/src/libraw/src/metadata/nikon.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2025 LibRaw LLC (info@libraw.org) |
3 | | * |
4 | | LibRaw is free software; you can redistribute it and/or modify |
5 | | it under the terms of the one of two licenses as you choose: |
6 | | |
7 | | 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
8 | | (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
9 | | |
10 | | 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
11 | | (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
12 | | |
13 | | */ |
14 | | |
15 | | #include "../../internal/dcraw_defs.h" |
16 | | |
17 | | // void hexDump(char *title, void *addr, int len); |
18 | | |
19 | | unsigned sget4_order (short _order, uchar *s); |
20 | | double sget_fixed32u (short _order, uchar *s); |
21 | | double AngleConversion_a (short _order, uchar *s); |
22 | | double AngleConversion (short _order, uchar *s); |
23 | | |
24 | | static const uchar xlat[2][256] = { |
25 | | {0xc1, 0xbf, 0x6d, 0x0d, 0x59, 0xc5, 0x13, 0x9d, 0x83, 0x61, 0x6b, 0x4f, |
26 | | 0xc7, 0x7f, 0x3d, 0x3d, 0x53, 0x59, 0xe3, 0xc7, 0xe9, 0x2f, 0x95, 0xa7, |
27 | | 0x95, 0x1f, 0xdf, 0x7f, 0x2b, 0x29, 0xc7, 0x0d, 0xdf, 0x07, 0xef, 0x71, |
28 | | 0x89, 0x3d, 0x13, 0x3d, 0x3b, 0x13, 0xfb, 0x0d, 0x89, 0xc1, 0x65, 0x1f, |
29 | | 0xb3, 0x0d, 0x6b, 0x29, 0xe3, 0xfb, 0xef, 0xa3, 0x6b, 0x47, 0x7f, 0x95, |
30 | | 0x35, 0xa7, 0x47, 0x4f, 0xc7, 0xf1, 0x59, 0x95, 0x35, 0x11, 0x29, 0x61, |
31 | | 0xf1, 0x3d, 0xb3, 0x2b, 0x0d, 0x43, 0x89, 0xc1, 0x9d, 0x9d, 0x89, 0x65, |
32 | | 0xf1, 0xe9, 0xdf, 0xbf, 0x3d, 0x7f, 0x53, 0x97, 0xe5, 0xe9, 0x95, 0x17, |
33 | | 0x1d, 0x3d, 0x8b, 0xfb, 0xc7, 0xe3, 0x67, 0xa7, 0x07, 0xf1, 0x71, 0xa7, |
34 | | 0x53, 0xb5, 0x29, 0x89, 0xe5, 0x2b, 0xa7, 0x17, 0x29, 0xe9, 0x4f, 0xc5, |
35 | | 0x65, 0x6d, 0x6b, 0xef, 0x0d, 0x89, 0x49, 0x2f, 0xb3, 0x43, 0x53, 0x65, |
36 | | 0x1d, 0x49, 0xa3, 0x13, 0x89, 0x59, 0xef, 0x6b, 0xef, 0x65, 0x1d, 0x0b, |
37 | | 0x59, 0x13, 0xe3, 0x4f, 0x9d, 0xb3, 0x29, 0x43, 0x2b, 0x07, 0x1d, 0x95, |
38 | | 0x59, 0x59, 0x47, 0xfb, 0xe5, 0xe9, 0x61, 0x47, 0x2f, 0x35, 0x7f, 0x17, |
39 | | 0x7f, 0xef, 0x7f, 0x95, 0x95, 0x71, 0xd3, 0xa3, 0x0b, 0x71, 0xa3, 0xad, |
40 | | 0x0b, 0x3b, 0xb5, 0xfb, 0xa3, 0xbf, 0x4f, 0x83, 0x1d, 0xad, 0xe9, 0x2f, |
41 | | 0x71, 0x65, 0xa3, 0xe5, 0x07, 0x35, 0x3d, 0x0d, 0xb5, 0xe9, 0xe5, 0x47, |
42 | | 0x3b, 0x9d, 0xef, 0x35, 0xa3, 0xbf, 0xb3, 0xdf, 0x53, 0xd3, 0x97, 0x53, |
43 | | 0x49, 0x71, 0x07, 0x35, 0x61, 0x71, 0x2f, 0x43, 0x2f, 0x11, 0xdf, 0x17, |
44 | | 0x97, 0xfb, 0x95, 0x3b, 0x7f, 0x6b, 0xd3, 0x25, 0xbf, 0xad, 0xc7, 0xc5, |
45 | | 0xc5, 0xb5, 0x8b, 0xef, 0x2f, 0xd3, 0x07, 0x6b, 0x25, 0x49, 0x95, 0x25, |
46 | | 0x49, 0x6d, 0x71, 0xc7}, |
47 | | {0xa7, 0xbc, 0xc9, 0xad, 0x91, 0xdf, 0x85, 0xe5, 0xd4, 0x78, 0xd5, 0x17, |
48 | | 0x46, 0x7c, 0x29, 0x4c, 0x4d, 0x03, 0xe9, 0x25, 0x68, 0x11, 0x86, 0xb3, |
49 | | 0xbd, 0xf7, 0x6f, 0x61, 0x22, 0xa2, 0x26, 0x34, 0x2a, 0xbe, 0x1e, 0x46, |
50 | | 0x14, 0x68, 0x9d, 0x44, 0x18, 0xc2, 0x40, 0xf4, 0x7e, 0x5f, 0x1b, 0xad, |
51 | | 0x0b, 0x94, 0xb6, 0x67, 0xb4, 0x0b, 0xe1, 0xea, 0x95, 0x9c, 0x66, 0xdc, |
52 | | 0xe7, 0x5d, 0x6c, 0x05, 0xda, 0xd5, 0xdf, 0x7a, 0xef, 0xf6, 0xdb, 0x1f, |
53 | | 0x82, 0x4c, 0xc0, 0x68, 0x47, 0xa1, 0xbd, 0xee, 0x39, 0x50, 0x56, 0x4a, |
54 | | 0xdd, 0xdf, 0xa5, 0xf8, 0xc6, 0xda, 0xca, 0x90, 0xca, 0x01, 0x42, 0x9d, |
55 | | 0x8b, 0x0c, 0x73, 0x43, 0x75, 0x05, 0x94, 0xde, 0x24, 0xb3, 0x80, 0x34, |
56 | | 0xe5, 0x2c, 0xdc, 0x9b, 0x3f, 0xca, 0x33, 0x45, 0xd0, 0xdb, 0x5f, 0xf5, |
57 | | 0x52, 0xc3, 0x21, 0xda, 0xe2, 0x22, 0x72, 0x6b, 0x3e, 0xd0, 0x5b, 0xa8, |
58 | | 0x87, 0x8c, 0x06, 0x5d, 0x0f, 0xdd, 0x09, 0x19, 0x93, 0xd0, 0xb9, 0xfc, |
59 | | 0x8b, 0x0f, 0x84, 0x60, 0x33, 0x1c, 0x9b, 0x45, 0xf1, 0xf0, 0xa3, 0x94, |
60 | | 0x3a, 0x12, 0x77, 0x33, 0x4d, 0x44, 0x78, 0x28, 0x3c, 0x9e, 0xfd, 0x65, |
61 | | 0x57, 0x16, 0x94, 0x6b, 0xfb, 0x59, 0xd0, 0xc8, 0x22, 0x36, 0xdb, 0xd2, |
62 | | 0x63, 0x98, 0x43, 0xa1, 0x04, 0x87, 0x86, 0xf7, 0xa6, 0x26, 0xbb, 0xd6, |
63 | | 0x59, 0x4d, 0xbf, 0x6a, 0x2e, 0xaa, 0x2b, 0xef, 0xe6, 0x78, 0xb6, 0x4e, |
64 | | 0xe0, 0x2f, 0xdc, 0x7c, 0xbe, 0x57, 0x19, 0x32, 0x7e, 0x2a, 0xd0, 0xb8, |
65 | | 0xba, 0x29, 0x00, 0x3c, 0x52, 0x7d, 0xa8, 0x49, 0x3b, 0x2d, 0xeb, 0x25, |
66 | | 0x49, 0xfa, 0xa3, 0xaa, 0x39, 0xa7, 0xc5, 0xa7, 0x50, 0x11, 0x36, 0xfb, |
67 | | 0xc6, 0x67, 0x4a, 0xf5, 0xa5, 0x12, 0x65, 0x7e, 0xb0, 0xdf, 0xaf, 0x4e, |
68 | | 0xb3, 0x61, 0x7f, 0x2f} }; |
69 | | |
70 | | void LibRaw::processNikonLensData(uchar *LensData, unsigned len) |
71 | 58 | { |
72 | | |
73 | 58 | ushort i=0; |
74 | 58 | if (imgdata.lens.nikon.LensType & 0x80) { |
75 | 8 | strcpy (ilm.LensFeatures_pre, "AF-P"); |
76 | 50 | } else if (!(imgdata.lens.nikon.LensType & 0x01)) { |
77 | 42 | ilm.LensFeatures_pre[0] = 'A'; |
78 | 42 | ilm.LensFeatures_pre[1] = 'F'; |
79 | 42 | } else { |
80 | 8 | ilm.LensFeatures_pre[0] = 'M'; |
81 | 8 | ilm.LensFeatures_pre[1] = 'F'; |
82 | 8 | } |
83 | | |
84 | 58 | if (imgdata.lens.nikon.LensType & 0x40) { |
85 | 6 | ilm.LensFeatures_suf[0] = 'E'; |
86 | 52 | } else if (imgdata.lens.nikon.LensType & 0x04) { |
87 | 5 | ilm.LensFeatures_suf[0] = 'G'; |
88 | 47 | } else if (imgdata.lens.nikon.LensType & 0x02) { |
89 | 18 | ilm.LensFeatures_suf[0] = 'D'; |
90 | 18 | } |
91 | | |
92 | 58 | if (imgdata.lens.nikon.LensType & 0x08) |
93 | 7 | { |
94 | 7 | ilm.LensFeatures_suf[1] = ' '; |
95 | 7 | ilm.LensFeatures_suf[2] = 'V'; |
96 | 7 | ilm.LensFeatures_suf[3] = 'R'; |
97 | 7 | } |
98 | | |
99 | 58 | if (imgdata.lens.nikon.LensType & 0x10) |
100 | 11 | { |
101 | 11 | ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; |
102 | 11 | ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1INCH; |
103 | 11 | } |
104 | 47 | else |
105 | 47 | ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_F; |
106 | | |
107 | 58 | if (imgdata.lens.nikon.LensType & 0x20) |
108 | 7 | { |
109 | 7 | strcpy(ilm.Adapter, "FT-1"); |
110 | 7 | ilm.LensMount = LIBRAW_MOUNT_Nikon_F; |
111 | 7 | ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; |
112 | 7 | ilm.CameraFormat = LIBRAW_FORMAT_1INCH; |
113 | 7 | } |
114 | | |
115 | 58 | imgdata.lens.nikon.LensType = imgdata.lens.nikon.LensType & 0xdf; |
116 | | |
117 | 58 | if ((len < 20) || (len == 58) || (len == 108)) |
118 | 48 | { |
119 | 48 | switch (len) |
120 | 48 | { |
121 | 3 | case 9: |
122 | 3 | i = 2; |
123 | 3 | break; |
124 | 28 | case 15: |
125 | 28 | i = 7; |
126 | 28 | break; |
127 | 1 | case 16: |
128 | 1 | i = 8; |
129 | 1 | break; |
130 | 5 | case 58: // "Z 6", "Z 6 II", "Z 7", "Z 7 II", "Z 50", D780, "Z 5", "Z fc" |
131 | 16 | case 108: // "Z 9", "Z 30", "Z 8", "Z6_2" |
132 | 16 | if (model[6] == 'Z') |
133 | 1 | ilm.CameraMount = LIBRAW_MOUNT_Nikon_Z; |
134 | 16 | if (imNikon.HighSpeedCropFormat != 12) |
135 | 16 | ilm.CameraFormat = LIBRAW_FORMAT_FF; |
136 | 16 | i = 1; |
137 | 24 | while ((LensData[i] == LensData[0]) && (i < 17)) |
138 | 8 | i++; |
139 | 16 | if (i == 17) |
140 | 0 | { |
141 | 0 | ilm.LensMount = LIBRAW_MOUNT_Nikon_Z; |
142 | 0 | ilm.LensID = sget2(LensData + 0x2c); |
143 | 0 | if ( |
144 | 0 | (ilm.LensID == 11) |
145 | 0 | || (ilm.LensID == 12) |
146 | 0 | || (ilm.LensID == 26) |
147 | 0 | || (ilm.LensID == 41) |
148 | 0 | || (ilm.LensID == 43) |
149 | 0 | || (ilm.LensID == 0xd003) |
150 | 0 | ) ilm.LensFormat = LIBRAW_FORMAT_APSC; |
151 | 0 | else ilm.LensFormat = LIBRAW_FORMAT_FF; |
152 | 0 | if (ilm.MaxAp4CurFocal < 0.7f) |
153 | 0 | ilm.MaxAp4CurFocal = libraw_powf64l( |
154 | 0 | 2.0f, (float)sget2(LensData + 0x32) / 384.0f - 1.0f); |
155 | 0 | if (ilm.CurAp < 0.7f) |
156 | 0 | ilm.CurAp = libraw_powf64l( |
157 | 0 | 2.0f, (float)sget2(LensData + 0x34) / 384.0f - 1.0f); |
158 | 0 | if (fabsf(ilm.CurFocal) < 1.1f) |
159 | 0 | ilm.CurFocal = sget2(LensData + 0x38); |
160 | 0 | return; |
161 | 0 | } |
162 | 16 | i = 9; |
163 | 16 | ilm.LensMount = LIBRAW_MOUNT_Nikon_F; |
164 | 16 | if (ilm.CameraMount == LIBRAW_MOUNT_Nikon_Z) |
165 | 1 | strcpy(ilm.Adapter, "FTZ"); |
166 | 16 | break; |
167 | 48 | } |
168 | 48 | imgdata.lens.nikon.LensIDNumber = LensData[i]; |
169 | 48 | imgdata.lens.nikon.LensFStops = LensData[i + 1]; |
170 | 48 | ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f; |
171 | 48 | if (fabsf(ilm.MinFocal) < 1.1f) |
172 | 31 | { |
173 | 31 | if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 2]) |
174 | 29 | ilm.MinFocal = |
175 | 29 | 5.0f * libraw_powf64l(2.0f, (float)LensData[i + 2] / 24.0f); |
176 | 31 | if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 3]) |
177 | 29 | ilm.MaxFocal = |
178 | 29 | 5.0f * libraw_powf64l(2.0f, (float)LensData[i + 3] / 24.0f); |
179 | 31 | if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 4]) |
180 | 29 | ilm.MaxAp4MinFocal = |
181 | 29 | libraw_powf64l(2.0f, (float)LensData[i + 4] / 24.0f); |
182 | 31 | if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 5]) |
183 | 30 | ilm.MaxAp4MaxFocal = |
184 | 30 | libraw_powf64l(2.0f, (float)LensData[i + 5] / 24.0f); |
185 | 31 | } |
186 | 48 | imgdata.lens.nikon.MCUVersion = LensData[i + 6]; |
187 | 48 | if (i != 2) |
188 | 45 | { |
189 | 45 | if ((LensData[i - 1]) && (fabsf(ilm.CurFocal) < 1.1f)) |
190 | 38 | ilm.CurFocal = |
191 | 38 | 5.0f * libraw_powf64l(2.0f, (float)LensData[i - 1] / 24.0f); |
192 | 45 | if (LensData[i + 7]) |
193 | 39 | imgdata.lens.nikon.EffectiveMaxAp = |
194 | 39 | libraw_powf64l(2.0f, (float)LensData[i + 7] / 24.0f); |
195 | 45 | } |
196 | 48 | ilm.LensID = (unsigned long long)LensData[i] << 56 | |
197 | 48 | (unsigned long long)LensData[i + 1] << 48 | |
198 | 48 | (unsigned long long)LensData[i + 2] << 40 | |
199 | 48 | (unsigned long long)LensData[i + 3] << 32 | |
200 | 48 | (unsigned long long)LensData[i + 4] << 24 | |
201 | 48 | (unsigned long long)LensData[i + 5] << 16 | |
202 | 48 | (unsigned long long)LensData[i + 6] << 8 | |
203 | 48 | (unsigned long long)imgdata.lens.nikon.LensType; |
204 | 48 | } |
205 | 10 | else if ((len == 459) || (len == 590)) |
206 | 5 | { |
207 | 5 | memcpy(ilm.Lens, LensData + 390, 64); |
208 | 5 | } |
209 | 5 | else if (len == 509) |
210 | 2 | { |
211 | 2 | memcpy(ilm.Lens, LensData + 391, 64); |
212 | 2 | } |
213 | 3 | else if (len == 879) |
214 | 3 | { |
215 | 3 | memcpy(ilm.Lens, LensData + 680, 64); |
216 | 3 | } |
217 | | |
218 | 58 | return; |
219 | 58 | } |
220 | | |
221 | | void LibRaw::Nikon_NRW_WBtag(int wb, int skip) |
222 | 44.4k | { |
223 | | |
224 | 44.4k | int r, g0, g1, b; |
225 | 44.4k | if (skip) |
226 | 35.6k | get4(); // skip wb "CCT", it is not unique |
227 | 44.4k | r = get4(); |
228 | 44.4k | g0 = get4(); |
229 | 44.4k | g1 = get4(); |
230 | 44.4k | b = get4(); |
231 | 44.4k | if (r && g0 && g1 && b) |
232 | 35.9k | { |
233 | 35.9k | icWBC[wb][0] = r << 1; |
234 | 35.9k | icWBC[wb][1] = g0; |
235 | 35.9k | icWBC[wb][2] = b << 1; |
236 | 35.9k | icWBC[wb][3] = g1; |
237 | 35.9k | } |
238 | 44.4k | return; |
239 | 44.4k | } |
240 | | |
241 | | void LibRaw::parseNikonMakernote(INT64 base, int uptag, unsigned /*dng_writer */) |
242 | 95.4k | { |
243 | | |
244 | 95.4k | unsigned offset = 0, entries, tag, type, len; |
245 | 95.4k | INT64 save; |
246 | | |
247 | 95.4k | unsigned c, i; |
248 | 95.4k | unsigned LensData_len = 0; |
249 | 95.4k | uchar *LensData_buf=0; |
250 | 95.4k | uchar ColorBalanceData_buf[324]; |
251 | 95.4k | int ColorBalanceData_ready = 0; |
252 | 95.4k | uchar ci, cj, ck; |
253 | 95.4k | unsigned serial = 0; |
254 | 95.4k | unsigned custom_serial = 0; |
255 | | |
256 | 95.4k | unsigned ShotInfo_len = 0; |
257 | 95.4k | uchar *ShotInfo_buf=0; |
258 | | |
259 | | /* for dump: |
260 | | uchar *cj_block, *ck_block; |
261 | | */ |
262 | | |
263 | 95.4k | short morder, sorder = order; |
264 | 95.4k | char buf[10]; |
265 | 95.4k | INT64 fsize = ifp->size(); |
266 | | |
267 | 95.4k | fread(buf, 1, 10, ifp); |
268 | | |
269 | 95.4k | if (!strcmp(buf, "Nikon")) |
270 | 1.61k | { |
271 | 1.61k | if (buf[6] != '\2') |
272 | 1.11k | return; |
273 | 495 | base = ftell(ifp); |
274 | 495 | order = get2(); |
275 | 495 | if (get2() != 42) |
276 | 132 | goto quit; |
277 | 363 | offset = get4(); |
278 | 363 | fseek(ifp, INT64(offset) - 8LL, SEEK_CUR); |
279 | 363 | } |
280 | 93.8k | else |
281 | 93.8k | { |
282 | 93.8k | fseek(ifp, -10, SEEK_CUR); |
283 | 93.8k | } |
284 | | |
285 | 94.1k | entries = get2(); |
286 | 94.1k | if (entries > 1000) |
287 | 21.7k | return; |
288 | 72.3k | morder = order; |
289 | | |
290 | 15.9M | while (entries--) |
291 | 15.8M | { |
292 | 15.8M | order = morder; |
293 | 15.8M | tiff_get(base, &tag, &type, &len, &save); |
294 | | |
295 | 15.8M | INT64 pos = ifp->tell(); |
296 | 15.8M | if (len > 8 && pos + len > 2 * fsize) |
297 | 12.2M | { |
298 | 12.2M | fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! |
299 | 12.2M | continue; |
300 | 12.2M | } |
301 | 3.56M | tag |= uptag << 16; |
302 | 3.56M | if (len > 100 * 1024 * 1024) |
303 | 0 | goto next; // 100Mb tag? No! |
304 | | |
305 | 3.56M | if (callbacks.makernotes_cb) |
306 | 0 | { |
307 | 0 | INT64 _savepos = ifp->tell(); |
308 | 0 | callbacks.makernotes_cb(callbacks.makernotesparser_data, tag, type, len, order, ifp, base); |
309 | 0 | fseek(ifp, _savepos, SEEK_SET); |
310 | 0 | } |
311 | | |
312 | 3.56M | if (tag == 0x0002) |
313 | 32.0k | { |
314 | 32.0k | if (!iso_speed) |
315 | 2.48k | iso_speed = (get2(), get2()); |
316 | 32.0k | } |
317 | 3.53M | else if (tag == 0x000a) |
318 | 8.23k | { |
319 | 8.23k | ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens; |
320 | 8.23k | ilm.FocalType = LIBRAW_FT_ZOOM_LENS; |
321 | 8.23k | } |
322 | 3.52M | else if ((tag == 0x000c) && (len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL)) |
323 | 895 | { |
324 | 895 | cam_mul[0] = getrealf(type); |
325 | 895 | cam_mul[2] = getrealf(type); |
326 | 895 | cam_mul[1] = getrealf(type); |
327 | 895 | cam_mul[3] = getrealf(type); |
328 | 895 | } |
329 | 3.52M | else if (tag == 0x0011) |
330 | 3.58k | { |
331 | 3.58k | if (is_raw) |
332 | 2.70k | { |
333 | 2.70k | fseek(ifp, get4() + base, SEEK_SET); |
334 | 2.70k | parse_tiff_ifd(base); |
335 | 2.70k | } |
336 | 3.58k | } |
337 | 3.51M | else if (tag == 0x0012) |
338 | 6.39k | { |
339 | 6.39k | uchar uc1 = fgetc(ifp); |
340 | 6.39k | uchar uc2 = fgetc(ifp); |
341 | 6.39k | uchar uc3 = fgetc(ifp); |
342 | 6.39k | if (uc3) |
343 | 3.64k | imCommon.FlashEC = (float)(uc1 * uc2) / (float)uc3; |
344 | 6.39k | } |
345 | 3.51M | else if (tag == 0x0014) |
346 | 22.0k | { |
347 | 22.0k | if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) |
348 | 11.5k | { |
349 | 11.5k | if (len == 2560) |
350 | 673 | { // E5400, E8400, E8700, E8800 |
351 | 673 | fseek(ifp, 0x4e0L, SEEK_CUR); |
352 | 673 | order = 0x4d4d; |
353 | 673 | cam_mul[0] = float(get2()) / 256.f; |
354 | 673 | cam_mul[2] = float(get2()) / 256.f; |
355 | 673 | cam_mul[1] = cam_mul[3] = 1.0; |
356 | 673 | icWBC[LIBRAW_WBI_Auto][0] = get2(); |
357 | 673 | icWBC[LIBRAW_WBI_Auto][2] = get2(); |
358 | 673 | icWBC[LIBRAW_WBI_Daylight][0] = get2(); |
359 | 673 | icWBC[LIBRAW_WBI_Daylight][2] = get2(); |
360 | 673 | fseek(ifp, 0x18L, SEEK_CUR); |
361 | 673 | icWBC[LIBRAW_WBI_Tungsten][0] = get2(); |
362 | 673 | icWBC[LIBRAW_WBI_Tungsten][2] = get2(); |
363 | 673 | fseek(ifp, 0x18L, SEEK_CUR); |
364 | 673 | icWBC[LIBRAW_WBI_FL_W][0] = get2(); |
365 | 673 | icWBC[LIBRAW_WBI_FL_W][2] = get2(); |
366 | 673 | icWBC[LIBRAW_WBI_FL_N][0] = get2(); |
367 | 673 | icWBC[LIBRAW_WBI_FL_N][2] = get2(); |
368 | 673 | icWBC[LIBRAW_WBI_FL_D][0] = get2(); |
369 | 673 | icWBC[LIBRAW_WBI_FL_D][2] = get2(); |
370 | 673 | icWBC[LIBRAW_WBI_Cloudy][0] = get2(); |
371 | 673 | icWBC[LIBRAW_WBI_Cloudy][2] = get2(); |
372 | 673 | fseek(ifp, 0x18L, SEEK_CUR); |
373 | 673 | icWBC[LIBRAW_WBI_Flash][0] = get2(); |
374 | 673 | icWBC[LIBRAW_WBI_Flash][2] = get2(); |
375 | | |
376 | 673 | icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = |
377 | 673 | icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] = |
378 | 673 | icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] = |
379 | 673 | icWBC[LIBRAW_WBI_FL_W][1] = icWBC[LIBRAW_WBI_FL_W][3] = |
380 | 673 | icWBC[LIBRAW_WBI_FL_N][1] = icWBC[LIBRAW_WBI_FL_N][3] = |
381 | 673 | icWBC[LIBRAW_WBI_FL_D][1] = icWBC[LIBRAW_WBI_FL_D][3] = |
382 | 673 | icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] = |
383 | 673 | icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = 256; |
384 | | |
385 | 673 | if (strncmp(model, "E8700", 5)) |
386 | 159 | { |
387 | 159 | fseek(ifp, 0x18L, SEEK_CUR); |
388 | 159 | icWBC[LIBRAW_WBI_Shade][0] = get2(); |
389 | 159 | icWBC[LIBRAW_WBI_Shade][2] = get2(); |
390 | 159 | icWBC[LIBRAW_WBI_Shade][1] = icWBC[LIBRAW_WBI_Shade][3] = 256; |
391 | 159 | } |
392 | 673 | } |
393 | 10.9k | else if (len == 1280) |
394 | 1.51k | { // E5000, E5700 |
395 | 1.51k | cam_mul[0] = cam_mul[1] = cam_mul[2] = cam_mul[3] = 1.0; |
396 | 1.51k | } |
397 | 9.40k | else |
398 | 9.40k | { |
399 | 9.40k | fread(buf, 1, 10, ifp); |
400 | 9.40k | if (!strncmp(buf, "NRW ", 4)) |
401 | 5.97k | { // P6000, P7000, P7100, B700, P1000 |
402 | 5.97k | if (!strcmp(buf + 4, "0100")) |
403 | 1.25k | { // P6000 |
404 | 1.25k | fseek(ifp, 0x13deL, SEEK_CUR); |
405 | 1.25k | cam_mul[0] = float(get4() << 1); |
406 | 1.25k | cam_mul[1] = float(get4()); |
407 | 1.25k | cam_mul[3] = float(get4()); |
408 | 1.25k | cam_mul[2] = float(get4() << 1); |
409 | 1.25k | Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 0); |
410 | 1.25k | Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 0); |
411 | 1.25k | fseek(ifp, 0x10L, SEEK_CUR); |
412 | 1.25k | Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 0); |
413 | 1.25k | Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 0); |
414 | 1.25k | Nikon_NRW_WBtag(LIBRAW_WBI_Flash, 0); |
415 | 1.25k | fseek(ifp, 0x10L, SEEK_CUR); |
416 | 1.25k | Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 0); |
417 | 1.25k | Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 0); |
418 | 1.25k | } |
419 | 4.72k | else |
420 | 4.72k | { // P7000, P7100, B700, P1000 |
421 | 4.72k | fseek(ifp, 0x16L, SEEK_CUR); |
422 | 4.72k | black = get2(); |
423 | 4.72k | if (cam_mul[0] < 0.1f) |
424 | 733 | { |
425 | 733 | fseek(ifp, 0x16L, SEEK_CUR); |
426 | 733 | cam_mul[0] = float(get4() << 1); |
427 | 733 | cam_mul[1] = float(get4()); |
428 | 733 | cam_mul[3] = float(get4()); |
429 | 733 | cam_mul[2] = float(get4() << 1); |
430 | 733 | } |
431 | 3.98k | else |
432 | 3.98k | { |
433 | 3.98k | fseek(ifp, 0x26L, SEEK_CUR); |
434 | 3.98k | } |
435 | 4.72k | if (len != 332) |
436 | 3.43k | { // not A1000 |
437 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 1); |
438 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 1); |
439 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_Shade, 1); |
440 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 1); |
441 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 1); |
442 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_FL_N, 1); |
443 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_FL_D, 1); |
444 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_HT_Mercury, 1); |
445 | 3.43k | fseek(ifp, 0x14L, SEEK_CUR); |
446 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 1); |
447 | 3.43k | Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1); |
448 | 3.43k | } |
449 | 1.28k | else |
450 | 1.28k | { |
451 | 1.28k | fseek(ifp, 0xc8L, SEEK_CUR); |
452 | 1.28k | Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1); |
453 | 1.28k | } |
454 | 4.72k | } |
455 | 5.97k | } |
456 | 9.40k | } |
457 | 11.5k | } |
458 | 22.0k | } |
459 | 3.49M | else if (tag == 0x001b) |
460 | 8.03k | { |
461 | 8.03k | imNikon.HighSpeedCropFormat = get2(); |
462 | 8.03k | imNikon.SensorHighSpeedCrop.cwidth = get2(); |
463 | 8.03k | imNikon.SensorHighSpeedCrop.cheight = get2(); |
464 | 8.03k | imNikon.SensorWidth = get2(); |
465 | 8.03k | imNikon.SensorHeight = get2(); |
466 | 8.03k | imNikon.SensorHighSpeedCrop.cleft = get2(); |
467 | 8.03k | imNikon.SensorHighSpeedCrop.ctop = get2(); |
468 | 8.03k | switch (imNikon.HighSpeedCropFormat) |
469 | 8.03k | { |
470 | 803 | case 0: |
471 | 1.28k | case 1: |
472 | 2.02k | case 2: |
473 | 2.83k | case 4: |
474 | 2.83k | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; |
475 | 2.83k | break; |
476 | 1.25k | case 11: |
477 | 1.25k | ilm.CameraFormat = LIBRAW_FORMAT_FF; |
478 | 1.25k | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; |
479 | 1.25k | break; |
480 | 817 | case 12: |
481 | 817 | ilm.CameraFormat = LIBRAW_FORMAT_APSC; |
482 | 817 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; |
483 | 817 | break; |
484 | 318 | case 3: |
485 | 318 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4; |
486 | 318 | break; |
487 | 489 | case 6: |
488 | 489 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; |
489 | 489 | break; |
490 | 800 | case 17: |
491 | 800 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; |
492 | 800 | break; |
493 | 1.52k | default: |
494 | 1.52k | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER; |
495 | 1.52k | break; |
496 | 8.03k | } |
497 | 8.03k | } |
498 | 3.48M | else if (tag == 0x001d) |
499 | 20.4k | { // serial number |
500 | 20.4k | if (len > 0) |
501 | 18.7k | { |
502 | 18.7k | int model_len = (int)strbuflen(model); |
503 | 105k | while ((c = fgetc(ifp)) && (len-- > 0) && (c != (unsigned)EOF)) |
504 | 96.5k | { |
505 | 96.5k | if ((!custom_serial) && (!isdigit(c))) |
506 | 9.52k | { |
507 | 9.52k | if (((model_len == 3) && !strcmp(model, "D50")) || |
508 | 9.29k | ((model_len >= 4) && !isalnum(model[model_len - 4]) && |
509 | 1.13k | !strncmp(&model[model_len - 3], "D50", 3))) |
510 | 717 | { |
511 | 717 | custom_serial = 34; |
512 | 717 | } |
513 | 8.81k | else |
514 | 8.81k | { |
515 | 8.81k | custom_serial = 96; |
516 | 8.81k | } |
517 | 9.52k | break; |
518 | 9.52k | } |
519 | 87.0k | serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10); |
520 | 87.0k | } |
521 | 18.7k | if (!imgdata.shootinginfo.BodySerial[0]) |
522 | 1.09k | sprintf(imgdata.shootinginfo.BodySerial, "%d", serial); |
523 | 18.7k | } |
524 | 20.4k | } |
525 | 3.46M | else if (tag == 0x001e) { |
526 | 6.61k | switch (get2()) { |
527 | 877 | case 1: |
528 | 877 | imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; |
529 | 877 | break; |
530 | 1.26k | case 2: |
531 | 1.26k | imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; |
532 | 1.26k | break; |
533 | 729 | case 4: |
534 | 729 | imCommon.ColorSpace = LIBRAW_COLORSPACE_Rec2020; |
535 | 729 | break; |
536 | 3.74k | default: |
537 | 3.74k | imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; |
538 | 3.74k | break; |
539 | 6.61k | } |
540 | 3.45M | } else if (tag == 0x0025) |
541 | 2.78k | { |
542 | 2.78k | imCommon.real_ISO = float(100.f * float(libraw_powf64l(2.f, float((uchar)fgetc(ifp)) / 12.f - 5.f))); |
543 | 2.78k | if (!iso_speed || (iso_speed == 65535)) |
544 | 363 | { |
545 | 363 | iso_speed = imCommon.real_ISO; |
546 | 363 | } |
547 | 2.78k | } |
548 | 3.45M | else if (tag == 0x0022) |
549 | 3.78k | { |
550 | 3.78k | imNikon.Active_D_Lighting = get2(); |
551 | 3.78k | } |
552 | 3.44M | else if (tag == 0x0023) |
553 | 3.34k | { |
554 | 13.3k | FORC4 imNikon.PictureControlVersion = |
555 | 13.3k | imNikon.PictureControlVersion * 10 + fgetc(ifp) - '0'; |
556 | 3.34k | if ((imNikon.PictureControlVersion >= 300) && |
557 | 3.33k | (imNikon.PictureControlVersion <= 399)) |
558 | 3 | { |
559 | 3 | fseek(ifp, 4, SEEK_CUR); |
560 | 3 | } |
561 | 3.34k | stmread (imNikon.PictureControlName, 20, ifp); |
562 | 3.34k | stmread (imNikon.PictureControlBase, 20, ifp); |
563 | 3.34k | if (!strncmp(imNikon.PictureControlBase, "STANDARD(HLG)", 13)) |
564 | 847 | { |
565 | 847 | imCommon.ExposureCalibrationShift -= 2; |
566 | 847 | } |
567 | 3.34k | } |
568 | 3.44M | else if (tag == 0x003b) |
569 | 2.14k | { // WB for multi-exposure (ME); all 1s for regular exposures |
570 | 2.14k | imNikon.ME_WB[0] = getreal(type); |
571 | 2.14k | imNikon.ME_WB[2] = getreal(type); |
572 | 2.14k | imNikon.ME_WB[1] = getreal(type); |
573 | 2.14k | imNikon.ME_WB[3] = getreal(type); |
574 | 2.14k | } |
575 | 3.44M | else if (tag == 0x003d) |
576 | 4.59k | { // not corrected for file bitcount, to be patched in open_datastream |
577 | 18.3k | FORC4 cblack[RGGB_2_RGBG(c)] = get2(); |
578 | 4.59k | i = cblack[3]; |
579 | 13.7k | FORC3 if (i > cblack[c]) i = cblack[c]; |
580 | 18.3k | FORC4 cblack[c] -= i; |
581 | 4.59k | black += i; |
582 | 4.59k | } |
583 | 3.43M | else if (tag == 0x0045) |
584 | 1.55k | { /* upper left pixel (x,y), size (width,height) */ |
585 | 1.55k | imgdata.sizes.raw_inset_crops[0].cleft = get2(); |
586 | 1.55k | imgdata.sizes.raw_inset_crops[0].ctop = get2(); |
587 | 1.55k | imgdata.sizes.raw_inset_crops[0].cwidth = get2(); |
588 | 1.55k | imgdata.sizes.raw_inset_crops[0].cheight = get2(); |
589 | 1.55k | } |
590 | 3.43M | else if (tag == 0x0051) |
591 | 2.69k | { |
592 | 2.69k | fseek(ifp, 10LL, SEEK_CUR); |
593 | 2.69k | imNikon.NEFCompression = get2(); |
594 | 2.69k | } |
595 | | |
596 | | // BurstTable_0x0056 |
597 | | /* |
598 | | photo shooting menu -> [Pixel shift shooting] : |
599 | | [Pixel shift shooting mode] : On(series) | On(single photo) | Off (default is Off) |
600 | | [Number of shots] : 4 | 8 | 16 | 32 (default is 16) |
601 | | [Delay] : (default is 2 s) |
602 | | [Interval until next shot] : (default is 0) |
603 | | */ |
604 | 3.43M | else if ((tag == 0x0056) && !strncmp(model+6, "Z ", 2)) |
605 | 586 | { |
606 | 586 | imNikon.BurstTable_0x0056_len = len; |
607 | 586 | if (imNikon.BurstTable_0x0056_len == 16) { |
608 | 276 | imNikon.BurstTable_0x0056 = (uchar *)calloc(imNikon.BurstTable_0x0056_len,1); |
609 | 276 | fread(imNikon.BurstTable_0x0056, imNikon.BurstTable_0x0056_len, 1, ifp); |
610 | 1.10k | FORC4 imNikon.BurstTable_0x0056_ver = imNikon.BurstTable_0x0056_ver * 10 + (imNikon.BurstTable_0x0056[c] - '0'); |
611 | 276 | imNikon.BurstTable_0x0056_gid = (imNikon.BurstTable_0x0056[5]<<8) | imNikon.BurstTable_0x0056[4]; |
612 | 276 | imNikon.BurstTable_0x0056_fnum = imNikon.BurstTable_0x0056[8]; |
613 | | /* |
614 | | printf (">> camera: %s; BurstTable_0x0056: len %d, ver %d, gid 0x%04x, fnum %d\n", |
615 | | model, imNikon.BurstTable_0x0056_len, imNikon.BurstTable_0x0056_ver, imNikon.BurstTable_0x0056_gid, imNikon.BurstTable_0x0056_fnum); |
616 | | printf (" 0x6: 0x%02x 0x7: 0x%02x\n 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", |
617 | | imNikon.BurstTable_0x0056[0x6], imNikon.BurstTable_0x0056[0x7], |
618 | | imNikon.BurstTable_0x0056[0x9], imNikon.BurstTable_0x0056[0xa], |
619 | | imNikon.BurstTable_0x0056[0xb], imNikon.BurstTable_0x0056[0xc], |
620 | | imNikon.BurstTable_0x0056[0xd], imNikon.BurstTable_0x0056[0xe], |
621 | | imNikon.BurstTable_0x0056[0xf]); |
622 | | |
623 | | printf ("BurstTable_0x0056[5 .. 4]: "); |
624 | | for (c = 1 << 7; c > 0; c = c / 2) |
625 | | (imNikon.BurstTable_0x0056[5] & c) ? printf("1") : printf("0"); |
626 | | printf (" "); |
627 | | for (c = 1 << 7; c > 0; c = c / 2) |
628 | | (imNikon.BurstTable_0x0056[4] & c) ? printf("1") : printf("0"); |
629 | | printf ("\n"); |
630 | | printf ("BurstTable_0x0056[7 .. 6]: "); |
631 | | for (c = 1 << 7; c > 0; c = c / 2) |
632 | | (imNikon.BurstTable_0x0056[7] & c) ? printf("1") : printf("0"); |
633 | | printf (" "); |
634 | | for (c = 1 << 7; c > 0; c = c / 2) |
635 | | (imNikon.BurstTable_0x0056[6] & c) ? printf("1") : printf("0"); |
636 | | printf ("\n"); |
637 | | */ |
638 | 276 | } |
639 | | /* |
640 | | else { |
641 | | printf (">> camera: =%s=; table 0x0056 len!=16, len %d\n", model, len); |
642 | | } |
643 | | */ |
644 | 586 | } |
645 | | |
646 | 3.43M | else if (tag == 0x0082) |
647 | 1.98k | { // lens attachment |
648 | 1.98k | stmread(ilm.Attachment, len, ifp); |
649 | 1.98k | } |
650 | 3.43M | else if (tag == 0x0083) |
651 | 7.24k | { // lens type |
652 | 7.24k | imgdata.lens.nikon.LensType = fgetc(ifp); |
653 | 7.24k | } |
654 | 3.42M | else if (tag == 0x0084) |
655 | 1.40k | { // lens |
656 | 1.40k | ilm.MinFocal = getrealf(type); |
657 | 1.40k | ilm.MaxFocal = getrealf(type); |
658 | 1.40k | ilm.MaxAp4MinFocal = getrealf(type); |
659 | 1.40k | ilm.MaxAp4MaxFocal = getrealf(type); |
660 | 1.40k | } |
661 | 3.42M | else if (tag == 0x0088) // AFInfo |
662 | 1.19k | { |
663 | 1.19k | if (!imCommon.afcount) |
664 | 167 | { |
665 | 167 | imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; |
666 | 167 | imCommon.afdata[imCommon.afcount].AFInfoData_order = order; |
667 | 167 | imCommon.afdata[imCommon.afcount].AFInfoData_length = len; |
668 | 167 | imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); |
669 | 167 | fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); |
670 | 167 | imCommon.afcount = 1; |
671 | 167 | } |
672 | 1.19k | } |
673 | 3.42M | else if (tag == 0x008b) // lens f-stops |
674 | 3.13k | { |
675 | 3.13k | uchar uc1 = fgetc(ifp); |
676 | 3.13k | uchar uc2 = fgetc(ifp); |
677 | 3.13k | uchar uc3 = fgetc(ifp); |
678 | 3.13k | if (uc3) |
679 | 2.08k | { |
680 | 2.08k | imgdata.lens.nikon.LensFStops = uc1 * uc2 * (12 / uc3); |
681 | 2.08k | ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f; |
682 | 2.08k | } |
683 | 3.13k | } |
684 | 3.41M | else if ((tag == 0x008c) || (tag == 0x0096)) |
685 | 11.5k | { |
686 | 11.5k | meta_offset = ftell(ifp); |
687 | 11.5k | } |
688 | 3.40M | else if ((tag == 0x0091) && (len > 4)) |
689 | 5.74k | { |
690 | 5.74k | ShotInfo_len = len; |
691 | 5.74k | ShotInfo_buf = (uchar *)calloc(ShotInfo_len,1); |
692 | | |
693 | | /* for dump: |
694 | | cj_block = (uchar *)malloc(ShotInfo_len); |
695 | | ck_block = (uchar *)malloc(ShotInfo_len); |
696 | | */ |
697 | | |
698 | 5.74k | fread(ShotInfo_buf, ShotInfo_len, 1, ifp); |
699 | 22.9k | FORC4 imNikon.ShotInfoVersion = |
700 | 22.9k | imNikon.ShotInfoVersion * 10 + ShotInfo_buf[c] - '0'; |
701 | 5.74k | } |
702 | 3.40M | else if (tag == 0x0093) |
703 | 9.59k | { |
704 | 9.59k | imNikon.NEFCompression = i = get2(); |
705 | 9.59k | if ((i == 7) || (i == 9)) |
706 | 820 | { |
707 | 820 | ilm.LensMount = LIBRAW_MOUNT_FixedLens; |
708 | 820 | ilm.CameraMount = LIBRAW_MOUNT_FixedLens; |
709 | 820 | } |
710 | 9.59k | } |
711 | 3.39M | else if (tag == 0x0097) |
712 | 9.75k | { // ver97 |
713 | 39.0k | FORC4 imNikon.ColorBalanceVersion = |
714 | 39.0k | imNikon.ColorBalanceVersion * 10 + fgetc(ifp) - '0'; |
715 | 9.75k | switch (imNikon.ColorBalanceVersion) |
716 | 9.75k | { |
717 | 3 | case 100: // NIKON D100 |
718 | 3 | fseek(ifp, 0x44L, SEEK_CUR); |
719 | 12 | FORC4 cam_mul[RBGG_2_RGBG(c)] = get2(); |
720 | 3 | break; |
721 | 2 | case 102: // NIKON D2H |
722 | 2 | fseek(ifp, 0x6L, SEEK_CUR); |
723 | 8 | FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); |
724 | 2 | break; |
725 | 2 | case 103: // NIKON D70, D70s |
726 | 2 | fseek(ifp, 0x10L, SEEK_CUR); |
727 | 8 | FORC4 cam_mul[c] = get2(); |
728 | 9.75k | } |
729 | 9.75k | if (imNikon.ColorBalanceVersion >= 200) |
730 | 9.17k | { |
731 | | /* |
732 | | 204: NIKON D2X, D2Xs |
733 | | 205: NIKON D50 |
734 | | 206: NIKON D2Hs |
735 | | 207: NIKON D200 |
736 | | 208: NIKON D40, D40X, D80 |
737 | | 209: NIKON D3, D3X, D300, D700 |
738 | | 210: NIKON D60 |
739 | | 211: NIKON D90, D5000 |
740 | | 212: NIKON D300S |
741 | | 213: NIKON D3000 |
742 | | 214: NIKON D3S |
743 | | 215: NIKON D3100 |
744 | | 216: NIKON D5100, D7000 |
745 | | 217: NIKON D4, D600, D800, D800E, D3200 |
746 | | -= unknown =- |
747 | | 218: NIKON D5200, D7100 |
748 | | 219: NIKON D5300 |
749 | | 220: NIKON D610, Df |
750 | | 221: NIKON D3300 |
751 | | 222: NIKON D4S |
752 | | 223: NIKON D750, D810 |
753 | | 224: NIKON D3400, D3500, D5500, D5600, D7200 |
754 | | 225: NIKON D5, D500 |
755 | | 226: NIKON D7500 |
756 | | 227: NIKON D850 |
757 | | */ |
758 | 9.17k | if (imNikon.ColorBalanceVersion != 205) |
759 | 9.16k | { |
760 | 9.16k | fseek(ifp, 0x118L, SEEK_CUR); |
761 | 9.16k | } |
762 | 9.17k | ColorBalanceData_ready = |
763 | 9.17k | (fread(ColorBalanceData_buf, 324, 1, ifp) == 1); |
764 | 9.17k | } |
765 | 9.75k | if ((imNikon.ColorBalanceVersion >= 400) && |
766 | 9.12k | (imNikon.ColorBalanceVersion <= 405)) |
767 | 6 | { // 1 J1, 1 V1, 1 J2, 1 V2, 1 J3, 1 S1, 1 AW1, 1 S2, 1 J4, 1 V3, 1 J5 |
768 | 6 | ilm.CameraFormat = LIBRAW_FORMAT_1INCH; |
769 | 6 | ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; |
770 | 6 | } |
771 | 9.74k | else if ((imNikon.ColorBalanceVersion >= 500) && |
772 | 9.11k | (imNikon.ColorBalanceVersion <= 502)) |
773 | 1 | { // P7700, P7800, P330, P340 |
774 | 1 | ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; |
775 | 1 | ilm.FocalType = LIBRAW_FT_ZOOM_LENS; |
776 | 1 | } |
777 | 9.74k | else if (imNikon.ColorBalanceVersion == 601) |
778 | 2 | { // Coolpix A |
779 | 2 | ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; |
780 | 2 | ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; |
781 | 2 | ilm.FocalType = LIBRAW_FT_PRIME_LENS; |
782 | 2 | } |
783 | 9.75k | } |
784 | 3.38M | else if (tag == 0x0098) // contains lens data |
785 | 8.71k | { |
786 | 34.8k | FORC4 imNikon.LensDataVersion = |
787 | 34.8k | imNikon.LensDataVersion * 10 + fgetc(ifp) - '0'; |
788 | 8.71k | switch (imNikon.LensDataVersion) |
789 | 8.71k | { |
790 | 11 | case 100: |
791 | 11 | LensData_len = 9; |
792 | 11 | break; |
793 | 5 | case 101: |
794 | 23 | case 201: // encrypted, starting from v.201 |
795 | 27 | case 202: |
796 | 29 | case 203: |
797 | 29 | LensData_len = 15; |
798 | 29 | break; |
799 | 1 | case 204: |
800 | 1 | LensData_len = 16; |
801 | 1 | break; |
802 | 2 | case 400: |
803 | 2 | LensData_len = 459; |
804 | 2 | break; |
805 | 3 | case 401: |
806 | 3 | LensData_len = 590; |
807 | 3 | break; |
808 | 2 | case 402: |
809 | 2 | LensData_len = 509; |
810 | 2 | break; |
811 | 3 | case 403: |
812 | 3 | LensData_len = 879; |
813 | 3 | break; |
814 | 1 | case 800: |
815 | 6 | case 801: |
816 | 6 | LensData_len = 58; |
817 | 6 | break; |
818 | 12 | case 802: |
819 | 12 | LensData_len = 108; |
820 | 12 | break; |
821 | 8.71k | } |
822 | 8.71k | if (LensData_len) |
823 | 89 | { |
824 | 89 | LensData_buf = (uchar *)calloc(LensData_len,1); |
825 | 89 | fread(LensData_buf, LensData_len, 1, ifp); |
826 | 89 | } |
827 | 8.71k | } |
828 | 3.37M | else if (tag == 0x00a0) |
829 | 3.72k | { |
830 | 3.72k | stmread(imgdata.shootinginfo.BodySerial, len, ifp); |
831 | 3.72k | } |
832 | 3.36M | else if (tag == 0x00a7) // shutter count |
833 | 6.30k | { |
834 | 6.30k | imNikon.key = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp); |
835 | 6.30k | if (custom_serial) |
836 | 741 | { |
837 | 741 | ci = xlat[0][custom_serial]; |
838 | 741 | } |
839 | 5.56k | else |
840 | 5.56k | { |
841 | 5.56k | ci = xlat[0][serial & 0xff]; |
842 | 5.56k | } |
843 | 6.30k | cj = xlat[1][imNikon.key]; |
844 | 6.30k | ck = 0x60; |
845 | 6.30k | if (((unsigned)(imNikon.ColorBalanceVersion - 200) < 18) && |
846 | 225 | ColorBalanceData_ready) |
847 | 100 | { |
848 | 32.5k | for (i = 0; i < 324; i++) |
849 | 32.4k | ColorBalanceData_buf[i] ^= (cj += ci * ck++); |
850 | 100 | i = "66666>666;6A;:;555"[imNikon.ColorBalanceVersion - 200] - '0'; |
851 | 400 | FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = |
852 | 400 | sget2(ColorBalanceData_buf + (i & -2) + c * 2); |
853 | 100 | } |
854 | | |
855 | 6.30k | if (LensData_len) |
856 | 58 | { |
857 | 58 | if (imNikon.LensDataVersion > 200) |
858 | 52 | { |
859 | 52 | cj = xlat[1][imNikon.key]; |
860 | 52 | ck = 0x60; |
861 | 8.25k | for (i = 0; i < LensData_len; i++) |
862 | 8.20k | { |
863 | 8.20k | LensData_buf[i] ^= (cj += ci * ck++); |
864 | 8.20k | } |
865 | 52 | } |
866 | 58 | processNikonLensData(LensData_buf, LensData_len); |
867 | 58 | LensData_len = 0; |
868 | 58 | free(LensData_buf); |
869 | 58 | } |
870 | 6.30k | if (ShotInfo_len && (imNikon.ShotInfoVersion >= 208)) { |
871 | 2.15k | unsigned RotationOffset = 0, |
872 | 2.15k | OrientationOffset = 0; |
873 | | |
874 | 2.15k | cj = xlat[1][imNikon.key]; |
875 | 2.15k | ck = 0x60; |
876 | 179k | for (i = 4; i < ShotInfo_len; i++) { |
877 | 177k | ShotInfo_buf[i] ^= (cj += ci * ck++); |
878 | | |
879 | | /* for dump: |
880 | | cj_block[i-4] = cj; |
881 | | ck_block[i-4] = ck-1; |
882 | | */ |
883 | 177k | } |
884 | | /* for dump: |
885 | | printf ("==>> ci: 0x%02x, cj at start: 0x%02x\n", |
886 | | ci, xlat[1][imNikon.key]); |
887 | | hexDump("ck array:", ck_block, ShotInfo_len-4); |
888 | | hexDump("cj array:", cj_block, ShotInfo_len-4); |
889 | | free(cj_block); |
890 | | free(ck_block); |
891 | | */ |
892 | | |
893 | 2.15k | switch (imNikon.ShotInfoVersion) { |
894 | 14 | case 208: // ShotInfoD80, Rotation |
895 | 14 | RotationOffset = 590; |
896 | 14 | if (RotationOffset<ShotInfo_len) { |
897 | 4 | imNikon.MakernotesFlip = *(ShotInfo_buf+RotationOffset) & 0x07; |
898 | 4 | } |
899 | 14 | break; |
900 | | |
901 | 4 | case 231: // ShotInfoD4S, Rotation, Roll/Pitch/Yaw |
902 | 4 | OrientationOffset = 0x350b; |
903 | 4 | RotationOffset = 0x3693; |
904 | 4 | if (RotationOffset<ShotInfo_len) { |
905 | 0 | imNikon.MakernotesFlip = (*(ShotInfo_buf+RotationOffset)>>4) & 0x03; |
906 | 0 | } |
907 | 4 | break; |
908 | | |
909 | 3 | case 233: // ShotInfoD810, Roll/Pitch/Yaw |
910 | 3 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84); |
911 | 3 | break; |
912 | | |
913 | 7 | case 238: // D5, ShotInfoD500, Rotation, Roll/Pitch/Yaw |
914 | 7 | case 239: // D500, ShotInfoD500, Rotation, Roll/Pitch/Yaw |
915 | 7 | RotationOffset = sget4_order(morder, ShotInfo_buf+0x10) + 0xca; |
916 | 7 | if (RotationOffset > 0xca) { |
917 | 4 | RotationOffset -= 0xb0; |
918 | 4 | } |
919 | 7 | if (RotationOffset<ShotInfo_len) { |
920 | 0 | imNikon.MakernotesFlip = *(ShotInfo_buf+RotationOffset) & 0x03; |
921 | 0 | } |
922 | 7 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0xa0); |
923 | 7 | break; |
924 | | |
925 | 2 | case 243: // ShotInfoD850, Roll/Pitch/Yaw |
926 | 2 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0xa0); |
927 | 2 | break; |
928 | | |
929 | 2 | case 246: // ShotInfoD6, Roll/Pitch/Yaw |
930 | 2 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0x9c); |
931 | 2 | break; |
932 | | |
933 | 2 | case 800: // "Z 6", "Z 7", ShotInfoZ7II, Roll/Pitch/Yaw |
934 | 6 | case 801: // "Z 50", ShotInfoZ7II, Roll/Pitch/Yaw |
935 | 8 | case 802: // "Z 5", ShotInfoZ7II, Roll/Pitch/Yaw |
936 | 12 | case 803: // "Z 6_2", "Z 7_2", ShotInfoZ7II, Roll/Pitch/Yaw |
937 | 15 | case 804: // "Z fc" ShotInfoZ7II, Roll/Pitch/Yaw |
938 | 15 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0x98); |
939 | 15 | break; |
940 | | |
941 | 2 | case 805: // "Z 9", ShotInfoZ9, Roll/Pitch/Yaw |
942 | 2 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84); |
943 | 2 | break; |
944 | 4 | case 806: // "Z 8" |
945 | 4 | if (ShotInfo_len >= 12) { |
946 | 1 | memcpy (imNikon.ShotInfoFirmware, ShotInfo_buf+4, 8*sizeof(char)); |
947 | 1 | imNikon.ShotInfoFirmware[8] = '\0'; |
948 | | // printf (">> camera: =%s= exifSW: =%s= ShotInfo: Version %d, Firmware =%s=\n", |
949 | | // model, software, imNikon.ShotInfoVersion, imNikon.ShotInfoFirmware); |
950 | 1 | } |
951 | 4 | break; |
952 | 0 | case 807: // "Z 30" |
953 | 0 | break; |
954 | 8 | case 808: // "Z f" |
955 | 8 | if (ShotInfo_len >= 12) { |
956 | 4 | memcpy (imNikon.ShotInfoFirmware, ShotInfo_buf+4, 8*sizeof(char)); |
957 | 4 | imNikon.ShotInfoFirmware[8] = '\0'; |
958 | | // printf (">> camera: =%s= exifSW: =%s= ShotInfo: Version %d, Firmware =%s=\n", |
959 | | // model, software, imNikon.ShotInfoVersion, imNikon.ShotInfoFirmware); |
960 | 4 | } |
961 | 8 | break; |
962 | 2.15k | } |
963 | | |
964 | 2.15k | if (OrientationOffset && ((OrientationOffset+12)<ShotInfo_len) && OrientationOffset < 0xffff) { |
965 | 4 | if (imNikon.ShotInfoVersion == 231) // ShotInfoD4S |
966 | 0 | imNikon.RollAngle = AngleConversion_a(morder, ShotInfo_buf+OrientationOffset); |
967 | 4 | else |
968 | 4 | imNikon.RollAngle = AngleConversion(morder, ShotInfo_buf+OrientationOffset); |
969 | 4 | imNikon.PitchAngle = AngleConversion (morder, ShotInfo_buf+OrientationOffset+4); |
970 | 4 | imNikon.YawAngle = AngleConversion (morder, ShotInfo_buf+OrientationOffset+8); |
971 | 4 | } |
972 | 2.15k | if ((RotationOffset) && (imNikon.MakernotesFlip < 4) && (imNikon.MakernotesFlip >= 0)) |
973 | 21 | imNikon.MakernotesFlip = "0863"[imNikon.MakernotesFlip] - '0'; |
974 | 2.15k | ShotInfo_len = 0; |
975 | 2.15k | free(ShotInfo_buf); |
976 | 2.15k | } |
977 | 6.30k | } |
978 | 3.36M | else if (tag == 0x00a8) |
979 | 3.11k | { // contains flash data |
980 | 12.4k | FORC4 imNikon.FlashInfoVersion = |
981 | 12.4k | imNikon.FlashInfoVersion * 10 + fgetc(ifp) - '0'; |
982 | 3.11k | } |
983 | 3.36M | else if (tag == 0x00b0) |
984 | 3.04k | { |
985 | 3.04k | get4(); // ME (multi-exposure) tag version, 4 symbols |
986 | 3.04k | imNikon.ExposureMode = get4(); |
987 | 3.04k | imNikon.nMEshots = get4(); |
988 | 3.04k | imNikon.MEgainOn = get4(); |
989 | 3.04k | } |
990 | 3.35M | else if (tag == 0x00b7) // AFInfo2 |
991 | 1.56k | { |
992 | 1.56k | if (!imCommon.afcount && len > 4) |
993 | 35 | { |
994 | 35 | imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; |
995 | 35 | imCommon.afdata[imCommon.afcount].AFInfoData_order = order; |
996 | 35 | int ver = 0; |
997 | 140 | FORC4 ver = ver * 10 + (fgetc(ifp) - '0'); |
998 | 35 | imCommon.afdata[imCommon.afcount].AFInfoData_version = ver; |
999 | 35 | imCommon.afdata[imCommon.afcount].AFInfoData_length = len-4; |
1000 | 35 | imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); |
1001 | 35 | fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); |
1002 | 35 | imCommon.afcount = 1; |
1003 | 35 | } |
1004 | 1.56k | } |
1005 | 3.35M | else if (tag == 0x00b9) |
1006 | 2.04k | { |
1007 | 2.04k | imNikon.AFFineTune = fgetc(ifp); |
1008 | 2.04k | imNikon.AFFineTuneIndex = fgetc(ifp); |
1009 | 2.04k | imNikon.AFFineTuneAdj = (int8_t)fgetc(ifp); |
1010 | 2.04k | } |
1011 | 3.35M | else if ((tag == 0x0100) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) |
1012 | 1.41k | { |
1013 | 1.41k | thumb_offset = ftell(ifp); |
1014 | 1.41k | thumb_length = len; |
1015 | 1.41k | } |
1016 | 3.35M | else if (tag == 0x0e01) |
1017 | 2.40k | { /* Nikon Software / in-camera edit Note */ |
1018 | 2.40k | int loopc = 0; |
1019 | 2.40k | int WhiteBalanceAdj_active = 0; |
1020 | 2.40k | order = 0x4949; |
1021 | 2.40k | fseek(ifp, 22, SEEK_CUR); |
1022 | 19.2k | for (offset = 22; offset + 22 < len; offset += 22 + i) |
1023 | 16.8k | { |
1024 | 16.8k | if (loopc++ > 1024) |
1025 | 1 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
1026 | 16.7k | tag = get4(); |
1027 | 16.7k | fseek(ifp, 14, SEEK_CUR); |
1028 | 16.7k | i = get4() - 4; |
1029 | | |
1030 | 16.7k | if (tag == 0x76a43204) |
1031 | 103 | { |
1032 | 103 | WhiteBalanceAdj_active = fgetc(ifp); |
1033 | 103 | } |
1034 | 16.6k | else if (tag == 0xbf3c6c20) |
1035 | 0 | { |
1036 | 0 | if (WhiteBalanceAdj_active) |
1037 | 0 | { |
1038 | 0 | union { |
1039 | 0 | double dbl; |
1040 | 0 | unsigned long long lng; |
1041 | 0 | } un; |
1042 | 0 | un.dbl = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE); |
1043 | 0 | if ((un.lng != 0x3FF0000000000000ULL) && |
1044 | 0 | (un.lng != 0x000000000000F03FULL)) |
1045 | 0 | { |
1046 | 0 | cam_mul[0] = float(un.dbl); |
1047 | 0 | cam_mul[2] = getrealf(LIBRAW_EXIFTAG_TYPE_DOUBLE); |
1048 | 0 | cam_mul[1] = cam_mul[3] = 1.f; |
1049 | 0 | i -= 16; |
1050 | 0 | } |
1051 | 0 | else |
1052 | 0 | i -= 8; |
1053 | 0 | } |
1054 | 0 | fseek(ifp, i, SEEK_CUR); |
1055 | 0 | } |
1056 | 16.6k | else if (tag == 0x76a43207) |
1057 | 577 | { |
1058 | 577 | flip = get2(); |
1059 | 577 | } |
1060 | 16.1k | else |
1061 | 16.1k | { |
1062 | 16.1k | fseek(ifp, i, SEEK_CUR); |
1063 | 16.1k | } |
1064 | 16.7k | } |
1065 | 2.40k | } |
1066 | 3.34M | else if (tag == 0x0e22) |
1067 | 1.15k | { |
1068 | 4.63k | FORC4 imNikon.NEFBitDepth[c] = get2(); |
1069 | 1.15k | } |
1070 | 3.56M | next: |
1071 | 3.56M | fseek(ifp, save, SEEK_SET); |
1072 | 3.56M | } |
1073 | 72.0k | quit: |
1074 | 72.0k | order = sorder; |
1075 | 72.0k | } |
1076 | | |
1077 | 50 | unsigned sget4_order (short _order, uchar *s) { |
1078 | 50 | unsigned v; |
1079 | 50 | if (_order == 0x4949) |
1080 | 47 | v= s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; |
1081 | 3 | else |
1082 | 3 | v= s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; |
1083 | 50 | return v; |
1084 | 50 | } |
1085 | | |
1086 | 12 | double sget_fixed32u (short _order, uchar *s) { |
1087 | 12 | unsigned v = sget4_order (_order, s); |
1088 | 12 | return ((double)v / 6.5536 + 0.5) / 10000.0; |
1089 | 12 | } |
1090 | | |
1091 | 0 | double AngleConversion_a (short _order, uchar *s) { |
1092 | 0 | double v = sget_fixed32u(_order, s); |
1093 | 0 | if (v < 180.0) return -v; |
1094 | 0 | return 360.0-v; |
1095 | 0 | } |
1096 | | |
1097 | 12 | double AngleConversion (short _order, uchar *s) { |
1098 | 12 | double v = sget_fixed32u(_order, s); |
1099 | 12 | if (v <= 180.0) return v; |
1100 | 9 | return v-360.0; |
1101 | 12 | } |
1102 | | |
1103 | | /* ========= */ |
1104 | | /* |
1105 | | void hexDump(char *title, void *addr, int len) |
1106 | | { |
1107 | | int i; |
1108 | | unsigned char buff[17]; |
1109 | | unsigned char *pc = (unsigned char*)addr; |
1110 | | |
1111 | | // Output description if given. |
1112 | | if (title != NULL) |
1113 | | printf ("%s:\n", title); |
1114 | | |
1115 | | // Process every byte in the data. |
1116 | | for (i = 0; i < len; i++) { |
1117 | | // Multiple of 16 means new line (with line offset). |
1118 | | |
1119 | | if ((i % 16) == 0) { |
1120 | | // Just don't print ASCII for the zeroth line. |
1121 | | if (i != 0) |
1122 | | printf(" %s\n", buff); |
1123 | | |
1124 | | // Output the offset. |
1125 | | printf(" %04x ", i); |
1126 | | } |
1127 | | |
1128 | | // Now the hex code for the specific character. |
1129 | | printf(" %02x", pc[i]); |
1130 | | |
1131 | | // And store a printable ASCII character for later. |
1132 | | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) { |
1133 | | buff[i % 16] = '.'; |
1134 | | } else { |
1135 | | buff[i % 16] = pc[i]; |
1136 | | } |
1137 | | |
1138 | | buff[(i % 16) + 1] = '\0'; |
1139 | | } |
1140 | | |
1141 | | // Pad out last line if not exactly 16 characters. |
1142 | | while ((i % 16) != 0) { |
1143 | | printf(" "); |
1144 | | i++; |
1145 | | } |
1146 | | |
1147 | | // And print the final ASCII bit. |
1148 | | printf(" %s\n", buff); |
1149 | | } |
1150 | | */ |