/src/libraw/src/metadata/fuji.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2025 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 | | #include "../../internal/libraw_checked_buffer.h" |
21 | | |
22 | | |
23 | | int LibRaw::guess_RAFDataGeneration (uchar *RAFData_start) // returns offset to first valid width/height pair |
24 | 11.3k | { |
25 | | |
26 | | /* RAFDataGeneration codes, values are 4 bytes, little endian |
27 | | |
28 | | RAFData gen. 0: no RAFData |
29 | | DBP for GX680 / DX-2000 |
30 | | E550, E900, (F500 / F505?) F550, F600 / F605, F700, F770 / F775, F800, F810, F900 |
31 | | HS10 HS11, HS20 / HS22, HS30 / HS33 / HS35, HS50 |
32 | | S1, SL1000, S100, S200 / S205, S20Pro, S2Pro, S3Pro, S5Pro |
33 | | S5000, S5100 / S5500, S5200 / S5600, S6000 / S6500, S7000, S9000 / S9500, S9100 / S9600 |
34 | | |
35 | | RAFData gen. 1, offset to WH pair (offsetWH_inRAFData) = 0: |
36 | | - number in bytes 0..1 is less than 10000 |
37 | | - contains WH pair, recommended image size WH pair, 16 bytes unknown, 2*13 values (for crops, scales?) |
38 | | X100, X-Pro1, X-S1, X10, XF1 |
39 | | |
40 | | RAFData gen. 2, offset to WH pair = 4: |
41 | | - bytes 0..1 contain a number greater than 10000; bytes 2..3 contain zero; |
42 | | version is in bytes 0..1, possibly big endian |
43 | | - contains WH pair, recommended image size WH pair, 16 bytes unknown, 2*13 values |
44 | | X-E1 |
45 | | |
46 | | RAFData gen. 3, offset to WH pair = 4: |
47 | | - bytes 0..1 contain zero; bytes 2..3 contain version; |
48 | | - contains a table of 3+2*13 values; first 3 values look like WHW |
49 | | X-A1, X-A2, X-E2, X-M1 |
50 | | X-T1, X-T10 |
51 | | X100S, X100T |
52 | | X20, X30, X70, XQ1, XQ2 |
53 | | |
54 | | RAFData gen. 4, offset to WH pair = 8: |
55 | | - same conditions as for RAFData gen. 3, but also adds WRTS in bytes 4..7 |
56 | | - contains a table of 3+2*13 values; first 3 values look like WHW |
57 | | - H in WHW group has a different meaning if the shot is taken in crop 2 mode |
58 | | GFX 100, GFX 100S, GFX 100 II |
59 | | GFX 50R, GFX 50S, GFX 50S II |
60 | | X-E2S, X-E3, X-H1, X-S10, X-H2 |
61 | | X-T2, X-T3, X-T4, X-T20, X-T30 |
62 | | X-Pro2, X-Pro3 |
63 | | X100F, X100V, X100VI |
64 | | |
65 | | RAFData gen. set to 4096: |
66 | | - RAFData length is exactly 4096 |
67 | | X-A3, X-A5, X-A7, X-A10, X-A20 |
68 | | X-T100, X-T200, |
69 | | XF10 |
70 | | */ |
71 | | |
72 | 11.3k | int offsetWH_inRAFData=0; /* clang warns about not initialized value */ |
73 | 11.3k | ushort b01 = sget2(RAFData_start); // bytes 0..1 |
74 | 11.3k | ushort b23 = sget2(RAFData_start+2); // bytes 2..3 |
75 | 11.3k | int is_WRTS = (sget4(RAFData_start + 4) == 0x53545257); // STRW |
76 | 11.3k | if (b01 && !b23 && (b01<10000)) |
77 | 474 | { |
78 | 474 | imFuji.RAFDataGeneration = 1; |
79 | 474 | offsetWH_inRAFData = 0; |
80 | 474 | } |
81 | 10.8k | else if ((b01>10000) && !b23) |
82 | 305 | { |
83 | 305 | imFuji.RAFDataGeneration = 2; |
84 | 305 | imFuji.RAFDataVersion = b01; |
85 | 305 | offsetWH_inRAFData = 4; |
86 | 305 | } |
87 | 10.5k | else if (!b01) |
88 | 5.28k | { |
89 | 5.28k | if (!is_WRTS) |
90 | 5.28k | { |
91 | 5.28k | imFuji.RAFDataGeneration = 3; |
92 | 5.28k | offsetWH_inRAFData = 4; |
93 | 5.28k | } |
94 | 0 | else |
95 | 0 | { |
96 | 0 | imFuji.RAFDataGeneration = 4; |
97 | 0 | offsetWH_inRAFData = 8; |
98 | 0 | } |
99 | 5.28k | imFuji.RAFDataVersion = b23; |
100 | 5.28k | } |
101 | | |
102 | | // printf (">> ID: 0x%llx, RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", |
103 | | // ilm.CamID, imFuji.RAFDataVersion, imFuji.RAFDataGeneration); |
104 | | |
105 | 11.3k | return offsetWH_inRAFData; |
106 | 11.3k | } |
107 | | |
108 | | class fuji_wb_checked_buffer_t : public checked_buffer_t |
109 | | { |
110 | | public: |
111 | | bool isWB(unsigned offset) |
112 | 12.8k | { |
113 | 12.8k | return sget2(offset) != 0 && sget2(offset + 2) != 0 && sget2(offset + 4) != 0 && sget2(offset + 6) != 0 && |
114 | 3.81k | sget2(offset + 8) != 0 && sget2(offset + 10) != 0 && sget2(offset) != 0xff && sget2(offset + 2) != 0xff && |
115 | 3.16k | sget2(offset + 4) != 0xff && sget2(offset + 6) != 0xff && sget2(offset + 8) != 0xff && |
116 | 2.66k | sget2(offset + 10) != 0xff && sget2(offset) == sget2(offset + 6) && sget2(offset) < sget2(offset + 2) && |
117 | 1.95k | sget2(offset) < sget2(offset + 4) && sget2(offset) < sget2(offset + 8) && sget2(offset) < sget2(offset + 10) |
118 | 12.8k | ; |
119 | 12.8k | } |
120 | 13.7k | fuji_wb_checked_buffer_t(short ord, int size) : checked_buffer_t(ord, size) {} |
121 | 3.21M | void set_order(short o) { _order = o; } |
122 | | }; |
123 | | |
124 | | struct tag2wb_t |
125 | | { |
126 | | unsigned tag; |
127 | | int wb; |
128 | | } tag2wbtable[] = |
129 | | { |
130 | | {0x2000, LIBRAW_WBI_Auto }, |
131 | | {0x2100, LIBRAW_WBI_FineWeather }, |
132 | | {0x2200, LIBRAW_WBI_Shade}, |
133 | | {0x2300, LIBRAW_WBI_FL_D }, |
134 | | {0x2301, LIBRAW_WBI_FL_N}, |
135 | | {0x2302, LIBRAW_WBI_FL_W }, |
136 | | {0x2310, LIBRAW_WBI_FL_WW}, |
137 | | {0x2311, LIBRAW_WBI_FL_L}, |
138 | | {0x2400, LIBRAW_WBI_Tungsten}, |
139 | | {0x2410, LIBRAW_WBI_Flash} |
140 | | }; |
141 | | const int tag2wbtable_size = sizeof(tag2wbtable) / sizeof(tag2wbtable[0]); |
142 | | |
143 | | |
144 | | void LibRaw::parseAdobeRAFMakernote() |
145 | 13.8k | { |
146 | | |
147 | 13.8k | unsigned posPrivateMknBuf=0; /* clang warns about not inited value */ |
148 | 13.8k | unsigned PrivateMknLength; |
149 | 13.8k | unsigned PrivateOrder; |
150 | 13.8k | unsigned ifd_start, ifd_len; |
151 | 13.8k | unsigned PrivateEntries, PrivateTagID; |
152 | 13.8k | unsigned PrivateTagBytes; |
153 | 13.8k | int FujiShotSelect; |
154 | 13.8k | unsigned wb_section_offset = 0; |
155 | 13.8k | int posWB; |
156 | 13.8k | int c; |
157 | | |
158 | | #if 0 |
159 | | #define isWB(posWB) \ |
160 | | sget2(posWB) != 0 && sget2(posWB + 2) != 0 && sget2(posWB + 4) != 0 && \ |
161 | | sget2(posWB + 6) != 0 && sget2(posWB + 8) != 0 && \ |
162 | | sget2(posWB + 10) != 0 && sget2(posWB) != 0xff && \ |
163 | | sget2(posWB + 2) != 0xff && sget2(posWB + 4) != 0xff && \ |
164 | | sget2(posWB + 6) != 0xff && sget2(posWB + 8) != 0xff && \ |
165 | | sget2(posWB + 10) != 0xff && sget2(posWB) == sget2(posWB + 6) && \ |
166 | | sget2(posWB) < sget2(posWB + 2) && sget2(posWB) < sget2(posWB + 4) && \ |
167 | | sget2(posWB) < sget2(posWB + 8) && sget2(posWB) < sget2(posWB + 10) |
168 | | #endif |
169 | | |
170 | 13.8k | #define get_average_WB(wb_index) \ |
171 | 13.8k | do { \ |
172 | 19.7k | FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ |
173 | 19.7k | PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1)); \ |
174 | 4.94k | if ((PrivateTagBytes == 16) && average_WBData) { \ |
175 | 4.00k | FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ |
176 | 4.00k | (icWBC[wb_index][GRGB_2_RGBG(c)] + \ |
177 | 4.00k | PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1)+8)) /2; \ |
178 | 1.00k | } \ |
179 | 4.94k | if (use_WBcorr_coeffs) { \ |
180 | 1.13k | icWBC[wb_index][0] = int(icWBC[wb_index][0]*wbR_corr); \ |
181 | 1.13k | icWBC[wb_index][2] = int(icWBC[wb_index][2]*wbB_corr); \ |
182 | 1.13k | } \ |
183 | 4.94k | } while(0) |
184 | | |
185 | 13.8k | ushort use_WBcorr_coeffs = 0; |
186 | 13.8k | double wbR_corr = 1.0; |
187 | 13.8k | double wbB_corr = 1.0; |
188 | | |
189 | 13.8k | if (strstr(model, "S2Pro") |
190 | 13.7k | || strstr(model, "S20Pro") |
191 | 13.6k | || strstr(model, "F700") |
192 | 13.4k | || strstr(model, "S5000") |
193 | 13.3k | || strstr(model, "S7000") |
194 | 13.8k | ) { |
195 | 528 | use_WBcorr_coeffs = 1; |
196 | 528 | wbR_corr = 10.0 / 17.0 / 0.652941; |
197 | 528 | wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0); |
198 | 13.2k | } else if (strstr(model, "DBP") || strstr(model, "DX-2000")) { |
199 | 236 | use_WBcorr_coeffs = 1; |
200 | 236 | wbR_corr = 0.7632653061; |
201 | 236 | wbB_corr = 0.8591549296; |
202 | 236 | } |
203 | | |
204 | 13.8k | FujiShotSelect = LIM(shot_select, 0, 1); |
205 | 13.8k | int average_WBData = 1; |
206 | | |
207 | 13.8k | order = 0x4d4d; |
208 | 13.8k | PrivateMknLength = get4(); |
209 | | |
210 | | // At least 0x36 bytes because of memcpy(imFuji.RAFVersion, PrivateMknBuf + 0x32, 4); |
211 | 13.8k | if ((PrivateMknLength >= 0x36) && (PrivateMknLength < 10240000)) // 1024b for safety |
212 | 13.7k | { |
213 | 13.7k | fuji_wb_checked_buffer_t PrivateMknBuf(order, PrivateMknLength+1024); |
214 | 13.7k | fread(PrivateMknBuf.data(), PrivateMknLength, 1, ifp); |
215 | 13.7k | memcpy(imFuji.SerialSignature, PrivateMknBuf.data() + 6, 0x0c); |
216 | 13.7k | imFuji.SerialSignature[0x0c] = 0; |
217 | 13.7k | memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04); |
218 | 13.7k | imFuji.SensorID[0x04] = 0; |
219 | 13.7k | c = 11; |
220 | 14.4k | while (isdigit(imFuji.SerialSignature[c]) && (c>0)) |
221 | 728 | c--; |
222 | 13.7k | ilm.CamID = unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1); |
223 | 13.7k | memcpy(model, PrivateMknBuf.data() + 0x12, 0x20); |
224 | 13.7k | model[0x20] = 0; |
225 | 13.7k | memcpy(imFuji.RAFVersion, PrivateMknBuf.data() + 0x32, 4); |
226 | 13.7k | imFuji.RAFVersion[4] = 0; |
227 | | |
228 | 13.7k | PrivateOrder = PrivateMknBuf.sget2(0); |
229 | 13.7k | unsigned s, l; |
230 | 13.7k | s = ifd_start = PrivateMknBuf.sget4(2)+6; |
231 | 13.7k | l = ifd_len = PrivateMknBuf.sget4(ifd_start); |
232 | | |
233 | 13.7k | if (!PrivateMknBuf.sget4(ifd_start+ifd_len+4)) |
234 | 1.94k | FujiShotSelect = 0; |
235 | | |
236 | 13.7k | if ((FujiShotSelect == 1) && (PrivateMknLength > ifd_len*2)) { |
237 | 0 | ifd_start += (ifd_len+4); |
238 | 0 | ifd_len = PrivateMknBuf.sget4(ifd_start); |
239 | 0 | if ((ifd_start+ifd_len) > PrivateMknLength) { |
240 | 0 | ifd_start = s; |
241 | 0 | ifd_len = l; |
242 | 0 | FujiShotSelect = 0; |
243 | 0 | } |
244 | 13.7k | } else FujiShotSelect = 0; |
245 | | |
246 | 13.7k | PrivateEntries = PrivateMknBuf.sget4(ifd_start + 4); |
247 | 13.7k | if ((PrivateEntries > 1000) || |
248 | 12.1k | ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) |
249 | 703 | { |
250 | 703 | return; |
251 | 703 | } |
252 | 13.0k | posPrivateMknBuf = (ifd_start+8); |
253 | | |
254 | | /* |
255 | | * because Adobe DNG converter strips or misplaces 0xfnnn tags, |
256 | | * for now, Auto WB is missing for the following cameras: |
257 | | * - F550EXR / F600EXR / F770EXR / F800EXR / F900EXR |
258 | | * - HS10 / HS11 / HS20EXR / HS30EXR / HS33EXR / HS35EXR / HS50EXR |
259 | | * - S1 / SL1000 |
260 | | **/ |
261 | 1.61M | while (PrivateEntries--) |
262 | 1.60M | { |
263 | 1.60M | PrivateMknBuf.set_order(0x4d4d); |
264 | 1.60M | order = 0x4d4d; |
265 | 1.60M | PrivateTagID = PrivateMknBuf.sget2(posPrivateMknBuf); |
266 | 1.60M | PrivateTagBytes = PrivateMknBuf.sget2(posPrivateMknBuf + 2); |
267 | 1.60M | posPrivateMknBuf += 4; |
268 | 1.60M | PrivateMknBuf.set_order(PrivateOrder); |
269 | 1.60M | order = PrivateOrder; |
270 | | |
271 | 1.60M | if (PrivateTagID >= 0x2000 && PrivateTagID <= 0x2410) |
272 | 4.16k | { |
273 | 32.8k | for(int q = 0; q < tag2wbtable_size; q++) |
274 | 31.3k | if (tag2wbtable[q].tag == PrivateTagID) |
275 | 2.69k | { |
276 | 2.69k | get_average_WB(tag2wbtable[q].wb); |
277 | 2.69k | break; |
278 | 2.69k | } |
279 | 4.16k | } |
280 | 1.59M | else if (PrivateTagID == 0x2f00) |
281 | 3.34k | { |
282 | 3.34k | int nWBs = MIN(PrivateMknBuf.sget4(posPrivateMknBuf), 6); |
283 | 3.34k | posWB = posPrivateMknBuf + 4; |
284 | 22.2k | for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) { |
285 | 75.7k | FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = |
286 | 75.7k | PrivateMknBuf.sget2(posWB + (c << 1)); |
287 | 18.9k | if ((PrivateTagBytes >= unsigned(4+16*nWBs)) && average_WBData) { |
288 | 162 | posWB += 8; |
289 | 648 | FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = |
290 | 648 | (icWBC[wb_ind][GRGB_2_RGBG(c)] + |
291 | 648 | PrivateMknBuf.sget2(posWB + (c << 1))) /2; |
292 | 162 | } |
293 | 18.9k | if (use_WBcorr_coeffs) { |
294 | 3.76k | icWBC[wb_ind][0] = int(icWBC[wb_ind][0]*wbR_corr); |
295 | 3.76k | icWBC[wb_ind][2] = int(icWBC[wb_ind][2]*wbB_corr); |
296 | 3.76k | } |
297 | 18.9k | posWB += 8; |
298 | 18.9k | } |
299 | 3.34k | } |
300 | 1.59M | else if (PrivateTagID == 0x2ff0) |
301 | 2.24k | { |
302 | 2.24k | get_average_WB(LIBRAW_WBI_AsShot); |
303 | 8.99k | FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_AsShot][c]); |
304 | 2.24k | } |
305 | 1.59M | else if ((PrivateTagID == 0x4000) && |
306 | 780 | ((PrivateTagBytes == 8) || (PrivateTagBytes == 16))) |
307 | 431 | { |
308 | 431 | imFuji.BlackLevel[0] = PrivateTagBytes / 2; |
309 | 1.72k | FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] = |
310 | 1.72k | PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1)); |
311 | 431 | if (imFuji.BlackLevel[0] == 8) { |
312 | 1.23k | FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c) + 5] = |
313 | 1.23k | PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1) + 8); |
314 | 308 | } |
315 | 431 | } |
316 | 1.59M | else if (PrivateTagID == 0x9650) |
317 | 97 | { |
318 | 97 | short a = (short)PrivateMknBuf.sget2(posPrivateMknBuf); |
319 | 97 | float b = fMAX(1.0f, PrivateMknBuf.sget2(posPrivateMknBuf + 2)); |
320 | 97 | imFuji.ExpoMidPointShift = a / b; |
321 | 97 | imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift; |
322 | 97 | } |
323 | 1.59M | else if ((PrivateTagID == 0xc000) && (PrivateTagBytes > 3) && |
324 | 11.7k | (PrivateTagBytes < 10240000)) |
325 | 11.7k | { |
326 | 11.7k | PrivateMknBuf.set_order(0x4949); |
327 | 11.7k | order = 0x4949; |
328 | 11.7k | if (PrivateTagBytes != 4096) // not one of Fuji X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 |
329 | 11.1k | { |
330 | 11.1k | int is34 = 0; |
331 | 11.1k | PrivateMknBuf.checkoffset(posPrivateMknBuf + 8); // will raise exception if no space |
332 | 11.1k | guess_RAFDataGeneration (PrivateMknBuf.data() + posPrivateMknBuf); |
333 | | |
334 | | // printf (">> ID: 0x%llx, RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", |
335 | | // ilm.CamID, imFuji.RAFDataVersion, imFuji.RAFDataGeneration); |
336 | | |
337 | 21.4M | for (posWB = 0; posWB < (int)PrivateTagBytes - 16; posWB++) |
338 | 21.4M | { |
339 | 21.4M | PrivateMknBuf.checkoffset(posWB + 12); // will raise exception if no space |
340 | 21.4M | if ((!memcmp(PrivateMknBuf.data() + posWB, "TSNERDTS", 8) && |
341 | 392 | (PrivateMknBuf.sget2( posWB + 10) > 125))) |
342 | 340 | { |
343 | 340 | posWB += 10; |
344 | 340 | icWBC[LIBRAW_WBI_Auto][1] = |
345 | 340 | icWBC[LIBRAW_WBI_Auto][3] = |
346 | 340 | PrivateMknBuf.sget2(posWB); |
347 | 340 | icWBC[LIBRAW_WBI_Auto][0] = |
348 | 340 | PrivateMknBuf.sget2(posWB + 2); |
349 | 340 | icWBC[LIBRAW_WBI_Auto][2] = |
350 | 340 | PrivateMknBuf.sget2(posWB + 4); |
351 | 340 | break; |
352 | 340 | } |
353 | 21.4M | } |
354 | | |
355 | 11.1k | if ((imFuji.RAFDataVersion == 0x0260) || // X-Pro3, GFX 100S |
356 | 10.8k | (imFuji.RAFDataVersion == 0x0261) || // X100V, GFX 50S II |
357 | 10.8k | (imFuji.RAFDataVersion == 0x0262) || // X-T4 |
358 | 10.7k | (imFuji.RAFDataVersion == 0x0263) || // X-H2s |
359 | 10.7k | (imFuji.RAFDataVersion == 0x0264) || // X-S10, X-H2 |
360 | 10.6k | (imFuji.RAFDataVersion == 0x0265) || // X-E4, X-T5 |
361 | 10.5k | (imFuji.RAFDataVersion == 0x0266) || // X-T30 II |
362 | 10.2k | (imFuji.RAFDataVersion == 0x0267) || // GFX 100 II |
363 | 10.1k | (imFuji.RAFDataVersion == 0x0368) || // GFX 100S II |
364 | 10.1k | (imFuji.RAFDataVersion == 0x0369) || // X100VI |
365 | 9.65k | (imFuji.RAFDataVersion == 0x036a) || // X-T50 |
366 | 9.65k | (imFuji.RAFDataVersion == 0x036b) || // X-M5 |
367 | 9.62k | !strcmp(model, "X-Pro3") || |
368 | 9.53k | !strcmp(model, "GFX 100S II") || !strcmp(model, "GFX100S II") || |
369 | 9.50k | !strcmp(model, "GFX 100S") || !strcmp(model, "GFX100S") || |
370 | 9.43k | !strcmp(model, "GFX 100 II") || !strcmp(model, "GFX100 II") || |
371 | 9.34k | !strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II") || |
372 | 9.33k | !strcmp(model, "X100VI") || |
373 | 9.24k | !strcmp(model, "X100V") || |
374 | 9.20k | !strcmp(model, "X-H2") || |
375 | 9.01k | !strcmp(model, "X-H2S") || |
376 | 8.88k | !strcmp(model, "X-T4") || |
377 | 8.79k | !strcmp(model, "X-T50") || |
378 | 8.69k | !strcmp(model, "X-T5") || |
379 | 8.57k | !strcmp(model, "X-M5") || |
380 | 8.52k | !strcmp(model, "X-E4") || |
381 | 8.50k | !strcmp(model, "X-T30 II") || |
382 | 8.41k | !strcmp(model, "X-S10")) |
383 | 2.56k | is34 = 1; |
384 | | |
385 | 11.1k | if (imFuji.RAFDataVersion == 0x4500) // X-E1, RAFData gen. 3 |
386 | 66 | { |
387 | 66 | wb_section_offset = 0x13ac; |
388 | 66 | } |
389 | 11.0k | else if (imFuji.RAFDataVersion == 0x0146 || // X20 |
390 | 10.7k | imFuji.RAFDataVersion == 0x0149 || // X100S |
391 | 10.6k | imFuji.RAFDataVersion == 0x0249) // X100S |
392 | 153 | { |
393 | 153 | wb_section_offset = 0x1410; |
394 | 153 | } |
395 | 10.9k | else if (imFuji.RAFDataVersion == 0x014d || // X-M1 |
396 | 10.6k | imFuji.RAFDataVersion == 0x014e) // X-A1, X-A2 |
397 | 96 | { |
398 | 96 | wb_section_offset = 0x1474; |
399 | 96 | } |
400 | 10.8k | else if (imFuji.RAFDataVersion == 0x014f || // X-E2 |
401 | 10.4k | imFuji.RAFDataVersion == 0x024f || // X-E2 |
402 | 9.78k | imFuji.RAFDataVersion == 0x025d || // X-H1 |
403 | 9.75k | imFuji.RAFDataVersion == 0x035d) // X-H1 |
404 | 866 | { |
405 | 866 | wb_section_offset = 0x1480; |
406 | 866 | } |
407 | 9.95k | else if (imFuji.RAFDataVersion == 0x0150) // XQ1, XQ2 |
408 | 79 | { |
409 | 79 | wb_section_offset = 0x1414; |
410 | 79 | } |
411 | 9.87k | else if (imFuji.RAFDataVersion == 0x0151 || // X-T1 w/diff. fws |
412 | 9.60k | imFuji.RAFDataVersion == 0x0251 || imFuji.RAFDataVersion == 0x0351 || |
413 | 9.54k | imFuji.RAFDataVersion == 0x0451 || imFuji.RAFDataVersion == 0x0551) |
414 | 121 | { |
415 | 121 | wb_section_offset = 0x14b0; |
416 | 121 | } |
417 | 9.75k | else if (imFuji.RAFDataVersion == 0x0152 || // X30 |
418 | 9.45k | imFuji.RAFDataVersion == 0x0153) // X100T |
419 | 89 | { |
420 | 89 | wb_section_offset = 0x1444; |
421 | 89 | } |
422 | 9.66k | else if (imFuji.RAFDataVersion == 0x0154) // X-T10 |
423 | 19 | { |
424 | 19 | wb_section_offset = 0x1824; |
425 | 19 | } |
426 | 9.64k | else if (imFuji.RAFDataVersion == 0x0155) // X70 |
427 | 18 | { |
428 | 18 | wb_section_offset = 0x17b4; |
429 | 18 | } |
430 | 9.62k | else if (imFuji.RAFDataVersion == 0x0255 || // X-Pro2 |
431 | 9.36k | imFuji.RAFDataVersion == 0x0455) |
432 | 52 | { |
433 | 52 | wb_section_offset = 0x135c; |
434 | 52 | } |
435 | 9.57k | else if (imFuji.RAFDataVersion == 0x0258 || // X-T2 |
436 | 9.12k | imFuji.RAFDataVersion == 0x025b) // X-T20 |
437 | 217 | { |
438 | 217 | wb_section_offset = 0x13dc; |
439 | 217 | } |
440 | 9.35k | else if (imFuji.RAFDataVersion == 0x0259) // X100F |
441 | 77 | { |
442 | 77 | wb_section_offset = 0x1370; |
443 | 77 | } |
444 | 9.28k | else if (imFuji.RAFDataVersion == 0x025a || // GFX 50S |
445 | 9.01k | imFuji.RAFDataVersion == 0x045a) |
446 | 58 | { |
447 | 58 | wb_section_offset = 0x1424; |
448 | 58 | } |
449 | 9.22k | else if (imFuji.RAFDataVersion == 0x025c) // X-E3 |
450 | 48 | { |
451 | 48 | wb_section_offset = 0x141c; |
452 | 48 | } |
453 | 9.17k | else if (imFuji.RAFDataVersion == 0x025e) // X-T3 |
454 | 31 | { |
455 | 31 | wb_section_offset = 0x2014; |
456 | 31 | } |
457 | 9.14k | else if (imFuji.RAFDataVersion == 0x025f) // X-T30, GFX 50R, GFX 100 (? RAFDataVersion 0x045f) |
458 | 364 | { |
459 | 364 | if (!strcmp(model, "X-T30")) { |
460 | 235 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20b8)) |
461 | 0 | wb_section_offset = 0x20b8; |
462 | 235 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20c8)) |
463 | 0 | wb_section_offset = 0x20c8; |
464 | 235 | } |
465 | 129 | else if (!strcmp(model, "GFX 50R")) |
466 | 13 | wb_section_offset = 0x1424; |
467 | 116 | else if (!strcmp(model, "GFX 100")) |
468 | 25 | wb_section_offset = 0x20e4; |
469 | 364 | } |
470 | 8.78k | else if (imFuji.RAFDataVersion == 0x0260) // X-Pro3, GFX 100S |
471 | 40 | { |
472 | 40 | if (!strcmp(model, "X-Pro3")) |
473 | 0 | wb_section_offset = 0x20e8; |
474 | 40 | else if (!strcmp(model, "GFX 100S") || !strcmp(model, "GFX100S")) |
475 | 0 | wb_section_offset = 0x2108; |
476 | 40 | } |
477 | 8.74k | else if (imFuji.RAFDataVersion == 0x0261) // X100V, GFX 50S II |
478 | 41 | { |
479 | 41 | if (!strcmp(model, "X100V")) |
480 | 0 | wb_section_offset = 0x2078; |
481 | 41 | else if (!strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II")) |
482 | 0 | wb_section_offset = 0x214c; |
483 | 41 | } |
484 | 8.70k | else if (imFuji.RAFDataVersion == 0x0262) // X-T4 |
485 | 67 | { |
486 | 67 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21c8)) |
487 | 0 | wb_section_offset = 0x21c8; |
488 | 67 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc)) |
489 | 0 | wb_section_offset = 0x21cc; |
490 | 67 | } |
491 | 8.63k | else if (imFuji.RAFDataVersion == 0x0263) // X-H2S |
492 | 11 | { |
493 | 11 | wb_section_offset = 0x0b40; |
494 | 11 | } |
495 | 8.62k | else if (imFuji.RAFDataVersion == 0x0264) // X-S10, X-H2 |
496 | 95 | { |
497 | 95 | if (!strcmp(model, "X-S10")) |
498 | 43 | wb_section_offset = 0x21de; |
499 | 52 | else if (!strcmp(model, "X-H2")) |
500 | 20 | wb_section_offset = 0x0b3e; |
501 | 95 | } |
502 | 8.52k | else if ((imFuji.RAFDataVersion == 0x0265) || // X-E4, X-T5 |
503 | 8.16k | (imFuji.RAFDataVersion == 0x0266)) // X-T30 II, X-S20 |
504 | 369 | { |
505 | 369 | if (!strcmp(model, "X-T5") || |
506 | 330 | !strcmp(model, "X-S20")) |
507 | 50 | wb_section_offset = 0x0c72; |
508 | 319 | else |
509 | 319 | wb_section_offset = 0x21cc; |
510 | 369 | } |
511 | 8.15k | else if (imFuji.RAFDataVersion == 0x0267) // GFX 100 II |
512 | 89 | { |
513 | 89 | wb_section_offset = 0x0cae; |
514 | 89 | } |
515 | 8.06k | else if (imFuji.RAFDataVersion == 0x0355) // X-E2S |
516 | 69 | { |
517 | 69 | wb_section_offset = 0x1840; |
518 | 69 | } |
519 | 8.00k | else if (imFuji.RAFDataVersion == 0x0368) // GFX 100S II |
520 | 62 | { |
521 | 62 | wb_section_offset = 0x0cba; |
522 | 62 | } |
523 | 7.93k | else if (imFuji.RAFDataVersion == 0x0369) // X100VI |
524 | 463 | { |
525 | 463 | wb_section_offset = 0x0c5a; |
526 | 463 | } |
527 | 7.47k | else if (imFuji.RAFDataVersion == 0x036a) // X-T50 |
528 | 0 | { |
529 | 0 | wb_section_offset = 0x0cca; |
530 | 0 | } |
531 | 7.47k | else if (imFuji.RAFDataVersion == 0x036b) // X-M5 |
532 | 28 | { |
533 | 28 | wb_section_offset = 0x0cea; |
534 | 28 | } |
535 | | |
536 | | /* try for unknown RAF Data versions */ |
537 | 7.44k | else if (!strcmp(model, "X-Pro2")) |
538 | 189 | { |
539 | 189 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x135c)) |
540 | 84 | wb_section_offset = 0x135c; |
541 | 189 | } |
542 | 7.25k | else if (!strcmp(model, "X100F")) |
543 | 60 | { |
544 | 60 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1370)) |
545 | 9 | wb_section_offset = 0x1370; |
546 | 60 | } |
547 | 7.19k | else if (!strcmp(model, "X-E1")) |
548 | 106 | { |
549 | 106 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13ac)) |
550 | 22 | wb_section_offset = 0x13ac; |
551 | 106 | } |
552 | 7.09k | else if (!strcmp(model, "X-T2") || |
553 | 6.72k | !strcmp(model, "X-T20")) |
554 | 140 | { |
555 | 140 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13dc)) |
556 | 1 | wb_section_offset = 0x13dc; |
557 | 140 | } |
558 | 6.95k | else if (!strcmp(model, "X20") || |
559 | 5.98k | !strcmp(model, "X100S")) |
560 | 800 | { |
561 | 800 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1410)) |
562 | 90 | wb_section_offset = 0x1410; |
563 | 800 | } |
564 | 6.15k | else if (!strcmp(model, "XQ1") || |
565 | 5.74k | !strcmp(model, "XQ2")) |
566 | 254 | { |
567 | 254 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1414)) |
568 | 75 | wb_section_offset = 0x1414; |
569 | 254 | } |
570 | 5.89k | else if (!strcmp(model, "X-E3")) |
571 | 103 | { |
572 | 103 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x141c)) |
573 | 11 | wb_section_offset = 0x141c; |
574 | 103 | } |
575 | 5.79k | else if (!strcmp(model, "GFX 50S") || |
576 | 5.47k | !strcmp(model, "GFX 50R")) |
577 | 222 | { |
578 | 222 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1424)) |
579 | 62 | wb_section_offset = 0x1424; |
580 | 222 | } |
581 | 5.57k | else if (!strcmp(model, "GFX 50S II") || |
582 | 5.31k | !strcmp(model, "GFX50S II")) { |
583 | 10 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x214c)) |
584 | 0 | wb_section_offset = 0x214c; |
585 | 10 | } |
586 | 5.56k | else if (!strcmp(model, "X30") || |
587 | 5.26k | !strcmp(model, "X100T")) |
588 | 147 | { |
589 | 147 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1444)) |
590 | 0 | wb_section_offset = 0x1444; |
591 | 147 | } |
592 | 5.41k | else if (!strcmp(model, "X-M1") || |
593 | 5.03k | !strcmp(model, "X-A1") || |
594 | 4.79k | !strcmp(model, "X-A2")) |
595 | 487 | { |
596 | 487 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1474)) |
597 | 35 | wb_section_offset = 0x1474; |
598 | 487 | } |
599 | 4.92k | else if (!strcmp(model, "X-E2") || |
600 | 4.67k | !strcmp(model, "X-H1")) |
601 | 84 | { |
602 | 84 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1480)) |
603 | 0 | wb_section_offset = 0x1480; |
604 | 84 | } |
605 | 4.84k | else if (!strcmp(model, "X-T1")) |
606 | 120 | { |
607 | 120 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x14b0)) |
608 | 3 | wb_section_offset = 0x14b0; |
609 | 120 | } |
610 | 4.72k | else if (!strcmp(model, "X70")) |
611 | 161 | { |
612 | 161 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x17b4)) |
613 | 60 | wb_section_offset = 0x17b4; |
614 | 161 | } |
615 | 4.56k | else if (!strcmp(model, "X-T10")) |
616 | 56 | { |
617 | 56 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1824)) |
618 | 17 | wb_section_offset = 0x1824; |
619 | 56 | } |
620 | 4.50k | else if (!strcmp(model, "X-E2S")) |
621 | 67 | { |
622 | 67 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1840)) |
623 | 11 | wb_section_offset = 0x1840; |
624 | 67 | } |
625 | 4.44k | else if (!strcmp(model, "X-T3")) |
626 | 38 | { |
627 | 38 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2014)) |
628 | 0 | wb_section_offset = 0x2014; |
629 | 38 | } |
630 | 4.40k | else if (!strcmp(model, "X100VI")) |
631 | 89 | { |
632 | 89 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0c5a)) |
633 | 45 | wb_section_offset = 0x0c5a; |
634 | 89 | } |
635 | 4.31k | else if (!strcmp(model, "X100V")) |
636 | 39 | { |
637 | 39 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2078)) |
638 | 0 | wb_section_offset = 0x2078; |
639 | 39 | } |
640 | 4.27k | else if (!strcmp(model, "X-T30")) |
641 | 195 | { |
642 | 195 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20b8)) |
643 | 0 | wb_section_offset = 0x20b8; |
644 | 195 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20c8)) |
645 | 0 | wb_section_offset = 0x20c8; |
646 | 195 | } |
647 | 4.08k | else if (!strcmp(model, "GFX 100")) |
648 | 147 | { |
649 | 147 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20e4)) |
650 | 0 | wb_section_offset = 0x20e4; |
651 | 147 | } |
652 | 3.93k | else if (!strcmp(model, "X-Pro3")) |
653 | 87 | { |
654 | 87 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20e8)) |
655 | 0 | wb_section_offset = 0x20e8; |
656 | 87 | } |
657 | 3.84k | else if (!strcmp(model, "GFX100S") || |
658 | 3.59k | !strcmp(model, "GFX 100S")) |
659 | 67 | { |
660 | 67 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2108)) |
661 | 0 | wb_section_offset = 0x2108; |
662 | 67 | } |
663 | 3.77k | else if (!strcmp(model, "X-T4")) |
664 | 86 | { |
665 | 86 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21c8)) |
666 | 0 | wb_section_offset = 0x21c8; |
667 | 86 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc)) |
668 | 0 | wb_section_offset = 0x21cc; |
669 | 86 | } |
670 | 3.69k | else if ((!strcmp(model, "X-E4")) || |
671 | 3.43k | (!strcmp(model, "X-T30 II"))) |
672 | 67 | { |
673 | 67 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc)) |
674 | 0 | wb_section_offset = 0x21cc; |
675 | 67 | } |
676 | 3.62k | else if (!strcmp(model, "X-S10")) |
677 | 62 | { |
678 | 62 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21de)) |
679 | 0 | wb_section_offset = 0x21de; |
680 | 62 | } |
681 | 3.56k | else if (!strcmp(model, "X-H2")) |
682 | 193 | { |
683 | 193 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0b3e)) |
684 | 18 | wb_section_offset = 0x0b3e; |
685 | 193 | } |
686 | 3.37k | else if (!strcmp(model, "X-H2S")) |
687 | 130 | { |
688 | 130 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0b40)) |
689 | 4 | wb_section_offset = 0x0b40; |
690 | 130 | } |
691 | 3.24k | else if (!strcmp(model, "X-T5") || |
692 | 2.88k | !strcmp(model, "X-S20")) |
693 | 162 | { |
694 | 162 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0c72)) |
695 | 72 | wb_section_offset = 0x0c72; |
696 | 162 | } |
697 | 3.07k | else if (!strcmp(model, "GFX 100 II") || |
698 | 2.74k | !strcmp(model, "GFX100 II")) |
699 | 94 | { |
700 | 94 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cae)) |
701 | 4 | wb_section_offset = 0x0cae; |
702 | 94 | } |
703 | 2.98k | else if (!strcmp(model, "GFX 100S II") || |
704 | 2.74k | !strcmp(model, "GFX100S II")) |
705 | 34 | { |
706 | 34 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cba)) |
707 | 0 | wb_section_offset = 0x0cba; |
708 | 34 | } |
709 | 2.95k | else if (!strcmp(model, "X-T50")) |
710 | 20 | { |
711 | 20 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cca)) |
712 | 0 | wb_section_offset = 0x0cca; |
713 | 20 | } |
714 | 2.93k | else if (!strcmp(model, "X-M5")) |
715 | 56 | { |
716 | 56 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cea)) |
717 | 6 | wb_section_offset = 0x0cea; |
718 | 56 | } |
719 | | |
720 | | /* no RAF Data version for the models below */ |
721 | 2.87k | else if (!strcmp(model, "FinePix X100")) // X100 0 0x19f0 0x19e8 |
722 | 291 | { |
723 | 291 | if (!strcmp(imFuji.RAFVersion, "0069")) |
724 | 90 | wb_section_offset = 0x19e8; |
725 | 201 | else if (!strcmp(imFuji.RAFVersion, "0100") || |
726 | 125 | !strcmp(imFuji.RAFVersion, "0110")) |
727 | 97 | wb_section_offset = 0x19f0; |
728 | 104 | else |
729 | 104 | { |
730 | 104 | if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x19e8)) |
731 | 32 | wb_section_offset = 0x19e8; |
732 | 72 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x19f0)) |
733 | 0 | wb_section_offset = 0x19f0; |
734 | 104 | } |
735 | 291 | } |
736 | 2.58k | else if (!strcmp(model, "X-Pro1")) // X-Pro1 0 0x13a4 |
737 | 393 | { |
738 | 393 | if (!strcmp(imFuji.RAFVersion, "0100") || |
739 | 311 | !strcmp(imFuji.RAFVersion, "0101") || |
740 | 238 | !strcmp(imFuji.RAFVersion, "0204")) |
741 | 174 | wb_section_offset = 0x13a4; |
742 | 219 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13a4)) |
743 | 44 | wb_section_offset = 0x13a4; |
744 | 393 | } |
745 | 2.19k | else if (!strcmp(model, "XF1")) // XF1 0 0x138c |
746 | 265 | { |
747 | 265 | if (!strcmp(imFuji.RAFVersion, "0100")) |
748 | 82 | wb_section_offset = 0x138c; |
749 | 183 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x138c)) |
750 | 71 | wb_section_offset = 0x138c; |
751 | 265 | } |
752 | 1.92k | else if (!strcmp(model, "X-S1")) // X-S1 0 0x1284 |
753 | 61 | { |
754 | 61 | if (!strcmp(imFuji.RAFVersion, "0100")) |
755 | 17 | wb_section_offset = 0x1284; |
756 | 44 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1284)) |
757 | 11 | wb_section_offset = 0x1284; |
758 | 61 | } |
759 | 1.86k | else if (!strcmp(model, "X10")) // X10 0 0x1280 0x12d4 |
760 | 1.19k | { |
761 | 1.19k | if (!strcmp(imFuji.RAFVersion, "0100") || |
762 | 1.13k | !strcmp(imFuji.RAFVersion, "0102")) |
763 | 73 | wb_section_offset = 0x1280; |
764 | 1.11k | else if (!strcmp(imFuji.RAFVersion, "0103")) |
765 | 79 | wb_section_offset = 0x12d4; |
766 | 1.03k | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1280)) |
767 | 57 | wb_section_offset = 0x1280; |
768 | 982 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x12d4)) |
769 | 63 | wb_section_offset = 0x12d4; |
770 | 1.19k | } |
771 | 674 | else if (!strcmp(model, "XF1")) // XF1 0 0x138c |
772 | 0 | { |
773 | 0 | if (!strcmp(imFuji.RAFVersion, "0100")) |
774 | 0 | wb_section_offset = 0x138c; |
775 | 0 | else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x138c)) |
776 | 0 | wb_section_offset = 0x138c; |
777 | 0 | } |
778 | | |
779 | 11.1k | if (wb_section_offset && PrivateMknBuf.isWB(posPrivateMknBuf + wb_section_offset)) |
780 | 908 | { |
781 | | |
782 | 908 | if (!imFuji.RAFDataVersion) |
783 | 692 | { |
784 | 692 | posWB = posPrivateMknBuf + wb_section_offset - 6; |
785 | 692 | icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = PrivateMknBuf.sget2(posWB); |
786 | 692 | icWBC[LIBRAW_WBI_Auto][0] = PrivateMknBuf.sget2(posWB + 2); |
787 | 692 | icWBC[LIBRAW_WBI_Auto][2] = PrivateMknBuf.sget2(posWB + 4); |
788 | 692 | } |
789 | | |
790 | 908 | posWB = posPrivateMknBuf + wb_section_offset; |
791 | 6.35k | for (int wb_ind = 0; wb_ind < (int)Fuji_wb_list1.size(); posWB += 6, wb_ind++) |
792 | 5.44k | { |
793 | 5.44k | icWBC[Fuji_wb_list1[wb_ind]][1] = icWBC[Fuji_wb_list1[wb_ind]][3] = PrivateMknBuf.sget2(posWB); |
794 | 5.44k | icWBC[Fuji_wb_list1[wb_ind]][0] = PrivateMknBuf.sget2(posWB + 2); |
795 | 5.44k | icWBC[Fuji_wb_list1[wb_ind]][2] = PrivateMknBuf.sget2(posWB + 4); |
796 | 5.44k | } |
797 | 908 | int found = 0; |
798 | 908 | if (is34) |
799 | 143 | posWB += 0x30; |
800 | 908 | posWB += 0xc0; |
801 | 908 | ushort Gval = PrivateMknBuf.sget2(posWB); |
802 | 3.73k | for (int posEndCCTsection = posWB; posEndCCTsection < (posWB + 30); |
803 | 2.82k | posEndCCTsection += 6) |
804 | 3.26k | { |
805 | 3.26k | if (PrivateMknBuf.sget2(posEndCCTsection) != Gval) |
806 | 441 | { |
807 | 441 | if (is34) |
808 | 127 | wb_section_offset = posEndCCTsection - 34*3*2; // 34 records, 3 2-byte values in a record |
809 | 314 | else |
810 | 314 | wb_section_offset = posEndCCTsection - 31*3*2; // 31 records, 3 2-byte values in a record |
811 | 441 | found = 1; |
812 | 441 | break; |
813 | 441 | } |
814 | 3.26k | } |
815 | | |
816 | 908 | if (found) |
817 | 441 | { |
818 | 14.1k | for (int iCCT = 0; iCCT < 31; iCCT++) |
819 | 13.6k | { |
820 | 13.6k | icWBCCTC[iCCT][0] = float(FujiCCT_K[iCCT]); |
821 | 13.6k | icWBCCTC[iCCT][1] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6 + 2); |
822 | 13.6k | icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6); |
823 | 13.6k | icWBCCTC[iCCT][3] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6 + 4); |
824 | 13.6k | } |
825 | 441 | } |
826 | 908 | } |
827 | 11.1k | } |
828 | 568 | else // process 4K raf data |
829 | 568 | { |
830 | 568 | int wb[4]; |
831 | 568 | int nWB, tWB, pWB; |
832 | 568 | int iCCT = 0; |
833 | 568 | imFuji.RAFDataGeneration = 4096; // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 |
834 | 568 | posWB = posPrivateMknBuf + 0x200; |
835 | 23.4k | for (int wb_ind = 0; wb_ind < 42; wb_ind++) |
836 | 22.8k | { |
837 | 22.8k | nWB = PrivateMknBuf.sget4(posWB); |
838 | 22.8k | posWB += 4; |
839 | 22.8k | tWB = PrivateMknBuf.sget4(posWB); |
840 | 22.8k | posWB += 4; |
841 | 22.8k | wb[0] = PrivateMknBuf.sget4(posWB) << 1; |
842 | 22.8k | posWB += 4; |
843 | 22.8k | wb[1] = PrivateMknBuf.sget4(posWB); |
844 | 22.8k | posWB += 4; |
845 | 22.8k | wb[3] = PrivateMknBuf.sget4(posWB); |
846 | 22.8k | posWB += 4; |
847 | 22.8k | wb[2] = PrivateMknBuf.sget4(posWB) << 1; |
848 | 22.8k | posWB += 4; |
849 | | |
850 | 22.8k | if (tWB && (iCCT < 64)) |
851 | 13.9k | { |
852 | 13.9k | icWBCCTC[iCCT][0] = float(tWB); |
853 | 55.6k | FORC4 icWBCCTC[iCCT][c + 1] = float(wb[c]); |
854 | 13.9k | iCCT++; |
855 | 13.9k | } |
856 | 22.8k | if (nWB != 0x46) |
857 | 22.6k | { |
858 | 165k | for (pWB = 1; pWB < (int)Fuji_wb_list2.size(); pWB += 2) |
859 | 152k | { |
860 | 152k | if (Fuji_wb_list2[pWB] == nWB) |
861 | 9.75k | { |
862 | 39.0k | FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] = wb[c]; |
863 | 9.75k | break; |
864 | 9.75k | } |
865 | 152k | } |
866 | 22.6k | } |
867 | 22.8k | } |
868 | 568 | } |
869 | 11.7k | } |
870 | 1.60M | posPrivateMknBuf += PrivateTagBytes; |
871 | 1.60M | } |
872 | 13.0k | } |
873 | 13.8k | #undef get_average_WB |
874 | 13.8k | } |
875 | | |
876 | | void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len, |
877 | | unsigned /*dng_writer*/) |
878 | 178k | { |
879 | 178k | if (tag == 0x0010) |
880 | 6.67k | { |
881 | 6.67k | char FujiSerial[sizeof(imgdata.shootinginfo.InternalBodySerial)]; |
882 | 6.67k | char *words[4] = { 0,0,0,0 }; |
883 | 6.67k | char yy[2], mm[3], dd[3], ystr[16], ynum[16]; |
884 | 6.67k | int year, nwords, ynum_len; |
885 | 6.67k | unsigned c; |
886 | 6.67k | memset(FujiSerial, 0, sizeof(imgdata.shootinginfo.InternalBodySerial)); |
887 | 6.67k | ifp->read(FujiSerial, MIN(len,sizeof(FujiSerial)), 1); |
888 | 6.67k | nwords = getwords(FujiSerial, words, 4, |
889 | 6.67k | sizeof(imgdata.shootinginfo.InternalBodySerial)); |
890 | 12.4k | for (int i = 0; i < nwords; i++) |
891 | 5.75k | { |
892 | 5.75k | if (!words[i]) break; // probably damaged input |
893 | 5.75k | mm[2] = dd[2] = 0; |
894 | 5.75k | if (strnlen(words[i], |
895 | 5.75k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) < 18) |
896 | 2.86k | { |
897 | 2.86k | if (i == 0) |
898 | 1.91k | { |
899 | 1.91k | strncpy(imgdata.shootinginfo.InternalBodySerial, words[0], |
900 | 1.91k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); |
901 | 1.91k | } |
902 | 956 | else |
903 | 956 | { |
904 | 956 | char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; |
905 | 956 | snprintf(tbuf, sizeof(tbuf)-1, "%s %s", |
906 | 956 | imgdata.shootinginfo.InternalBodySerial, words[i]); |
907 | 956 | strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, |
908 | 956 | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); |
909 | 956 | } |
910 | 2.86k | } |
911 | 2.88k | else |
912 | 2.88k | { |
913 | 2.88k | strncpy( |
914 | 2.88k | dd, |
915 | 2.88k | words[i] + |
916 | 2.88k | strnlen(words[i], |
917 | 2.88k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - |
918 | 2.88k | 14, |
919 | 2.88k | 2); |
920 | 2.88k | strncpy( |
921 | 2.88k | mm, |
922 | 2.88k | words[i] + |
923 | 2.88k | strnlen(words[i], |
924 | 2.88k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - |
925 | 2.88k | 16, |
926 | 2.88k | 2); |
927 | 2.88k | strncpy( |
928 | 2.88k | yy, |
929 | 2.88k | words[i] + |
930 | 2.88k | strnlen(words[i], |
931 | 2.88k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - |
932 | 2.88k | 18, |
933 | 2.88k | 2); |
934 | 2.88k | year = (yy[0] - '0') * 10 + (yy[1] - '0'); |
935 | 2.88k | if (year < 70) |
936 | 2.51k | year += 2000; |
937 | 376 | else |
938 | 376 | year += 1900; |
939 | | |
940 | 2.88k | ynum_len = MIN( |
941 | 2.88k | int(sizeof(ynum) - 1), |
942 | 2.88k | (int)strnlen(words[i], |
943 | 2.88k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - |
944 | 2.88k | 18); |
945 | 2.88k | strncpy(ynum, words[i], ynum_len); |
946 | 2.88k | ynum[ynum_len] = 0; |
947 | 4.29k | for (int j = 0; ynum[j] && ynum[j + 1] && sscanf(ynum + j, "%2x", &c); |
948 | 2.88k | j += 2) |
949 | 1.41k | ystr[j / 2] = c; |
950 | 2.88k | ynum_len /= 2; |
951 | 2.88k | ystr[ynum_len + 1] = 0; |
952 | 2.88k | strcpy(model2, ystr); |
953 | | |
954 | 2.88k | if (i == 0) |
955 | 1.87k | { |
956 | 1.87k | char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; |
957 | | |
958 | 1.87k | if (nwords == 1) |
959 | 1.21k | { |
960 | 1.21k | snprintf( |
961 | 1.21k | tbuf, sizeof(tbuf), "%s %d:%s:%s %s", |
962 | 1.21k | ystr, year, mm, dd, |
963 | 1.21k | words[0] + |
964 | 1.21k | strnlen(words[0], sizeof(imgdata.shootinginfo.InternalBodySerial)-1)-12); |
965 | 1.21k | } |
966 | 657 | else |
967 | 657 | { |
968 | 657 | snprintf( |
969 | 657 | tbuf, sizeof(tbuf), "%s %d:%s:%s %s", ystr, year, mm, dd, |
970 | 657 | words[0] + |
971 | 657 | strnlen(words[0], |
972 | 657 | sizeof(imgdata.shootinginfo.InternalBodySerial) - |
973 | 657 | 1) - |
974 | 657 | 12); |
975 | 657 | } |
976 | 1.87k | strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, |
977 | 1.87k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); |
978 | 1.87k | } |
979 | 1.01k | else |
980 | 1.01k | { |
981 | 1.01k | char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; |
982 | 1.01k | snprintf( |
983 | 1.01k | tbuf, sizeof(tbuf), "%s %s %d:%s:%s %s", |
984 | 1.01k | imgdata.shootinginfo.InternalBodySerial, ystr, year, mm, dd, |
985 | 1.01k | words[i] + |
986 | 1.01k | strnlen(words[i], |
987 | 1.01k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - |
988 | 1.01k | 12); |
989 | 1.01k | strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, |
990 | 1.01k | sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); |
991 | 1.01k | } |
992 | 2.88k | } |
993 | 5.75k | } |
994 | 6.67k | } |
995 | 171k | else |
996 | 171k | switch (tag) |
997 | 171k | { |
998 | 222 | case 0x1002: |
999 | 222 | imFuji.WB_Preset = get2(); |
1000 | 222 | break; |
1001 | 190 | case 0x1011: |
1002 | 190 | imCommon.FlashEC = getrealf(type); |
1003 | 190 | break; |
1004 | 574 | case 0x1020: |
1005 | 574 | imFuji.Macro = get2(); |
1006 | 574 | break; |
1007 | 381 | case 0x1021: |
1008 | 381 | imFuji.FocusMode = imgdata.shootinginfo.FocusMode = get2(); |
1009 | 381 | break; |
1010 | 979 | case 0x1022: |
1011 | 979 | imFuji.AFMode = get2(); |
1012 | 979 | break; |
1013 | 614 | case 0x1023: |
1014 | 614 | imFuji.FocusPixel[0] = get2(); |
1015 | 614 | imFuji.FocusPixel[1] = get2(); |
1016 | 614 | break; |
1017 | 390 | case 0x102b: |
1018 | 390 | imFuji.PrioritySettings = get2(); |
1019 | 390 | break; |
1020 | 132 | case 0x102d: |
1021 | 132 | imFuji.FocusSettings = get4(); |
1022 | 132 | break; |
1023 | 50 | case 0x102e: |
1024 | 50 | imFuji.AF_C_Settings = get4(); |
1025 | 50 | break; |
1026 | 304 | case 0x1034: |
1027 | 304 | imFuji.ExrMode = get2(); |
1028 | 304 | break; |
1029 | 217 | case 0x104d: |
1030 | 217 | FujiCropMode = get2(); // odd: one of raw dimensions here can be lost |
1031 | 217 | break; |
1032 | 396 | case 0x1050: |
1033 | 396 | imFuji.ShutterType = get2(); |
1034 | 396 | break; |
1035 | 118 | case 0x1100: |
1036 | 118 | imFuji.AutoBracketing = get2(); // AutoBracketing = 6 for pixel shift mode |
1037 | 118 | break; |
1038 | 792 | case 0x1101: |
1039 | 792 | imFuji.SequenceNumber = get2(); |
1040 | 792 | break; |
1041 | 76 | case 0x1103: |
1042 | 76 | imgdata.shootinginfo.DriveMode = get2(); |
1043 | 76 | imFuji.DriveMode = imgdata.shootinginfo.DriveMode & 0xff; |
1044 | 76 | break; |
1045 | 86 | case 0x1105: |
1046 | 86 | imFuji.SeriesLength = get2(); |
1047 | 86 | break; |
1048 | 251 | case 0x1106: |
1049 | 251 | imFuji.PixelShiftOffset[0] = getrealf(type); |
1050 | 251 | imFuji.PixelShiftOffset[1] = getrealf(type); |
1051 | 251 | break; |
1052 | 245 | case 0x1301: |
1053 | 245 | imFuji.FocusWarning = get2(); |
1054 | 245 | break; |
1055 | 340 | case 0x1400: |
1056 | 340 | imFuji.DynamicRange = get2(); |
1057 | 340 | break; |
1058 | 206 | case 0x1401: |
1059 | 206 | imFuji.FilmMode = get2(); |
1060 | 206 | break; |
1061 | 768 | case 0x1402: |
1062 | 768 | imFuji.DynamicRangeSetting = get2(); |
1063 | 768 | break; |
1064 | 90 | case 0x1403: |
1065 | 90 | imFuji.DevelopmentDynamicRange = get2(); |
1066 | 90 | break; |
1067 | 960 | case 0x1404: |
1068 | 960 | ilm.MinFocal = getrealf(type); |
1069 | 960 | break; |
1070 | 200 | case 0x1405: |
1071 | 200 | ilm.MaxFocal = getrealf(type); |
1072 | 200 | break; |
1073 | 169 | case 0x1406: |
1074 | 169 | ilm.MaxAp4MinFocal = getrealf(type); |
1075 | 169 | break; |
1076 | 9 | case 0x1407: |
1077 | 9 | ilm.MaxAp4MaxFocal = getrealf(type); |
1078 | 9 | break; |
1079 | 286 | case 0x140b: |
1080 | 286 | imFuji.AutoDynamicRange = get2(); |
1081 | 286 | break; |
1082 | 261 | case 0x1422: |
1083 | 261 | imFuji.ImageStabilization[0] = get2(); |
1084 | 261 | imFuji.ImageStabilization[1] = get2(); |
1085 | 261 | imFuji.ImageStabilization[2] = get2(); |
1086 | 261 | imgdata.shootinginfo.ImageStabilization = |
1087 | 261 | (imFuji.ImageStabilization[0] << 9) + imFuji.ImageStabilization[1]; |
1088 | 261 | break; |
1089 | 100 | case 0x1438: |
1090 | 100 | imFuji.ImageCount = get2(); |
1091 | 100 | break; |
1092 | 169 | case 0x1431: |
1093 | 169 | imFuji.Rating = get4(); |
1094 | 169 | break; |
1095 | 135 | case 0x1443: |
1096 | 135 | imFuji.DRangePriority = get2(); |
1097 | 135 | break; |
1098 | 131 | case 0x1444: |
1099 | 131 | imFuji.DRangePriorityAuto = get2(); |
1100 | 131 | break; |
1101 | 462 | case 0x1445: |
1102 | 462 | imFuji.DRangePriorityFixed = get2(); |
1103 | 462 | break; |
1104 | 299 | case 0x1447: |
1105 | 299 | stmread(imFuji.FujiModel, len, ifp); |
1106 | 299 | break; |
1107 | 708 | case 0x1448: |
1108 | 708 | stmread(imFuji.FujiModel2, len, ifp); |
1109 | 708 | break; |
1110 | 171k | } |
1111 | 178k | return; |
1112 | 178k | } |
1113 | | |
1114 | | void LibRaw::parse_fuji_thumbnail(INT64 offset) |
1115 | 1.86k | { |
1116 | 1.86k | uchar xmpmarker[] = "http://ns.adobe.com/xap/1.0/"; |
1117 | 1.86k | uchar buf[sizeof(xmpmarker)+1]; |
1118 | 1.86k | int xmpsz = sizeof(xmpmarker); // we do not |
1119 | | |
1120 | 1.86k | INT64 pos = ftell(ifp); |
1121 | 1.86k | fseek(ifp, offset, SEEK_SET); |
1122 | 1.86k | ushort s_order = order; |
1123 | 1.86k | order = 0x4a4a; // JPEG is always in MM order |
1124 | | |
1125 | 1.86k | if (get2() == 0xFFD8) |
1126 | 209 | { |
1127 | 416 | while (1) |
1128 | 416 | { |
1129 | 416 | ushort tag = get2(); |
1130 | 416 | if (tag != 0xFFE1 && tag != 0xFFE2) // allow APP1/APP2 only |
1131 | 208 | break; |
1132 | 208 | INT64 tpos = ftell(ifp); |
1133 | 208 | int len = get2(); |
1134 | 208 | if (len > xmpsz + 2) |
1135 | 203 | { |
1136 | 203 | if ((fread(buf, 1, xmpsz, ifp) == xmpsz) && !memcmp(buf, xmpmarker, xmpsz)) // got it |
1137 | 1 | { |
1138 | 1 | xmplen = len - xmpsz - 2; |
1139 | 1 | xmpdata = (char*) calloc(xmplen+1,1); |
1140 | 1 | unsigned br = fread(xmpdata, 1, xmplen, ifp); |
1141 | 1 | xmpdata[br] = 0; |
1142 | 1 | break; |
1143 | 1 | } |
1144 | 203 | } |
1145 | 207 | fseek(ifp, tpos + len, SEEK_SET); |
1146 | 207 | } |
1147 | 209 | } |
1148 | | |
1149 | 1.86k | order = s_order; |
1150 | 1.86k | fseek(ifp, pos, SEEK_SET); |
1151 | 1.86k | } |
1152 | | |
1153 | | void LibRaw::parse_fuji(INT64 offset) |
1154 | 3.05k | { |
1155 | 3.05k | unsigned entries, tag, len, c; |
1156 | 3.05k | INT64 save; |
1157 | | |
1158 | 3.05k | #define get_average_WB(wb_index) \ |
1159 | 3.05k | do { \ |
1160 | 6.63k | FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = get2(); \ |
1161 | 1.65k | if ((len == 16) && average_WBData) { \ |
1162 | 908 | FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ |
1163 | 908 | (icWBC[wb_index][GRGB_2_RGBG(c)] + get2())/2; \ |
1164 | 227 | } \ |
1165 | 1.65k | if (use_WBcorr_coeffs) { \ |
1166 | 333 | icWBC[wb_index][0] = int(icWBC[wb_index][0] * wbR_corr); \ |
1167 | 333 | icWBC[wb_index][2] = int( icWBC[wb_index][2] * wbB_corr); \ |
1168 | 333 | } \ |
1169 | 1.65k | } while(0) |
1170 | | |
1171 | 3.05k | ushort raw_inset_present = 0; |
1172 | 3.05k | ushort use_WBcorr_coeffs = 0; |
1173 | 3.05k | double wbR_corr = 1.0; |
1174 | 3.05k | double wbB_corr = 1.0; |
1175 | 3.05k | ilm.CamID = unique_id; |
1176 | 3.05k | int average_WBData = 1; |
1177 | | |
1178 | 3.05k | fseek(ifp, offset, SEEK_SET); |
1179 | 3.05k | entries = get4(); |
1180 | 3.05k | if (entries > 255) |
1181 | 1.70k | return; |
1182 | 1.35k | imgdata.process_warnings |= LIBRAW_WARN_PARSEFUJI_PROCESSED; |
1183 | | |
1184 | 1.35k | if (strstr(model, "S2Pro") |
1185 | 1.33k | || strstr(model, "S20Pro") |
1186 | 1.32k | || strstr(model, "F700") |
1187 | 1.31k | || strstr(model, "S5000") |
1188 | 1.30k | || strstr(model, "S7000") |
1189 | 1.35k | ) { |
1190 | 54 | use_WBcorr_coeffs = 1; |
1191 | 54 | wbR_corr = 10.0 / 17.0 / 0.652941; |
1192 | 54 | wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0); |
1193 | 1.29k | } else if (strstr(model, "DBP") || strstr(model, "DX-2000")) { |
1194 | 18 | use_WBcorr_coeffs = 1; |
1195 | 18 | wbR_corr = 0.7632653061; |
1196 | 18 | wbB_corr = 0.8591549296; |
1197 | 18 | } |
1198 | | |
1199 | 68.1k | while (entries--) |
1200 | 66.8k | { |
1201 | 66.8k | tag = get2(); |
1202 | 66.8k | len = get2(); |
1203 | 66.8k | save = ftell(ifp); |
1204 | 66.8k | if (tag == 0x0100) // RawImageFullSize |
1205 | 1.04k | { |
1206 | 1.04k | raw_height = get2(); |
1207 | 1.04k | raw_width = get2(); |
1208 | 1.04k | raw_inset_present = 1; |
1209 | 1.04k | } |
1210 | 65.7k | else if ((tag == 0x0110) && raw_inset_present) // RawImageCropTopLeft |
1211 | 135 | { |
1212 | 135 | imgdata.sizes.raw_inset_crops[0].ctop = get2(); |
1213 | 135 | imgdata.sizes.raw_inset_crops[0].cleft = get2(); |
1214 | 135 | } |
1215 | 65.6k | else if ((tag == 0x0111) && raw_inset_present) // RawImageCroppedSize |
1216 | 185 | { |
1217 | 185 | imgdata.sizes.raw_inset_crops[0].cheight = get2(); |
1218 | 185 | imgdata.sizes.raw_inset_crops[0].cwidth = get2(); |
1219 | 185 | } |
1220 | 65.4k | else if ((tag == 0x0115) && raw_inset_present) // RawImageAspectRatio |
1221 | 220 | { |
1222 | 220 | int a = get2(); |
1223 | 220 | int b = get2(); |
1224 | 220 | if (a * b == 6) |
1225 | 56 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; |
1226 | 164 | else if (a * b == 12) |
1227 | 61 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; |
1228 | 103 | else if (a * b == 144) |
1229 | 25 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; |
1230 | 78 | else if (a * b == 1) |
1231 | 17 | imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; |
1232 | 220 | } |
1233 | 65.2k | else if (tag == 0x0121) // RawImageSize |
1234 | 143 | { |
1235 | 143 | height = get2(); |
1236 | 143 | if ((width = get2()) == 4284) |
1237 | 1 | width += 3; |
1238 | 143 | } |
1239 | 65.1k | else if (tag == 0x0130) // FujiLayout, |
1240 | 162 | { |
1241 | 162 | fuji_layout = fgetc(ifp) >> 7; |
1242 | 162 | fuji_width = !(fgetc(ifp) & 8); |
1243 | 162 | } |
1244 | 64.9k | else if (tag == 0x0131) // XTransLayout |
1245 | 50 | { |
1246 | 50 | filters = 9; |
1247 | 50 | char *xtrans_abs_alias = &xtrans_abs[0][0]; |
1248 | 50 | FORC(36) |
1249 | 1.80k | { |
1250 | 1.80k | int q = fgetc(ifp); |
1251 | 1.80k | xtrans_abs_alias[35 - c] = MAX(0, MIN(q, 2)); /* & 3;*/ |
1252 | 1.80k | } |
1253 | 50 | } |
1254 | 64.8k | else if (tag == 0x2ff0) // WB_GRGBLevels |
1255 | 748 | { |
1256 | 748 | get_average_WB(LIBRAW_WBI_AsShot); |
1257 | 2.99k | FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_AsShot][c]); |
1258 | 748 | } |
1259 | 64.1k | else if ((tag == 0x4000) && |
1260 | 171 | ((len == 8) || (len == 16))) |
1261 | 118 | { |
1262 | 118 | imFuji.BlackLevel[0] = len / 2; |
1263 | 472 | FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] = get2(); |
1264 | 118 | if (imFuji.BlackLevel[0] == 8) |
1265 | 252 | FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+5] = get2(); |
1266 | 118 | if (imFuji.BlackLevel[0] == 4) |
1267 | 220 | FORC4 cblack[c] = imFuji.BlackLevel[c+1]; |
1268 | 63 | else if (imFuji.BlackLevel[0] == 8) |
1269 | 252 | FORC4 cblack[c] = (imFuji.BlackLevel[c+1]+imFuji.BlackLevel[c+5]) /2; |
1270 | 118 | } |
1271 | 64.0k | else if (tag == 0x9200) // RelativeExposure |
1272 | 543 | { |
1273 | 543 | int s1 = get2(); |
1274 | 543 | int s2 = get2(); |
1275 | 543 | if ((s1 == s2) || !s1) |
1276 | 44 | imFuji.BrightnessCompensation = 0.0f; |
1277 | 499 | else if ((s1*4) == s2) |
1278 | 12 | imFuji.BrightnessCompensation = 2.0f; |
1279 | 487 | else if ((s1*16) == s2) |
1280 | 72 | imFuji.BrightnessCompensation = 4.0f; |
1281 | 415 | else |
1282 | 415 | imFuji.BrightnessCompensation = logf(float(s2)/float(s1))/logf(2.f); |
1283 | 543 | } |
1284 | 63.4k | else if (tag == 0x9650) // RawExposureBias |
1285 | 42 | { |
1286 | 42 | short a = (short)get2(); |
1287 | 42 | float b = fMAX(1.0f, get2()); |
1288 | 42 | imFuji.ExpoMidPointShift = a / b; |
1289 | 42 | imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift; |
1290 | 42 | } |
1291 | 66.8k | if (tag >= 0x2000 && tag <= 0x2410) |
1292 | 1.25k | { |
1293 | 7.67k | for (int q = 0; q < tag2wbtable_size; q++) |
1294 | 7.33k | if (tag2wbtable[q].tag == tag) |
1295 | 911 | { |
1296 | 911 | get_average_WB(tag2wbtable[q].wb); |
1297 | 911 | break; |
1298 | 911 | } |
1299 | 1.25k | } |
1300 | 65.5k | else if (tag == 0x2f00) // WB_GRGBLevels |
1301 | 413 | { |
1302 | 413 | int nWBs = get4(); |
1303 | 413 | nWBs = MIN(nWBs, 6); |
1304 | 1.85k | for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) { |
1305 | 5.76k | FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = get2(); |
1306 | 1.44k | if ((len >= unsigned(4+16*nWBs)) && average_WBData) { |
1307 | 448 | FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = |
1308 | 448 | (icWBC[wb_ind][GRGB_2_RGBG(c)] +get2()) /2; |
1309 | 112 | } |
1310 | 1.44k | if (use_WBcorr_coeffs) { |
1311 | 661 | icWBC[LIBRAW_WBI_Custom1 + wb_ind][0] = int(icWBC[LIBRAW_WBI_Custom1 + wb_ind][0] * wbR_corr); |
1312 | 661 | icWBC[LIBRAW_WBI_Custom1 + wb_ind][2] = int(icWBC[LIBRAW_WBI_Custom1 + wb_ind][2] * wbB_corr); |
1313 | 661 | } |
1314 | 1.44k | } |
1315 | 413 | } |
1316 | | |
1317 | 65.1k | else if (tag == 0xc000) // RAFData |
1318 | 284 | { |
1319 | 284 | int offsetWH_inRAFData; |
1320 | 284 | unsigned save_order = order; |
1321 | 284 | order = 0x4949; |
1322 | 284 | if (len > 20000) |
1323 | 198 | { |
1324 | 198 | uchar RAFDataHeader[16]; |
1325 | 198 | libraw_internal_data.unpacker_data.posRAFData = save; |
1326 | 198 | libraw_internal_data.unpacker_data.lenRAFData = (len >> 1); |
1327 | 198 | memset(RAFDataHeader, 0, sizeof(RAFDataHeader)); |
1328 | 198 | fread(RAFDataHeader, sizeof RAFDataHeader, 1, ifp); |
1329 | 198 | offsetWH_inRAFData = guess_RAFDataGeneration(RAFDataHeader); |
1330 | 198 | fseek(ifp, offsetWH_inRAFData-int(sizeof RAFDataHeader), SEEK_CUR); |
1331 | 198 | for (int i=0; |
1332 | 6.53k | i< (int)((sizeof imFuji.RAFData_ImageSizeTable) / (sizeof imFuji.RAFData_ImageSizeTable[0])); |
1333 | 6.33k | i++) { |
1334 | 6.33k | imFuji.RAFData_ImageSizeTable[i] = get4(); |
1335 | 6.33k | } |
1336 | | |
1337 | | // if ((width > raw_width) |
1338 | | // || (raw_inset_present && (width < imgdata.sizes.raw_inset_crops[0].cwidth)) |
1339 | | // ) |
1340 | | // width = raw_width; |
1341 | | // if ((height > raw_height) |
1342 | | // || (raw_inset_present && (height < imgdata.sizes.raw_inset_crops[0].cheight)) |
1343 | | // ) |
1344 | | // height = raw_height; |
1345 | | // |
1346 | | |
1347 | 198 | } |
1348 | 86 | else if (len == 4096) // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 |
1349 | 72 | { // Ill.A aligned to CCT 2850 |
1350 | 72 | int wb[4]; |
1351 | 72 | int nWB, tWB; |
1352 | 72 | int iCCT = 0; |
1353 | 72 | imFuji.RAFDataGeneration = 4096; |
1354 | 72 | fseek(ifp, save + 0x200, SEEK_SET); |
1355 | 3.09k | for (int wb_ind = 0; wb_ind < 42; wb_ind++) |
1356 | 3.02k | { |
1357 | 3.02k | nWB = get4(); |
1358 | 3.02k | tWB = get4(); |
1359 | 3.02k | wb[0] = get4() << 1; |
1360 | 3.02k | wb[1] = get4(); |
1361 | 3.02k | wb[3] = get4(); |
1362 | 3.02k | wb[2] = get4() << 1; |
1363 | 3.02k | if (tWB && (iCCT < 64)) |
1364 | 2.06k | { |
1365 | 2.06k | icWBCCTC[iCCT][0] = float(tWB); |
1366 | 8.25k | FORC4 icWBCCTC[iCCT][c + 1] = float(wb[c]); |
1367 | 2.06k | iCCT++; |
1368 | 2.06k | } |
1369 | 3.02k | if (nWB != 70) |
1370 | 3.01k | { |
1371 | 25.4k | for (int pWB = 1; pWB < (int)Fuji_wb_list2.size(); pWB += 2) |
1372 | 23.4k | { |
1373 | 23.4k | if (Fuji_wb_list2[pWB] == nWB) |
1374 | 992 | { |
1375 | 3.96k | FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] = wb[c]; |
1376 | 992 | break; |
1377 | 992 | } |
1378 | 23.4k | } |
1379 | 3.01k | } |
1380 | 3.02k | } |
1381 | 72 | } |
1382 | 284 | order = save_order; |
1383 | 284 | } |
1384 | 66.8k | fseek(ifp, save + len, SEEK_SET); |
1385 | 66.8k | } |
1386 | | |
1387 | 1.35k | if (!imFuji.RAFDataGeneration) { |
1388 | 1.21k | height <<= fuji_layout; |
1389 | 1.21k | width >>= fuji_layout; |
1390 | 1.21k | } |
1391 | 1.35k | #undef get_average_WB |
1392 | 1.35k | } |
1393 | | |