File indexing completed on 2025-01-05 03:57:01

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
0005  dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
0006  LibRaw do not use RESTRICTED code from dcraw.c
0007 
0008  LibRaw is free software; you can redistribute it and/or modify
0009  it under the terms of the one of two licenses as you choose:
0010 
0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0012    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0013 
0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0015    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0016 
0017  */
0018 
0019 #include "../../internal/dcraw_defs.h"
0020 
0021 void LibRaw::parse_phase_one(int base)
0022 {
0023   unsigned entries, tag, type, len, data, i, c;
0024   INT64 save;
0025   float romm_cam[3][3];
0026   char *cp;
0027 
0028   memset(&ph1, 0, sizeof ph1);
0029   fseek(ifp, base, SEEK_SET);
0030   order = get4() & 0xffff;
0031   if (get4() >> 8 != 0x526177)
0032     return; /* "Raw" */
0033   unsigned offset = get4();
0034   if (offset == 0xbad0bad)
0035     return;
0036   fseek(ifp, offset + base, SEEK_SET);
0037   entries = get4();
0038   if (entries > 8192)
0039     return; // too much??
0040   get4();
0041   while (entries--)
0042   {
0043     tag = get4();
0044     type = get4();
0045     len = get4();
0046     if (feof(ifp))
0047         break;
0048     data = get4();
0049     save = ftell(ifp);
0050     bool do_seek = (tag < 0x0108 || tag > 0x0110); // to make it single rule, not copy-paste
0051     if(do_seek)
0052         fseek(ifp, base + data, SEEK_SET);
0053     switch (tag)
0054     {
0055 
0056     case 0x0100:
0057       flip = "0653"[data & 3] - '0';
0058       break;
0059     case 0x0102:
0060       stmread(imgdata.shootinginfo.BodySerial, len, ifp);
0061       if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && (imgdata.shootinginfo.BodySerial[1] == 0x49))
0062       {
0063         unique_id =
0064             (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - 0x41;
0065       }
0066       else
0067       {
0068         unique_id =
0069             (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - 0x41;
0070       }
0071       setPhaseOneFeatures(unique_id);
0072       break;
0073     case 0x0106:
0074       for (i = 0; i < 9; i++)
0075         imgdata.color.P1_color[0].romm_cam[i] = ((float *)romm_cam)[i] =
0076             (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT);
0077       romm_coeff(romm_cam);
0078       break;
0079     case 0x0107:
0080       FORC3 cam_mul[c] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT);
0081       break;
0082     case 0x0108:
0083       raw_width = data;
0084       break;
0085     case 0x0109:
0086       raw_height = data;
0087       break;
0088     case 0x010a:
0089       left_margin = data;
0090       break;
0091     case 0x010b:
0092       top_margin = data;
0093       break;
0094     case 0x010c:
0095       width = data;
0096       break;
0097     case 0x010d:
0098       height = data;
0099       break;
0100     case 0x010e:
0101       ph1.format = data;
0102       break;
0103     case 0x010f:
0104       data_offset = data + base;
0105       data_size = len;
0106       break;
0107     case 0x0110:
0108       meta_offset = data + base;
0109       meta_length = len;
0110       break;
0111     case 0x0112:
0112       ph1.key_off = int(save - 4);
0113       break;
0114     case 0x0203:
0115       stmread(imPhaseOne.Software, len, ifp);
0116     case 0x0204:
0117       stmread(imPhaseOne.SystemType, len, ifp);
0118     case 0x0210:
0119       ph1.tag_210 = int_to_float(data);
0120       imCommon.SensorTemperature = ph1.tag_210;
0121       break;
0122     case 0x0211:
0123       imCommon.SensorTemperature2 = int_to_float(data);
0124       break;
0125     case 0x021a:
0126       ph1.tag_21a = data;
0127       break;
0128     case 0x021c:
0129       strip_offset = data + base;
0130       break;
0131     case 0x021d:
0132       ph1.t_black = data;
0133       break;
0134     case 0x0222:
0135       ph1.split_col = data;
0136       break;
0137     case 0x0223:
0138       ph1.black_col = data + base;
0139       break;
0140     case 0x0224:
0141       ph1.split_row = data;
0142       break;
0143     case 0x0225:
0144       ph1.black_row = data + base;
0145       break;
0146     case 0x0226:
0147       for (i = 0; i < 9; i++)
0148         imgdata.color.P1_color[1].romm_cam[i] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT);
0149       break;
0150     case 0x0301:
0151       model[63] = 0;
0152       fread(imPhaseOne.FirmwareString, 1, 255, ifp);
0153       imPhaseOne.FirmwareString[255] = 0;
0154       memcpy(model, imPhaseOne.FirmwareString, 63);
0155       model[63] = 0;
0156       if ((cp = strstr(model, " camera")))
0157         *cp = 0;
0158       else if ((cp = strchr(model, ',')))
0159         *cp = 0;
0160       /* minus and the letter after it are not always present
0161         if present, last letter means:
0162           C : Contax 645AF
0163           H : Hasselblad H1 / H2
0164           M : Mamiya
0165           V : Hasselblad 555ELD / 553ELX / 503CW / 501CM; not included below
0166         because of adapter conflicts (Mamiya RZ body) if not present, Phase One
0167         645 AF, Mamiya 645AFD Series, or anything
0168        */
0169       strcpy(imPhaseOne.SystemModel, model);
0170       if ((cp = strchr(model, '-')))
0171       {
0172         if (cp[1] == 'C')
0173         {
0174           strcpy(ilm.body, "Contax 645AF");
0175           ilm.CameraMount = LIBRAW_MOUNT_Contax645;
0176           ilm.CameraFormat = LIBRAW_FORMAT_645;
0177         }
0178         else if (cp[1] == 'M')
0179         {
0180           strcpy(ilm.body, "Mamiya 645");
0181           ilm.CameraMount = LIBRAW_MOUNT_Mamiya645;
0182           ilm.CameraFormat = LIBRAW_FORMAT_645;
0183         }
0184         else if (cp[1] == 'H')
0185         {
0186           strcpy(ilm.body, "Hasselblad H1/H2");
0187           ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H;
0188           ilm.CameraFormat = LIBRAW_FORMAT_645;
0189         }
0190         *cp = 0;
0191       }
0192     case 0x0401:
0193       if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0194         ilm.CurAp = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f));
0195       else
0196         ilm.CurAp = libraw_powf64l(2.0f, float(getreal(type) / 2.0f));
0197       break;
0198     case 0x0403:
0199       if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0200         ilm.CurFocal = int_to_float(data);
0201       else
0202         ilm.CurFocal = (float)getreal(type);
0203       break;
0204     case 0x0410:
0205       stmread(ilm.body, len, ifp);
0206       if (((unsigned char)ilm.body[0]) == 0xff)
0207         ilm.body[0] = 0;
0208       break;
0209     case 0x0412:
0210       stmread(ilm.Lens, len, ifp);
0211       if (((unsigned char)ilm.Lens[0]) == 0xff)
0212         ilm.Lens[0] = 0;
0213       break;
0214     case 0x0414:
0215       if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0216       {
0217         ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f));
0218       }
0219       else
0220       {
0221         ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, float(getreal(type) / 2.0f));
0222       }
0223       break;
0224     case 0x0415:
0225       if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0226       {
0227         ilm.MinAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f));
0228       }
0229       else
0230       {
0231         ilm.MinAp4CurFocal = libraw_powf64l(2.0f, float(getreal(type) / 2.0f));
0232       }
0233       break;
0234     case 0x0416:
0235       if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0236       {
0237         ilm.MinFocal = int_to_float(data);
0238       }
0239       else
0240       {
0241         ilm.MinFocal = (float)getreal(type);
0242       }
0243       if (ilm.MinFocal > 1000.0f)
0244       {
0245         ilm.MinFocal = 0.0f;
0246       }
0247       break;
0248     case 0x0417:
0249       if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0250       {
0251         ilm.MaxFocal = int_to_float(data);
0252       }
0253       else
0254       {
0255         ilm.MaxFocal = (float)getreal(type);
0256       }
0257       break;
0258     }
0259     if (do_seek)
0260       fseek(ifp, save, SEEK_SET);
0261   }
0262 
0263   if (!ilm.body[0] && !imgdata.shootinginfo.BodySerial[0])
0264   {
0265     fseek(ifp, meta_offset, SEEK_SET);
0266     order = get2();
0267     fseek(ifp, 6, SEEK_CUR);
0268     fseek(ifp, meta_offset + get4(), SEEK_SET);
0269     entries = get4();
0270     if (entries > 8192)
0271       return; // too much??
0272     get4();
0273     while (entries--)
0274     {
0275       tag = get4();
0276       len = get4();
0277       if (feof(ifp))
0278           break;
0279       data = get4();
0280       save = ftell(ifp);
0281       fseek(ifp, meta_offset + data, SEEK_SET);
0282       if (tag == 0x0407)
0283       {
0284         stmread(imgdata.shootinginfo.BodySerial, len, ifp);
0285         if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) &&
0286             (imgdata.shootinginfo.BodySerial[1] == 0x49))
0287         {
0288           unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) |
0289                        (imgdata.shootinginfo.BodySerial[2] & 0x3f)) -
0290                       0x41;
0291         }
0292         else
0293         {
0294           unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) |
0295                        (imgdata.shootinginfo.BodySerial[1] & 0x3f)) -
0296                       0x41;
0297         }
0298         setPhaseOneFeatures(unique_id);
0299       }
0300       fseek(ifp, save, SEEK_SET);
0301     }
0302   }
0303 
0304   if ((ilm.MaxAp4CurFocal > 0.7f) &&
0305       (ilm.MinAp4CurFocal > 0.7f)) {
0306     float MinAp4CurFocal = MAX(ilm.MaxAp4CurFocal,ilm.MinAp4CurFocal);
0307     ilm.MaxAp4CurFocal   = MIN(ilm.MaxAp4CurFocal,ilm.MinAp4CurFocal);
0308     ilm.MinAp4CurFocal = MinAp4CurFocal;
0309   }
0310 
0311   if (ph1.format == 6)
0312       load_raw = &LibRaw::phase_one_load_raw_s;
0313   else
0314     load_raw = ph1.format < 3 ? &LibRaw::phase_one_load_raw : &LibRaw::phase_one_load_raw_c;
0315   maximum = 0xffff; // Always scaled to 16bit?
0316   strcpy(make, "Phase One");
0317   if (model[0])
0318     return;
0319   switch (raw_height)
0320   {
0321   case 2060:
0322     strcpy(model, "LightPhase");
0323     break;
0324   case 2682:
0325     strcpy(model, "H 10");
0326     break;
0327   case 4128:
0328     strcpy(model, "H 20");
0329     break;
0330   case 5488:
0331     strcpy(model, "H 25");
0332     break;
0333   }
0334 }
0335 
0336 void LibRaw::parse_mos(INT64 offset)
0337 {
0338   char data[40];
0339   int i, c, neut[4], planes = 0, frot = 0;
0340   INT64 from;
0341   unsigned skip;
0342   static const char *mod[] = {
0343       /* DM22, DM28, DM40, DM56 are somewhere here too */
0344       "",             //  0
0345       "DCB2",         //  1
0346       "Volare",       //  2
0347       "Cantare",      //  3
0348       "CMost",        //  4
0349       "Valeo 6",      //  5
0350       "Valeo 11",     //  6
0351       "Valeo 22",     //  7
0352       "Valeo 11p",    //  8
0353       "Valeo 17",     //  9
0354       "",             // 10
0355       "Aptus 17",     // 11
0356       "Aptus 22",     // 12
0357       "Aptus 75",     // 13
0358       "Aptus 65",     // 14
0359       "Aptus 54S",    // 15
0360       "Aptus 65S",    // 16
0361       "Aptus 75S",    // 17
0362       "AFi 5",        // 18
0363       "AFi 6",        // 19
0364       "AFi 7",        // 20
0365       "AFi-II 7",     // 21
0366       "Aptus-II 7",   // 22 (same CMs as Mamiya DM33)
0367       "",             // 23
0368       "Aptus-II 6",   // 24 (same CMs as Mamiya DM28)
0369       "AFi-II 10",    // 25
0370       "",             // 26
0371       "Aptus-II 10",  // 27 (same CMs as Mamiya DM56)
0372       "Aptus-II 5",   // 28 (same CMs as Mamiya DM22)
0373       "",             // 29
0374       "DM33",         // 30, make is Mamiya
0375       "",             // 31
0376       "",             // 32
0377       "Aptus-II 10R", // 33
0378       "Aptus-II 8",   // 34 (same CMs as Mamiya DM40)
0379       "",             // 35
0380       "Aptus-II 12",  // 36
0381       "",             // 37
0382       "AFi-II 12"     // 38
0383   };
0384   float romm_cam[3][3];
0385 
0386   fseek(ifp, offset, SEEK_SET);
0387   while (!feof(ifp))
0388   {
0389     if (get4() != 0x504b5453)
0390       break;
0391     get4();
0392     fread(data, 1, 40, ifp);
0393     skip = get4();
0394     from = ftell(ifp);
0395 
0396     if (!strcmp(data, "CameraObj_camera_type"))
0397     {
0398       stmread(ilm.body, (unsigned)skip, ifp);
0399       if (ilm.body[0])
0400       {
0401         if (!strncmp(ilm.body, "Mamiya R", 8))
0402         {
0403           ilm.CameraMount = LIBRAW_MOUNT_Mamiya67;
0404           ilm.CameraFormat = LIBRAW_FORMAT_67;
0405         }
0406         else if (!strncmp(ilm.body, "Hasselblad 5", 12))
0407         {
0408           ilm.CameraFormat = LIBRAW_FORMAT_66;
0409           ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V;
0410         }
0411         else if (!strncmp(ilm.body, "Hasselblad H", 12))
0412         {
0413           ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H;
0414           ilm.CameraFormat = LIBRAW_FORMAT_645;
0415         }
0416         else if (!strncmp(ilm.body, "Mamiya 6", 8) ||
0417                  !strncmp(ilm.body, "Phase One 6", 11))
0418         {
0419           ilm.CameraMount = LIBRAW_MOUNT_Mamiya645;
0420           ilm.CameraFormat = LIBRAW_FORMAT_645;
0421         }
0422         else if (!strncmp(ilm.body, "Large F", 7))
0423         {
0424           ilm.CameraMount = LIBRAW_MOUNT_LF;
0425           ilm.CameraFormat = LIBRAW_FORMAT_LF;
0426         }
0427         else if (!strncmp(model, "Leaf AFi", 8))
0428         {
0429           ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet;
0430           ilm.CameraFormat = LIBRAW_FORMAT_66;
0431         }
0432       }
0433     }
0434     if (!strcmp(data, "back_serial_number"))
0435     {
0436       char buffer[sizeof(imgdata.shootinginfo.BodySerial)];
0437       char *words[4] = {0, 0, 0, 0};
0438       stmread(buffer, (unsigned)skip, ifp);
0439       /*nwords = */
0440           getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.BodySerial));
0441       if(words[0])
0442         strcpy(imgdata.shootinginfo.BodySerial, words[0]);
0443     }
0444     if (!strcmp(data, "CaptProf_serial_number"))
0445     {
0446       char buffer[sizeof(imgdata.shootinginfo.InternalBodySerial)];
0447       char *words[4] = {0, 0, 0, 0};
0448       stmread(buffer, (unsigned)skip, ifp);
0449       getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.InternalBodySerial));
0450       if(words[0])
0451         strcpy(imgdata.shootinginfo.InternalBodySerial, words[0]);
0452     }
0453 
0454     if (!strcmp(data, "JPEG_preview_data"))
0455     {
0456       thumb_offset = from;
0457       thumb_length = skip;
0458     }
0459     if (!strcmp(data, "icc_camera_profile"))
0460     {
0461       profile_offset = from;
0462       profile_length = skip;
0463     }
0464     if (!strcmp(data, "ShootObj_back_type"))
0465     {
0466       fscanf(ifp, "%d", &i);
0467       if ((unsigned)i < sizeof mod / sizeof(*mod))
0468       {
0469         strcpy(model, mod[i]);
0470         if (!strncmp(model, "AFi", 3))
0471         {
0472           ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet;
0473           ilm.CameraFormat = LIBRAW_FORMAT_66;
0474         }
0475         ilm.CamID = i;
0476       }
0477     }
0478     if (!strcmp(data, "icc_camera_to_tone_matrix"))
0479     {
0480       for (i = 0; i < 9; i++)
0481         ((float *)romm_cam)[i] = int_to_float(get4());
0482       romm_coeff(romm_cam);
0483     }
0484     if (!strcmp(data, "CaptProf_color_matrix"))
0485     {
0486       for (i = 0; i < 9; i++)
0487         fscanf(ifp, "%f", (float *)romm_cam + i);
0488       romm_coeff(romm_cam);
0489     }
0490     if (!strcmp(data, "CaptProf_number_of_planes"))
0491       fscanf(ifp, "%d", &planes);
0492     if (!strcmp(data, "CaptProf_raw_data_rotation"))
0493       fscanf(ifp, "%d", &flip);
0494     if (!strcmp(data, "CaptProf_mosaic_pattern"))
0495       FORC4
0496       {
0497         fscanf(ifp, "%d", &i);
0498         if (i == 1)
0499           frot = c ^ (c >> 1); // 0123 -> 0132
0500       }
0501     if (!strcmp(data, "ImgProf_rotation_angle"))
0502     {
0503       fscanf(ifp, "%d", &i);
0504       flip = i - flip;
0505     }
0506     if (!strcmp(data, "NeutObj_neutrals") && !cam_mul[0])
0507     {
0508       FORC4 fscanf(ifp, "%d", neut + c);
0509       FORC3
0510       if (neut[c + 1])
0511         cam_mul[c] = (float)neut[0] / neut[c + 1];
0512     }
0513     if (!strcmp(data, "Rows_data"))
0514       load_flags = get4();
0515     parse_mos(from);
0516     fseek(ifp, skip + from, SEEK_SET);
0517   }
0518   if (planes)
0519     filters = (planes == 1) * 0x01010101U *
0520               (uchar) "\x94\x61\x16\x49"[(flip / 90 + frot) & 3];
0521 }