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