/src/LibRaw/src/metadata/mediumformat.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 | | |
21 | | void LibRaw::parse_phase_one(INT64 base) |
22 | 3.53k | { |
23 | 3.53k | unsigned entries, tag, type, len, data, i, c; |
24 | 3.53k | INT64 save; |
25 | 3.53k | float romm_cam[3][3]; |
26 | 3.53k | char *cp; |
27 | | |
28 | 3.53k | memset(&ph1, 0, sizeof ph1); |
29 | 3.53k | fseek(ifp, base, SEEK_SET); |
30 | 3.53k | order = get4() & 0xffff; |
31 | 3.53k | if (get4() >> 8 != 0x526177) |
32 | 586 | return; /* "Raw" */ |
33 | 2.94k | unsigned offset = get4(); |
34 | 2.94k | if (offset == 0xbad0bad) |
35 | 0 | return; |
36 | 2.94k | fseek(ifp, offset + base, SEEK_SET); |
37 | 2.94k | entries = get4(); |
38 | 2.94k | if (entries > 8192) |
39 | 34 | return; // too much?? |
40 | 2.91k | get4(); |
41 | 2.91k | INT64 fsize = ifp->size(); |
42 | | |
43 | 4.22M | while (entries--) |
44 | 4.22M | { |
45 | 4.22M | tag = get4(); |
46 | 4.22M | type = get4(); |
47 | 4.22M | len = get4(); |
48 | 4.22M | if (feof(ifp)) |
49 | 2.45k | break; |
50 | 4.22M | data = get4(); |
51 | 4.22M | save = ftell(ifp); |
52 | 4.22M | bool do_seek = (tag < 0x0108 || tag > 0x0110); // to make it single rule, not copy-paste |
53 | 4.22M | if(do_seek) |
54 | 4.18M | fseek(ifp, base + data, SEEK_SET); |
55 | | |
56 | 4.22M | INT64 savepos = ftell(ifp); |
57 | 4.22M | if (len > 8 && savepos + len > 2 * fsize) |
58 | 3.18M | { |
59 | 3.18M | fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! |
60 | 3.18M | continue; |
61 | 3.18M | } |
62 | | |
63 | 1.04M | switch (tag) |
64 | 1.04M | { |
65 | | |
66 | 7.83k | case 0x0100: |
67 | 7.83k | flip = "0653"[data & 3] - '0'; |
68 | 7.83k | break; |
69 | 552 | case 0x0102: |
70 | 552 | stmread(imgdata.shootinginfo.BodySerial, len, ifp); |
71 | 552 | if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && (imgdata.shootinginfo.BodySerial[1] == 0x49)) |
72 | 34 | { |
73 | 34 | unique_id = |
74 | 34 | (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - 0x41; |
75 | 34 | } |
76 | 518 | else |
77 | 518 | { |
78 | 518 | unique_id = |
79 | 518 | (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - 0x41; |
80 | 518 | } |
81 | 552 | setPhaseOneFeatures(unique_id); |
82 | 552 | break; |
83 | 20 | case 0x0106: |
84 | 200 | for (i = 0; i < 9; i++) |
85 | 180 | imgdata.color.P1_color[0].romm_cam[i] = ((float *)romm_cam)[i] = |
86 | 180 | (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); |
87 | 20 | romm_coeff(romm_cam); |
88 | 20 | break; |
89 | 24 | case 0x0107: |
90 | 72 | FORC3 cam_mul[c] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); |
91 | 24 | break; |
92 | 312 | case 0x0108: |
93 | 312 | raw_width = data; |
94 | 312 | break; |
95 | 2.52k | case 0x0109: |
96 | 2.52k | raw_height = data; |
97 | 2.52k | break; |
98 | 130 | case 0x010a: |
99 | 130 | left_margin = data; |
100 | 130 | break; |
101 | 6 | case 0x010b: |
102 | 6 | top_margin = data; |
103 | 6 | break; |
104 | 78 | case 0x010c: |
105 | 78 | width = data; |
106 | 78 | break; |
107 | 6 | case 0x010d: |
108 | 6 | height = data; |
109 | 6 | break; |
110 | 1.94k | case 0x010e: |
111 | 1.94k | ph1.format = data; |
112 | 1.94k | break; |
113 | 1.02k | case 0x010f: |
114 | 1.02k | data_offset = data + base; |
115 | 1.02k | data_size = len; |
116 | 1.02k | break; |
117 | 942 | case 0x0110: |
118 | 942 | meta_offset = data + base; |
119 | 942 | meta_length = len; |
120 | 942 | break; |
121 | 68 | case 0x0112: |
122 | 68 | ph1.key_off = int(save - 4); |
123 | 68 | break; |
124 | 100 | case 0x0203: |
125 | 100 | stmread(imPhaseOne.Software, len, ifp); |
126 | 100 | break; |
127 | 28 | case 0x0204: |
128 | 28 | stmread(imPhaseOne.SystemType, len, ifp); |
129 | 28 | break; |
130 | 110 | case 0x0210: |
131 | 110 | ph1.tag_210 = int_to_float(data); |
132 | 110 | imCommon.SensorTemperature = ph1.tag_210; |
133 | 110 | break; |
134 | 176 | case 0x0211: |
135 | 176 | imCommon.SensorTemperature2 = int_to_float(data); |
136 | 176 | break; |
137 | 26 | case 0x021a: |
138 | 26 | ph1.tag_21a = data; |
139 | 26 | break; |
140 | 1.25k | case 0x021c: |
141 | 1.25k | strip_offset = data + base; |
142 | 1.25k | break; |
143 | 54 | case 0x021d: |
144 | 54 | ph1.t_black = data; |
145 | 54 | break; |
146 | 44 | case 0x0222: |
147 | 44 | ph1.split_col = data; |
148 | 44 | break; |
149 | 256 | case 0x0223: |
150 | 256 | ph1.black_col = int(data + base); |
151 | 256 | break; |
152 | 142 | case 0x0224: |
153 | 142 | ph1.split_row = data; |
154 | 142 | break; |
155 | 114 | case 0x0225: |
156 | 114 | ph1.black_row = int(data + base); |
157 | 114 | break; |
158 | 74 | case 0x0226: |
159 | 740 | for (i = 0; i < 9; i++) |
160 | 666 | imgdata.color.P1_color[1].romm_cam[i] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); |
161 | 74 | break; |
162 | 448 | case 0x0301: |
163 | 448 | model[63] = 0; |
164 | 448 | fread(imPhaseOne.FirmwareString, 1, 255, ifp); |
165 | 448 | imPhaseOne.FirmwareString[255] = 0; |
166 | 448 | memcpy(model, imPhaseOne.FirmwareString, 63); |
167 | 448 | model[63] = 0; |
168 | 448 | if ((cp = strstr(model, " camera"))) |
169 | 0 | *cp = 0; |
170 | 448 | else if ((cp = strchr(model, ','))) |
171 | 36 | *cp = 0; |
172 | | /* minus and the letter after it are not always present |
173 | | if present, last letter means: |
174 | | C : Contax 645AF |
175 | | H : Hasselblad H1 / H2 |
176 | | M : Mamiya |
177 | | V : Hasselblad 555ELD / 553ELX / 503CW / 501CM; not included below |
178 | | because of adapter conflicts (Mamiya RZ body) if not present, Phase One |
179 | | 645 AF, Mamiya 645AFD Series, or anything |
180 | | */ |
181 | 448 | strcpy(imPhaseOne.SystemModel, model); |
182 | 448 | if ((cp = strchr(model, '-'))) |
183 | 62 | { |
184 | 62 | if (cp[1] == 'C') |
185 | 0 | { |
186 | 0 | strcpy(ilm.body, "Contax 645AF"); |
187 | 0 | ilm.CameraMount = LIBRAW_MOUNT_Contax645; |
188 | 0 | ilm.CameraFormat = LIBRAW_FORMAT_645; |
189 | 0 | } |
190 | 62 | else if (cp[1] == 'M') |
191 | 6 | { |
192 | 6 | strcpy(ilm.body, "Mamiya 645"); |
193 | 6 | ilm.CameraMount = LIBRAW_MOUNT_Mamiya645; |
194 | 6 | ilm.CameraFormat = LIBRAW_FORMAT_645; |
195 | 6 | } |
196 | 56 | else if (cp[1] == 'H') |
197 | 14 | { |
198 | 14 | strcpy(ilm.body, "Hasselblad H1/H2"); |
199 | 14 | ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H; |
200 | 14 | ilm.CameraFormat = LIBRAW_FORMAT_645; |
201 | 14 | } |
202 | 62 | *cp = 0; |
203 | 62 | } |
204 | 448 | break; |
205 | 990 | case 0x0401: |
206 | 990 | if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) |
207 | 44 | ilm.CurAp = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); |
208 | 946 | else |
209 | 946 | ilm.CurAp = libraw_powf64l(2.0f, getrealf(type) / 2.0f); |
210 | 990 | break; |
211 | 330 | case 0x0403: |
212 | 330 | if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) |
213 | 26 | ilm.CurFocal = int_to_float(data); |
214 | 304 | else |
215 | 304 | ilm.CurFocal = (float)getreal(type); |
216 | 330 | break; |
217 | 4.03k | case 0x0410: |
218 | 4.03k | stmread(ilm.body, len, ifp); |
219 | 4.03k | if (((unsigned char)ilm.body[0]) == 0xff) |
220 | 248 | ilm.body[0] = 0; |
221 | 4.03k | break; |
222 | 1.07k | case 0x0412: |
223 | 1.07k | stmread(ilm.Lens, len, ifp); |
224 | 1.07k | if (((unsigned char)ilm.Lens[0]) == 0xff) |
225 | 132 | ilm.Lens[0] = 0; |
226 | 1.07k | break; |
227 | 226 | case 0x0414: |
228 | 226 | if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) |
229 | 26 | { |
230 | 26 | ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); |
231 | 26 | } |
232 | 200 | else |
233 | 200 | { |
234 | 200 | ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, getrealf(type) / 2.0f); |
235 | 200 | } |
236 | 226 | break; |
237 | 300 | case 0x0415: |
238 | 300 | if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) |
239 | 114 | { |
240 | 114 | ilm.MinAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); |
241 | 114 | } |
242 | 186 | else |
243 | 186 | { |
244 | 186 | ilm.MinAp4CurFocal = libraw_powf64l(2.0f, getrealf(type) / 2.0f); |
245 | 186 | } |
246 | 300 | break; |
247 | 198 | case 0x0416: |
248 | 198 | if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) |
249 | 88 | { |
250 | 88 | ilm.MinFocal = int_to_float(data); |
251 | 88 | } |
252 | 110 | else |
253 | 110 | { |
254 | 110 | ilm.MinFocal = (float)getreal(type); |
255 | 110 | } |
256 | 198 | if (ilm.MinFocal > 1000.0f) |
257 | 18 | { |
258 | 18 | ilm.MinFocal = 0.0f; |
259 | 18 | } |
260 | 198 | break; |
261 | 128 | case 0x0417: |
262 | 128 | if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) |
263 | 66 | { |
264 | 66 | ilm.MaxFocal = int_to_float(data); |
265 | 66 | } |
266 | 62 | else |
267 | 62 | { |
268 | 62 | ilm.MaxFocal = (float)getreal(type); |
269 | 62 | } |
270 | 128 | break; |
271 | 1.04M | } |
272 | 1.04M | if (do_seek) |
273 | 1.03M | fseek(ifp, save, SEEK_SET); |
274 | 1.04M | } |
275 | | |
276 | 2.91k | if (!ilm.body[0] && !imgdata.shootinginfo.BodySerial[0]) |
277 | 640 | { |
278 | 640 | fseek(ifp, meta_offset, SEEK_SET); |
279 | 640 | order = get2(); |
280 | 640 | fseek(ifp, 6, SEEK_CUR); |
281 | 640 | fseek(ifp, meta_offset + get4(), SEEK_SET); |
282 | 640 | entries = get4(); |
283 | 640 | if (entries > 8192) |
284 | 274 | return; // too much?? |
285 | 366 | get4(); |
286 | 187k | while (entries--) |
287 | 187k | { |
288 | 187k | tag = get4(); |
289 | 187k | len = get4(); |
290 | 187k | if (feof(ifp)) |
291 | 304 | break; |
292 | 187k | data = get4(); |
293 | 187k | save = ftell(ifp); |
294 | 187k | fseek(ifp, meta_offset + data, SEEK_SET); |
295 | | |
296 | 187k | INT64 savepos = ftell(ifp); |
297 | 187k | if (len > 8 && savepos + len > 2 * fsize) |
298 | 135k | { |
299 | 135k | fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! |
300 | 135k | continue; |
301 | 135k | } |
302 | | |
303 | 51.3k | if (tag == 0x0407) |
304 | 134 | { |
305 | 134 | stmread(imgdata.shootinginfo.BodySerial, len, ifp); |
306 | 134 | if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && |
307 | 20 | (imgdata.shootinginfo.BodySerial[1] == 0x49)) |
308 | 14 | { |
309 | 14 | unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | |
310 | 14 | (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - |
311 | 14 | 0x41; |
312 | 14 | } |
313 | 120 | else |
314 | 120 | { |
315 | 120 | unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | |
316 | 120 | (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - |
317 | 120 | 0x41; |
318 | 120 | } |
319 | 134 | setPhaseOneFeatures(unique_id); |
320 | 134 | } |
321 | 51.3k | fseek(ifp, save, SEEK_SET); |
322 | 51.3k | } |
323 | 366 | } |
324 | | |
325 | 2.63k | if ((ilm.MaxAp4CurFocal > 0.7f) && |
326 | 16 | (ilm.MinAp4CurFocal > 0.7f)) { |
327 | 4 | float MinAp4CurFocal = MAX(ilm.MaxAp4CurFocal,ilm.MinAp4CurFocal); |
328 | 4 | ilm.MaxAp4CurFocal = MIN(ilm.MaxAp4CurFocal,ilm.MinAp4CurFocal); |
329 | 4 | ilm.MinAp4CurFocal = MinAp4CurFocal; |
330 | 4 | } |
331 | | |
332 | 2.63k | if (ph1.format == 6) |
333 | 1.05k | load_raw = &LibRaw::phase_one_load_raw_s; |
334 | 1.58k | else |
335 | 1.58k | load_raw = ph1.format < 3 ? &LibRaw::phase_one_load_raw : &LibRaw::phase_one_load_raw_c; |
336 | 2.63k | maximum = 0xffff; // Always scaled to 16bit? |
337 | 2.63k | strcpy(make, "Phase One"); |
338 | 2.63k | if (model[0]) |
339 | 186 | return; |
340 | 2.45k | switch (raw_height) |
341 | 2.45k | { |
342 | 0 | case 2060: |
343 | 0 | strcpy(model, "LightPhase"); |
344 | 0 | break; |
345 | 0 | case 2682: |
346 | 0 | strcpy(model, "H 10"); |
347 | 0 | break; |
348 | 0 | case 4128: |
349 | 0 | strcpy(model, "H 20"); |
350 | 0 | break; |
351 | 0 | case 5488: |
352 | 0 | strcpy(model, "H 25"); |
353 | 0 | break; |
354 | 2.45k | } |
355 | 2.45k | } |
356 | | |
357 | | void LibRaw::parse_mos(INT64 offset) |
358 | 8.90k | { |
359 | 8.90k | char data[40]; |
360 | 8.90k | int i, c, neut[4], planes = 0, frot = 0; |
361 | 8.90k | INT64 from; |
362 | 8.90k | unsigned skip; |
363 | 8.90k | static const char *mod[] = { |
364 | | /* DM22, DM28, DM40, DM56 are somewhere here too */ |
365 | 8.90k | "", // 0 |
366 | 8.90k | "DCB2", // 1 |
367 | 8.90k | "Volare", // 2 |
368 | 8.90k | "Cantare", // 3 |
369 | 8.90k | "CMost", // 4 |
370 | 8.90k | "Valeo 6", // 5 |
371 | 8.90k | "Valeo 11", // 6 |
372 | 8.90k | "Valeo 22", // 7 |
373 | 8.90k | "Valeo 11p", // 8 |
374 | 8.90k | "Valeo 17", // 9 |
375 | 8.90k | "", // 10 |
376 | 8.90k | "Aptus 17", // 11 |
377 | 8.90k | "Aptus 22", // 12 |
378 | 8.90k | "Aptus 75", // 13 |
379 | 8.90k | "Aptus 65", // 14 |
380 | 8.90k | "Aptus 54S", // 15 |
381 | 8.90k | "Aptus 65S", // 16 |
382 | 8.90k | "Aptus 75S", // 17 |
383 | 8.90k | "AFi 5", // 18 |
384 | 8.90k | "AFi 6", // 19 |
385 | 8.90k | "AFi 7", // 20 |
386 | 8.90k | "AFi-II 7", // 21 |
387 | 8.90k | "Aptus-II 7", // 22 (same CMs as Mamiya DM33) |
388 | 8.90k | "", // 23 |
389 | 8.90k | "Aptus-II 6", // 24 (same CMs as Mamiya DM28) |
390 | 8.90k | "AFi-II 10", // 25 |
391 | 8.90k | "", // 26 |
392 | 8.90k | "Aptus-II 10", // 27 (same CMs as Mamiya DM56) |
393 | 8.90k | "Aptus-II 5", // 28 (same CMs as Mamiya DM22) |
394 | 8.90k | "", // 29 |
395 | 8.90k | "DM33", // 30, make is Mamiya |
396 | 8.90k | "", // 31 |
397 | 8.90k | "", // 32 |
398 | 8.90k | "Aptus-II 10R", // 33 |
399 | 8.90k | "Aptus-II 8", // 34 (same CMs as Mamiya DM40) |
400 | 8.90k | "", // 35 |
401 | 8.90k | "Aptus-II 12", // 36 |
402 | 8.90k | "", // 37 |
403 | 8.90k | "AFi-II 12" // 38 |
404 | 8.90k | }; |
405 | 8.90k | float romm_cam[3][3]; |
406 | | |
407 | 8.90k | libraw_internal_data.unpacker_data.CR3_Version--; |
408 | 8.90k | if (libraw_internal_data.unpacker_data.CR3_Version < 1) |
409 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
410 | | |
411 | 8.90k | fseek(ifp, offset, SEEK_SET); |
412 | 13.4k | while (!feof(ifp)) |
413 | 13.0k | { |
414 | 13.0k | if (get4() != 0x504b5453) |
415 | 8.56k | break; |
416 | 4.50k | get4(); |
417 | 4.50k | memset(data,0,sizeof(data)); |
418 | 4.50k | fread(data, 1, 40, ifp); |
419 | 4.50k | data[39] = 0; |
420 | 4.50k | skip = get4(); |
421 | 4.50k | from = ftell(ifp); |
422 | | |
423 | 4.50k | if (!strcmp(data, "CameraObj_camera_type")) |
424 | 742 | { |
425 | 742 | stmread(ilm.body, (unsigned)skip, ifp); |
426 | 742 | if (ilm.body[0]) |
427 | 668 | { |
428 | 668 | if (!strncmp(ilm.body, "Mamiya R", 8)) |
429 | 34 | { |
430 | 34 | ilm.CameraMount = LIBRAW_MOUNT_Mamiya67; |
431 | 34 | ilm.CameraFormat = LIBRAW_FORMAT_67; |
432 | 34 | } |
433 | 634 | else if (!strncmp(ilm.body, "Hasselblad 5", 12)) |
434 | 82 | { |
435 | 82 | ilm.CameraFormat = LIBRAW_FORMAT_66; |
436 | 82 | ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V; |
437 | 82 | } |
438 | 552 | else if (!strncmp(ilm.body, "Hasselblad H", 12)) |
439 | 72 | { |
440 | 72 | ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H; |
441 | 72 | ilm.CameraFormat = LIBRAW_FORMAT_645; |
442 | 72 | } |
443 | 480 | else if (!strncmp(ilm.body, "Mamiya 6", 8) || |
444 | 326 | !strncmp(ilm.body, "Phase One 6", 11)) |
445 | 228 | { |
446 | 228 | ilm.CameraMount = LIBRAW_MOUNT_Mamiya645; |
447 | 228 | ilm.CameraFormat = LIBRAW_FORMAT_645; |
448 | 228 | } |
449 | 252 | else if (!strncmp(ilm.body, "Large F", 7)) |
450 | 76 | { |
451 | 76 | ilm.CameraMount = LIBRAW_MOUNT_LF; |
452 | 76 | ilm.CameraFormat = LIBRAW_FORMAT_LF; |
453 | 76 | } |
454 | 176 | else if (!strncmp(model, "Leaf AFi", 8)) |
455 | 0 | { |
456 | 0 | ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet; |
457 | 0 | ilm.CameraFormat = LIBRAW_FORMAT_66; |
458 | 0 | } |
459 | 668 | } |
460 | 742 | } |
461 | 4.50k | if (!strcmp(data, "back_serial_number")) |
462 | 278 | { |
463 | 278 | char buffer[sizeof(imgdata.shootinginfo.BodySerial)]; |
464 | 278 | char *words[4] = {0, 0, 0, 0}; |
465 | 278 | stmread(buffer, (unsigned)skip, ifp); |
466 | | /*nwords = */ |
467 | 278 | getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.BodySerial)); |
468 | 278 | if(words[0]) |
469 | 278 | strcpy(imgdata.shootinginfo.BodySerial, words[0]); |
470 | 278 | } |
471 | 4.50k | if (!strcmp(data, "CaptProf_serial_number")) |
472 | 190 | { |
473 | 190 | char buffer[sizeof(imgdata.shootinginfo.InternalBodySerial)]; |
474 | 190 | char *words[4] = {0, 0, 0, 0}; |
475 | 190 | stmread(buffer, (unsigned)skip, ifp); |
476 | 190 | getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.InternalBodySerial)); |
477 | 190 | if(words[0]) |
478 | 147 | strcpy(imgdata.shootinginfo.InternalBodySerial, words[0]); |
479 | 190 | } |
480 | | |
481 | 4.50k | if (!strcmp(data, "JPEG_preview_data")) |
482 | 0 | { |
483 | 0 | thumb_offset = from; |
484 | 0 | thumb_length = skip; |
485 | 0 | } |
486 | 4.50k | if (!strcmp(data, "icc_camera_profile")) |
487 | 54 | { |
488 | 54 | profile_offset = from; |
489 | 54 | profile_length = skip; |
490 | 54 | } |
491 | 4.50k | if (!strcmp(data, "ShootObj_back_type")) |
492 | 242 | { |
493 | 242 | fscanf(ifp, "%d", &i); |
494 | 242 | if ((unsigned)i < sizeof mod / sizeof(*mod)) |
495 | 240 | { |
496 | 240 | strcpy(model, mod[i]); |
497 | 240 | if (!strncmp(model, "AFi", 3)) |
498 | 0 | { |
499 | 0 | ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet; |
500 | 0 | ilm.CameraFormat = LIBRAW_FORMAT_66; |
501 | 0 | } |
502 | 240 | ilm.CamID = i; |
503 | 240 | } |
504 | 242 | } |
505 | 4.50k | if (!strcmp(data, "icc_camera_to_tone_matrix")) |
506 | 0 | { |
507 | 0 | for (i = 0; i < 9; i++) |
508 | 0 | ((float *)romm_cam)[i] = int_to_float(get4()); |
509 | 0 | romm_coeff(romm_cam); |
510 | 0 | } |
511 | 4.50k | if (!strcmp(data, "CaptProf_color_matrix")) |
512 | 122 | { |
513 | 1.22k | for (i = 0; i < 9; i++) |
514 | 1.09k | fscanf(ifp, "%f", (float *)romm_cam + i); |
515 | 122 | romm_coeff(romm_cam); |
516 | 122 | } |
517 | 4.50k | if (!strcmp(data, "CaptProf_number_of_planes")) |
518 | 0 | fscanf(ifp, "%d", &planes); |
519 | 4.50k | if (!strcmp(data, "CaptProf_raw_data_rotation")) |
520 | 0 | fscanf(ifp, "%d", &flip); |
521 | 4.50k | if (!strcmp(data, "CaptProf_mosaic_pattern")) |
522 | 1.47k | FORC4 |
523 | 5.91k | { |
524 | 5.91k | fscanf(ifp, "%d", &i); |
525 | 5.91k | if (i == 1) |
526 | 248 | frot = c ^ (c >> 1); // 0123 -> 0132 |
527 | 5.91k | } |
528 | 4.50k | if (!strcmp(data, "ImgProf_rotation_angle")) |
529 | 112 | { |
530 | 112 | fscanf(ifp, "%d", &i); |
531 | 112 | flip = i - flip; |
532 | 112 | } |
533 | 4.50k | if (!strcmp(data, "NeutObj_neutrals") && !cam_mul[0]) |
534 | 0 | { |
535 | 0 | FORC4 fscanf(ifp, "%d", neut + c); |
536 | 0 | FORC3 |
537 | 0 | if (neut[c + 1]) |
538 | 0 | cam_mul[c] = (float)neut[0] / neut[c + 1]; |
539 | 0 | } |
540 | 4.50k | if (!strcmp(data, "Rows_data")) |
541 | 64 | load_flags = get4(); |
542 | 4.50k | parse_mos(from); |
543 | 4.50k | fseek(ifp, skip + from, SEEK_SET); |
544 | 4.50k | } |
545 | 8.90k | if (planes) |
546 | 0 | filters = (planes == 1) * 0x01010101U * |
547 | 0 | (uchar) "\x94\x61\x16\x49"[(flip / 90 + frot) & 3]; |
548 | 8.90k | libraw_internal_data.unpacker_data.CR3_Version++; |
549 | | |
550 | 8.90k | } |