1 /* -*- C++ -*-
2 * Copyright 2019-2020 LibRaw LLC (info@libraw.org)
3 *
4 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6 LibRaw do not use RESTRICTED code from dcraw.c
7
8 LibRaw is free software; you can redistribute it and/or modify
9 it under the terms of the one of two licenses as you choose:
10
11 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12 (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15 (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17 */
18
19 #include "../../internal/dcraw_defs.h"
20
parseAdobeRAFMakernote()21 void LibRaw::parseAdobeRAFMakernote()
22 {
23
24 uchar *PrivateMknBuf;
25 unsigned posPrivateMknBuf;
26 unsigned PrivateMknLength;
27 unsigned PrivateOrder;
28 unsigned PrivateEntries, PrivateTagID;
29 unsigned PrivateTagBytes;
30 unsigned wb_section_offset = 0;
31 int posWB;
32 int c;
33
34 #define CHECKSPACE(s) \
35 if (posPrivateMknBuf + (s) > PrivateMknLength) \
36 { \
37 free(PrivateMknBuf); \
38 return; \
39 }
40 #define isWB(posWB) \
41 sget2(posWB) != 0 && sget2(posWB + 2) != 0 && sget2(posWB + 4) != 0 && \
42 sget2(posWB + 6) != 0 && sget2(posWB + 8) != 0 && \
43 sget2(posWB + 10) != 0 && sget2(posWB) != 0xff && \
44 sget2(posWB + 2) != 0xff && sget2(posWB + 4) != 0xff && \
45 sget2(posWB + 6) != 0xff && sget2(posWB + 8) != 0xff && \
46 sget2(posWB + 10) != 0xff && sget2(posWB) == sget2(posWB + 6) && \
47 sget2(posWB) < sget2(posWB + 2) && sget2(posWB) < sget2(posWB + 4) && \
48 sget2(posWB) < sget2(posWB + 8) && sget2(posWB) < sget2(posWB + 10)
49 #define imfRAFDataVersion imFuji.RAFDataVersion
50 #define imfRAFVersion imFuji.RAFVersion
51
52 ushort use_WBcorr_coeffs = 0;
53 double wbR_corr = 1.0;
54 double wbB_corr = 1.0;
55
56 if (strstr(model, "S7000") ||
57 strstr(model, "S5000") ||
58 strstr(model, "F700") ||
59 strstr(model, "S2Pro") ||
60 strstr(model, "S20Pro")) {
61 use_WBcorr_coeffs = 1;
62 wbR_corr = 10.0 / 17.0 / 0.652941;
63 wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0);
64 }
65
66 order = 0x4d4d;
67 PrivateMknLength = get4();
68
69 if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) &&
70 (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024)))
71 { // 1024b for safety
72 fread(PrivateMknBuf, PrivateMknLength, 1, ifp);
73 PrivateOrder = sget2(PrivateMknBuf);
74 posPrivateMknBuf = sget4(PrivateMknBuf + 2) + 12;
75
76 memcpy(imFuji.SerialSignature, PrivateMknBuf + 6, 0x0c);
77 imFuji.SerialSignature[0x0c] = 0;
78 memcpy(model, PrivateMknBuf + 0x12, 0x20);
79 model[0x20] = 0;
80 memcpy(model2, PrivateMknBuf + 0x32, 4);
81 model2[4] = 0;
82 strcpy(imFuji.RAFVersion, model2);
83 PrivateEntries = sget2(PrivateMknBuf + posPrivateMknBuf);
84 if ((PrivateEntries > 1000) ||
85 ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949)))
86 {
87 free(PrivateMknBuf);
88 return;
89 }
90 posPrivateMknBuf += 2;
91 /*
92 * because Adobe DNG converter strips or misplaces 0xfnnn tags,
93 * Auto WB for following cameras is missing for now
94 * - F550EXR
95 * - F600EXR
96 * - F770EXR
97 * - F800EXR
98 * - F900EXR
99 * - HS10
100 * - HS11
101 * - HS20EXR
102 * - HS30EXR
103 * - HS50EXR
104 * - S1
105 * - SL1000
106 **/
107 while (PrivateEntries--)
108 {
109 order = 0x4d4d;
110 CHECKSPACE(4);
111 PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf);
112 PrivateTagBytes = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
113 posPrivateMknBuf += 4;
114 order = PrivateOrder;
115
116 if (PrivateTagID == 0x2000)
117 {
118 FORC4 icWBC[LIBRAW_WBI_Auto][GRGB_2_RGBG(c)] =
119 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
120 if (use_WBcorr_coeffs) {
121 icWBC[LIBRAW_WBI_Auto][0] *= wbR_corr;
122 icWBC[LIBRAW_WBI_Auto][2] *= wbB_corr;
123 }
124 }
125 else if (PrivateTagID == 0x2100)
126 {
127 FORC4 icWBC[LIBRAW_WBI_FineWeather][GRGB_2_RGBG(c)] =
128 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
129 if (use_WBcorr_coeffs) {
130 icWBC[LIBRAW_WBI_FineWeather][0] *= wbR_corr;
131 icWBC[LIBRAW_WBI_FineWeather][2] *= wbB_corr;
132 }
133 }
134 else if (PrivateTagID == 0x2200)
135 {
136 FORC4 icWBC[LIBRAW_WBI_Shade][GRGB_2_RGBG(c)] =
137 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
138 if (use_WBcorr_coeffs) {
139 icWBC[LIBRAW_WBI_Shade][0] *= wbR_corr;
140 icWBC[LIBRAW_WBI_Shade][2] *= wbB_corr;
141 }
142 }
143 else if (PrivateTagID == 0x2300)
144 {
145 FORC4 icWBC[LIBRAW_WBI_FL_D][GRGB_2_RGBG(c)] =
146 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
147 if (use_WBcorr_coeffs) {
148 icWBC[LIBRAW_WBI_FL_D][0] *= wbR_corr;
149 icWBC[LIBRAW_WBI_FL_D][2] *= wbB_corr;
150 }
151 }
152 else if (PrivateTagID == 0x2301)
153 {
154 FORC4 icWBC[LIBRAW_WBI_FL_N][GRGB_2_RGBG(c)] =
155 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
156 if (use_WBcorr_coeffs) {
157 icWBC[LIBRAW_WBI_FL_N][0] *= wbR_corr;
158 icWBC[LIBRAW_WBI_FL_N][2] *= wbB_corr;
159 }
160 }
161 else if (PrivateTagID == 0x2302)
162 {
163 FORC4 icWBC[LIBRAW_WBI_FL_WW][GRGB_2_RGBG(c)] =
164 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
165 if (use_WBcorr_coeffs) {
166 icWBC[LIBRAW_WBI_FL_WW][0] *= wbR_corr;
167 icWBC[LIBRAW_WBI_FL_WW][2] *= wbB_corr;
168 }
169 }
170 else if (PrivateTagID == 0x2310)
171 {
172 FORC4 icWBC[LIBRAW_WBI_FL_L][GRGB_2_RGBG(c)] =
173 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
174 if (use_WBcorr_coeffs) {
175 icWBC[LIBRAW_WBI_FL_L][0] *= wbR_corr;
176 icWBC[LIBRAW_WBI_FL_L][2] *= wbB_corr;
177 }
178 }
179 else if (PrivateTagID == 0x2311)
180 {
181 FORC4 icWBC[LIBRAW_WBI_FL_W][GRGB_2_RGBG(c)] =
182 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
183 if (use_WBcorr_coeffs) {
184 icWBC[LIBRAW_WBI_FL_W][0] *= wbR_corr;
185 icWBC[LIBRAW_WBI_FL_W][2] *= wbB_corr;
186 }
187 }
188 else if (PrivateTagID == 0x2400)
189 {
190 FORC4 icWBC[LIBRAW_WBI_Tungsten][GRGB_2_RGBG(c)] =
191 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
192 if (use_WBcorr_coeffs) {
193 icWBC[LIBRAW_WBI_Tungsten][0] *= wbR_corr;
194 icWBC[LIBRAW_WBI_Tungsten][2] *= wbB_corr;
195 }
196 }
197 else if (PrivateTagID == 0x2410)
198 {
199 FORC4 icWBC[LIBRAW_WBI_Flash][GRGB_2_RGBG(c)] =
200 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
201 if (use_WBcorr_coeffs) {
202 icWBC[LIBRAW_WBI_Flash][0] *= wbR_corr;
203 icWBC[LIBRAW_WBI_Flash][2] *= wbB_corr;
204 }
205 }
206 else if (PrivateTagID == 0x2f00)
207 {
208 int nWBs = MIN(sget4(PrivateMknBuf + posPrivateMknBuf), 6);
209 posWB = posPrivateMknBuf + 4;
210 for (int wb_ind = 0; wb_ind < nWBs; wb_ind++)
211 {
212 FORC4 icWBC[LIBRAW_WBI_Custom1 + wb_ind][GRGB_2_RGBG(c)] =
213 sget2(PrivateMknBuf + posWB + (c << 1));
214 if (use_WBcorr_coeffs) {
215 icWBC[LIBRAW_WBI_Custom1 + wb_ind][0] *= wbR_corr;
216 icWBC[LIBRAW_WBI_Custom1 + wb_ind][2] *= wbB_corr;
217 }
218 posWB += 8;
219 }
220 }
221 else if (PrivateTagID == 0x2ff0)
222 {
223 FORC4 cam_mul[GRGB_2_RGBG(c)] =
224 sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
225 if (use_WBcorr_coeffs) {
226 cam_mul[0] *= wbR_corr;
227 cam_mul[2] *= wbB_corr;
228 }
229 }
230
231 else if (PrivateTagID == 0x9650)
232 {
233 CHECKSPACE(4);
234 short a = (short)sget2(PrivateMknBuf + posPrivateMknBuf);
235 float b = fMAX(1.0f, sget2(PrivateMknBuf + posPrivateMknBuf + 2));
236 imFuji.ExpoMidPointShift = a / b;
237 }
238 else if ((PrivateTagID == 0xc000) && (PrivateTagBytes > 3) &&
239 (PrivateTagBytes < 10240000))
240 {
241 order = 0x4949;
242 if (PrivateTagBytes != 4096) // not one of Fuji X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10
243 {
244 if (!sget2(PrivateMknBuf + posPrivateMknBuf))
245 imfRAFDataVersion = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
246
247 for (posWB = 0; posWB < (int)PrivateTagBytes - 16; posWB++)
248 {
249 if ((!memcmp(PrivateMknBuf + posWB, "TSNERDTS", 8) &&
250 (sget2(PrivateMknBuf + posWB + 10) > 125)))
251 {
252 posWB += 10;
253 icWBC[LIBRAW_WBI_Auto][1] =
254 icWBC[LIBRAW_WBI_Auto][3] =
255 sget2(PrivateMknBuf + posWB);
256 icWBC[LIBRAW_WBI_Auto][0] =
257 sget2(PrivateMknBuf + posWB + 2);
258 icWBC[LIBRAW_WBI_Auto][2] =
259 sget2(PrivateMknBuf + posWB + 4);
260 break;
261 }
262 }
263 if (imfRAFDataVersion == 0x0146 || // X20
264 imfRAFDataVersion == 0x0149 || // X100S
265 imfRAFDataVersion == 0x0249) // X100S
266 {
267 wb_section_offset = 0x1410;
268 }
269 else if (imfRAFDataVersion == 0x014d || // X-M1
270 imfRAFDataVersion == 0x014e) // X-A1, X-A2
271 {
272 wb_section_offset = 0x1474;
273 }
274 else if (imfRAFDataVersion == 0x014f || // X-E2
275 imfRAFDataVersion == 0x024f || // X-E2
276 imfRAFDataVersion == 0x025d) // X-H1
277 {
278 wb_section_offset = 0x1480;
279 }
280 else if (imfRAFDataVersion == 0x0150) // XQ1, XQ2
281 {
282 wb_section_offset = 0x1414;
283 }
284 else if (imfRAFDataVersion == 0x0151 || // X-T1 w/diff. fws
285 imfRAFDataVersion == 0x0251 || imfRAFDataVersion == 0x0351 ||
286 imfRAFDataVersion == 0x0451 || imfRAFDataVersion == 0x0551)
287 {
288 wb_section_offset = 0x14b0;
289 }
290 else if (imfRAFDataVersion == 0x0152 || // X30
291 imfRAFDataVersion == 0x0153) // X100T
292 {
293 wb_section_offset = 0x1444;
294 }
295 else if (imfRAFDataVersion == 0x0154) // X-T10
296 {
297 wb_section_offset = 0x1824;
298 }
299 else if (imfRAFDataVersion == 0x0155) // X70
300 {
301 wb_section_offset = 0x17b4;
302 }
303 else if (imfRAFDataVersion == 0x0255) // X-Pro2
304 {
305 wb_section_offset = 0x135c;
306 }
307 else if (imfRAFDataVersion == 0x0258 || // X-T2
308 imfRAFDataVersion == 0x025b) // X-T20
309 {
310 wb_section_offset = 0x13dc;
311 }
312 else if (imfRAFDataVersion == 0x0259) // X100F
313 {
314 wb_section_offset = 0x1370;
315 }
316 else if (imfRAFDataVersion == 0x025a) // GFX 50S
317 {
318 wb_section_offset = 0x1424;
319 }
320 else if (imfRAFDataVersion == 0x025c) // X-E3
321 {
322 wb_section_offset = 0x141c;
323 }
324 else if (imfRAFDataVersion == 0x025e) // X-T3
325 {
326 wb_section_offset = 0x2014;
327 }
328 else if (imfRAFDataVersion == 0x025f) // X-T30, GFX 50R, GFX 100
329 {
330 if (!strcmp(model, "X-T30")) {
331 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8))
332 wb_section_offset = 0x20b8;
333 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20c8))
334 wb_section_offset = 0x20c8;
335 }
336 else if (!strcmp(model, "GFX 50R"))
337 wb_section_offset = 0x1424;
338 else if (!strcmp(model, "GFX 100"))
339 wb_section_offset = 0x20e4;
340 }
341 else if (imfRAFDataVersion == 0x0260) // X-Pro3
342 {
343 wb_section_offset = 0x20e8;
344 }
345 else if (imfRAFDataVersion == 0x0261) // X100V
346 {
347 wb_section_offset = 0x2078;
348 }
349 else if (imfRAFDataVersion == 0x0262) // X-T4
350 {
351 wb_section_offset = 0x21c8;
352 }
353
354 /* try for unknown RAF Data versions */
355 else if (!strcmp(model, "X-Pro2"))
356 {
357 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x135c))
358 wb_section_offset = 0x135c;
359 }
360 else if (!strcmp(model, "X100F"))
361 {
362 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1370))
363 wb_section_offset = 0x1370;
364 }
365 else if (!strcmp(model, "X-T2"))
366 {
367 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13dc))
368 wb_section_offset = 0x13dc;
369 }
370 else if (!strcmp(model, "X-T20"))
371 {
372 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13dc))
373 wb_section_offset = 0x13dc;
374 }
375 else if (!strcmp(model, "X20"))
376 {
377 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1410))
378 wb_section_offset = 0x1410;
379 }
380 else if (!strcmp(model, "X100S"))
381 {
382 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1410))
383 wb_section_offset = 0x1410;
384 }
385 else if (!strcmp(model, "XQ1"))
386 {
387 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1414))
388 wb_section_offset = 0x1414;
389 }
390 else if (!strcmp(model, "XQ2"))
391 {
392 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1414))
393 wb_section_offset = 0x1414;
394 }
395 else if (!strcmp(model, "X-E3"))
396 {
397 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x141c))
398 wb_section_offset = 0x141c;
399 }
400 else if (!strcmp(model, "GFX 50S"))
401 {
402 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1424))
403 wb_section_offset = 0x1424;
404 }
405 else if (!strcmp(model, "GFX 50R"))
406 {
407 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1424))
408 wb_section_offset = 0x1424;
409 }
410 else if (!strcmp(model, "X30"))
411 {
412 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1444))
413 wb_section_offset = 0x1444;
414 }
415 else if (!strcmp(model, "X100T"))
416 {
417 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1444))
418 wb_section_offset = 0x1444;
419 }
420 else if (!strcmp(model, "X-M1"))
421 {
422 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474))
423 wb_section_offset = 0x1474;
424 }
425 else if (!strcmp(model, "X-A1"))
426 {
427 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474))
428 wb_section_offset = 0x1474;
429 }
430 else if (!strcmp(model, "X-A2"))
431 {
432 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474))
433 wb_section_offset = 0x1474;
434 }
435 else if (!strcmp(model, "X-E2"))
436 {
437 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1480))
438 wb_section_offset = 0x1480;
439 }
440 else if (!strcmp(model, "X-H1"))
441 {
442 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1480))
443 wb_section_offset = 0x1480;
444 }
445 else if (!strcmp(model, "X-T1"))
446 {
447 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x14b0))
448 wb_section_offset = 0x14b0;
449 }
450 else if (!strcmp(model, "X70"))
451 {
452 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x17b4))
453 wb_section_offset = 0x17b4;
454 }
455 else if (!strcmp(model, "X-T10"))
456 {
457 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1824))
458 wb_section_offset = 0x1824;
459 }
460 else if (!strcmp(model, "X-E2S"))
461 {
462 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1840))
463 wb_section_offset = 0x1840;
464 }
465 else if (!strcmp(model, "X-T3"))
466 {
467 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2014))
468 wb_section_offset = 0x2014;
469 }
470 else if (!strcmp(model, "X100V"))
471 {
472 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e8))
473 wb_section_offset = 0x2078;
474 }
475 else if (!strcmp(model, "X-T30"))
476 {
477 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8))
478 wb_section_offset = 0x20b8;
479 }
480 else if (!strcmp(model, "GFX 100"))
481 {
482 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e4))
483 wb_section_offset = 0x20e4;
484 }
485 else if (!strcmp(model, "X-Pro3"))
486 {
487 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e8))
488 wb_section_offset = 0x20e8;
489 }
490 else if (!strcmp(model, "X-T4"))
491 {
492 if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21c8))
493 wb_section_offset = 0x21c8;
494 }
495
496 /* no RAF Data version for the models below */
497 else if (!strcmp(model, "FinePix X100")) // X100 0 0x19f0 0x19e8
498 {
499 if (!strcmp(imfRAFVersion, "0069"))
500 wb_section_offset = 0x19e8;
501 else if (!strcmp(imfRAFVersion, "0100"))
502 wb_section_offset = 0x19f0;
503 else if (!strcmp(imfRAFVersion, "0110"))
504 wb_section_offset = 0x19f0;
505 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19e8))
506 wb_section_offset = 0x19e8;
507 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19f0))
508 wb_section_offset = 0x19f0;
509 }
510 else if (!strcmp(model, "X-E1")) // X-E1 0 0x13ac
511 {
512 if (!strcmp(imfRAFVersion, "0101"))
513 wb_section_offset = 0x13ac;
514 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13ac))
515 wb_section_offset = 0x13ac;
516 }
517 else if (!strcmp(model, "X-Pro1")) // X-Pro1 0 0x13a4
518 {
519 if (!strcmp(imfRAFVersion, "0100"))
520 wb_section_offset = 0x13a4;
521 else if (!strcmp(imfRAFVersion, "0101"))
522 wb_section_offset = 0x13a4;
523 else if (!strcmp(imfRAFVersion, "0204"))
524 wb_section_offset = 0x13a4;
525 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13a4))
526 wb_section_offset = 0x13a4;
527 }
528 else if (!strcmp(model, "XF1")) // XF1 0 0x138c
529 {
530 if (!strcmp(imfRAFVersion, "0100"))
531 wb_section_offset = 0x138c;
532 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c))
533 wb_section_offset = 0x138c;
534 }
535 else if (!strcmp(model, "X-S1")) // X-S1 0 0x1284
536 {
537 if (!strcmp(imfRAFVersion, "0100"))
538 wb_section_offset = 0x1284;
539 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1284))
540 wb_section_offset = 0x1284;
541 }
542 else if (!strcmp(model, "X10")) // X10 0 0x1280 0x12d4
543 {
544 if (!strcmp(imfRAFVersion, "0100"))
545 wb_section_offset = 0x1280;
546 else if (!strcmp(imfRAFVersion, "0102"))
547 wb_section_offset = 0x1280;
548 else if (!strcmp(imfRAFVersion, "0103"))
549 wb_section_offset = 0x12d4;
550 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1280))
551 wb_section_offset = 0x1280;
552 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x12d4))
553 wb_section_offset = 0x12d4;
554 }
555 else if (!strcmp(model, "XF1")) // XF1 0 0x138c
556 {
557 if (!strcmp(imfRAFVersion, "0100"))
558 wb_section_offset = 0x138c;
559 else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c))
560 wb_section_offset = 0x138c;
561 }
562 if (wb_section_offset &&
563 isWB(PrivateMknBuf + posPrivateMknBuf + wb_section_offset))
564 {
565
566 if (!imfRAFDataVersion)
567 {
568 posWB = posPrivateMknBuf + wb_section_offset - 6;
569 icWBC[LIBRAW_WBI_Auto][1] =
570 icWBC[LIBRAW_WBI_Auto][3] =
571 sget2(PrivateMknBuf + posWB);
572 icWBC[LIBRAW_WBI_Auto][0] =
573 sget2(PrivateMknBuf + posWB + 2);
574 icWBC[LIBRAW_WBI_Auto][2] =
575 sget2(PrivateMknBuf + posWB + 4);
576 }
577
578 posWB = posPrivateMknBuf + wb_section_offset;
579 for (int wb_ind = 0; wb_ind < Fuji_wb_list1.size(); posWB += 6, wb_ind++)
580 {
581 icWBC[Fuji_wb_list1[wb_ind]][1] =
582 icWBC[Fuji_wb_list1[wb_ind]][3] =
583 sget2(PrivateMknBuf + posWB);
584 icWBC[Fuji_wb_list1[wb_ind]][0] =
585 sget2(PrivateMknBuf + posWB + 2);
586 icWBC[Fuji_wb_list1[wb_ind]][2] =
587 sget2(PrivateMknBuf + posWB + 4);
588 }
589 int found = 0;
590 if ((imfRAFDataVersion == 0x0260) ||
591 (imfRAFDataVersion == 0x0261) ||
592 (imfRAFDataVersion == 0x0262))
593 posWB += 0x30;
594 posWB += 0xc0;
595 ushort Gval = sget2(PrivateMknBuf + posWB);
596 for (int posEndCCTsection = posWB; posEndCCTsection < (posWB + 30);
597 posEndCCTsection += 6)
598 {
599 if (sget2(PrivateMknBuf + posEndCCTsection) != Gval)
600 {
601 if ((imfRAFDataVersion == 0x0260) ||
602 (imfRAFDataVersion == 0x0261) ||
603 (imfRAFDataVersion == 0x0262))
604 wb_section_offset = posEndCCTsection - 34*3*2; // 34 records, 3 2-byte values in a record
605 else
606 wb_section_offset = posEndCCTsection - 31*3*2; // 31 records, 3 2-byte values in a record
607 found = 1;
608 break;
609 }
610 }
611
612 if (found)
613 {
614 for (int iCCT = 0; iCCT < 31; iCCT++)
615 {
616 icWBCCTC[iCCT][0] = FujiCCT_K[iCCT];
617 icWBCCTC[iCCT][1] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 2);
618 icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6);
619 icWBCCTC[iCCT][3] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 4);
620 }
621 }
622 }
623 }
624 else // process 4K raf data
625 {
626 int wb[4];
627 int nWB, tWB, pWB;
628 int iCCT = 0;
629 is_4K_RAFdata = 1; /* X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 */
630 posWB = posPrivateMknBuf + 0x200;
631 for (int wb_ind = 0; wb_ind < 42; wb_ind++)
632 {
633 nWB = sget4(PrivateMknBuf + posWB);
634 posWB += 4;
635 tWB = sget4(PrivateMknBuf + posWB);
636 posWB += 4;
637 wb[0] = sget4(PrivateMknBuf + posWB) << 1;
638 posWB += 4;
639 wb[1] = sget4(PrivateMknBuf + posWB);
640 posWB += 4;
641 wb[3] = sget4(PrivateMknBuf + posWB);
642 posWB += 4;
643 wb[2] = sget4(PrivateMknBuf + posWB) << 1;
644 posWB += 4;
645
646 if (tWB && (iCCT < 255))
647 {
648 icWBCCTC[iCCT][0] = tWB;
649 FORC4 icWBCCTC[iCCT][c + 1] = wb[c];
650 iCCT++;
651 }
652 if (nWB != 0x46)
653 {
654 for (pWB = 1; pWB < Fuji_wb_list2.size(); pWB += 2)
655 {
656 if (Fuji_wb_list2[pWB] == nWB)
657 {
658 FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] =
659 wb[c];
660 break;
661 }
662 }
663 }
664 }
665 }
666 }
667 posPrivateMknBuf += PrivateTagBytes;
668 }
669 free(PrivateMknBuf);
670 }
671 #undef imfRAFVersion
672 #undef imfRAFDataVersion
673 #undef CHECKSPACE
674 }
parseFujiMakernotes(unsigned tag,unsigned type,unsigned len,unsigned dng_writer)675 void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len,
676 unsigned dng_writer)
677 {
678 if ((dng_writer == nonDNG) && (tag == 0x0010))
679 {
680 char FujiSerial[sizeof(imgdata.shootinginfo.InternalBodySerial)];
681 char *words[4];
682 char yy[2], mm[3], dd[3], ystr[16], ynum[16];
683 int year, nwords, ynum_len;
684 unsigned c;
685 memset(FujiSerial, 0, sizeof(imgdata.shootinginfo.InternalBodySerial));
686 ifp->read(FujiSerial, MIN(len,sizeof(FujiSerial)), 1);
687 nwords = getwords(FujiSerial, words, 4,
688 sizeof(imgdata.shootinginfo.InternalBodySerial));
689 for (int i = 0; i < nwords; i++)
690 {
691 mm[2] = dd[2] = 0;
692 if (strnlen(words[i],
693 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) < 18)
694 {
695 if (i == 0)
696 {
697 strncpy(imgdata.shootinginfo.InternalBodySerial, words[0],
698 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
699 }
700 else
701 {
702 char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];
703 snprintf(tbuf, sizeof(tbuf)-1, "%s %s",
704 imgdata.shootinginfo.InternalBodySerial, words[i]);
705 strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
706 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
707 }
708 }
709 else
710 {
711 strncpy(
712 dd,
713 words[i] +
714 strnlen(words[i],
715 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
716 14,
717 2);
718 strncpy(
719 mm,
720 words[i] +
721 strnlen(words[i],
722 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
723 16,
724 2);
725 strncpy(
726 yy,
727 words[i] +
728 strnlen(words[i],
729 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
730 18,
731 2);
732 year = (yy[0] - '0') * 10 + (yy[1] - '0');
733 if (year < 70)
734 year += 2000;
735 else
736 year += 1900;
737
738 ynum_len = MIN(
739 int(sizeof(ynum) - 1),
740 (int)strnlen(words[i],
741 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
742 18);
743 strncpy(ynum, words[i], ynum_len);
744 ynum[ynum_len] = 0;
745 for (int j = 0; ynum[j] && ynum[j + 1] && sscanf(ynum + j, "%2x", &c);
746 j += 2)
747 ystr[j / 2] = c;
748 ystr[ynum_len / 2 + 1] = 0;
749 strcpy(model2, ystr);
750
751 if (i == 0)
752 {
753 char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];
754
755 if (nwords == 1)
756 {
757 snprintf(
758 tbuf, sizeof(tbuf), "%s %s %d:%s:%s",
759 words[0] +
760 strnlen(words[0],
761 sizeof(imgdata.shootinginfo.InternalBodySerial) -
762 1) -
763 12,
764 ystr, year, mm, dd);
765 }
766 else
767 {
768 snprintf(
769 tbuf, sizeof(tbuf), "%s %d:%s:%s %s", ystr, year, mm, dd,
770 words[0] +
771 strnlen(words[0],
772 sizeof(imgdata.shootinginfo.InternalBodySerial) -
773 1) -
774 12);
775 }
776 strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
777 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
778 }
779 else
780 {
781 char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];
782 snprintf(
783 tbuf, sizeof(tbuf), "%s %s %d:%s:%s %s",
784 imgdata.shootinginfo.InternalBodySerial, ystr, year, mm, dd,
785 words[i] +
786 strnlen(words[i],
787 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
788 12);
789 strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
790 sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
791 }
792 }
793 }
794 }
795 else
796 switch (tag)
797 {
798 case 0x1002:
799 imFuji.WB_Preset = get2();
800 break;
801 case 0x1011:
802 imCommon.FlashEC = getreal(type);
803 break;
804 case 0x1020:
805 imFuji.Macro = get2();
806 break;
807 case 0x1021:
808 imFuji.FocusMode = imgdata.shootinginfo.FocusMode = get2();
809 break;
810 case 0x1022:
811 imFuji.AFMode = get2();
812 break;
813 case 0x1023:
814 imFuji.FocusPixel[0] = get2();
815 imFuji.FocusPixel[1] = get2();
816 break;
817 case 0x1034:
818 imFuji.ExrMode = get2();
819 break;
820 case 0x104d:
821 FujiCropMode = get2(); // odd: one of raw dimensions here can be lost
822 break;
823 case 0x1050:
824 imFuji.ShutterType = get2();
825 break;
826 case 0x1103:
827 imgdata.shootinginfo.DriveMode = get2();
828 imFuji.DriveMode = imgdata.shootinginfo.DriveMode & 0xff;
829 break;
830
831 case 0x1400:
832 imFuji.DynamicRange = get2();
833 break;
834 case 0x1401:
835 imFuji.FilmMode = get2();
836 break;
837 case 0x1402:
838 imFuji.DynamicRangeSetting = get2();
839 break;
840 case 0x1403:
841 imFuji.DevelopmentDynamicRange = get2();
842 break;
843 case 0x140b:
844 imFuji.AutoDynamicRange = get2();
845 break;
846 case 0x1443:
847 imFuji.DRangePriority = get2();
848 break;
849 case 0x1444:
850 imFuji.DRangePriorityAuto = get2();
851 break;
852 case 0x1445:
853 imFuji.DRangePriorityFixed = get2();
854 break;
855
856 case 0x1404:
857 ilm.MinFocal = getreal(type);
858 break;
859 case 0x1405:
860 ilm.MaxFocal = getreal(type);
861 break;
862 case 0x1406:
863 ilm.MaxAp4MinFocal = getreal(type);
864 break;
865 case 0x1407:
866 ilm.MaxAp4MaxFocal = getreal(type);
867 break;
868 case 0x1422:
869 imFuji.ImageStabilization[0] = get2();
870 imFuji.ImageStabilization[1] = get2();
871 imFuji.ImageStabilization[2] = get2();
872 imgdata.shootinginfo.ImageStabilization =
873 (imFuji.ImageStabilization[0] << 9) + imFuji.ImageStabilization[1];
874 break;
875 case 0x1431:
876 imFuji.Rating = get4();
877 break;
878 case 0x3820:
879 imFuji.FrameRate = get2();
880 break;
881 case 0x3821:
882 imFuji.FrameWidth = get2();
883 break;
884 case 0x3822:
885 imFuji.FrameHeight = get2();
886 break;
887 }
888 return;
889 }
890
parse_fuji(int offset)891 void LibRaw::parse_fuji(int offset)
892 {
893 unsigned entries, tag, len, save, c;
894 ushort raw_inset_present = 0;
895 ushort use_WBcorr_coeffs = 0;
896 double wbR_corr = 1.0;
897 double wbB_corr = 1.0;
898
899 fseek(ifp, offset, SEEK_SET);
900 entries = get4();
901 if (entries > 255)
902 return;
903 imgdata.process_warnings |= LIBRAW_WARN_PARSEFUJI_PROCESSED;
904
905 if (strstr(model, "S7000") ||
906 strstr(model, "S5000") ||
907 strstr(model, "F700") ||
908 strstr(model, "S2Pro") ||
909 strstr(model, "S20Pro")) {
910 use_WBcorr_coeffs = 1;
911 wbR_corr = 10.0 / 17.0 / 0.652941;
912 wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0);
913 }
914
915 while (entries--)
916 {
917 tag = get2();
918 len = get2();
919 save = ftell(ifp);
920
921 if (tag == 0x0100) // RawImageFullSize
922 {
923 raw_height = get2();
924 raw_width = get2();
925 raw_inset_present = 1;
926 }
927 else if (tag == 0x0121) // RawImageSize
928 {
929 height = get2();
930 if ((width = get2()) == 4284)
931 width += 3;
932 }
933 else if (tag == 0x0130) // FujiLayout
934 {
935 fuji_layout = fgetc(ifp) >> 7;
936 fuji_width = !(fgetc(ifp) & 8);
937 }
938 else if (tag == 0x0131) // XTransLayout
939 {
940 filters = 9;
941 char *xtrans_abs_alias = &xtrans_abs[0][0];
942 FORC(36)
943 {
944 int q = fgetc(ifp);
945 xtrans_abs_alias[35 - c] = MAX(0, MIN(q, 2)); /* & 3;*/
946 }
947 }
948 else if (tag == 0x2ff0) // WB_GRGBLevels
949 {
950 FORC4 cam_mul[GRGB_2_RGBG(c)] = get2();
951 if (use_WBcorr_coeffs) {
952 cam_mul[0] *= wbR_corr;
953 cam_mul[2] *= wbB_corr;
954 }
955 }
956
957 else if ((tag == 0x0110) && raw_inset_present) // RawImageCropTopLeft
958 {
959 imgdata.sizes.raw_inset_crop.ctop = get2();
960 imgdata.sizes.raw_inset_crop.cleft = get2();
961 }
962 else if ((tag == 0x0111) && raw_inset_present) // RawImageCroppedSize
963 {
964 imgdata.sizes.raw_inset_crop.cheight = get2();
965 imgdata.sizes.raw_inset_crop.cwidth = get2();
966 }
967 else if ((tag == 0x0115) && raw_inset_present) // RawImageAspectRatio
968 {
969 int a = get2();
970 int b = get2();
971 if (a * b == 6)
972 imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_3to2;
973 else if (a * b == 12)
974 imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_4to3;
975 else if (a * b == 144)
976 imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_16to9;
977 else if (a * b == 1)
978 imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_1to1;
979 }
980 else if (tag == 0x9200) // RelativeExposure
981 {
982 int a = get4();
983 if ((a == 0x01000100) || (a <= 0))
984 imFuji.BrightnessCompensation = 0.0f;
985 else if (a == 0x00100100)
986 imFuji.BrightnessCompensation = 4.0f;
987 else
988 imFuji.BrightnessCompensation =
989 24.0f - float(log((double)a) / log(2.0));
990 }
991 else if (tag == 0x9650) // RawExposureBias
992 {
993 short a = (short)get2();
994 float b = fMAX(1.0f, get2());
995 imFuji.ExpoMidPointShift = a / b;
996 }
997 else if (tag == 0x2f00) // WB_GRGBLevels
998 {
999 int nWBs = get4();
1000 nWBs = MIN(nWBs, 6);
1001 for (int wb_ind = 0; wb_ind < nWBs; wb_ind++)
1002 {
1003 FORC4 icWBC[LIBRAW_WBI_Custom1 + wb_ind][GRGB_2_RGBG(c)] = get2();
1004 if (use_WBcorr_coeffs) {
1005 icWBC[LIBRAW_WBI_Custom1 + wb_ind][0] *= wbR_corr;
1006 icWBC[LIBRAW_WBI_Custom1 + wb_ind][2] *= wbB_corr;
1007 }
1008 fseek(ifp, 8, SEEK_CUR);
1009 }
1010 }
1011 else if (tag == 0x2000) // WB_GRGBLevelsAuto
1012 {
1013 FORC4 icWBC[LIBRAW_WBI_Auto][GRGB_2_RGBG(c)] = get2();
1014 if (use_WBcorr_coeffs) {
1015 icWBC[LIBRAW_WBI_Auto][0] *= wbR_corr;
1016 icWBC[LIBRAW_WBI_Auto][2] *= wbB_corr;
1017 }
1018 }
1019 else if (tag == 0x2100) // WB_GRGBLevelsDaylight
1020 {
1021 FORC4 icWBC[LIBRAW_WBI_FineWeather][GRGB_2_RGBG(c)] = get2();
1022 if (use_WBcorr_coeffs) {
1023 icWBC[LIBRAW_WBI_FineWeather][0] *= wbR_corr;
1024 icWBC[LIBRAW_WBI_FineWeather][2] *= wbB_corr;
1025 }
1026 }
1027 else if (tag == 0x2200) // WB_GRGBLevelsCloudy
1028 {
1029 FORC4 icWBC[LIBRAW_WBI_Shade][GRGB_2_RGBG(c)] = get2();
1030 if (use_WBcorr_coeffs) {
1031 icWBC[LIBRAW_WBI_Shade][0] *= wbR_corr;
1032 icWBC[LIBRAW_WBI_Shade][2] *= wbB_corr;
1033 }
1034 }
1035 else if (tag == 0x2300) // WB_GRGBLevelsDaylightFluor
1036 {
1037 FORC4 icWBC[LIBRAW_WBI_FL_D][GRGB_2_RGBG(c)] = get2();
1038 if (use_WBcorr_coeffs) {
1039 icWBC[LIBRAW_WBI_FL_D][0] *= wbR_corr;
1040 icWBC[LIBRAW_WBI_FL_D][2] *= wbB_corr;
1041 }
1042 }
1043 else if (tag == 0x2301) // WB_GRGBLevelsDayWhiteFluor
1044 {
1045 FORC4 icWBC[LIBRAW_WBI_FL_N][GRGB_2_RGBG(c)] = get2();
1046 if (use_WBcorr_coeffs) {
1047 icWBC[LIBRAW_WBI_FL_N][0] *= wbR_corr;
1048 icWBC[LIBRAW_WBI_FL_N][2] *= wbB_corr;
1049 }
1050 }
1051 else if (tag == 0x2302) // WB_GRGBLevelsWhiteFluorescent
1052 {
1053 FORC4 icWBC[LIBRAW_WBI_FL_WW][GRGB_2_RGBG(c)] = get2();
1054 if (use_WBcorr_coeffs) {
1055 icWBC[LIBRAW_WBI_FL_WW][0] *= wbR_corr;
1056 icWBC[LIBRAW_WBI_FL_WW][2] *= wbB_corr;
1057 }
1058 }
1059 else if (tag == 0x2310) // WB_GRGBLevelsWarmWhiteFluor
1060 {
1061 FORC4 icWBC[LIBRAW_WBI_FL_L][GRGB_2_RGBG(c)] = get2();
1062 if (use_WBcorr_coeffs) {
1063 icWBC[LIBRAW_WBI_FL_L][0] *= wbR_corr;
1064 icWBC[LIBRAW_WBI_FL_L][2] *= wbB_corr;
1065 }
1066 }
1067 else if (tag == 0x2311) // WB_GRGBLevelsLivingRoomWarmWhiteFluor
1068 {
1069 FORC4 icWBC[LIBRAW_WBI_FL_W][GRGB_2_RGBG(c)] = get2();
1070 if (use_WBcorr_coeffs) {
1071 icWBC[LIBRAW_WBI_FL_W][0] *= wbR_corr;
1072 icWBC[LIBRAW_WBI_FL_W][2] *= wbB_corr;
1073 }
1074 }
1075 else if (tag == 0x2400) // WB_GRGBLevelsTungsten
1076 {
1077 FORC4 icWBC[LIBRAW_WBI_Tungsten][GRGB_2_RGBG(c)] = get2();
1078 if (use_WBcorr_coeffs) {
1079 icWBC[LIBRAW_WBI_Tungsten][0] *= wbR_corr;
1080 icWBC[LIBRAW_WBI_Tungsten][2] *= wbB_corr;
1081 }
1082 }
1083 else if (tag == 0x2410)
1084 {
1085 FORC4 icWBC[LIBRAW_WBI_Flash][GRGB_2_RGBG(c)] = get2();
1086 if (use_WBcorr_coeffs) {
1087 icWBC[LIBRAW_WBI_Flash][0] *= wbR_corr;
1088 icWBC[LIBRAW_WBI_Flash][2] *= wbB_corr;
1089 }
1090 }
1091
1092 else if (tag == 0xc000) // RAFData
1093 {
1094 c = order;
1095 order = 0x4949;
1096 if (len > 20000)
1097 {
1098 tag = get4();
1099 if (tag > 10000)
1100 {
1101 imFuji.RAFDataVersion = tag >> 16;
1102 if (!imFuji.RAFDataVersion)
1103 imFuji.RAFDataVersion = tag;
1104 tag = get4();
1105 }
1106 if (tag > 10000)
1107 { // if it is >1000 it normally contains 0x53545257, "WRTS"
1108 tag = get4();
1109 }
1110 width = tag;
1111 height = get4();
1112 if (width > raw_width)
1113 width = raw_width;
1114 if (height > raw_height)
1115 height = raw_height;
1116 }
1117 if (len == 4096) // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10
1118 { // Ill.A aligned to CCT 2850
1119 int wb[4];
1120 int nWB, tWB, pWB;
1121 int iCCT = 0;
1122 is_4K_RAFdata = 1;
1123 fseek(ifp, save + 0x200, SEEK_SET);
1124 for (int wb_ind = 0; wb_ind < 42; wb_ind++)
1125 {
1126 nWB = get4();
1127 tWB = get4();
1128 wb[0] = get4() << 1;
1129 wb[1] = get4();
1130 wb[3] = get4();
1131 wb[2] = get4() << 1;
1132 if (tWB && (iCCT < 255))
1133 {
1134 icWBCCTC[iCCT][0] = tWB;
1135 FORC4 icWBCCTC[iCCT][c + 1] = wb[c];
1136 iCCT++;
1137 }
1138 if (nWB != 70)
1139 {
1140 for (pWB = 1; pWB < Fuji_wb_list2.size(); pWB += 2)
1141 {
1142 if (Fuji_wb_list2[pWB] == nWB)
1143 {
1144 FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] =
1145 wb[c];
1146 break;
1147 }
1148 }
1149 }
1150 }
1151 }
1152 else
1153 {
1154 libraw_internal_data.unpacker_data.posRAFData = save;
1155 libraw_internal_data.unpacker_data.lenRAFData = (len >> 1);
1156 }
1157 order = c;
1158 }
1159 fseek(ifp, save + len, SEEK_SET);
1160 }
1161 height <<= fuji_layout;
1162 width >>= fuji_layout;
1163 }
1164