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

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw is free software; you can redistribute it and/or modify
0005  it under the terms of the one of two licenses as you choose:
0006 
0007 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0008    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0009 
0010 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0011    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0012 
0013  */
0014 
0015 #include "../../internal/dcraw_defs.h"
0016 
0017 void LibRaw::Kodak_KDC_WBtags(int wb, int wbi)
0018 {
0019   int c;
0020   FORC3 icWBC[wb][c] = get4();
0021   icWBC[wb][3] = icWBC[wb][1];
0022   if (wbi == wb)
0023     FORC4 cam_mul[c] = icWBC[wb][c];
0024   return;
0025 }
0026 
0027 void LibRaw::Kodak_DCR_WBtags(int wb, unsigned type, int wbi)
0028 {
0029   float mul[3] = {1.0f, 1.0f, 1.0f}, num, mul2;
0030   int c;
0031   FORC3 mul[c] = (num = getreal(type)) <= 0.001f ? 1.0f : num;
0032   icWBC[wb][1] = icWBC[wb][3] = mul[1];
0033   mul2 = mul[1] * mul[1];
0034   icWBC[wb][0] = mul2 / mul[0];
0035   icWBC[wb][2] = mul2 / mul[2];
0036   if (wbi == wb)
0037     FORC4 cam_mul[c] = icWBC[wb][c];
0038   return;
0039 }
0040 
0041 short LibRaw::KodakIllumMatrix(unsigned type, float *romm_camIllum)
0042 {
0043   int c, j, romm_camTemp[9], romm_camScale[3];
0044   if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL))
0045   {
0046     for (j = 0; j < 9; j++)
0047       ((float *)romm_camIllum)[j] = getreal(type);
0048     return 1;
0049   }
0050   else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG))
0051   {
0052     FORC3
0053     {
0054       romm_camScale[c] = 0;
0055       for (j = 0; j < 3; j++)
0056       {
0057         romm_camTemp[c * 3 + j] = get4();
0058         romm_camScale[c] += romm_camTemp[c * 3 + j];
0059       }
0060     }
0061     if ((romm_camScale[0] > 0x1fff) && (romm_camScale[1] > 0x1fff) &&
0062         (romm_camScale[2] > 0x1fff))
0063     {
0064       FORC3 for (j = 0; j < 3; j++)((float *)romm_camIllum)[c * 3 + j] =
0065           ((float)romm_camTemp[c * 3 + j]) / ((float)romm_camScale[c]);
0066       return 1;
0067     }
0068   }
0069   return 0;
0070 }
0071 
0072 /* Thanks to Alexey Danilchenko for wb as-shot parsing code */
0073 void LibRaw::parse_kodak_ifd(int base)
0074 {
0075   unsigned entries, tag, type, len, save;
0076   int c, wbi = -1;
0077 
0078   static const int wbtag_kdc[] = {
0079       LIBRAW_WBI_Auto,        // 64037 / 0xfa25
0080       LIBRAW_WBI_Fluorescent, // 64040 / 0xfa28
0081       LIBRAW_WBI_Tungsten,    // 64039 / 0xfa27
0082       LIBRAW_WBI_Daylight,    // 64041 / 0xfa29
0083       -1,
0084       -1,
0085       LIBRAW_WBI_Shade // 64042 / 0xfa2a
0086   };
0087 
0088   static const int wbtag_dcr[] = {
0089       LIBRAW_WBI_Daylight,    // 2120 / 0x0848
0090       LIBRAW_WBI_Tungsten,    // 2121 / 0x0849
0091       LIBRAW_WBI_Fluorescent, // 2122 / 0x084a
0092       LIBRAW_WBI_Flash,       // 2123 / 0x084b
0093       LIBRAW_WBI_Custom,      // 2124 / 0x084c
0094       LIBRAW_WBI_Auto         // 2125 / 0x084d
0095   };
0096 
0097   //  int a_blck = 0;
0098 
0099   entries = get2();
0100   if (entries > 1024)
0101     return;
0102   INT64 fsize = ifp->size();
0103   while (entries--)
0104   {
0105     tiff_get(base, &tag, &type, &len, &save);
0106     INT64 savepos = ftell(ifp);
0107     if (len > 8 && len + savepos > 2 * fsize)
0108     {
0109       fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0110       continue;
0111     }
0112     if (callbacks.exif_cb)
0113     {
0114       callbacks.exif_cb(callbacks.exifparser_data, tag | 0x20000, type, len,
0115                         order, ifp, base);
0116       fseek(ifp, savepos, SEEK_SET);
0117     }
0118     if (tag == 0x03eb) // 1003
0119       imgdata.sizes.raw_inset_crops[0].cleft = get2();
0120     else if (tag == 0x03ec) // 1004
0121       imgdata.sizes.raw_inset_crops[0].ctop = get2();
0122     else if (tag == 0x03ed) // 1005
0123       imgdata.sizes.raw_inset_crops[0].cwidth = get2();
0124     else if (tag == 0x03ee) // 1006
0125       imgdata.sizes.raw_inset_crops[0].cheight = get2();
0126     else if (tag == 0x03ef) // 1007
0127     {
0128       if (!strcmp(model, "EOS D2000C"))
0129         black = get2();
0130       else
0131         imKodak.BlackLevelTop = get2();
0132     }
0133     else if (tag == 0x03f0) // 1008
0134     {
0135       if (!strcmp(model, "EOS D2000C"))
0136       {
0137         if (black) // already set by tag 1007 (0x03ef)
0138           black = (black + get2()) / 2;
0139         else
0140           black = get2();
0141       }
0142       else
0143         imKodak.BlackLevelBottom = get2();
0144     }
0145 
0146     else if (tag == 0x03f1)
0147     { // 1009 Kodak TextualInfo
0148       if (len > 0)
0149       {
0150         char kti[1024];
0151         char *pkti;
0152         int nsym = MIN(len, 1023);
0153         fread(kti, 1, nsym, ifp);
0154         kti[nsym] = 0;
0155 #ifdef LIBRAW_WIN32_CALLS
0156         pkti = strtok(kti, "\x0a");
0157 #else
0158         char *last = 0;
0159         pkti = strtok_r(kti, "\x0a", &last);
0160 #endif
0161         while (pkti != NULL)
0162         {
0163           c = 12;
0164           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Camera body:", c)))
0165           {
0166             while ((pkti[c] == ' ') && (c < (int)strlen(pkti)))
0167             {
0168               c++;
0169             }
0170             strcpy(ilm.body, pkti + c);
0171           }
0172           c = 5;
0173           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Lens:", c)))
0174           {
0175             ilm.CurFocal = atoi(pkti + c);
0176           }
0177           c = 9;
0178           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Aperture:", c)))
0179           {
0180             while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
0181             {
0182               c++;
0183             }
0184             ilm.CurAp = atof(pkti + c);
0185           }
0186           c = 10;
0187           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "ISO Speed:", c)))
0188           {
0189             iso_speed = atoi(pkti + c);
0190           }
0191           c = 13;
0192           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Focal Length:", c)))
0193           {
0194             ilm.CurFocal = atoi(pkti + c);
0195           }
0196           c = 13;
0197           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Max Aperture:", c)))
0198           {
0199             while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
0200             {
0201               c++;
0202             }
0203             ilm.MaxAp4CurFocal = atof(pkti + c);
0204           }
0205           c = 13;
0206           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Min Aperture:", c)))
0207           {
0208             while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
0209             {
0210               c++;
0211             }
0212             ilm.MinAp4CurFocal = atof(pkti + c);
0213           }
0214 #ifdef LIBRAW_WIN32_CALLS
0215           pkti = strtok(NULL, "\x0a");
0216 #else
0217           pkti = strtok_r(NULL, "\x0a", &last);
0218 #endif
0219         }
0220       }
0221     }
0222 
0223     else if (tag == 0x03f3) // 1011
0224       imCommon.FlashEC = getreal(type);
0225 
0226     else if (tag == 0x03fc) // 1020
0227     {
0228       wbi = getint(type);
0229       if ((wbi >= 0) && (wbi < 6) && (wbi != -2))
0230         wbi = wbtag_dcr[wbi];
0231     }
0232     else if (tag == 0x03fd && len == 72) // 1021
0233     {                                    /* WB set in software */
0234       fseek(ifp, 40, SEEK_CUR);
0235       FORC3 cam_mul[c] = 2048.0 / fMAX(1.0f, get2());
0236       wbi = -2;
0237     }
0238 
0239     else if ((tag == 0x0406) && (len == 1)) // 1030
0240       imCommon.CameraTemperature = getreal(type);
0241     else if ((tag == 0x0413) && (len == 1)) // 1043
0242       imCommon.SensorTemperature = getreal(type);
0243     else if (tag == 0x0848) // 2120
0244       Kodak_DCR_WBtags(LIBRAW_WBI_Daylight, type, wbi);
0245     else if (tag == 0x0849) // 2121
0246       Kodak_DCR_WBtags(LIBRAW_WBI_Tungsten, type, wbi);
0247     else if (tag == 0x084a) // 2122
0248       Kodak_DCR_WBtags(LIBRAW_WBI_Fluorescent, type, wbi);
0249     else if (tag == 0x084b) // 2123
0250       Kodak_DCR_WBtags(LIBRAW_WBI_Flash, type, wbi);
0251     else if (tag == 0x084c) // 2124
0252       Kodak_DCR_WBtags(LIBRAW_WBI_Custom, type, wbi);
0253     else if (tag == 0x084d) // 2125
0254     {
0255       if (wbi == -1)
0256         wbi = LIBRAW_WBI_Auto;
0257       Kodak_DCR_WBtags(LIBRAW_WBI_Auto, type, wbi);
0258     }
0259     else if (tag == 0x089f) // 2207
0260       imKodak.ISOCalibrationGain = getreal(type);
0261     else if (tag == 0x0903) // 2307
0262       imKodak.AnalogISO = iso_speed = getreal(type);
0263     else if (tag == 0x090d) // 2317
0264       linear_table(len);
0265     else if (tag == 0x09ce) // 2510
0266       stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp);
0267     else if (tag == 0x0e92) // 3730
0268     {
0269       imKodak.val018percent = get2();
0270       imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
0271           imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
0272               (int)(((float)imKodak.val018percent) / 18.0f * 170.0f);
0273     }
0274     else if (tag == 0x0e93) // 3731
0275       imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
0276           imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
0277               imKodak.val170percent = get2();
0278     else if (tag == 0x0e94) // 3732
0279       imKodak.val100percent = get2();
0280     /*
0281         else if (tag == 0x1784)    // 6020
0282           iso_speed = getint(type);
0283     */
0284     else if (tag == 0xfa00) // 64000
0285       stmread(imgdata.shootinginfo.BodySerial, len, ifp);
0286     else if (tag == 0xfa0d) // 64013
0287     {
0288       wbi = fgetc(ifp);
0289       if ((wbi >= 0) && (wbi < 7))
0290         wbi = wbtag_kdc[wbi];
0291     }
0292     else if (tag == 0xfa13) // 64019
0293       width = getint(type);
0294     else if (tag == 0xfa14) // 64020
0295       height = (getint(type) + 1) & -2;
0296     /*
0297           height = getint(type);
0298 
0299         else if (tag == 0xfa16)  // 64022
0300           raw_width = get2();
0301         else if (tag == 0xfa17)  // 64023
0302           raw_height = get2();
0303     */
0304     else if (tag == 0xfa18) // 64024
0305     {
0306       imKodak.offset_left = getint(LIBRAW_EXIFTAG_TYPE_SSHORT);
0307       if (type != LIBRAW_EXIFTAG_TYPE_SSHORT)
0308         imKodak.offset_left += 1;
0309     }
0310     else if (tag == 0xfa19) // 64025
0311     {
0312       imKodak.offset_top = getint(LIBRAW_EXIFTAG_TYPE_SSHORT);
0313       if (type != LIBRAW_EXIFTAG_TYPE_SSHORT)
0314         imKodak.offset_top += 1;
0315     }
0316 
0317     else if (tag == 0xfa25) // 64037
0318       Kodak_KDC_WBtags(LIBRAW_WBI_Auto, wbi);
0319     else if (tag == 0xfa27) // 64039
0320       Kodak_KDC_WBtags(LIBRAW_WBI_Tungsten, wbi);
0321     else if (tag == 0xfa28) // 64040
0322       Kodak_KDC_WBtags(LIBRAW_WBI_Fluorescent, wbi);
0323     else if (tag == 0xfa29) // 64041
0324       Kodak_KDC_WBtags(LIBRAW_WBI_Daylight, wbi);
0325     else if (tag == 0xfa2a) // 64042
0326       Kodak_KDC_WBtags(LIBRAW_WBI_Shade, wbi);
0327 
0328     else if (tag == 0xfa31) // 64049
0329       imgdata.sizes.raw_inset_crops[0].cwidth = get2();
0330     else if (tag == 0xfa32) // 64050
0331       imgdata.sizes.raw_inset_crops[0].cheight = get2();
0332     else if (tag == 0xfa3e) // 64062
0333       imgdata.sizes.raw_inset_crops[0].cleft = get2();
0334     else if (tag == 0xfa3f) // 64063
0335       imgdata.sizes.raw_inset_crops[0].ctop = get2();
0336 
0337     else if (((tag == 0x07e4) || (tag == 0xfb01)) &&
0338              (len == 9)) // 2020 or 64257
0339     {
0340       if (KodakIllumMatrix(type, (float *)imKodak.romm_camDaylight))
0341       {
0342         romm_coeff(imKodak.romm_camDaylight);
0343       }
0344     }
0345     else if (((tag == 0x07e5) || (tag == 0xfb02)) &&
0346              (len == 9)) // 2021 or 64258
0347       KodakIllumMatrix(type, (float *)imKodak.romm_camTungsten);
0348     else if (((tag == 0x07e6) || (tag == 0xfb03)) &&
0349              (len == 9)) // 2022 or 64259
0350       KodakIllumMatrix(type, (float *)imKodak.romm_camFluorescent);
0351     else if (((tag == 0x07e7) || (tag == 0xfb04)) &&
0352              (len == 9)) // 2023 or 64260
0353       KodakIllumMatrix(type, (float *)imKodak.romm_camFlash);
0354     else if (((tag == 0x07e8) || (tag == 0xfb05)) &&
0355              (len == 9)) // 2024 or 64261
0356       KodakIllumMatrix(type, (float *)imKodak.romm_camCustom);
0357     else if (((tag == 0x07e9) || (tag == 0xfb06)) &&
0358              (len == 9)) // 2025 or 64262
0359       KodakIllumMatrix(type, (float *)imKodak.romm_camAuto);
0360 
0361     fseek(ifp, save, SEEK_SET);
0362   }
0363 }