/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 | 19 | { |
72 | | |
73 | 19 | ushort i=0; |
74 | 19 | if (imgdata.lens.nikon.LensType & 0x80) { |
75 | 2 | strcpy (ilm.LensFeatures_pre, "AF-P"); |
76 | 17 | } else if (!(imgdata.lens.nikon.LensType & 0x01)) { |
77 | 14 | ilm.LensFeatures_pre[0] = 'A'; |
78 | 14 | ilm.LensFeatures_pre[1] = 'F'; |
79 | 14 | } else { |
80 | 3 | ilm.LensFeatures_pre[0] = 'M'; |
81 | 3 | ilm.LensFeatures_pre[1] = 'F'; |
82 | 3 | } |
83 | | |
84 | 19 | if (imgdata.lens.nikon.LensType & 0x40) { |
85 | 1 | ilm.LensFeatures_suf[0] = 'E'; |
86 | 18 | } else if (imgdata.lens.nikon.LensType & 0x04) { |
87 | 2 | ilm.LensFeatures_suf[0] = 'G'; |
88 | 16 | } else if (imgdata.lens.nikon.LensType & 0x02) { |
89 | 1 | ilm.LensFeatures_suf[0] = 'D'; |
90 | 1 | } |
91 | | |
92 | 19 | if (imgdata.lens.nikon.LensType & 0x08) |
93 | 1 | { |
94 | 1 | ilm.LensFeatures_suf[1] = ' '; |
95 | 1 | ilm.LensFeatures_suf[2] = 'V'; |
96 | 1 | ilm.LensFeatures_suf[3] = 'R'; |
97 | 1 | } |
98 | | |
99 | 19 | if (imgdata.lens.nikon.LensType & 0x10) |
100 | 2 | { |
101 | 2 | ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; |
102 | 2 | ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1INCH; |
103 | 2 | } |
104 | 17 | else |
105 | 17 | ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_F; |
106 | | |
107 | 19 | if (imgdata.lens.nikon.LensType & 0x20) |
108 | 2 | { |
109 | 2 | strcpy(ilm.Adapter, "FT-1"); |
110 | 2 | ilm.LensMount = LIBRAW_MOUNT_Nikon_F; |
111 | 2 | ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; |
112 | 2 | ilm.CameraFormat = LIBRAW_FORMAT_1INCH; |
113 | 2 | } |
114 | | |
115 | 19 | imgdata.lens.nikon.LensType = imgdata.lens.nikon.LensType & 0xdf; |
116 | | |
117 | 19 | if ((len < 20) || (len == 58) || (len == 108)) |
118 | 14 | { |
119 | 14 | switch (len) |
120 | 14 | { |
121 | 1 | case 9: |
122 | 1 | i = 2; |
123 | 1 | break; |
124 | 6 | case 15: |
125 | 6 | i = 7; |
126 | 6 | break; |
127 | 0 | case 16: |
128 | 0 | i = 8; |
129 | 0 | break; |
130 | 1 | case 58: // "Z 6", "Z 6 II", "Z 7", "Z 7 II", "Z 50", D780, "Z 5", "Z fc" |
131 | 7 | case 108: // "Z 9", "Z 30", "Z 8", "Z6_2" |
132 | 7 | if (model[6] == 'Z') |
133 | 2 | ilm.CameraMount = LIBRAW_MOUNT_Nikon_Z; |
134 | 7 | if (imNikon.HighSpeedCropFormat != 12) |
135 | 7 | ilm.CameraFormat = LIBRAW_FORMAT_FF; |
136 | 7 | i = 1; |
137 | 8 | while ((LensData[i] == LensData[0]) && (i < 17)) |
138 | 1 | i++; |
139 | 7 | 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 | 7 | i = 9; |
163 | 7 | ilm.LensMount = LIBRAW_MOUNT_Nikon_F; |
164 | 7 | if (ilm.CameraMount == LIBRAW_MOUNT_Nikon_Z) |
165 | 2 | strcpy(ilm.Adapter, "FTZ"); |
166 | 7 | break; |
167 | 14 | } |
168 | 14 | imgdata.lens.nikon.LensIDNumber = LensData[i]; |
169 | 14 | imgdata.lens.nikon.LensFStops = LensData[i + 1]; |
170 | 14 | ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f; |
171 | 14 | if (fabsf(ilm.MinFocal) < 1.1f) |
172 | 11 | { |
173 | 11 | if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 2]) |
174 | 10 | ilm.MinFocal = |
175 | 10 | 5.0f * libraw_powf64l(2.0f, (float)LensData[i + 2] / 24.0f); |
176 | 11 | if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 3]) |
177 | 10 | ilm.MaxFocal = |
178 | 10 | 5.0f * libraw_powf64l(2.0f, (float)LensData[i + 3] / 24.0f); |
179 | 11 | if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 4]) |
180 | 10 | ilm.MaxAp4MinFocal = |
181 | 10 | libraw_powf64l(2.0f, (float)LensData[i + 4] / 24.0f); |
182 | 11 | if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 5]) |
183 | 11 | ilm.MaxAp4MaxFocal = |
184 | 11 | libraw_powf64l(2.0f, (float)LensData[i + 5] / 24.0f); |
185 | 11 | } |
186 | 14 | imgdata.lens.nikon.MCUVersion = LensData[i + 6]; |
187 | 14 | if (i != 2) |
188 | 13 | { |
189 | 13 | if ((LensData[i - 1]) && (fabsf(ilm.CurFocal) < 1.1f)) |
190 | 9 | ilm.CurFocal = |
191 | 9 | 5.0f * libraw_powf64l(2.0f, (float)LensData[i - 1] / 24.0f); |
192 | 13 | if (LensData[i + 7]) |
193 | 9 | imgdata.lens.nikon.EffectiveMaxAp = |
194 | 9 | libraw_powf64l(2.0f, (float)LensData[i + 7] / 24.0f); |
195 | 13 | } |
196 | 14 | ilm.LensID = (unsigned long long)LensData[i] << 56 | |
197 | 14 | (unsigned long long)LensData[i + 1] << 48 | |
198 | 14 | (unsigned long long)LensData[i + 2] << 40 | |
199 | 14 | (unsigned long long)LensData[i + 3] << 32 | |
200 | 14 | (unsigned long long)LensData[i + 4] << 24 | |
201 | 14 | (unsigned long long)LensData[i + 5] << 16 | |
202 | 14 | (unsigned long long)LensData[i + 6] << 8 | |
203 | 14 | (unsigned long long)imgdata.lens.nikon.LensType; |
204 | 14 | } |
205 | 5 | else if ((len == 459) || (len == 590)) |
206 | 4 | { |
207 | 4 | memcpy(ilm.Lens, LensData + 390, 64); |
208 | 4 | } |
209 | 1 | else if (len == 509) |
210 | 0 | { |
211 | 0 | memcpy(ilm.Lens, LensData + 391, 64); |
212 | 0 | } |
213 | 1 | else if (len == 879) |
214 | 1 | { |
215 | 1 | memcpy(ilm.Lens, LensData + 680, 64); |
216 | 1 | } |
217 | | |
218 | 19 | return; |
219 | 19 | } |
220 | | |
221 | | void LibRaw::Nikon_NRW_WBtag(int wb, int skip) |
222 | 23.4k | { |
223 | | |
224 | 23.4k | int r, g0, g1, b; |
225 | 23.4k | if (skip) |
226 | 18.8k | get4(); // skip wb "CCT", it is not unique |
227 | 23.4k | r = get4(); |
228 | 23.4k | g0 = get4(); |
229 | 23.4k | g1 = get4(); |
230 | 23.4k | b = get4(); |
231 | 23.4k | if (r && g0 && g1 && b) |
232 | 16.2k | { |
233 | 16.2k | icWBC[wb][0] = r << 1; |
234 | 16.2k | icWBC[wb][1] = g0; |
235 | 16.2k | icWBC[wb][2] = b << 1; |
236 | 16.2k | icWBC[wb][3] = g1; |
237 | 16.2k | } |
238 | 23.4k | return; |
239 | 23.4k | } |
240 | | |
241 | | void LibRaw::parseNikonMakernote(INT64 base, int uptag, unsigned /*dng_writer */) |
242 | 32.6k | { |
243 | | |
244 | 32.6k | unsigned offset = 0, entries, tag, type, len; |
245 | 32.6k | INT64 save; |
246 | | |
247 | 32.6k | unsigned c, i; |
248 | 32.6k | unsigned LensData_len = 0; |
249 | 32.6k | uchar *LensData_buf=0; |
250 | 32.6k | uchar ColorBalanceData_buf[324]; |
251 | 32.6k | int ColorBalanceData_ready = 0; |
252 | 32.6k | uchar ci, cj, ck; |
253 | 32.6k | unsigned serial = 0; |
254 | 32.6k | unsigned custom_serial = 0; |
255 | | |
256 | 32.6k | unsigned ShotInfo_len = 0; |
257 | 32.6k | uchar *ShotInfo_buf=0; |
258 | | |
259 | | /* for dump: |
260 | | uchar *cj_block, *ck_block; |
261 | | */ |
262 | | |
263 | 32.6k | short morder, sorder = order; |
264 | 32.6k | char buf[10] = {0,0,0,0,0,0,0,0,0,0}; |
265 | 32.6k | INT64 fsize = ifp->size(); |
266 | | |
267 | 32.6k | fread(buf, 1, 10, ifp); |
268 | 32.6k | buf[9] = 0; |
269 | | |
270 | 32.6k | if (!strcmp(buf, "Nikon")) |
271 | 460 | { |
272 | 460 | if (buf[6] != '\2') |
273 | 322 | return; |
274 | 138 | base = ftell(ifp); |
275 | 138 | order = get2(); |
276 | 138 | if (get2() != 42) |
277 | 65 | goto quit; |
278 | 73 | offset = get4(); |
279 | 73 | fseek(ifp, INT64(offset) - 8LL, SEEK_CUR); |
280 | 73 | } |
281 | 32.1k | else |
282 | 32.1k | { |
283 | 32.1k | fseek(ifp, -10, SEEK_CUR); |
284 | 32.1k | } |
285 | | |
286 | 32.2k | entries = get2(); |
287 | 32.2k | if (entries > 1000) |
288 | 7.52k | return; |
289 | 24.6k | morder = order; |
290 | | |
291 | 2.35M | while (entries--) |
292 | 2.33M | { |
293 | 2.33M | order = morder; |
294 | 2.33M | tiff_get(base, &tag, &type, &len, &save); |
295 | | |
296 | 2.33M | INT64 pos = ifp->tell(); |
297 | 2.33M | if (len > 8 && pos + len > 2 * fsize) |
298 | 1.91M | { |
299 | 1.91M | fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! |
300 | 1.91M | continue; |
301 | 1.91M | } |
302 | 413k | tag |= uptag << 16; |
303 | 413k | if (len > 100 * 1024 * 1024) |
304 | 0 | goto next; // 100Mb tag? No! |
305 | | |
306 | 413k | if (callbacks.makernotes_cb) |
307 | 0 | { |
308 | 0 | INT64 _savepos = ifp->tell(); |
309 | 0 | callbacks.makernotes_cb(callbacks.makernotesparser_data, tag, type, len, order, ifp, base); |
310 | 0 | fseek(ifp, _savepos, SEEK_SET); |
311 | 0 | } |
312 | | |
313 | 413k | if (tag == 0x0002) |
314 | 4.55k | { |
315 | 4.55k | if (!iso_speed) |
316 | 776 | iso_speed = (get2(), get2()); |
317 | 4.55k | } |
318 | 408k | else if (tag == 0x000a) |
319 | 855 | { |
320 | 855 | ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens; |
321 | 855 | ilm.FocalType = LIBRAW_FT_ZOOM_LENS; |
322 | 855 | } |
323 | 407k | else if ((tag == 0x000c) && (len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL)) |
324 | 36 | { |
325 | 36 | cam_mul[0] = getrealf(type); |
326 | 36 | cam_mul[2] = getrealf(type); |
327 | 36 | cam_mul[1] = getrealf(type); |
328 | 36 | cam_mul[3] = getrealf(type); |
329 | 36 | } |
330 | 407k | else if (tag == 0x0011) |
331 | 317 | { |
332 | 317 | if (is_raw) |
333 | 260 | { |
334 | 260 | fseek(ifp, get4() + base, SEEK_SET); |
335 | 260 | parse_tiff_ifd(base); |
336 | 260 | } |
337 | 317 | } |
338 | 407k | else if (tag == 0x0012) |
339 | 847 | { |
340 | 847 | uchar uc1 = fgetc(ifp); |
341 | 847 | uchar uc2 = fgetc(ifp); |
342 | 847 | uchar uc3 = fgetc(ifp); |
343 | 847 | if (uc3) |
344 | 494 | imCommon.FlashEC = (float)(uc1 * uc2) / (float)uc3; |
345 | 847 | } |
346 | 406k | else if (tag == 0x0014) |
347 | 6.37k | { |
348 | 6.37k | if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) |
349 | 5.54k | { |
350 | 5.54k | if (len == 2560) |
351 | 49 | { // E5400, E8400, E8700, E8800 |
352 | 49 | fseek(ifp, 0x4e0L, SEEK_CUR); |
353 | 49 | order = 0x4d4d; |
354 | 49 | cam_mul[0] = float(get2()) / 256.f; |
355 | 49 | cam_mul[2] = float(get2()) / 256.f; |
356 | 49 | cam_mul[1] = cam_mul[3] = 1.0; |
357 | 49 | icWBC[LIBRAW_WBI_Auto][0] = get2(); |
358 | 49 | icWBC[LIBRAW_WBI_Auto][2] = get2(); |
359 | 49 | icWBC[LIBRAW_WBI_Daylight][0] = get2(); |
360 | 49 | icWBC[LIBRAW_WBI_Daylight][2] = get2(); |
361 | 49 | fseek(ifp, 0x18L, SEEK_CUR); |
362 | 49 | icWBC[LIBRAW_WBI_Tungsten][0] = get2(); |
363 | 49 | icWBC[LIBRAW_WBI_Tungsten][2] = get2(); |
364 | 49 | fseek(ifp, 0x18L, SEEK_CUR); |
365 | 49 | icWBC[LIBRAW_WBI_FL_W][0] = get2(); |
366 | 49 | icWBC[LIBRAW_WBI_FL_W][2] = get2(); |
367 | 49 | icWBC[LIBRAW_WBI_FL_N][0] = get2(); |
368 | 49 | icWBC[LIBRAW_WBI_FL_N][2] = get2(); |
369 | 49 | icWBC[LIBRAW_WBI_FL_D][0] = get2(); |
370 | 49 | icWBC[LIBRAW_WBI_FL_D][2] = get2(); |
371 | 49 | icWBC[LIBRAW_WBI_Cloudy][0] = get2(); |
372 | 49 | icWBC[LIBRAW_WBI_Cloudy][2] = get2(); |
373 | 49 | fseek(ifp, 0x18L, SEEK_CUR); |
374 | 49 | icWBC[LIBRAW_WBI_Flash][0] = get2(); |
375 | 49 | icWBC[LIBRAW_WBI_Flash][2] = get2(); |
376 | | |
377 | 49 | icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = |
378 | 49 | icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] = |
379 | 49 | icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] = |
380 | 49 | icWBC[LIBRAW_WBI_FL_W][1] = icWBC[LIBRAW_WBI_FL_W][3] = |
381 | 49 | icWBC[LIBRAW_WBI_FL_N][1] = icWBC[LIBRAW_WBI_FL_N][3] = |
382 | 49 | icWBC[LIBRAW_WBI_FL_D][1] = icWBC[LIBRAW_WBI_FL_D][3] = |
383 | 49 | icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] = |
384 | 49 | icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = 256; |
385 | | |
386 | 49 | if (strncmp(model, "E8700", 5)) |
387 | 49 | { |
388 | 49 | fseek(ifp, 0x18L, SEEK_CUR); |
389 | 49 | icWBC[LIBRAW_WBI_Shade][0] = get2(); |
390 | 49 | icWBC[LIBRAW_WBI_Shade][2] = get2(); |
391 | 49 | icWBC[LIBRAW_WBI_Shade][1] = icWBC[LIBRAW_WBI_Shade][3] = 256; |
392 | 49 | } |
393 | 49 | } |
394 | 5.49k | else if (len == 1280) |
395 | 327 | { // E5000, E5700 |
396 | 327 | cam_mul[0] = cam_mul[1] = cam_mul[2] = cam_mul[3] = 1.0; |
397 | 327 | } |
398 | 5.17k | else |
399 | 5.17k | { |
400 | 5.17k | memset(buf,0,sizeof(buf)); |
401 | 5.17k | fread(buf, 1, 10, ifp); |
402 | 5.17k | buf[9] = 0; |
403 | 5.17k | if (!strncmp(buf, "NRW ", 4)) |
404 | 2.54k | { // P6000, P7000, P7100, B700, P1000 |
405 | 2.54k | if (!strcmp(buf + 4, "0100")) |
406 | 658 | { // P6000 |
407 | 658 | fseek(ifp, 0x13deL, SEEK_CUR); |
408 | 658 | cam_mul[0] = float(get4() << 1); |
409 | 658 | cam_mul[1] = float(get4()); |
410 | 658 | cam_mul[3] = float(get4()); |
411 | 658 | cam_mul[2] = float(get4() << 1); |
412 | 658 | Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 0); |
413 | 658 | Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 0); |
414 | 658 | fseek(ifp, 0x10L, SEEK_CUR); |
415 | 658 | Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 0); |
416 | 658 | Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 0); |
417 | 658 | Nikon_NRW_WBtag(LIBRAW_WBI_Flash, 0); |
418 | 658 | fseek(ifp, 0x10L, SEEK_CUR); |
419 | 658 | Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 0); |
420 | 658 | Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 0); |
421 | 658 | } |
422 | 1.88k | else |
423 | 1.88k | { // P7000, P7100, B700, P1000 |
424 | 1.88k | fseek(ifp, 0x16L, SEEK_CUR); |
425 | 1.88k | black = get2(); |
426 | 1.88k | if (cam_mul[0] < 0.1f) |
427 | 579 | { |
428 | 579 | fseek(ifp, 0x16L, SEEK_CUR); |
429 | 579 | cam_mul[0] = float(get4() << 1); |
430 | 579 | cam_mul[1] = float(get4()); |
431 | 579 | cam_mul[3] = float(get4()); |
432 | 579 | cam_mul[2] = float(get4() << 1); |
433 | 579 | } |
434 | 1.30k | else |
435 | 1.30k | { |
436 | 1.30k | fseek(ifp, 0x26L, SEEK_CUR); |
437 | 1.30k | } |
438 | 1.88k | if (len != 332) |
439 | 1.88k | { // not A1000 |
440 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 1); |
441 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 1); |
442 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_Shade, 1); |
443 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 1); |
444 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 1); |
445 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_FL_N, 1); |
446 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_FL_D, 1); |
447 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_HT_Mercury, 1); |
448 | 1.88k | fseek(ifp, 0x14L, SEEK_CUR); |
449 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 1); |
450 | 1.88k | Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1); |
451 | 1.88k | } |
452 | 0 | else |
453 | 0 | { |
454 | 0 | fseek(ifp, 0xc8L, SEEK_CUR); |
455 | 0 | Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1); |
456 | 0 | } |
457 | 1.88k | } |
458 | 2.54k | } |
459 | 5.17k | } |
460 | 5.54k | } |
461 | 6.37k | } |
462 | 400k | else if (tag == 0x001b) |
463 | 4.52k | { |
464 | 4.52k | imNikon.HighSpeedCropFormat = get2(); |
465 | 4.52k | imNikon.SensorHighSpeedCrop.cwidth = get2(); |
466 | 4.52k | imNikon.SensorHighSpeedCrop.cheight = get2(); |
467 | 4.52k | imNikon.SensorWidth = get2(); |
468 | 4.52k | imNikon.SensorHeight = get2(); |
469 | 4.52k | imNikon.SensorHighSpeedCrop.cleft = get2(); |
470 | 4.52k | imNikon.SensorHighSpeedCrop.ctop = get2(); |
471 | 4.52k | switch (imNikon.HighSpeedCropFormat) |
472 | 4.52k | { |
473 | 287 | case 0: |
474 | 664 | case 1: |
475 | 1.36k | case 2: |
476 | 1.46k | case 4: |
477 | 1.46k | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; |
478 | 1.46k | break; |
479 | 398 | case 11: |
480 | 398 | ilm.CameraFormat = LIBRAW_FORMAT_FF; |
481 | 398 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; |
482 | 398 | break; |
483 | 926 | case 12: |
484 | 926 | ilm.CameraFormat = LIBRAW_FORMAT_APSC; |
485 | 926 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; |
486 | 926 | break; |
487 | 477 | case 3: |
488 | 477 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4; |
489 | 477 | break; |
490 | 230 | case 6: |
491 | 230 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; |
492 | 230 | break; |
493 | 138 | case 17: |
494 | 138 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; |
495 | 138 | break; |
496 | 895 | default: |
497 | 895 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER; |
498 | 895 | break; |
499 | 4.52k | } |
500 | 4.52k | } |
501 | 395k | else if (tag == 0x001d) |
502 | 5.89k | { // serial number |
503 | 5.89k | if (len > 0) |
504 | 5.27k | { |
505 | 5.27k | int model_len = (int)strbuflen(model); |
506 | 12.8k | while ((c = fgetc(ifp)) && (len-- > 0) && (c != (unsigned)EOF)) |
507 | 10.1k | { |
508 | 10.1k | if ((!custom_serial) && (!isdigit(c))) |
509 | 2.55k | { |
510 | 2.55k | if (((model_len == 3) && !strcmp(model, "D50")) || |
511 | 2.51k | ((model_len >= 4) && !isalnum(model[model_len - 4]) && |
512 | 520 | !strncmp(&model[model_len - 3], "D50", 3))) |
513 | 299 | { |
514 | 299 | custom_serial = 34; |
515 | 299 | } |
516 | 2.25k | else |
517 | 2.25k | { |
518 | 2.25k | custom_serial = 96; |
519 | 2.25k | } |
520 | 2.55k | break; |
521 | 2.55k | } |
522 | 7.56k | serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10); |
523 | 7.56k | } |
524 | 5.27k | if (!imgdata.shootinginfo.BodySerial[0]) |
525 | 215 | sprintf(imgdata.shootinginfo.BodySerial, "%d", serial); |
526 | 5.27k | } |
527 | 5.89k | } |
528 | 389k | else if (tag == 0x001e) { |
529 | 2.35k | switch (get2()) { |
530 | 155 | case 1: |
531 | 155 | imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; |
532 | 155 | break; |
533 | 200 | case 2: |
534 | 200 | imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; |
535 | 200 | break; |
536 | 1.55k | case 4: |
537 | 1.55k | imCommon.ColorSpace = LIBRAW_COLORSPACE_Rec2020; |
538 | 1.55k | break; |
539 | 442 | default: |
540 | 442 | imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; |
541 | 442 | break; |
542 | 2.35k | } |
543 | 387k | } else if (tag == 0x0025) |
544 | 674 | { |
545 | 674 | imCommon.real_ISO = float(100.f * float(libraw_powf64l(2.f, float((uchar)fgetc(ifp)) / 12.f - 5.f))); |
546 | 674 | if (!iso_speed || (iso_speed == 65535)) |
547 | 90 | { |
548 | 90 | iso_speed = imCommon.real_ISO; |
549 | 90 | } |
550 | 674 | } |
551 | 386k | else if (tag == 0x0022) |
552 | 559 | { |
553 | 559 | imNikon.Active_D_Lighting = get2(); |
554 | 559 | } |
555 | 386k | else if (tag == 0x0023) |
556 | 885 | { |
557 | 3.54k | FORC4 imNikon.PictureControlVersion = |
558 | 3.54k | imNikon.PictureControlVersion * 10 + fgetc(ifp) - '0'; |
559 | 885 | if ((imNikon.PictureControlVersion >= 300) && |
560 | 848 | (imNikon.PictureControlVersion <= 399)) |
561 | 1 | { |
562 | 1 | fseek(ifp, 4, SEEK_CUR); |
563 | 1 | } |
564 | 885 | stmread (imNikon.PictureControlName, 20, ifp); |
565 | 885 | stmread (imNikon.PictureControlBase, 20, ifp); |
566 | 885 | if (!strncmp(imNikon.PictureControlBase, "STANDARD(HLG)", 13)) |
567 | 74 | { |
568 | 74 | imCommon.ExposureCalibrationShift -= 2; |
569 | 74 | } |
570 | 885 | } |
571 | 385k | else if (tag == 0x003b) |
572 | 1.38k | { // WB for multi-exposure (ME); all 1s for regular exposures |
573 | 1.38k | imNikon.ME_WB[0] = getreal(type); |
574 | 1.38k | imNikon.ME_WB[2] = getreal(type); |
575 | 1.38k | imNikon.ME_WB[1] = getreal(type); |
576 | 1.38k | imNikon.ME_WB[3] = getreal(type); |
577 | 1.38k | } |
578 | 384k | else if (tag == 0x003d) |
579 | 1.95k | { // not corrected for file bitcount, to be patched in open_datastream |
580 | 7.82k | FORC4 cblack[RGGB_2_RGBG(c)] = get2(); |
581 | 1.95k | i = cblack[3]; |
582 | 5.86k | FORC3 if (i > cblack[c]) i = cblack[c]; |
583 | 7.82k | FORC4 cblack[c] -= i; |
584 | 1.95k | black += i; |
585 | 1.95k | } |
586 | 382k | else if (tag == 0x0045) |
587 | 114 | { /* upper left pixel (x,y), size (width,height) */ |
588 | 114 | imgdata.sizes.raw_inset_crops[0].cleft = get2(); |
589 | 114 | imgdata.sizes.raw_inset_crops[0].ctop = get2(); |
590 | 114 | imgdata.sizes.raw_inset_crops[0].cwidth = get2(); |
591 | 114 | imgdata.sizes.raw_inset_crops[0].cheight = get2(); |
592 | 114 | } |
593 | 382k | else if (tag == 0x0051) |
594 | 234 | { |
595 | 234 | fseek(ifp, 10LL, SEEK_CUR); |
596 | 234 | imNikon.NEFCompression = get2(); |
597 | 234 | } |
598 | | |
599 | | // BurstTable_0x0056 |
600 | | /* |
601 | | photo shooting menu -> [Pixel shift shooting] : |
602 | | [Pixel shift shooting mode] : On(series) | On(single photo) | Off (default is Off) |
603 | | [Number of shots] : 4 | 8 | 16 | 32 (default is 16) |
604 | | [Delay] : (default is 2 s) |
605 | | [Interval until next shot] : (default is 0) |
606 | | */ |
607 | 381k | else if ((tag == 0x0056) && !strncmp(model+6, "Z ", 2)) |
608 | 50 | { |
609 | 50 | imNikon.BurstTable_0x0056_len = len; |
610 | 50 | if (imNikon.BurstTable_0x0056_len == 16) { |
611 | 0 | imNikon.BurstTable_0x0056 = (uchar *)calloc(imNikon.BurstTable_0x0056_len+1,1); |
612 | 0 | fread(imNikon.BurstTable_0x0056, imNikon.BurstTable_0x0056_len, 1, ifp); |
613 | 0 | FORC4 imNikon.BurstTable_0x0056_ver = imNikon.BurstTable_0x0056_ver * 10 + (imNikon.BurstTable_0x0056[c] - '0'); |
614 | 0 | imNikon.BurstTable_0x0056_gid = (imNikon.BurstTable_0x0056[5]<<8) | imNikon.BurstTable_0x0056[4]; |
615 | 0 | imNikon.BurstTable_0x0056_fnum = imNikon.BurstTable_0x0056[8]; |
616 | | /* |
617 | | printf (">> camera: %s; BurstTable_0x0056: len %d, ver %d, gid 0x%04x, fnum %d\n", |
618 | | model, imNikon.BurstTable_0x0056_len, imNikon.BurstTable_0x0056_ver, imNikon.BurstTable_0x0056_gid, imNikon.BurstTable_0x0056_fnum); |
619 | | printf (" 0x6: 0x%02x 0x7: 0x%02x\n 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", |
620 | | imNikon.BurstTable_0x0056[0x6], imNikon.BurstTable_0x0056[0x7], |
621 | | imNikon.BurstTable_0x0056[0x9], imNikon.BurstTable_0x0056[0xa], |
622 | | imNikon.BurstTable_0x0056[0xb], imNikon.BurstTable_0x0056[0xc], |
623 | | imNikon.BurstTable_0x0056[0xd], imNikon.BurstTable_0x0056[0xe], |
624 | | imNikon.BurstTable_0x0056[0xf]); |
625 | | |
626 | | printf ("BurstTable_0x0056[5 .. 4]: "); |
627 | | for (c = 1 << 7; c > 0; c = c / 2) |
628 | | (imNikon.BurstTable_0x0056[5] & c) ? printf("1") : printf("0"); |
629 | | printf (" "); |
630 | | for (c = 1 << 7; c > 0; c = c / 2) |
631 | | (imNikon.BurstTable_0x0056[4] & c) ? printf("1") : printf("0"); |
632 | | printf ("\n"); |
633 | | printf ("BurstTable_0x0056[7 .. 6]: "); |
634 | | for (c = 1 << 7; c > 0; c = c / 2) |
635 | | (imNikon.BurstTable_0x0056[7] & c) ? printf("1") : printf("0"); |
636 | | printf (" "); |
637 | | for (c = 1 << 7; c > 0; c = c / 2) |
638 | | (imNikon.BurstTable_0x0056[6] & c) ? printf("1") : printf("0"); |
639 | | printf ("\n"); |
640 | | */ |
641 | 0 | } |
642 | | /* |
643 | | else { |
644 | | printf (">> camera: =%s=; table 0x0056 len!=16, len %d\n", model, len); |
645 | | } |
646 | | */ |
647 | 50 | } |
648 | | |
649 | 381k | else if (tag == 0x0082) |
650 | 811 | { // lens attachment |
651 | 811 | stmread(ilm.Attachment, len, ifp); |
652 | 811 | } |
653 | 380k | else if (tag == 0x0083) |
654 | 1.27k | { // lens type |
655 | 1.27k | imgdata.lens.nikon.LensType = fgetc(ifp); |
656 | 1.27k | } |
657 | 379k | else if (tag == 0x0084) |
658 | 364 | { // lens |
659 | 364 | ilm.MinFocal = getrealf(type); |
660 | 364 | ilm.MaxFocal = getrealf(type); |
661 | 364 | ilm.MaxAp4MinFocal = getrealf(type); |
662 | 364 | ilm.MaxAp4MaxFocal = getrealf(type); |
663 | 364 | } |
664 | 379k | else if (tag == 0x0088) // AFInfo |
665 | 359 | { |
666 | 359 | if (!imCommon.afcount) |
667 | 20 | { |
668 | 20 | imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; |
669 | 20 | imCommon.afdata[imCommon.afcount].AFInfoData_order = order; |
670 | 20 | imCommon.afdata[imCommon.afcount].AFInfoData_length = len; |
671 | 20 | imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length+1,1); |
672 | 20 | fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); |
673 | 20 | imCommon.afcount = 1; |
674 | 20 | } |
675 | 359 | } |
676 | 378k | else if (tag == 0x008b) // lens f-stops |
677 | 2.08k | { |
678 | 2.08k | uchar uc1 = fgetc(ifp); |
679 | 2.08k | uchar uc2 = fgetc(ifp); |
680 | 2.08k | uchar uc3 = fgetc(ifp); |
681 | 2.08k | if (uc3) |
682 | 1.16k | { |
683 | 1.16k | imgdata.lens.nikon.LensFStops = uc1 * uc2 * (12 / uc3); |
684 | 1.16k | ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f; |
685 | 1.16k | } |
686 | 2.08k | } |
687 | 376k | else if ((tag == 0x008c) || (tag == 0x0096)) |
688 | 491 | { |
689 | 491 | meta_offset = ftell(ifp); |
690 | 491 | } |
691 | 376k | else if ((tag == 0x0091) && (len > 4)) |
692 | 815 | { |
693 | 815 | ShotInfo_len = len; |
694 | 815 | ShotInfo_buf = (uchar *)calloc(ShotInfo_len+1,1); |
695 | | |
696 | | /* for dump: |
697 | | cj_block = (uchar *)malloc(ShotInfo_len); |
698 | | ck_block = (uchar *)malloc(ShotInfo_len); |
699 | | */ |
700 | | |
701 | 815 | fread(ShotInfo_buf, ShotInfo_len, 1, ifp); |
702 | 3.26k | FORC4 imNikon.ShotInfoVersion = |
703 | 3.26k | imNikon.ShotInfoVersion * 10 + ShotInfo_buf[c] - '0'; |
704 | 815 | } |
705 | 375k | else if (tag == 0x0093) |
706 | 1.19k | { |
707 | 1.19k | imNikon.NEFCompression = i = get2(); |
708 | 1.19k | if ((i == 7) || (i == 9)) |
709 | 279 | { |
710 | 279 | ilm.LensMount = LIBRAW_MOUNT_FixedLens; |
711 | 279 | ilm.CameraMount = LIBRAW_MOUNT_FixedLens; |
712 | 279 | } |
713 | 1.19k | } |
714 | 374k | else if (tag == 0x0097) |
715 | 2.64k | { // ver97 |
716 | 10.5k | FORC4 imNikon.ColorBalanceVersion = |
717 | 10.5k | imNikon.ColorBalanceVersion * 10 + fgetc(ifp) - '0'; |
718 | 2.64k | switch (imNikon.ColorBalanceVersion) |
719 | 2.64k | { |
720 | 1 | case 100: // NIKON D100 |
721 | 1 | fseek(ifp, 0x44L, SEEK_CUR); |
722 | 4 | FORC4 cam_mul[RBGG_2_RGBG(c)] = get2(); |
723 | 1 | break; |
724 | 1 | case 102: // NIKON D2H |
725 | 1 | fseek(ifp, 0x6L, SEEK_CUR); |
726 | 4 | FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); |
727 | 1 | break; |
728 | 1 | case 103: // NIKON D70, D70s |
729 | 1 | fseek(ifp, 0x10L, SEEK_CUR); |
730 | 4 | FORC4 cam_mul[c] = get2(); |
731 | 2.64k | } |
732 | 2.64k | if (imNikon.ColorBalanceVersion >= 200) |
733 | 2.57k | { |
734 | | /* |
735 | | 204: NIKON D2X, D2Xs |
736 | | 205: NIKON D50 |
737 | | 206: NIKON D2Hs |
738 | | 207: NIKON D200 |
739 | | 208: NIKON D40, D40X, D80 |
740 | | 209: NIKON D3, D3X, D300, D700 |
741 | | 210: NIKON D60 |
742 | | 211: NIKON D90, D5000 |
743 | | 212: NIKON D300S |
744 | | 213: NIKON D3000 |
745 | | 214: NIKON D3S |
746 | | 215: NIKON D3100 |
747 | | 216: NIKON D5100, D7000 |
748 | | 217: NIKON D4, D600, D800, D800E, D3200 |
749 | | -= unknown =- |
750 | | 218: NIKON D5200, D7100 |
751 | | 219: NIKON D5300 |
752 | | 220: NIKON D610, Df |
753 | | 221: NIKON D3300 |
754 | | 222: NIKON D4S |
755 | | 223: NIKON D750, D810 |
756 | | 224: NIKON D3400, D3500, D5500, D5600, D7200 |
757 | | 225: NIKON D5, D500 |
758 | | 226: NIKON D7500 |
759 | | 227: NIKON D850 |
760 | | */ |
761 | 2.57k | if (imNikon.ColorBalanceVersion != 205) |
762 | 2.56k | { |
763 | 2.56k | fseek(ifp, 0x118L, SEEK_CUR); |
764 | 2.56k | } |
765 | 2.57k | ColorBalanceData_ready = |
766 | 2.57k | (fread(ColorBalanceData_buf, 324, 1, ifp) == 1); |
767 | 2.57k | } |
768 | 2.64k | if ((imNikon.ColorBalanceVersion >= 400) && |
769 | 2.56k | (imNikon.ColorBalanceVersion <= 405)) |
770 | 1 | { // 1 J1, 1 V1, 1 J2, 1 V2, 1 J3, 1 S1, 1 AW1, 1 S2, 1 J4, 1 V3, 1 J5 |
771 | 1 | ilm.CameraFormat = LIBRAW_FORMAT_1INCH; |
772 | 1 | ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; |
773 | 1 | } |
774 | 2.64k | else if ((imNikon.ColorBalanceVersion >= 500) && |
775 | 2.56k | (imNikon.ColorBalanceVersion <= 502)) |
776 | 2 | { // P7700, P7800, P330, P340 |
777 | 2 | ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; |
778 | 2 | ilm.FocalType = LIBRAW_FT_ZOOM_LENS; |
779 | 2 | } |
780 | 2.64k | else if (imNikon.ColorBalanceVersion == 601) |
781 | 1 | { // Coolpix A |
782 | 1 | ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; |
783 | 1 | ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; |
784 | 1 | ilm.FocalType = LIBRAW_FT_PRIME_LENS; |
785 | 1 | } |
786 | 2.64k | } |
787 | 371k | else if (tag == 0x0098) // contains lens data |
788 | 2.43k | { |
789 | 9.72k | FORC4 imNikon.LensDataVersion = |
790 | 9.72k | imNikon.LensDataVersion * 10 + fgetc(ifp) - '0'; |
791 | 2.43k | switch (imNikon.LensDataVersion) |
792 | 2.43k | { |
793 | 1 | case 100: |
794 | 1 | LensData_len = 9; |
795 | 1 | break; |
796 | 5 | case 101: |
797 | 6 | case 201: // encrypted, starting from v.201 |
798 | 6 | case 202: |
799 | 6 | case 203: |
800 | 6 | LensData_len = 15; |
801 | 6 | break; |
802 | 0 | case 204: |
803 | 0 | LensData_len = 16; |
804 | 0 | break; |
805 | 4 | case 400: |
806 | 4 | LensData_len = 459; |
807 | 4 | break; |
808 | 1 | case 401: |
809 | 1 | LensData_len = 590; |
810 | 1 | break; |
811 | 1 | case 402: |
812 | 1 | LensData_len = 509; |
813 | 1 | break; |
814 | 1 | case 403: |
815 | 1 | LensData_len = 879; |
816 | 1 | break; |
817 | 1 | case 800: |
818 | 2 | case 801: |
819 | 2 | LensData_len = 58; |
820 | 2 | break; |
821 | 8 | case 802: |
822 | 8 | LensData_len = 108; |
823 | 8 | break; |
824 | 2.43k | } |
825 | 2.43k | if (LensData_len) |
826 | 33 | { |
827 | 33 | LensData_buf = (uchar *)calloc(LensData_len+1,1); |
828 | 33 | fread(LensData_buf, LensData_len, 1, ifp); |
829 | 33 | } |
830 | 2.43k | } |
831 | 369k | else if (tag == 0x00a0) |
832 | 961 | { |
833 | 961 | stmread(imgdata.shootinginfo.BodySerial, len, ifp); |
834 | 961 | } |
835 | 368k | else if (tag == 0x00a7) // shutter count |
836 | 1.32k | { |
837 | 1.32k | imNikon.key = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp); |
838 | 1.32k | if (custom_serial) |
839 | 324 | { |
840 | 324 | ci = xlat[0][custom_serial]; |
841 | 324 | } |
842 | 1.00k | else |
843 | 1.00k | { |
844 | 1.00k | ci = xlat[0][serial & 0xff]; |
845 | 1.00k | } |
846 | 1.32k | cj = xlat[1][imNikon.key]; |
847 | 1.32k | ck = 0x60; |
848 | 1.32k | if (((unsigned)(imNikon.ColorBalanceVersion - 200) < 18) && |
849 | 94 | ColorBalanceData_ready) |
850 | 58 | { |
851 | 18.8k | for (i = 0; i < 324; i++) |
852 | 18.7k | ColorBalanceData_buf[i] ^= (cj += ci * ck++); |
853 | 58 | i = "66666>666;6A;:;555"[imNikon.ColorBalanceVersion - 200] - '0'; |
854 | 232 | FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = |
855 | 232 | sget2(ColorBalanceData_buf + (i & -2) + c * 2); |
856 | 58 | } |
857 | | |
858 | 1.32k | if (LensData_len) |
859 | 19 | { |
860 | 19 | if (imNikon.LensDataVersion > 200) |
861 | 13 | { |
862 | 13 | cj = xlat[1][imNikon.key]; |
863 | 13 | ck = 0x60; |
864 | 3.58k | for (i = 0; i < LensData_len; i++) |
865 | 3.56k | { |
866 | 3.56k | LensData_buf[i] ^= (cj += ci * ck++); |
867 | 3.56k | } |
868 | 13 | } |
869 | 19 | processNikonLensData(LensData_buf, LensData_len); |
870 | 19 | LensData_len = 0; |
871 | 19 | free(LensData_buf); |
872 | 19 | } |
873 | 1.32k | if (ShotInfo_len && (imNikon.ShotInfoVersion >= 208)) { |
874 | 528 | unsigned RotationOffset = 0, |
875 | 528 | OrientationOffset = 0; |
876 | | |
877 | 528 | cj = xlat[1][imNikon.key]; |
878 | 528 | ck = 0x60; |
879 | 12.1k | for (i = 4; i < ShotInfo_len; i++) { |
880 | 11.6k | ShotInfo_buf[i] ^= (cj += ci * ck++); |
881 | | |
882 | | /* for dump: |
883 | | cj_block[i-4] = cj; |
884 | | ck_block[i-4] = ck-1; |
885 | | */ |
886 | 11.6k | } |
887 | | /* for dump: |
888 | | printf ("==>> ci: 0x%02x, cj at start: 0x%02x\n", |
889 | | ci, xlat[1][imNikon.key]); |
890 | | hexDump("ck array:", ck_block, ShotInfo_len-4); |
891 | | hexDump("cj array:", cj_block, ShotInfo_len-4); |
892 | | free(cj_block); |
893 | | free(ck_block); |
894 | | */ |
895 | | |
896 | 528 | switch (imNikon.ShotInfoVersion) { |
897 | 2 | case 208: // ShotInfoD80, Rotation |
898 | 2 | RotationOffset = 590; |
899 | 2 | if (RotationOffset<ShotInfo_len) { |
900 | 1 | imNikon.MakernotesFlip = *(ShotInfo_buf+RotationOffset) & 0x07; |
901 | 1 | } |
902 | 2 | break; |
903 | | |
904 | 1 | case 231: // ShotInfoD4S, Rotation, Roll/Pitch/Yaw |
905 | 1 | OrientationOffset = 0x350b; |
906 | 1 | RotationOffset = 0x3693; |
907 | 1 | if (RotationOffset<ShotInfo_len) { |
908 | 0 | imNikon.MakernotesFlip = (*(ShotInfo_buf+RotationOffset)>>4) & 0x03; |
909 | 0 | } |
910 | 1 | break; |
911 | | |
912 | 0 | case 233: // ShotInfoD810, Roll/Pitch/Yaw |
913 | 0 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84); |
914 | 0 | break; |
915 | | |
916 | 0 | case 238: // D5, ShotInfoD500, Rotation, Roll/Pitch/Yaw |
917 | 0 | case 239: // D500, ShotInfoD500, Rotation, Roll/Pitch/Yaw |
918 | 0 | RotationOffset = sget4_order(morder, ShotInfo_buf+0x10) + 0xca; |
919 | 0 | if (RotationOffset > 0xca) { |
920 | 0 | RotationOffset -= 0xb0; |
921 | 0 | } |
922 | 0 | if (RotationOffset<ShotInfo_len) { |
923 | 0 | imNikon.MakernotesFlip = *(ShotInfo_buf+RotationOffset) & 0x03; |
924 | 0 | } |
925 | 0 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0xa0); |
926 | 0 | break; |
927 | | |
928 | 1 | case 243: // ShotInfoD850, Roll/Pitch/Yaw |
929 | 1 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0xa0); |
930 | 1 | break; |
931 | | |
932 | 1 | case 246: // ShotInfoD6, Roll/Pitch/Yaw |
933 | 1 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0x9c); |
934 | 1 | break; |
935 | | |
936 | 1 | case 800: // "Z 6", "Z 7", ShotInfoZ7II, Roll/Pitch/Yaw |
937 | 3 | case 801: // "Z 50", ShotInfoZ7II, Roll/Pitch/Yaw |
938 | 4 | case 802: // "Z 5", ShotInfoZ7II, Roll/Pitch/Yaw |
939 | 5 | case 803: // "Z 6_2", "Z 7_2", ShotInfoZ7II, Roll/Pitch/Yaw |
940 | 5 | case 804: // "Z fc" ShotInfoZ7II, Roll/Pitch/Yaw |
941 | 5 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0x98); |
942 | 5 | break; |
943 | | |
944 | 0 | case 805: // "Z 9", ShotInfoZ9, Roll/Pitch/Yaw |
945 | 0 | OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84); |
946 | 0 | break; |
947 | 1 | case 806: // "Z 8" |
948 | 1 | if (ShotInfo_len >= 12) { |
949 | 0 | memcpy (imNikon.ShotInfoFirmware, ShotInfo_buf+4, 8*sizeof(char)); |
950 | 0 | imNikon.ShotInfoFirmware[8] = '\0'; |
951 | | // printf (">> camera: =%s= exifSW: =%s= ShotInfo: Version %d, Firmware =%s=\n", |
952 | | // model, software, imNikon.ShotInfoVersion, imNikon.ShotInfoFirmware); |
953 | 0 | } |
954 | 1 | break; |
955 | 0 | case 807: // "Z 30" |
956 | 0 | break; |
957 | 1 | case 808: // "Z f" |
958 | 1 | if (ShotInfo_len >= 12) { |
959 | 1 | memcpy (imNikon.ShotInfoFirmware, ShotInfo_buf+4, 8*sizeof(char)); |
960 | 1 | imNikon.ShotInfoFirmware[8] = '\0'; |
961 | | // printf (">> camera: =%s= exifSW: =%s= ShotInfo: Version %d, Firmware =%s=\n", |
962 | | // model, software, imNikon.ShotInfoVersion, imNikon.ShotInfoFirmware); |
963 | 1 | } |
964 | 1 | break; |
965 | 528 | } |
966 | | |
967 | 528 | if (OrientationOffset && ((OrientationOffset+12)<ShotInfo_len) && OrientationOffset < 0xffff) { |
968 | 0 | if (imNikon.ShotInfoVersion == 231) // ShotInfoD4S |
969 | 0 | imNikon.RollAngle = AngleConversion_a(morder, ShotInfo_buf+OrientationOffset); |
970 | 0 | else |
971 | 0 | imNikon.RollAngle = AngleConversion(morder, ShotInfo_buf+OrientationOffset); |
972 | 0 | imNikon.PitchAngle = AngleConversion (morder, ShotInfo_buf+OrientationOffset+4); |
973 | 0 | imNikon.YawAngle = AngleConversion (morder, ShotInfo_buf+OrientationOffset+8); |
974 | 0 | } |
975 | 528 | if ((RotationOffset) && (imNikon.MakernotesFlip < 4) && (imNikon.MakernotesFlip >= 0)) |
976 | 2 | imNikon.MakernotesFlip = "0863"[imNikon.MakernotesFlip] - '0'; |
977 | 528 | ShotInfo_len = 0; |
978 | 528 | free(ShotInfo_buf); |
979 | 528 | } |
980 | 1.32k | } |
981 | 366k | else if (tag == 0x00a8) |
982 | 561 | { // contains flash data |
983 | 2.24k | FORC4 imNikon.FlashInfoVersion = |
984 | 2.24k | imNikon.FlashInfoVersion * 10 + fgetc(ifp) - '0'; |
985 | 561 | } |
986 | 366k | else if (tag == 0x00b0) |
987 | 1.26k | { |
988 | 1.26k | get4(); // ME (multi-exposure) tag version, 4 symbols |
989 | 1.26k | imNikon.ExposureMode = get4(); |
990 | 1.26k | imNikon.nMEshots = get4(); |
991 | 1.26k | imNikon.MEgainOn = get4(); |
992 | 1.26k | } |
993 | 365k | else if (tag == 0x00b7) // AFInfo2 |
994 | 748 | { |
995 | 748 | if (!imCommon.afcount && len > 4) |
996 | 14 | { |
997 | 14 | imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; |
998 | 14 | imCommon.afdata[imCommon.afcount].AFInfoData_order = order; |
999 | 14 | int ver = 0; |
1000 | 56 | FORC4 ver = ver * 10 + (fgetc(ifp) - '0'); |
1001 | 14 | imCommon.afdata[imCommon.afcount].AFInfoData_version = ver; |
1002 | 14 | imCommon.afdata[imCommon.afcount].AFInfoData_length = len-4; |
1003 | 14 | imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length+1,1); |
1004 | 14 | fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); |
1005 | 14 | imCommon.afcount = 1; |
1006 | 14 | } |
1007 | 748 | } |
1008 | 364k | else if (tag == 0x00b9) |
1009 | 617 | { |
1010 | 617 | imNikon.AFFineTune = fgetc(ifp); |
1011 | 617 | imNikon.AFFineTuneIndex = fgetc(ifp); |
1012 | 617 | imNikon.AFFineTuneAdj = (int8_t)fgetc(ifp); |
1013 | 617 | } |
1014 | 363k | else if ((tag == 0x0100) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) |
1015 | 627 | { |
1016 | 627 | thumb_offset = ftell(ifp); |
1017 | 627 | thumb_length = len; |
1018 | 627 | } |
1019 | 363k | else if (tag == 0x0e01) |
1020 | 1.03k | { /* Nikon Software / in-camera edit Note */ |
1021 | 1.03k | int loopc = 0; |
1022 | 1.03k | int WhiteBalanceAdj_active = 0; |
1023 | 1.03k | order = 0x4949; |
1024 | 1.03k | fseek(ifp, 22, SEEK_CUR); |
1025 | 4.48k | for (offset = 22; offset + 22 < len; offset += 22 + i) |
1026 | 3.45k | { |
1027 | 3.45k | if (loopc++ > 1024) |
1028 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
1029 | 3.45k | tag = get4(); |
1030 | 3.45k | fseek(ifp, 14, SEEK_CUR); |
1031 | 3.45k | i = get4() - 4; |
1032 | | |
1033 | 3.45k | if (tag == 0x76a43204) |
1034 | 36 | { |
1035 | 36 | WhiteBalanceAdj_active = fgetc(ifp); |
1036 | 36 | } |
1037 | 3.41k | else if (tag == 0xbf3c6c20) |
1038 | 0 | { |
1039 | 0 | if (WhiteBalanceAdj_active) |
1040 | 0 | { |
1041 | 0 | union { |
1042 | 0 | double dbl; |
1043 | 0 | unsigned long long lng; |
1044 | 0 | } un; |
1045 | 0 | un.dbl = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE); |
1046 | 0 | if ((un.lng != 0x3FF0000000000000ULL) && |
1047 | 0 | (un.lng != 0x000000000000F03FULL)) |
1048 | 0 | { |
1049 | 0 | cam_mul[0] = float(un.dbl); |
1050 | 0 | cam_mul[2] = getrealf(LIBRAW_EXIFTAG_TYPE_DOUBLE); |
1051 | 0 | cam_mul[1] = cam_mul[3] = 1.f; |
1052 | 0 | i -= 16; |
1053 | 0 | } |
1054 | 0 | else |
1055 | 0 | i -= 8; |
1056 | 0 | } |
1057 | 0 | fseek(ifp, i, SEEK_CUR); |
1058 | 0 | } |
1059 | 3.41k | else if (tag == 0x76a43207) |
1060 | 39 | { |
1061 | 39 | flip = get2(); |
1062 | 39 | } |
1063 | 3.37k | else |
1064 | 3.37k | { |
1065 | 3.37k | fseek(ifp, i, SEEK_CUR); |
1066 | 3.37k | } |
1067 | 3.45k | } |
1068 | 1.03k | } |
1069 | 362k | else if (tag == 0x0e22) |
1070 | 212 | { |
1071 | 848 | FORC4 imNikon.NEFBitDepth[c] = get2(); |
1072 | 212 | } |
1073 | 413k | next: |
1074 | 413k | fseek(ifp, save, SEEK_SET); |
1075 | 413k | } |
1076 | 24.4k | quit: |
1077 | 24.4k | order = sorder; |
1078 | 24.4k | } |
1079 | | |
1080 | 7 | unsigned sget4_order (short _order, uchar *s) { |
1081 | 7 | unsigned v; |
1082 | 7 | if (_order == 0x4949) |
1083 | 7 | v= s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; |
1084 | 0 | else |
1085 | 0 | v= s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; |
1086 | 7 | return v; |
1087 | 7 | } |
1088 | | |
1089 | 0 | double sget_fixed32u (short _order, uchar *s) { |
1090 | 0 | unsigned v = sget4_order (_order, s); |
1091 | 0 | return ((double)v / 6.5536 + 0.5) / 10000.0; |
1092 | 0 | } |
1093 | | |
1094 | 0 | double AngleConversion_a (short _order, uchar *s) { |
1095 | 0 | double v = sget_fixed32u(_order, s); |
1096 | 0 | if (v < 180.0) return -v; |
1097 | 0 | return 360.0-v; |
1098 | 0 | } |
1099 | | |
1100 | 0 | double AngleConversion (short _order, uchar *s) { |
1101 | 0 | double v = sget_fixed32u(_order, s); |
1102 | 0 | if (v <= 180.0) return v; |
1103 | 0 | return v-360.0; |
1104 | 0 | } |
1105 | | |
1106 | | /* ========= */ |
1107 | | /* |
1108 | | void hexDump(char *title, void *addr, int len) |
1109 | | { |
1110 | | int i; |
1111 | | unsigned char buff[17]; |
1112 | | unsigned char *pc = (unsigned char*)addr; |
1113 | | |
1114 | | // Output description if given. |
1115 | | if (title != NULL) |
1116 | | printf ("%s:\n", title); |
1117 | | |
1118 | | // Process every byte in the data. |
1119 | | for (i = 0; i < len; i++) { |
1120 | | // Multiple of 16 means new line (with line offset). |
1121 | | |
1122 | | if ((i % 16) == 0) { |
1123 | | // Just don't print ASCII for the zeroth line. |
1124 | | if (i != 0) |
1125 | | printf(" %s\n", buff); |
1126 | | |
1127 | | // Output the offset. |
1128 | | printf(" %04x ", i); |
1129 | | } |
1130 | | |
1131 | | // Now the hex code for the specific character. |
1132 | | printf(" %02x", pc[i]); |
1133 | | |
1134 | | // And store a printable ASCII character for later. |
1135 | | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) { |
1136 | | buff[i % 16] = '.'; |
1137 | | } else { |
1138 | | buff[i % 16] = pc[i]; |
1139 | | } |
1140 | | |
1141 | | buff[(i % 16) + 1] = '\0'; |
1142 | | } |
1143 | | |
1144 | | // Pad out last line if not exactly 16 characters. |
1145 | | while ((i % 16) != 0) { |
1146 | | printf(" "); |
1147 | | i++; |
1148 | | } |
1149 | | |
1150 | | // And print the final ASCII bit. |
1151 | | printf(" %s\n", buff); |
1152 | | } |
1153 | | */ |