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::setLeicaBodyFeatures(int LeicaMakernoteSignature) 0018 { 0019 if (LeicaMakernoteSignature == -3) // M8 0020 { 0021 ilm.CameraFormat = LIBRAW_FORMAT_APSH; 0022 ilm.CameraMount = LIBRAW_MOUNT_Leica_M; 0023 } 0024 else if (LeicaMakernoteSignature == -2) // DMR 0025 { 0026 ilm.CameraFormat = LIBRAW_FORMAT_Leica_DMR; 0027 if ((model[0] == 'R') || (model[6] == 'R')) 0028 ilm.CameraMount = LIBRAW_MOUNT_Leica_R; 0029 } 0030 else if (LeicaMakernoteSignature == 0) // "DIGILUX 2" 0031 { 0032 ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; 0033 ilm.FocalType = LIBRAW_FT_ZOOM_LENS; 0034 } 0035 else if ((LeicaMakernoteSignature == 0x0100) || // X1 0036 (LeicaMakernoteSignature == 0x0500) || // X2, "X-E (Typ 102)" 0037 (LeicaMakernoteSignature == 0x0700) || // "X (Typ 113)" 0038 (LeicaMakernoteSignature == 0x1000)) // "X-U (Typ 113)" 0039 { 0040 ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; 0041 ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; 0042 ilm.FocalType = LIBRAW_FT_PRIME_LENS; 0043 } 0044 else if (LeicaMakernoteSignature == 0x0400) // "X VARIO (Typ 107)" 0045 { 0046 ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; 0047 ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; 0048 ilm.FocalType = LIBRAW_FT_ZOOM_LENS; 0049 } 0050 else if ((LeicaMakernoteSignature == 0051 0x0200) || // M10, M10-D, M10-R, "S (Typ 007)", M11 0052 (LeicaMakernoteSignature == 0053 0x02ff) || // "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)", 0054 // "M Monochrom (Typ 246)", "S (Typ 006)", "S-E (Typ 006)", S2, S3 0055 (LeicaMakernoteSignature == 0056 0x0300)) // M9, "M9 Monochrom", "M Monochrom", M-E 0057 { 0058 if ((model[0] == 'M') || (model[6] == 'M')) 0059 { 0060 ilm.CameraFormat = LIBRAW_FORMAT_FF; 0061 ilm.CameraMount = LIBRAW_MOUNT_Leica_M; 0062 } 0063 else if ((model[0] == 'S') || (model[6] == 'S')) 0064 { 0065 ilm.CameraFormat = LIBRAW_FORMAT_LeicaS; 0066 ilm.CameraMount = LIBRAW_MOUNT_Leica_S; 0067 } 0068 } 0069 else if ((LeicaMakernoteSignature == 0x0600) || // "T (Typ 701)", TL 0070 (LeicaMakernoteSignature == 0x0900) || // SL2, "SL2-S", "SL (Typ 601)", CL, Q2, "Q2 MONO" 0071 (LeicaMakernoteSignature == 0x1a00)) // TL2 0072 { 0073 if ((model[0] == 'S') || (model[6] == 'S')) 0074 { 0075 ilm.CameraFormat = LIBRAW_FORMAT_FF; 0076 ilm.CameraMount = LIBRAW_MOUNT_LPS_L; 0077 } 0078 else if ((model[0] == 'T') || (model[6] == 'T') || 0079 (model[0] == 'C') || (model[6] == 'C')) 0080 { 0081 ilm.CameraFormat = LIBRAW_FORMAT_APSC; 0082 ilm.CameraMount = LIBRAW_MOUNT_LPS_L; 0083 } 0084 else if (((model[0] == 'Q') || (model[6] == 'Q')) && 0085 ((model[1] == '2') || (model[7] == '2'))) 0086 { 0087 ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_FF; 0088 ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; 0089 ilm.FocalType = LIBRAW_FT_PRIME_LENS; 0090 } 0091 } 0092 else if (LeicaMakernoteSignature == 0x0800) // "Q (Typ 116)" 0093 { 0094 ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_FF; 0095 ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; 0096 ilm.FocalType = LIBRAW_FT_PRIME_LENS; 0097 } 0098 } 0099 0100 void LibRaw::parseLeicaLensID() 0101 { 0102 ilm.LensID = get4(); 0103 if (ilm.LensID) 0104 { 0105 ilm.LensID = ((ilm.LensID >> 2) << 8) | (ilm.LensID & 0x3); 0106 if ((ilm.LensID > 0x00ff) && (ilm.LensID < 0x3b00)) 0107 { 0108 ilm.LensMount = ilm.CameraMount; 0109 ilm.LensFormat = LIBRAW_FORMAT_FF; 0110 } 0111 } 0112 } 0113 0114 int LibRaw::parseLeicaLensName(unsigned len) 0115 { 0116 #define plln ilm.Lens 0117 if (!len) 0118 { 0119 strcpy(plln, "N/A"); 0120 return 0; 0121 } 0122 stmread(plln, len, ifp); 0123 if ((plln[0] == ' ') || !strncasecmp(plln, "not ", 4) || 0124 !strncmp(plln, "---", 3) || !strncmp(plln, "***", 3)) 0125 { 0126 strcpy(plln, "N/A"); 0127 return 0; 0128 } 0129 else 0130 return 1; 0131 #undef plln 0132 } 0133 0134 int LibRaw::parseLeicaInternalBodySerial(unsigned len) 0135 { 0136 #define plibs imgdata.shootinginfo.InternalBodySerial 0137 if (!len) 0138 { 0139 strcpy(plibs, "N/A"); 0140 return 0; 0141 } 0142 stmread(plibs, len, ifp); 0143 if (!strncmp(plibs, "000000000000", 12)) 0144 { 0145 plibs[0] = '0'; 0146 plibs[1] = '\0'; 0147 return 1; 0148 } 0149 0150 if (strnlen(plibs, len) == 13) 0151 { 0152 for (int i = 3; i < 13; i++) 0153 { 0154 if (!isdigit(plibs[i])) 0155 goto non_std; 0156 } 0157 memcpy(plibs + 15, plibs + 9, 4); 0158 memcpy(plibs + 12, plibs + 7, 2); 0159 memcpy(plibs + 9, plibs + 5, 2); 0160 memcpy(plibs + 6, plibs + 3, 2); 0161 plibs[3] = plibs[14] = ' '; 0162 plibs[8] = plibs[11] = '/'; 0163 if (((short)(plibs[3] - '0') * 10 + (short)(plibs[4] - '0')) < 70) 0164 { 0165 memcpy(plibs + 4, "20", 2); 0166 } 0167 else 0168 { 0169 memcpy(plibs + 4, "19", 2); 0170 } 0171 return 2; 0172 } 0173 non_std: 0174 #undef plibs 0175 return 1; 0176 } 0177 0178 void LibRaw::parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType) 0179 { 0180 int c; 0181 uchar ci, cj; 0182 unsigned entries, tag, type, len, save; 0183 short morder, sorder = order; 0184 char buf[10]; 0185 int LeicaMakernoteSignature = -1; 0186 INT64 fsize = ifp->size(); 0187 0188 fread(buf, 1, 10, ifp); 0189 if (strncmp(buf, "LEICA", 5)) 0190 { 0191 fseek(ifp, -10, SEEK_CUR); 0192 if (uptag == 0x3400) 0193 LeicaMakernoteSignature = 0x3400; 0194 else 0195 LeicaMakernoteSignature = -2; // DMR 0196 } 0197 else 0198 { 0199 fseek(ifp, -2, SEEK_CUR); 0200 LeicaMakernoteSignature = ((uchar)buf[6] << 8) | (uchar)buf[7]; 0201 // printf ("LeicaMakernoteSignature 0x%04x\n", LeicaMakernoteSignature); 0202 if (!LeicaMakernoteSignature && 0203 (!strncmp(model, "M8", 2) || !strncmp(model + 6, "M8", 2))) 0204 LeicaMakernoteSignature = -3; 0205 if ((LeicaMakernoteSignature != 0x0000) && 0206 (LeicaMakernoteSignature != 0x0200) && 0207 (LeicaMakernoteSignature != 0x0800) && 0208 (LeicaMakernoteSignature != 0x0900) && 0209 (LeicaMakernoteSignature != 0x02ff)) 0210 base = ftell(ifp) - 8; 0211 } 0212 setLeicaBodyFeatures(LeicaMakernoteSignature); 0213 0214 entries = get2(); 0215 if (entries > 1000) 0216 return; 0217 morder = order; 0218 0219 while (entries--) 0220 { 0221 order = morder; 0222 tiff_get(base, &tag, &type, &len, &save); 0223 0224 INT64 pos = ifp->tell(); 0225 if (len > 8 && pos + len > 2 * fsize) 0226 { 0227 fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! 0228 continue; 0229 } 0230 tag |= uptag << 16; 0231 if (len > 100 * 1024 * 1024) 0232 goto next; // 100Mb tag? No! 0233 0234 if (LeicaMakernoteSignature == -3) // M8 0235 { 0236 if (tag == 0x0310) 0237 { 0238 parseLeicaLensID(); 0239 } 0240 else if ((tag == 0x0313) && (fabs(ilm.CurAp) < 0.17f)) 0241 { 0242 ilm.CurAp = getreal(type); 0243 if (ilm.CurAp > 126.3) 0244 { 0245 ilm.CurAp = 0.0f; 0246 } else if (fabs(aperture) < 0.17f) 0247 aperture = ilm.CurAp; 0248 } 0249 else if (tag == 0x0320) 0250 { 0251 imCommon.CameraTemperature = getreal(type); 0252 } 0253 } 0254 else if (LeicaMakernoteSignature == -2) // DMR 0255 { 0256 if (tag == 0x000d) 0257 { 0258 FORC3 cam_mul[c] = get2(); 0259 cam_mul[3] = cam_mul[1]; 0260 } 0261 } 0262 else if (LeicaMakernoteSignature == 0) // "DIGILUX 2" 0263 { 0264 if (tag == 0x0007) 0265 { 0266 imgdata.shootinginfo.FocusMode = get2(); 0267 } 0268 else if (tag == 0x001a) 0269 { 0270 imgdata.shootinginfo.ImageStabilization = get2(); 0271 } 0272 } 0273 else if ((LeicaMakernoteSignature == 0x0100) || // X1 0274 (LeicaMakernoteSignature == 0x0400) || // "X VARIO" 0275 (LeicaMakernoteSignature == 0x0500) || // X2, "X-E (Typ 102)" 0276 (LeicaMakernoteSignature == 0x0700) || // "X (Typ 113)" 0277 (LeicaMakernoteSignature == 0x1000)) // "X-U (Typ 113)" 0278 { 0279 if (tag == 0x040d) 0280 { 0281 ci = fgetc(ifp); 0282 cj = fgetc(ifp); 0283 imgdata.shootinginfo.ExposureMode = ((ushort)ci << 8) | cj; 0284 } 0285 } 0286 else if ((LeicaMakernoteSignature == 0x0600) || // TL, "T (Typ 701)" 0287 (LeicaMakernoteSignature == 0x1a00)) // TL2 0288 { 0289 if (tag == 0x040d) 0290 { 0291 ci = fgetc(ifp); 0292 cj = fgetc(ifp); 0293 imgdata.shootinginfo.ExposureMode = ((ushort)ci << 8) | cj; 0294 } 0295 else if (tag == 0x0303) 0296 { 0297 parseLeicaLensName(len); 0298 } 0299 } 0300 else if (LeicaMakernoteSignature == 0x0200) // M10, M10-D, M10-R, "S (Typ 007)", M11 0301 { 0302 if ((tag == 0x035a) && (fabs(ilm.CurAp) < 0.17f)) 0303 { 0304 ilm.CurAp = get4() / 1000.0f; 0305 if (ilm.CurAp > 126.3) 0306 { 0307 ilm.CurAp = 0.0f; 0308 } else if (fabs(aperture) < 0.17f) 0309 aperture = ilm.CurAp; 0310 } 0311 } 0312 else if (LeicaMakernoteSignature == 0x02ff) 0313 // "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)" 0314 // "M Monochrom (Typ 246)" 0315 // "S (Typ 006)", "S-E (Typ 006)", S2, S3 0316 { 0317 if (tag == 0x0303) 0318 { 0319 if (parseLeicaLensName(len)) 0320 { 0321 ilm.LensMount = ilm.CameraMount; 0322 ilm.LensFormat = ilm.CameraFormat; 0323 } 0324 } 0325 } 0326 else if (LeicaMakernoteSignature == 0x0300) // M9, "M9 Monochrom", "M Monochrom", M-E 0327 { 0328 if (tag == 0x3400) 0329 { 0330 parseLeicaMakernote(base, 0x3400, MakernoteTagType); 0331 } 0332 } 0333 else if ((LeicaMakernoteSignature == 0x0800) || // "Q (Typ 116)" 0334 (LeicaMakernoteSignature == 0x0900)) // SL2, "SL2-S", "SL (Typ 601)", 0335 // CL, Q2, "Q2 MONO" 0336 { 0337 if ((tag == 0x0304) && (len == 1) && ((c = fgetc(ifp)) != 0) && 0338 (ilm.CameraMount == LIBRAW_MOUNT_LPS_L)) 0339 { 0340 strcpy(ilm.Adapter, "M-Adapter L"); 0341 ilm.LensMount = LIBRAW_MOUNT_Leica_M; 0342 ilm.LensFormat = LIBRAW_FORMAT_FF; 0343 if (c != 0xff) ilm.LensID = c * 256; 0344 } 0345 else if (tag == 0x0500) 0346 { 0347 parseLeicaInternalBodySerial(len); 0348 } 0349 } 0350 else if (LeicaMakernoteSignature == 0x3400) // tag 0x3400 in M9, "M9 Monochrom", "M Monochrom" 0351 { 0352 if (tag == 0x34003402) 0353 { 0354 imCommon.CameraTemperature = getreal(type); 0355 } 0356 else if (tag == 0x34003405) 0357 { 0358 parseLeicaLensID(); 0359 } 0360 else if ((tag == 0x34003406) && (fabs(ilm.CurAp) < 0.17f)) 0361 { 0362 ilm.CurAp = getreal(type); 0363 if (ilm.CurAp > 126.3) 0364 { 0365 ilm.CurAp = 0.0f; 0366 } else if (fabs(aperture) < 0.17f) 0367 aperture = ilm.CurAp; 0368 } 0369 } 0370 0371 next: 0372 fseek(ifp, save, SEEK_SET); 0373 } 0374 order = sorder; 0375 }