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 }