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