File indexing completed on 2025-01-05 03:56:58

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 #include "../../internal/libraw_cameraids.h"
0021 
0022 void LibRaw::parse_exif_interop(int base)
0023 {
0024     unsigned entries, tag, type, len, save;
0025     char value[4] = { 0,0,0,0 };
0026     entries = get2();
0027     INT64 fsize = ifp->size();
0028     while (entries--)
0029     {
0030         tiff_get(base, &tag, &type, &len, &save);
0031 
0032         INT64 savepos = ftell(ifp);
0033         if (len > 8 && savepos + len > fsize * 2)
0034         {
0035             fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0036             continue;
0037         }
0038         if (callbacks.exif_cb)
0039         {
0040             callbacks.exif_cb(callbacks.exifparser_data, tag | 0x40000, type, len, order, ifp, base);
0041             fseek(ifp, savepos, SEEK_SET);
0042         }
0043 
0044         switch (tag)
0045         {
0046         case 0x0001: // InteropIndex
0047             fread(value, 1, MIN(4, len), ifp);
0048             if (strncmp(value, "R98", 3) == 0 &&
0049                 // Canon bug, when [Canon].ColorSpace = AdobeRGB,
0050                 // but [ExifIFD].ColorSpace = Uncalibrated and
0051                 // [InteropIFD].InteropIndex = "R98"
0052                 imgdata.color.ExifColorSpace == LIBRAW_COLORSPACE_Unknown)
0053                 imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_sRGB;
0054             else if (strncmp(value, "R03", 3) == 0)
0055                 imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
0056             break;
0057         }
0058         fseek(ifp, save, SEEK_SET);
0059     }
0060 }
0061 
0062 void LibRaw::parse_exif(int base)
0063 {
0064   unsigned entries, tag, type, len, save, c;
0065   double expo, ape;
0066 
0067   unsigned kodak = !strncmp(make, "EASTMAN", 7) && tiff_nifds < 3;
0068 
0069   if (!libraw_internal_data.unpacker_data.exif_subdir_offset)
0070   {
0071     libraw_internal_data.unpacker_data.exif_offset = base;
0072     libraw_internal_data.unpacker_data.exif_subdir_offset = ftell(ifp);
0073   }
0074 
0075   entries = get2();
0076   if (!strncmp(make, "Hasselblad", 10) && (tiff_nifds > 3) && (entries > 512))
0077     return;
0078   INT64 fsize = ifp->size();
0079   while (entries--)
0080   {
0081     tiff_get(base, &tag, &type, &len, &save);
0082 
0083     INT64 savepos = ftell(ifp);
0084     if (len > 8 && savepos + len > fsize * 2)
0085     {
0086       fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0087       continue;
0088     }
0089     if (callbacks.exif_cb)
0090     {
0091       callbacks.exif_cb(callbacks.exifparser_data, tag, type, len, order, ifp,
0092                         base);
0093       fseek(ifp, savepos, SEEK_SET);
0094     }
0095 
0096     switch (tag)
0097     {
0098     case 0xA005: // Interoperability IFD
0099         fseek(ifp, get4() + base, SEEK_SET);
0100         parse_exif_interop(base);
0101         break;
0102     case 0xA001: // ExifIFD.ColorSpace
0103         c = get2();
0104         if (c == 1 && imgdata.color.ExifColorSpace == LIBRAW_COLORSPACE_Unknown)
0105             imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_sRGB;
0106         else if (c == 2)
0107             imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
0108         break;
0109     case 0x9400:
0110       imCommon.exifAmbientTemperature = getreal(type);
0111       if ((imCommon.CameraTemperature > -273.15f) &&
0112           ((OlyID == OlyID_TG_5) ||
0113            (OlyID == OlyID_TG_6))
0114       )
0115         imCommon.CameraTemperature += imCommon.exifAmbientTemperature;
0116       break;
0117     case 0x9401:
0118       imCommon.exifHumidity = getreal(type);
0119       break;
0120     case 0x9402:
0121       imCommon.exifPressure = getreal(type);
0122       break;
0123     case 0x9403:
0124       imCommon.exifWaterDepth = getreal(type);
0125       break;
0126     case 0x9404:
0127       imCommon.exifAcceleration = getreal(type);
0128       break;
0129     case 0x9405:
0130       imCommon.exifCameraElevationAngle = getreal(type);
0131       break;
0132 
0133     case 0xa405: // FocalLengthIn35mmFormat
0134       imgdata.lens.FocalLengthIn35mmFormat = get2();
0135       break;
0136     case 0xa431: // BodySerialNumber
0137       stmread(imgdata.shootinginfo.BodySerial, len, ifp);
0138       break;
0139     case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard
0140       imgdata.lens.MinFocal = getreal(type);
0141       imgdata.lens.MaxFocal = getreal(type);
0142       imgdata.lens.MaxAp4MinFocal = getreal(type);
0143       imgdata.lens.MaxAp4MaxFocal = getreal(type);
0144       break;
0145     case 0xa435: // LensSerialNumber
0146       stmread(imgdata.lens.LensSerial, len, ifp);
0147       if (!strncmp(imgdata.lens.LensSerial, "----", 4))
0148         imgdata.lens.LensSerial[0] = '\0';
0149       break;
0150     case 0xa420: /* 42016, ImageUniqueID */
0151       stmread(imgdata.color.ImageUniqueID, len, ifp);
0152       break;
0153     case 0xc65d: /* 50781, RawDataUniqueID */
0154       imgdata.color.RawDataUniqueID[16] = 0;
0155       fread(imgdata.color.RawDataUniqueID, 1, 16, ifp);
0156       break;
0157     case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard
0158       imgdata.lens.dng.MinFocal = getreal(type);
0159       imgdata.lens.dng.MaxFocal = getreal(type);
0160       imgdata.lens.dng.MaxAp4MinFocal = getreal(type);
0161       imgdata.lens.dng.MaxAp4MaxFocal = getreal(type);
0162       break;
0163     case 0xc68b: /* 50827, OriginalRawFileName */
0164       stmread(imgdata.color.OriginalRawFileName, len, ifp);
0165       break;
0166     case 0xa433: // LensMake
0167       stmread(imgdata.lens.LensMake, len, ifp);
0168       break;
0169     case 0xa434: // LensModel
0170       stmread(imgdata.lens.Lens, len, ifp);
0171       if (!strncmp(imgdata.lens.Lens, "----", 4))
0172         imgdata.lens.Lens[0] = '\0';
0173       break;
0174     case 0x9205:
0175       imgdata.lens.EXIF_MaxAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f));
0176       break;
0177     case 0x829a: // 33434
0178       shutter = getreal(type);
0179       if (tiff_nifds > 0 && tiff_nifds <= LIBRAW_IFD_MAXCOUNT)
0180           tiff_ifd[tiff_nifds - 1].t_shutter = shutter;
0181       break;
0182     case 0x829d: // 33437, FNumber
0183       aperture = getreal(type);
0184       break;
0185     case 0x8827: // 34855
0186       iso_speed = get2();
0187       break;
0188     case 0x8831: // 34865
0189       if (iso_speed == 0xffff && !strncasecmp(make, "FUJI", 4))
0190         iso_speed = getreal(type);
0191       break;
0192     case 0x8832: // 34866
0193       if (iso_speed == 0xffff &&
0194           (!strncasecmp(make, "SONY", 4) || !strncasecmp(make, "CANON", 5)))
0195         iso_speed = getreal(type);
0196       break;
0197     case 0x9003: // 36867
0198     case 0x9004: // 36868
0199       get_timestamp(0);
0200       break;
0201     case 0x9201: // 37377
0202        if ((expo = -getreal(type)) < 128 && shutter == 0.)
0203        {
0204             shutter = libraw_powf64l(2.0, expo);
0205             if (tiff_nifds > 0 && tiff_nifds <= LIBRAW_IFD_MAXCOUNT)
0206               tiff_ifd[tiff_nifds - 1].t_shutter = shutter;
0207        }
0208       break;
0209     case 0x9202: // 37378 ApertureValue
0210       if ((fabs(ape = getreal(type)) < 256.0) && (!aperture))
0211         aperture = libraw_powf64l(2.0, ape / 2);
0212       break;
0213     case 0x9209: // 37385
0214       flash_used = getreal(type);
0215       break;
0216     case 0x920a: // 37386
0217       focal_len = getreal(type);
0218       break;
0219     case 0x927c: // 37500
0220 #ifndef USE_6BY9RPI
0221       if (((make[0] == '\0') && !strncmp(model, "ov5647", 6)) ||
0222           (!strncmp(make, "RaspberryPi", 11) &&
0223            (!strncmp(model, "RP_OV5647", 9) ||
0224             !strncmp(model, "RP_imx219", 9))))
0225 #else
0226       if (((make[0] == '\0') && !strncmp(model, "ov5647", 6)) ||
0227           (!strncmp(make, "RaspberryPi", 11) &&
0228               (!strncmp(model, "RP_", 3) || !strncmp(model,"imx477",6))))
0229 #endif
0230       {
0231         char mn_text[512];
0232         char *pos;
0233         char ccms[512];
0234         ushort l;
0235         float num;
0236 
0237         fgets(mn_text, MIN(len, 511), ifp);
0238         mn_text[511] = 0;
0239 
0240         pos = strstr(mn_text, "ev=");
0241         if (pos)
0242           imCommon.ExposureCalibrationShift = atof(pos + 3);
0243 
0244         pos = strstr(mn_text, "gain_r=");
0245         if (pos)
0246           cam_mul[0] = atof(pos + 7);
0247         pos = strstr(mn_text, "gain_b=");
0248         if (pos)
0249           cam_mul[2] = atof(pos + 7);
0250         if ((cam_mul[0] > 0.001f) && (cam_mul[2] > 0.001f))
0251           cam_mul[1] = cam_mul[3] = 1.0f;
0252         else
0253           cam_mul[0] = cam_mul[2] = 0.0f;
0254 
0255         pos = strstr(mn_text, "ccm=");
0256         if (pos)
0257         {
0258           pos += 4;
0259           char *pos2 = strstr(pos, " ");
0260           if (pos2)
0261           {
0262             l = pos2 - pos;
0263             memcpy(ccms, pos, l);
0264             ccms[l] = '\0';
0265 #ifdef LIBRAW_WIN32_CALLS
0266             // Win32 strtok is already thread-safe
0267             pos = strtok(ccms, ",");
0268 #else
0269             char *last = 0;
0270             pos = strtok_r(ccms, ",", &last);
0271 #endif
0272             if (pos)
0273             {
0274               for (l = 0; l < 3; l++) // skip last row
0275               {
0276                 num = 0.0;
0277                 for (c = 0; c < 3; c++)
0278                 {
0279                   cmatrix[l][c] = (float)atoi(pos);
0280                   num += cmatrix[c][l];
0281 #ifdef LIBRAW_WIN32_CALLS
0282                   pos = strtok(NULL, ",");
0283 #else
0284                   pos = strtok_r(NULL, ",", &last);
0285 #endif
0286                   if (!pos)
0287                     goto end; // broken
0288                 }
0289                 if (num > 0.01)
0290                     FORC3 cmatrix[l][c] = cmatrix[l][c] / num;
0291               }
0292             }
0293           }
0294         }
0295       end:;
0296       }
0297       else if (!strncmp(make, "SONY", 4) &&
0298                (!strncmp(model, "DSC-V3", 6) || !strncmp(model, "DSC-F828", 8)))
0299       {
0300         parseSonySRF(len);
0301         break;
0302       }
0303       else if ((len == 1) && !strncmp(make, "NIKON", 5))
0304       {
0305         c = get4();
0306         if (c)
0307           fseek(ifp, c, SEEK_SET);
0308         is_NikonTransfer = 1;
0309       }
0310       parse_makernote(base, 0);
0311       break;
0312     case 0xa002: // 40962
0313       if (kodak)
0314         raw_width = get4();
0315       break;
0316     case 0xa003: // 40963
0317       if (kodak)
0318         raw_height = get4();
0319       break;
0320     case 0xa302: // 41730
0321       if (get4() == 0x20002)
0322         for (exif_cfa = c = 0; c < 8; c += 2)
0323           exif_cfa |= fgetc(ifp) * 0x01010101U << c;
0324     }
0325     fseek(ifp, save, SEEK_SET);
0326   }
0327 }
0328 
0329 void LibRaw::parse_gps_libraw(int base)
0330 {
0331   unsigned entries, tag, type, len, save, c;
0332 
0333   entries = get2();
0334   if (entries > 40)
0335     return;
0336   if (entries > 0)
0337     imgdata.other.parsed_gps.gpsparsed = 1;
0338   INT64 fsize = ifp->size();
0339   while (entries--)
0340   {
0341     tiff_get(base, &tag, &type, &len, &save);
0342     if (len > 1024)
0343     {
0344       fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0345       continue;                   // no GPS tags are 1k or larger
0346     }
0347     INT64 savepos = ftell(ifp);
0348     if (len > 8 && savepos + len > fsize * 2)
0349     {
0350         fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0351         continue;
0352     }
0353 
0354     if (callbacks.exif_cb)
0355     {
0356         callbacks.exif_cb(callbacks.exifparser_data, tag | 0x50000, type, len, order, ifp, base);
0357         fseek(ifp, savepos, SEEK_SET);
0358     }
0359 
0360     switch (tag)
0361     {
0362     case 0x0001:
0363       imgdata.other.parsed_gps.latref = getc(ifp);
0364       break;
0365     case 0x0003:
0366       imgdata.other.parsed_gps.longref = getc(ifp);
0367       break;
0368     case 0x0005:
0369       imgdata.other.parsed_gps.altref = getc(ifp);
0370       break;
0371     case 0x0002:
0372       if (len == 3)
0373         FORC(3) imgdata.other.parsed_gps.latitude[c] = getreal(type);
0374       break;
0375     case 0x0004:
0376       if (len == 3)
0377         FORC(3) imgdata.other.parsed_gps.longitude[c] = getreal(type);
0378       break;
0379     case 0x0007:
0380       if (len == 3)
0381         FORC(3) imgdata.other.parsed_gps.gpstimestamp[c] = getreal(type);
0382       break;
0383     case 0x0006:
0384       imgdata.other.parsed_gps.altitude = getreal(type);
0385       break;
0386     case 0x0009:
0387       imgdata.other.parsed_gps.gpsstatus = getc(ifp);
0388       break;
0389     }
0390     fseek(ifp, save, SEEK_SET);
0391   }
0392 }
0393 
0394 void LibRaw::parse_gps(int base)
0395 {
0396   unsigned entries, tag, type, len, save, c;
0397 
0398   entries = get2();
0399   if (entries > 40)
0400     return;
0401   while (entries--)
0402   {
0403     tiff_get(base, &tag, &type, &len, &save);
0404     if (len > 1024)
0405     {
0406       fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0407       continue;                   // no GPS tags are 1k or larger
0408     }
0409     switch (tag)
0410     {
0411     case 0x0001:
0412     case 0x0003:
0413     case 0x0005:
0414       gpsdata[29 + tag / 2] = getc(ifp);
0415       break;
0416     case 0x0002:
0417     case 0x0004:
0418     case 0x0007:
0419       FORC(6) gpsdata[tag / 3 * 6 + c] = get4();
0420       break;
0421     case 0x0006:
0422       FORC(2) gpsdata[18 + c] = get4();
0423       break;
0424     case 0x0012: // 18
0425     case 0x001d: // 29
0426       fgets((char *)(gpsdata + 14 + tag / 3), MIN(len, 12), ifp);
0427     }
0428     fseek(ifp, save, SEEK_SET);
0429   }
0430 }