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

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004 
0005  LibRaw is free software; you can redistribute it and/or modify
0006  it under the terms of the one of two licenses as you choose:
0007 
0008 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0009    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0010 
0011 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0012    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0013 
0014  */
0015 #include "../../internal/dcraw_defs.h"
0016 #include "../../internal/libraw_cameraids.h"
0017 
0018 libraw_area_t LibRaw::get_CanonArea() {
0019   libraw_area_t la = {};
0020   la.l = get2();
0021   la.t = get2();
0022   la.r = get2();
0023   la.b = get2();
0024   return la;
0025 }
0026 
0027 float LibRaw::_CanonConvertAperture(ushort in)
0028 {
0029   if ((in == (ushort)0xffe0) || (in == (ushort)0x7fff))
0030     return 0.0f;
0031   return LibRaw::libraw_powf64l(2.f, float(in) / 64.f);
0032 }
0033 
0034 static float _CanonConvertEV(short in)
0035 {
0036   short EV, Sign, Frac;
0037   float Frac_f;
0038   EV = in;
0039   if (EV < 0)
0040   {
0041     EV = -EV;
0042     Sign = -1;
0043   }
0044   else
0045   {
0046     Sign = 1;
0047   }
0048   Frac = EV & 0x1f;
0049   EV -= Frac; // remove fraction
0050 
0051   if (Frac == 0x0c)
0052   { // convert 1/3 and 2/3 codes
0053     Frac_f = 32.0f / 3.0f;
0054   }
0055   else if (Frac == 0x14)
0056   {
0057     Frac_f = 64.0f / 3.0f;
0058   }
0059   else
0060     Frac_f = (float)Frac;
0061 
0062   return ((float)Sign * ((float)EV + Frac_f)) / 32.0f;
0063 }
0064 
0065 void LibRaw::setCanonBodyFeatures(unsigned long long id)
0066 {
0067 
0068   ilm.CamID = id;
0069   if ((id == CanonID_EOS_1D)           ||
0070       (id == CanonID_EOS_1D_Mark_II)   ||
0071       (id == CanonID_EOS_1D_Mark_II_N) ||
0072       (id == CanonID_EOS_1D_Mark_III)  ||
0073       (id == CanonID_EOS_1D_Mark_IV))
0074   {
0075     ilm.CameraFormat = LIBRAW_FORMAT_APSH;
0076     ilm.CameraMount = LIBRAW_MOUNT_Canon_EF;
0077   }
0078   else if ((id == CanonID_EOS_1Ds)           ||
0079            (id == CanonID_EOS_1Ds_Mark_II)   ||
0080            (id == CanonID_EOS_1Ds_Mark_III)  ||
0081            (id == CanonID_EOS_1D_X)          ||
0082            (id == CanonID_EOS_1D_X_Mark_II)  ||
0083            (id == CanonID_EOS_1D_X_Mark_III) ||
0084            (id == CanonID_EOS_1D_C)          ||
0085            (id == CanonID_EOS_5D)            ||
0086            (id == CanonID_EOS_5D_Mark_II)    ||
0087            (id == CanonID_EOS_5D_Mark_III)   ||
0088            (id == CanonID_EOS_5D_Mark_IV)    ||
0089            (id == CanonID_EOS_5DS)           ||
0090            (id == CanonID_EOS_5DS_R)         ||
0091            (id == CanonID_EOS_6D)            ||
0092            (id == CanonID_EOS_6D_Mark_II))
0093   {
0094     ilm.CameraFormat = LIBRAW_FORMAT_FF;
0095     ilm.CameraMount = LIBRAW_MOUNT_Canon_EF;
0096   }
0097   else if ((id == CanonID_EOS_M)             ||
0098            (id == CanonID_EOS_M2)            ||
0099            (id == CanonID_EOS_M3)            ||
0100            (id == CanonID_EOS_M5)            ||
0101            (id == CanonID_EOS_M10)           ||
0102            (id == CanonID_EOS_M50)           ||
0103            (id == CanonID_EOS_M50_Mark_II)   ||
0104            (id == CanonID_EOS_M6)            ||
0105            (id == CanonID_EOS_M6_Mark_II)    ||
0106            (id == CanonID_EOS_M100))
0107   {
0108     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
0109     ilm.CameraMount = LIBRAW_MOUNT_Canon_EF_M;
0110   }
0111   else if ((id == CanonID_EOS_R)  ||
0112            (id == CanonID_EOS_RP) ||
0113            (id == CanonID_EOS_R3) ||
0114            (id == CanonID_EOS_R5) ||
0115            (id == CanonID_EOS_R6))
0116   {
0117     ilm.CameraFormat = LIBRAW_FORMAT_FF;
0118     ilm.CameraMount = LIBRAW_MOUNT_Canon_RF;
0119     ilm.LensFormat = LIBRAW_FORMAT_FF;
0120     ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0121   }
0122 
0123   else if ((id == CanonID_EOS_R7)  ||
0124            (id == CanonID_EOS_R10))
0125   {
0126     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
0127     ilm.CameraMount = LIBRAW_MOUNT_Canon_RF;
0128     ilm.LensFormat = LIBRAW_FORMAT_APSC;
0129     ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0130   }
0131 
0132   else if ((id == CanonID_EOS_D30) ||
0133            (id == CanonID_EOS_D60) ||
0134            (id > 0x80000000ULL))
0135   {
0136     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
0137     ilm.CameraMount = LIBRAW_MOUNT_Canon_EF;
0138   }
0139 }
0140 
0141 int CanonCameraInfo_checkFirmwareRecordLocation (uchar *offset) {
0142 // firmware record location allows
0143 // to determine the subversion of the CameraInfo table
0144 // and to adjust offsets accordingly
0145     if (
0146                 isdigit(*offset)     &&
0147                 isdigit(*(offset+2)) &&
0148                 isdigit(*(offset+4)) &&
0149                 (*(offset+1) == '.') &&
0150                 (*(offset+3) == '.') &&
0151                 ((*(offset+5) == 0) || isspace(*(offset+5)))
0152             ) return 1;
0153   else return 0; // error
0154 }
0155 
0156 void LibRaw::processCanonCameraInfo(unsigned long long id, uchar *CameraInfo,
0157                                     unsigned maxlen, unsigned type, unsigned dng_writer)
0158 {
0159   ushort iCanonLensID = 0, iCanonMaxFocal = 0, iCanonMinFocal = 0,
0160          iCanonLens = 0, iCanonCurFocal = 0, iCanonFocalType = 0,
0161          iMakernotesFlip = 0,
0162          iHTP = 0, iALO = 0;
0163   short SubVersion_offset = 0;
0164   ushort SubVersion = 0, mgck = 0;
0165 
0166   if (maxlen < 16)
0167     return; // too short
0168 
0169   mgck = sget2(CameraInfo);
0170   CameraInfo[0] = 0;
0171   CameraInfo[1] = 0;
0172   if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) {
0173     if ((maxlen == 94)  || (maxlen == 138) || (maxlen == 148) ||
0174         (maxlen == 156) || (maxlen == 162) || (maxlen == 167) ||
0175         (maxlen == 171) || (maxlen == 264) || (maxlen > 400))
0176       imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 3) << 2)));
0177     else if (maxlen == 72)
0178       imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 1) << 2)));
0179     else if ((maxlen == 85) || (maxlen == 93))
0180       imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 2) << 2)));
0181     else if ((maxlen == 96) || (maxlen == 104))
0182       imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 4) << 2)));
0183   }
0184 
0185   switch (id)
0186   {
0187   case CanonID_EOS_1D:
0188   case CanonID_EOS_1Ds:
0189     iCanonCurFocal  =  0x0a;
0190     iCanonLensID    =  0x0d;
0191     iCanonMinFocal  =  0x0e;
0192     iCanonMaxFocal  =  0x10;
0193     if (!ilm.CurFocal)
0194       ilm.CurFocal = sget2(CameraInfo + iCanonCurFocal);
0195     if (!ilm.MinFocal)
0196       ilm.MinFocal = sget2(CameraInfo + iCanonMinFocal);
0197     if (!ilm.MaxFocal)
0198       ilm.MaxFocal = sget2(CameraInfo + iCanonMaxFocal);
0199     imCommon.CameraTemperature = 0.0f;
0200     break;
0201 
0202   case CanonID_EOS_1D_Mark_II:
0203   case CanonID_EOS_1Ds_Mark_II:
0204     iCanonCurFocal  =  0x09;
0205     iCanonLensID    =  0x0c;
0206     iCanonMinFocal  =  0x11;
0207     iCanonMaxFocal  =  0x13;
0208     iCanonFocalType =  0x2d;
0209     break;
0210 
0211   case CanonID_EOS_1D_Mark_II_N:
0212     iCanonCurFocal  =  0x09;
0213     iCanonLensID    =  0x0c;
0214     iCanonMinFocal  =  0x11;
0215     iCanonMaxFocal  =  0x13;
0216     break;
0217 
0218   case CanonID_EOS_1D_Mark_III:
0219   case CanonID_EOS_1Ds_Mark_III:
0220     iCanonCurFocal  =  0x1d;
0221     iMakernotesFlip =  0x30;
0222     iCanonLensID    = 0x111;
0223     iCanonMinFocal  = 0x113;
0224     iCanonMaxFocal  = 0x115;
0225     break;
0226 
0227   case CanonID_EOS_1D_Mark_IV:
0228     if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1e8))
0229       SubVersion = 1;
0230     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1ed))
0231       SubVersion = 2;
0232 // printf ("==>> CanonID_EOS_1D_Mark_IV, SubVersion: %d\n", SubVersion);
0233     iHTP            =  0x07;
0234     iCanonCurFocal  =  0x1e;
0235     iMakernotesFlip =  0x35;
0236 
0237     if (!SubVersion)
0238       break;
0239     else if (SubVersion < 2)
0240       SubVersion_offset += -1;
0241 
0242     iCanonLensID    = 0x14f+SubVersion_offset;
0243     iCanonMinFocal  = 0x151+SubVersion_offset;
0244     iCanonMaxFocal  = 0x153+SubVersion_offset;
0245     break;
0246 
0247   case CanonID_EOS_1D_X:
0248     if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x271))
0249       SubVersion = 1;
0250     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x279))
0251       SubVersion = 2;
0252     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x280))
0253       SubVersion = 3;
0254     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x285))
0255       SubVersion = 4;
0256 // printf ("==>> CanonID_EOS_1D_X, SubVersion: %d\n", SubVersion);
0257 
0258     if (SubVersion < 3)
0259       SubVersion_offset += -3;
0260 
0261     iCanonCurFocal  =  0x23+SubVersion_offset;
0262     iMakernotesFlip =  0x7d+SubVersion_offset;
0263 
0264     if (SubVersion < 3)
0265       SubVersion_offset += -4;
0266     else if (SubVersion == 4)
0267       SubVersion_offset += 5;
0268 
0269     iCanonLensID    = 0x1a7+SubVersion_offset;
0270     iCanonMinFocal  = 0x1a9+SubVersion_offset;
0271     iCanonMaxFocal  = 0x1ab+SubVersion_offset;
0272     break;
0273 
0274   case CanonID_EOS_5D:
0275     iMakernotesFlip =  0x27;
0276     iCanonCurFocal  =  0x28;
0277     iCanonLensID    =  0x0c;
0278     if (!sget2Rev(CameraInfo + iCanonLensID))
0279       iCanonLensID  =  0x97;
0280     iCanonMinFocal  =  0x93;
0281     iCanonMaxFocal  =  0x95;
0282     break;
0283 
0284   case CanonID_EOS_5D_Mark_II:
0285     iHTP            =  0x07;
0286     iCanonCurFocal  =  0x1e;
0287     iMakernotesFlip =  0x31;
0288     iALO            =  0xbf;
0289     iCanonLensID    =  0xe6;
0290     iCanonMinFocal  =  0xe8;
0291     iCanonMaxFocal  =  0xea;
0292     break;
0293 
0294   case CanonID_EOS_5D_Mark_III:
0295     if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x22c))
0296       SubVersion = 1;
0297     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x22d))
0298       SubVersion = 2;
0299     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x23c))
0300       SubVersion = 3;
0301     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x242))
0302       SubVersion = 4;
0303     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x247))
0304       SubVersion = 5;
0305 // printf ("==>> CanonID_EOS_5D_Mark_III, SubVersion: %d\n", SubVersion);
0306 
0307     if (!SubVersion)
0308       break;
0309     else if (SubVersion < 3)
0310       SubVersion_offset += -1;
0311 
0312     iCanonCurFocal  =  0x23+SubVersion_offset;
0313 
0314     if (SubVersion == 1)
0315       SubVersion_offset += -3;
0316     else if (SubVersion == 2)
0317       SubVersion_offset += -2;
0318     else if (SubVersion >= 4)
0319       SubVersion_offset += 6;
0320 
0321     iMakernotesFlip =  0x7d+SubVersion_offset;
0322 
0323     if (SubVersion < 3)
0324       SubVersion_offset += -4;
0325     else if (SubVersion > 4)
0326       SubVersion_offset += 5;
0327 
0328     iCanonLensID    = 0x153+SubVersion_offset;
0329     iCanonMinFocal  = 0x155+SubVersion_offset;
0330     iCanonMaxFocal  = 0x157+SubVersion_offset;
0331     break;
0332 
0333   case CanonID_EOS_6D:
0334     iCanonCurFocal  =  0x23;
0335     iMakernotesFlip =  0x83;
0336     iCanonLensID    = 0x161;
0337     iCanonMinFocal  = 0x163;
0338     iCanonMaxFocal  = 0x165;
0339     break;
0340 
0341   case CanonID_EOS_7D:
0342     if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1a8))
0343       SubVersion = 1;
0344     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1ac))
0345       SubVersion = 2;
0346 // printf ("==>> CanonID_EOS_7D, SubVersion: %d\n", SubVersion);
0347     iHTP            =  0x07;
0348     iCanonCurFocal  =  0x1e;
0349 
0350     if (!SubVersion)
0351       break;
0352     else if (SubVersion < 2)
0353       SubVersion_offset += -4;
0354 
0355     iMakernotesFlip =  0x35+SubVersion_offset;
0356     iCanonLensID    = 0x112+SubVersion_offset;
0357     iCanonMinFocal  = 0x114+SubVersion_offset;
0358     iCanonMaxFocal  = 0x116+SubVersion_offset;
0359     break;
0360 
0361   case CanonID_EOS_40D:
0362     iCanonCurFocal  =  0x1d;
0363     iMakernotesFlip =  0x30;
0364     iCanonLensID    =  0xd6;
0365     iCanonMinFocal  =  0xd8;
0366     iCanonMaxFocal  =  0xda;
0367     iCanonLens      = 0x92b;
0368     break;
0369 
0370   case CanonID_EOS_50D:
0371     iHTP            =  0x07;
0372     iCanonCurFocal  =  0x1e;
0373     iMakernotesFlip =  0x31;
0374     iALO            =  0xbf;
0375     iCanonLensID    =  0xea;
0376     iCanonMinFocal  =  0xec;
0377     iCanonMaxFocal  =  0xee;
0378     break;
0379 
0380   case CanonID_EOS_60D:
0381   case CanonID_EOS_1200D:
0382     iCanonCurFocal  =  0x1e;
0383     if (id == CanonID_EOS_60D)
0384       iMakernotesFlip =  0x36;
0385     else
0386       iMakernotesFlip =  0x3a;
0387     iCanonLensID    =  0xe8;
0388     iCanonMinFocal  =  0xea;
0389     iCanonMaxFocal  =  0xec;
0390     break;
0391 
0392   case CanonID_EOS_70D:
0393     iCanonCurFocal  =  0x23;
0394     iMakernotesFlip =  0x84;
0395     iCanonLensID    = 0x166;
0396     iCanonMinFocal  = 0x168;
0397     iCanonMaxFocal  = 0x16a;
0398     break;
0399 
0400   case CanonID_EOS_80D:
0401     iCanonCurFocal  =  0x23;
0402     iMakernotesFlip =  0x96;
0403     iCanonLensID    = 0x189;
0404     iCanonMinFocal  = 0x18b;
0405     iCanonMaxFocal  = 0x18d;
0406     break;
0407 
0408   case CanonID_EOS_450D:
0409     iCanonCurFocal  =  0x1d;
0410     iMakernotesFlip =  0x30;
0411     iCanonLensID    =  0xde;
0412     iCanonLens      = 0x933;
0413     break;
0414 
0415   case CanonID_EOS_500D:
0416     iHTP            =  0x07;
0417     iCanonCurFocal  =  0x1e;
0418     iMakernotesFlip =  0x31;
0419     iALO            =  0xbe;
0420     iCanonLensID    =  0xf6;
0421     iCanonMinFocal  =  0xf8;
0422     iCanonMaxFocal  =  0xfa;
0423     break;
0424 
0425   case CanonID_EOS_550D:
0426     iHTP            =  0x07;
0427     iCanonCurFocal  =  0x1e;
0428     iMakernotesFlip =  0x35;
0429     iCanonLensID    =  0xff;
0430     iCanonMinFocal  = 0x101;
0431     iCanonMaxFocal  = 0x103;
0432     break;
0433 
0434   case CanonID_EOS_600D:
0435   case CanonID_EOS_1100D:
0436     iHTP            =  0x07;
0437     iCanonCurFocal  =  0x1e;
0438     iMakernotesFlip =  0x38;
0439     iCanonLensID    =  0xea;
0440     iCanonMinFocal  =  0xec;
0441     iCanonMaxFocal  =  0xee;
0442     break;
0443 
0444   case CanonID_EOS_650D:
0445   case CanonID_EOS_700D:
0446     iCanonCurFocal  =  0x23;
0447     iMakernotesFlip =  0x7d;
0448     iCanonLensID    = 0x127;
0449     iCanonMinFocal  = 0x129;
0450     iCanonMaxFocal  = 0x12b;
0451     break;
0452 
0453   case CanonID_EOS_750D:
0454   case CanonID_EOS_760D:
0455     iCanonCurFocal  =  0x23;
0456     iMakernotesFlip =  0x96;
0457     iCanonLensID    = 0x184;
0458     iCanonMinFocal  = 0x186;
0459     iCanonMaxFocal  = 0x188;
0460     break;
0461 
0462   case CanonID_EOS_1000D:
0463     iCanonCurFocal  =  0x1d;
0464     iMakernotesFlip =  0x30;
0465     iCanonLensID    =  0xe2;
0466     iCanonMinFocal  =  0xe4;
0467     iCanonMaxFocal  =  0xe6;
0468     iCanonLens      = 0x937;
0469     break;
0470   }
0471 
0472   if (iMakernotesFlip && (CameraInfo[iMakernotesFlip] < 3)) {
0473     imCanon.MakernotesFlip = "065"[CameraInfo[iMakernotesFlip]] - '0';
0474 // printf ("==>> iMakernotesFlip: 0x%x, flip: %d\n", iMakernotesFlip, imCanon.MakernotesFlip);
0475   } else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&
0476      (mgck == 0xaaaa) && (dng_writer == nonDNG)) { // CameraOrientation
0477     int c, i;
0478     for (i = 2; (sget2(CameraInfo+i) != 0xbbbb) && i < (int)maxlen; i++);
0479     i+=2;
0480     while (i < int(maxlen - 5))
0481       if ((sget4(CameraInfo+i) == 257) && ((c = CameraInfo[i+8]) < 3)) {
0482         imCanon.MakernotesFlip = "065"[c] - '0';
0483 // printf ("==>> MakernotesFlip offset: 0x%x, flip: %d\n", i+8, imCanon.MakernotesFlip);
0484         break;
0485       } else i+=4;
0486   }
0487 
0488   if (iHTP)
0489   {
0490     imCanon.HighlightTonePriority = CameraInfo[iHTP];
0491     if ((imCanon.HighlightTonePriority > 5) ||
0492         (imCanon.HighlightTonePriority < 0))
0493       imCanon.HighlightTonePriority = 0;
0494     if (imCanon.HighlightTonePriority) {
0495       imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority);
0496     }
0497   }
0498   if (iALO)
0499   {
0500     imCanon.AutoLightingOptimizer = CameraInfo[iALO];
0501     if ((imCanon.AutoLightingOptimizer > 3) ||
0502         (imCanon.AutoLightingOptimizer < 0))
0503       imCanon.AutoLightingOptimizer = 3;
0504   }
0505   if (iCanonFocalType)
0506   {
0507     if (iCanonFocalType >= maxlen)
0508       return; // broken;
0509     ilm.FocalType = CameraInfo[iCanonFocalType];
0510     if (!ilm.FocalType) // zero means 'prime' here, replacing with standard '1'
0511       ilm.FocalType = LIBRAW_FT_PRIME_LENS;
0512   }
0513   if (!ilm.CurFocal && iCanonCurFocal)
0514   {
0515     if (iCanonCurFocal >= maxlen)
0516       return; // broken;
0517     ilm.CurFocal = sget2Rev(CameraInfo + iCanonCurFocal);
0518   }
0519   if (!ilm.LensID && iCanonLensID)
0520   {
0521     if (iCanonLensID >= maxlen)
0522       return; // broken;
0523     ilm.LensID = sget2Rev(CameraInfo + iCanonLensID);
0524   }
0525   if (!ilm.MinFocal && iCanonMinFocal)
0526   {
0527     if (iCanonMinFocal >= maxlen)
0528       return; // broken;
0529     ilm.MinFocal = sget2Rev(CameraInfo + iCanonMinFocal);
0530   }
0531   if (!ilm.MaxFocal && iCanonMaxFocal)
0532   {
0533     if (iCanonMaxFocal >= maxlen)
0534       return; // broken;
0535     ilm.MaxFocal = sget2Rev(CameraInfo + iCanonMaxFocal);
0536   }
0537   if (!ilm.Lens[0] && iCanonLens)
0538   {
0539     if (iCanonLens + 64 >= (int)maxlen) // broken;
0540       return;
0541 
0542     char *pl = (char *)CameraInfo + iCanonLens;
0543     if (!strncmp(pl, "EF-S", 4))
0544     {
0545       memcpy(ilm.Lens, pl, 4);
0546       ilm.Lens[4] = ' ';
0547       memcpy(ilm.LensFeatures_pre, pl, 4);
0548       ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S;
0549       ilm.LensFormat = LIBRAW_FORMAT_APSC;
0550       memcpy(ilm.Lens + 5, pl + 4, 60);
0551     }
0552     else if (!strncmp(pl, "EF-M", 4))
0553     {
0554       memcpy(ilm.Lens, pl, 4);
0555       ilm.Lens[4] = ' ';
0556       memcpy(ilm.LensFeatures_pre, pl, 4);
0557       ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M;
0558       ilm.LensFormat = LIBRAW_FORMAT_APSC;
0559       memcpy(ilm.Lens + 5, pl + 4, 60);
0560     }
0561     else if (!strncmp(pl, "EF", 2))
0562     {
0563       memcpy(ilm.Lens, pl, 2);
0564       ilm.Lens[2] = ' ';
0565       memcpy(ilm.LensFeatures_pre, pl, 2);
0566       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0567       ilm.LensFormat = LIBRAW_FORMAT_FF;
0568       memcpy(ilm.Lens + 3, pl + 2, 62);
0569     }
0570     else if (!strncmp(ilm.Lens, "CN-E", 4))
0571     {
0572       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
0573       ilm.Lens[4] = ' ';
0574       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
0575       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0576       ilm.LensFormat = LIBRAW_FORMAT_FF;
0577     }
0578     else if (!strncmp(pl, "TS-E", 4))
0579     {
0580       memcpy(ilm.Lens, pl, 4);
0581       ilm.Lens[4] = ' ';
0582       memcpy(ilm.LensFeatures_pre, pl, 4);
0583       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0584       ilm.LensFormat = LIBRAW_FORMAT_FF;
0585       memcpy(ilm.Lens + 5, pl + 4, 60);
0586     }
0587     else if (!strncmp(pl, "MP-E", 4))
0588     {
0589       memcpy(ilm.Lens, pl, 4);
0590       ilm.Lens[4] = ' ';
0591       memcpy(ilm.LensFeatures_pre, pl, 4);
0592       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0593       ilm.LensFormat = LIBRAW_FORMAT_FF;
0594       memcpy(ilm.Lens + 5, pl + 4, 60);
0595     }
0596     else // non-Canon lens
0597       memcpy(ilm.Lens, pl, 64);
0598   }
0599   return;
0600 }
0601 
0602 void LibRaw::Canon_CameraSettings(unsigned len)
0603 {
0604   fseek(ifp, 6, SEEK_CUR);
0605   imCanon.Quality = get2();   // 3
0606   get2();
0607   imgdata.shootinginfo.DriveMode = get2(); // 5
0608   get2();
0609   imgdata.shootinginfo.FocusMode = get2(); // 7
0610   imCanon.RecordMode = (get2(), get2());   // 9, format
0611   fseek(ifp, 14, SEEK_CUR);
0612   imgdata.shootinginfo.MeteringMode = get2(); // 17
0613   get2();
0614   imgdata.shootinginfo.AFPoint = get2();      // 19
0615   imgdata.shootinginfo.ExposureMode = get2(); // 20
0616   get2();
0617   ilm.LensID = get2();          // 22
0618   ilm.MaxFocal = get2();        // 23
0619   ilm.MinFocal = get2();        // 24
0620   ilm.FocalUnits = get2();      // 25
0621   if (ilm.FocalUnits > 1)
0622   {
0623     ilm.MaxFocal /= (float)ilm.FocalUnits;
0624     ilm.MinFocal /= (float)ilm.FocalUnits;
0625   }
0626   ilm.MaxAp = _CanonConvertAperture(get2()); // 26
0627   ilm.MinAp = _CanonConvertAperture(get2()); // 27
0628   if (len >= 36)
0629   {
0630     fseek(ifp, 12, SEEK_CUR);
0631     imgdata.shootinginfo.ImageStabilization = get2(); // 34
0632   }
0633   else
0634     return;
0635   if (len >= 48)
0636   {
0637     fseek(ifp, 22, SEEK_CUR);
0638     imCanon.SRAWQuality = get2(); // 46
0639   }
0640 }
0641 
0642 void LibRaw::Canon_WBpresets(int skip1, int skip2)
0643 {
0644   int c;
0645   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][RGGB_2_RGBG(c)] = get2();
0646 
0647   if (skip1)
0648     fseek(ifp, skip1, SEEK_CUR);
0649   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][RGGB_2_RGBG(c)] = get2();
0650 
0651   if (skip1)
0652     fseek(ifp, skip1, SEEK_CUR);
0653   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][RGGB_2_RGBG(c)] = get2();
0654 
0655   if (skip1)
0656     fseek(ifp, skip1, SEEK_CUR);
0657   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][RGGB_2_RGBG(c)] = get2();
0658 
0659   if (skip1)
0660     fseek(ifp, skip1, SEEK_CUR);
0661   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][RGGB_2_RGBG(c)] = get2();
0662 
0663   if (skip2)
0664     fseek(ifp, skip2, SEEK_CUR);
0665   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][RGGB_2_RGBG(c)] = get2();
0666 
0667   return;
0668 }
0669 
0670 void LibRaw::Canon_WBCTpresets(short WBCTversion)
0671 {
0672 
0673   int i;
0674   float norm;
0675 
0676   if (WBCTversion == 0)
0677   { // tint, as shot R, as shot B, CСT
0678     for (i = 0; i < 15; i++)
0679     {
0680       icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f;
0681       fseek(ifp, 2, SEEK_CUR);
0682       icWBCCTC[i][1] = 1024.0f / fMAX(get2(), 1.f);
0683       icWBCCTC[i][3] = 1024.0f / fMAX(get2(), 1.f);
0684       icWBCCTC[i][0] = get2();
0685     }
0686   }
0687   else if (WBCTversion == 1)
0688   { // as shot R, as shot B, tint, CСT
0689     for (i = 0; i < 15; i++)
0690     {
0691       icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f;
0692       icWBCCTC[i][1] = 1024.0f / fMAX(get2(), 1.f);
0693       icWBCCTC[i][3] = 1024.0f / fMAX(get2(), 1.f);
0694       fseek(ifp, 2, SEEK_CUR);
0695       icWBCCTC[i][0] = get2();
0696     }
0697   }
0698   else if (WBCTversion == 2)
0699   { // tint, offset, as shot R, as shot B, CСT
0700     if ((unique_id == CanonID_EOS_M3)  ||
0701         (unique_id == CanonID_EOS_M10) ||
0702         (imCanon.ColorDataSubVer == 0xfffc))
0703     {
0704       for (i = 0; i < 15; i++)
0705       {
0706         fseek(ifp, 4, SEEK_CUR);
0707         icWBCCTC[i][2] = icWBCCTC[i][4] =
0708             1.0f;
0709         icWBCCTC[i][1] = 1024.0f / fMAX(1.f, get2());
0710         icWBCCTC[i][3] = 1024.0f / fMAX(1.f, get2());
0711         icWBCCTC[i][0] = get2();
0712       }
0713     }
0714     else if (imCanon.ColorDataSubVer == 0xfffd)
0715     {
0716       for (i = 0; i < 15; i++)
0717       {
0718         fseek(ifp, 2, SEEK_CUR);
0719         norm = (signed short)get2();
0720         norm = 512.0f + norm / 8.0f;
0721         icWBCCTC[i][2] = icWBCCTC[i][4] =
0722             1.0f;
0723         icWBCCTC[i][1] = (float)get2();
0724         if (norm > 0.001f)
0725           icWBCCTC[i][1] /= norm;
0726         icWBCCTC[i][3] = (float)get2();
0727         if (norm > 0.001f)
0728           icWBCCTC[i][3] /= norm;
0729         icWBCCTC[i][0] = get2();
0730       }
0731     }
0732   }
0733   return;
0734 }
0735 
0736 void LibRaw::parseCanonMakernotes(unsigned tag, unsigned /*type*/, unsigned len, unsigned dng_writer)
0737 {
0738 
0739 #define AsShot_Auto_MeasuredWB(offset)                       \
0740   imCanon.ColorDataSubVer = get2();                          \
0741   fseek(ifp, save1 + (offset << 1), SEEK_SET);               \
0742   FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2();             \
0743   get2();                                                    \
0744   FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();     \
0745   get2();                                                    \
0746   FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] = get2();
0747 
0748 #define sRAW_WB(offset)                                      \
0749   fseek(ifp, save1 + (offset << 1), SEEK_SET);               \
0750   FORC4 {                                                    \
0751     sraw_mul[RGGB_2_RGBG(c)] = get2();                       \
0752     if ((float)sraw_mul[RGGB_2_RGBG(c)] > sraw_mul_max) {    \
0753       sraw_mul_max = (float)sraw_mul[RGGB_2_RGBG(c)];        \
0754     }                                                        \
0755   }                                                          \
0756   sraw_mul_max /= 1024.f;                                    \
0757   FORC4 sraw_mul[c] = (ushort)((float)sraw_mul[c] * sraw_mul_max);
0758 
0759 #define CR3_ColorData(offset)                                \
0760   fseek(ifp, save1 + ((offset+0x0041) << 1), SEEK_SET);      \
0761   Canon_WBpresets(2, 12);                                    \
0762   fseek(ifp, save1 + ((offset+0x00c3) << 1), SEEK_SET);      \
0763   Canon_WBCTpresets(0);                                      \
0764   offsetChannelBlackLevel2 = save1 + ((offset+0x0102) << 1); \
0765   offsetChannelBlackLevel  = save1 + ((offset+0x02d1) << 1); \
0766   offsetWhiteLevels        = save1 + ((offset+0x02d5) << 1);
0767 
0768   int c;
0769   unsigned i;
0770 
0771   if (tag == 0x0001) {
0772     Canon_CameraSettings(len);
0773 
0774   } else if (tag == 0x0002) { // focal length
0775     ilm.FocalType = get2();
0776     ilm.CurFocal = get2();
0777     if (ilm.FocalUnits > 1) {
0778       ilm.CurFocal /= (float)ilm.FocalUnits;
0779     }
0780 
0781   } else if (tag == 0x0004) { // subdir, ShotInfo
0782     short tempAp;
0783     if (dng_writer == nonDNG) {
0784       get2();
0785       imCanon.ISOgain[0] = get2();
0786       imCanon.ISOgain[1] = get2();
0787       if (imCanon.ISOgain[1] != 0x7fff) {
0788         imCommon.real_ISO = floorf(100.f * libraw_powf64l(2.f, float(imCanon.ISOgain[0]+imCanon.ISOgain[1]) / 32.f - 5.f));
0789         if (!iso_speed || (iso_speed == 65535))
0790           iso_speed = imCommon.real_ISO;
0791       }
0792       get4();
0793       if (((i = get2()) != 0xffff) && !shutter) {
0794         shutter = libraw_powf64l(2.f, float((short)i) / -32.0f);
0795       }
0796       imCanon.wbi = (get2(), get2());
0797       shot_order = (get2(), get2());
0798       fseek(ifp, 4, SEEK_CUR);
0799     } else
0800       fseek(ifp, 24, SEEK_CUR);
0801     tempAp = get2();
0802     if (tempAp != 0)
0803       imCommon.CameraTemperature = (float)(tempAp - 128);
0804     tempAp = get2();
0805     if (tempAp != -1)
0806       imCommon.FlashGN = ((float)tempAp) / 32;
0807     get2();
0808 
0809     imCommon.FlashEC = _CanonConvertEV((signed short)get2());
0810     fseek(ifp, 8 - 32, SEEK_CUR);
0811     if ((tempAp = get2()) != 0x7fff)
0812       ilm.CurAp = _CanonConvertAperture(tempAp);
0813     if (ilm.CurAp < 0.7f) {
0814       fseek(ifp, 32, SEEK_CUR);
0815       ilm.CurAp = _CanonConvertAperture(get2());
0816     }
0817     if (!aperture)
0818       aperture = ilm.CurAp;
0819 
0820   } else if ((tag == 0x0007) && (dng_writer == nonDNG)) {
0821     fgets(model2, 64, ifp);
0822 
0823   } else if ((tag == 0x0008) && (dng_writer == nonDNG)) {
0824     shot_order = get4();
0825 
0826   } else if ((tag == 0x0009)  && (dng_writer == nonDNG)) {
0827     fread(artist, 64, 1, ifp);
0828 
0829   } else if (tag == 0x000c) {
0830     unsigned tS = get4();
0831     sprintf(imgdata.shootinginfo.BodySerial, "%d", tS);
0832 
0833   } else if ((tag == 0x0012) ||
0834              (tag == 0x0026) ||
0835              (tag == 0x003c)) {
0836     if (!imCommon.afcount) {
0837       imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
0838       imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
0839       imCommon.afdata[imCommon.afcount].AFInfoData_length = len;
0840       imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length);
0841       fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
0842       imCommon.afcount = 1;
0843     }
0844 
0845   } else if ((tag == 0x0029) && (dng_writer == nonDNG)) { // PowerShot G9
0846     int Got_AsShotWB = 0;
0847     fseek(ifp, 8, SEEK_CUR);
0848     for (unsigned linenum = 0; linenum < Canon_G9_linenums_2_StdWBi.size(); linenum++) {
0849       if (Canon_G9_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown ) {
0850         FORC4 icWBC[Canon_G9_linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get4();
0851         if (Canon_wbi2std[imCanon.wbi] == Canon_G9_linenums_2_StdWBi[linenum]) {
0852           FORC4 cam_mul[c] = float(icWBC[Canon_G9_linenums_2_StdWBi[linenum]][c]);
0853           Got_AsShotWB = 1;
0854         }
0855       }
0856       fseek(ifp, 16, SEEK_CUR);
0857     }
0858     if (!Got_AsShotWB)
0859       FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]);
0860 
0861   } else if ((tag == 0x0081) && (dng_writer == nonDNG)) { // -1D, -1Ds
0862     data_offset = get4();
0863     fseek(ifp, data_offset + 41, SEEK_SET);
0864     raw_height = get2() * 2;
0865     raw_width = get2();
0866     filters = 0x61616161;
0867 
0868   } else if (tag == 0x0093) {
0869     if (!imCanon.RF_lensID) {
0870       fseek(ifp, 0x03d<<1, SEEK_CUR);
0871       imCanon.RF_lensID = get2();
0872     }
0873 
0874   } else if (tag == 0x0095 && !ilm.Lens[0])
0875   { // lens model tag
0876     fread(ilm.Lens, 64, 1, ifp);
0877     if (!strncmp(ilm.Lens, "EF-S", 4))
0878     {
0879       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
0880       ilm.Lens[4] = ' ';
0881       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
0882       ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S;
0883       ilm.LensFormat = LIBRAW_FORMAT_APSC;
0884     }
0885     else if (!strncmp(ilm.Lens, "EF-M", 4))
0886     {
0887       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
0888       ilm.Lens[4] = ' ';
0889       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
0890       ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M;
0891       ilm.LensFormat = LIBRAW_FORMAT_APSC;
0892     }
0893     else if (!strncmp(ilm.Lens, "EF", 2))
0894     {
0895       memmove(ilm.Lens + 3, ilm.Lens + 2, 62);
0896       ilm.Lens[2] = ' ';
0897       memcpy(ilm.LensFeatures_pre, ilm.Lens, 2);
0898       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0899       ilm.LensFormat = LIBRAW_FORMAT_FF;
0900     }
0901     else if (!strncmp(ilm.Lens, "CN-E", 4))
0902     {
0903       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
0904       ilm.Lens[4] = ' ';
0905       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
0906       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0907       ilm.LensFormat = LIBRAW_FORMAT_FF;
0908     }
0909     else if (!strncmp(ilm.Lens, "TS-E", 4))
0910     {
0911       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
0912       ilm.Lens[4] = ' ';
0913       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
0914       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0915       ilm.LensFormat = LIBRAW_FORMAT_FF;
0916     }
0917     else if (!strncmp(ilm.Lens, "MP-E", 4))
0918     {
0919       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
0920       ilm.Lens[4] = ' ';
0921       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
0922       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
0923       ilm.LensFormat = LIBRAW_FORMAT_FF;
0924     }
0925 
0926     else if (!strncmp(ilm.Lens, "RF-S", 4))
0927     {
0928       memmove(ilm.Lens + 5, ilm.Lens + 4, 62);
0929       ilm.Lens[4] = ' ';
0930       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
0931       ilm.LensMount = LIBRAW_MOUNT_Canon_RF;
0932       ilm.LensFormat = LIBRAW_FORMAT_APSC;
0933     }
0934 
0935     else if (!strncmp(ilm.Lens, "RF", 2))
0936     {
0937       memmove(ilm.Lens + 3, ilm.Lens + 2, 62);
0938       ilm.Lens[2] = ' ';
0939       memcpy(ilm.LensFeatures_pre, ilm.Lens, 2);
0940       ilm.LensMount = LIBRAW_MOUNT_Canon_RF;
0941       ilm.LensFormat = LIBRAW_FORMAT_FF;
0942     }
0943   }
0944   else if (tag == 0x009a)
0945   { // AspectInfo
0946     i = get4();
0947     switch (i)
0948     {
0949     case 0:
0950     case 12: /* APS-H crop */
0951     case 13: /* APS-C crop */
0952       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
0953       break;
0954     case 1:
0955       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1;
0956       break;
0957     case 2:
0958       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3;
0959       break;
0960     case 7:
0961       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9;
0962       break;
0963     case 8:
0964       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4;
0965       break;
0966     default:
0967       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER;
0968       break;
0969     }
0970     imgdata.sizes.raw_inset_crops[0].cwidth = get4();
0971     imgdata.sizes.raw_inset_crops[0].cheight = get4();
0972     imgdata.sizes.raw_inset_crops[0].cleft = get4();
0973     imgdata.sizes.raw_inset_crops[0].ctop = get4();
0974 
0975   } else if ((tag == 0x00a4) && (dng_writer == nonDNG)) { // -1D, -1Ds
0976     fseek(ifp, imCanon.wbi * 48, SEEK_CUR);
0977     FORC3 cam_mul[c] = get2();
0978 
0979   } else if (tag == 0x00a9) {
0980     INT64 save1 = ftell(ifp);
0981     fseek(ifp, (0x1 << 1), SEEK_CUR);
0982     FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
0983     Canon_WBpresets(0, 0);
0984     fseek(ifp, save1, SEEK_SET);
0985   }
0986   else if (tag == 0x00b4)
0987   {
0988     switch (get2()) {
0989     case 1:
0990       imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB;
0991       break;
0992     case 2:
0993       imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
0994       break;
0995     default:
0996       imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown;
0997       break;
0998     }
0999   }
1000   else if (tag == 0x00e0) // SensorInfo
1001   {
1002     imCanon.SensorWidth  = (get2(), get2());
1003     imCanon.SensorHeight = get2();
1004     fseek(ifp, 4, SEEK_CUR);
1005     imCanon.DefaultCropAbsolute = get_CanonArea();
1006     imCanon.LeftOpticalBlack    = get_CanonArea();
1007   }
1008   else if (tag == 0x4001 && len > 500)
1009   {
1010     float sraw_mul_max = 0.f;
1011     int bls = 0;
1012     INT64 offsetChannelBlackLevel = 0L;
1013     INT64 offsetChannelBlackLevel2 = 0L;
1014     INT64 offsetWhiteLevels = 0L;
1015     INT64 save1 = ftell(ifp);
1016 
1017     switch (len)
1018     {
1019 
1020     case 582:
1021       imCanon.ColorDataVer = 1; // 20D, 350D
1022 
1023       fseek(ifp, save1 + (0x0019 << 1), SEEK_SET);
1024       FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2();
1025       fseek(ifp, save1 + (0x001e << 1), SEEK_SET);
1026       FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
1027       fseek(ifp, save1 + (0x0041 << 1), SEEK_SET);
1028       FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2();
1029       fseek(ifp, save1 + (0x0046 << 1), SEEK_SET);
1030       FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2();
1031 
1032       fseek(ifp, save1 + (0x0023 << 1), SEEK_SET);
1033       Canon_WBpresets(2, 2);
1034       fseek(ifp, save1 + (0x004b << 1), SEEK_SET);
1035       Canon_WBCTpresets(1); // ABCT
1036       offsetChannelBlackLevel = save1 + (0x00a6 << 1);
1037       break;
1038 
1039     case 653:
1040       imCanon.ColorDataVer = 2; // -1D Mark II, -1Ds Mark II
1041 
1042       fseek(ifp, save1 + (0x0018 << 1), SEEK_SET);
1043       FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
1044       fseek(ifp, save1 + (0x0022 << 1), SEEK_SET);
1045       FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2();
1046       fseek(ifp, save1 + (0x0090 << 1), SEEK_SET);
1047       FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2();
1048       fseek(ifp, save1 + (0x0095 << 1), SEEK_SET);
1049       FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2();
1050       fseek(ifp, save1 + (0x009a << 1), SEEK_SET);
1051       FORC4 icWBC[LIBRAW_WBI_Custom3][RGGB_2_RGBG(c)] = get2();
1052 
1053       fseek(ifp, save1 + (0x0027 << 1), SEEK_SET);
1054       Canon_WBpresets(2, 12);
1055       fseek(ifp, save1 + (0x00a4 << 1), SEEK_SET);
1056       Canon_WBCTpresets(1); // ABCT
1057       offsetChannelBlackLevel = save1 + (0x011e << 1);
1058       break;
1059 
1060     case 796:
1061       imCanon.ColorDataVer = 3; // -1D Mark II N, 5D, 30D, 400D; ColorDataSubVer: 1
1062       AsShot_Auto_MeasuredWB(0x003f);
1063 
1064       fseek(ifp, save1 + (0x0071 << 1), SEEK_SET);
1065       FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2();
1066       fseek(ifp, save1 + (0x0076 << 1), SEEK_SET);
1067       FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2();
1068       fseek(ifp, save1 + (0x007b << 1), SEEK_SET);
1069       FORC4 icWBC[LIBRAW_WBI_Custom3][RGGB_2_RGBG(c)] = get2();
1070       fseek(ifp, save1 + (0x0080 << 1), SEEK_SET);
1071       FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2();
1072 
1073       fseek(ifp, save1 + (0x004e << 1), SEEK_SET);
1074       Canon_WBpresets(2, 12);
1075       fseek(ifp, save1 + (0x0085 << 1), SEEK_SET);
1076       Canon_WBCTpresets(0); // BCAT
1077       offsetChannelBlackLevel = save1 + (0x00c4 << 1);
1078       break;
1079 
1080     case 674:  // -1D Mark III; ColorDataSubVer: 2
1081     case 692:  // 40D; ColorDataSubVer: 3
1082     case 702:  // -1Ds Mark III; ColorDataSubVer: 4
1083     case 1227: // 450D, 1000D; ColorDataSubVer: 5
1084     case 1250: // 5D Mark II, 50D; ColorDataSubVer: 6
1085     case 1251: // 500D; ColorDataSubVer: 7
1086     case 1337: // -1D Mark IV, 7D; ColorDataSubVer: 7
1087     case 1338: // 550D; ColorDataSubVer: 7
1088     case 1346: // 1100D, 60D; ColorDataSubVer: 9
1089       imCanon.ColorDataVer = 4;
1090       AsShot_Auto_MeasuredWB(0x003f);
1091       sRAW_WB(0x004e);
1092       fseek(ifp, save1 + (0x0053 << 1), SEEK_SET);
1093       Canon_WBpresets(2, 12);
1094       fseek(ifp, save1 + (0x00a8 << 1), SEEK_SET);
1095       Canon_WBCTpresets(0); // BCAT
1096 
1097       if ((imCanon.ColorDataSubVer == 4) ||
1098           (imCanon.ColorDataSubVer == 5))
1099       {
1100         offsetChannelBlackLevel = save1 + (0x02b4 << 1);
1101         offsetWhiteLevels = save1 + (0x02b8 << 1);
1102       }
1103       else if ((imCanon.ColorDataSubVer == 6) ||
1104                (imCanon.ColorDataSubVer == 7))
1105       {
1106         offsetChannelBlackLevel = save1 + (0x02cb << 1);
1107         offsetWhiteLevels = save1 + (0x02cf << 1);
1108       }
1109       else if (imCanon.ColorDataSubVer == 9)
1110       {
1111         offsetChannelBlackLevel = save1 + (0x02cf << 1);
1112         offsetWhiteLevels = save1 + (0x02d3 << 1);
1113       }
1114       else
1115         offsetChannelBlackLevel = save1 + (0x00e7 << 1);
1116       break;
1117 
1118     case 5120: // G10, G11, G12, G15, G16
1119                // G1 X, G1 X Mark II, G1 X Mark III
1120                // G3 X, G5 X
1121                // G7 X, G7 X Mark II
1122                // G9 X, G9 X Mark II
1123                // S90, S95, S100, S100V, S110, S120
1124                // SX1 IS, SX50 HS, SX60 HS
1125                // M3, M5, M6, M10, M100
1126       imCanon.ColorDataVer = 5;
1127       imCanon.ColorDataSubVer = get2();
1128 
1129       fseek(ifp, save1 + (0x0047 << 1), SEEK_SET);
1130       FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2();
1131 
1132       if (imCanon.ColorDataSubVer == 0xfffc) // ColorDataSubVer: 65532 (-4)
1133                                              // G7 X Mark II, G9 X Mark II, G1 X Mark III
1134                                              // M5, M100, M6
1135       {
1136         fseek(ifp, save1 + (0x004f << 1), SEEK_SET);
1137         FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
1138         fseek(ifp, 8, SEEK_CUR);
1139         FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] =
1140             get2();
1141         fseek(ifp, 8, SEEK_CUR);
1142         FORC4 icWBC[LIBRAW_WBI_Other][RGGB_2_RGBG(c)] = get2();
1143         fseek(ifp, 8, SEEK_CUR);
1144         Canon_WBpresets(8, 24);
1145         fseek(ifp, 168, SEEK_CUR);
1146         FORC4 icWBC[LIBRAW_WBI_FL_WW][RGGB_2_RGBG(c)] = get2();
1147         fseek(ifp, 24, SEEK_CUR);
1148         Canon_WBCTpresets(2); // BCADT
1149         offsetChannelBlackLevel = save1 + (0x014d << 1);
1150         offsetWhiteLevels = save1 + (0x0569 << 1);
1151       }
1152       else if (imCanon.ColorDataSubVer == 0xfffd) // ColorDataSubVer: 65533 (-3)
1153                                                   // M10, M3
1154                                                   // G1 X, G1 X Mark II
1155                                                   // G3 X, G5 X, G7 X, G9 X
1156                                                   // G10, G11, G12, G15, G16
1157                                                   // S90, S95, S100, S100V, S110, S120
1158                                                   // SX1 IS, SX50 HS, SX60 HS
1159       {
1160         fseek(ifp, save1 + (0x004c << 1), SEEK_SET);
1161         FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
1162         get2();
1163         FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] =
1164             get2();
1165         get2();
1166         FORC4 icWBC[LIBRAW_WBI_Other][RGGB_2_RGBG(c)] = get2();
1167         get2();
1168         Canon_WBpresets(2, 12);
1169         fseek(ifp, save1 + (0x00ba << 1), SEEK_SET);
1170         Canon_WBCTpresets(2); // BCADT
1171         offsetChannelBlackLevel = save1 + (0x0108 << 1);
1172       }
1173       break;
1174 
1175     case 1273: // 600D; ColorDataSubVer: 10
1176     case 1275: // 1200D; ColorDataSubVer: 10
1177       imCanon.ColorDataVer = 6;
1178       AsShot_Auto_MeasuredWB(0x003f);
1179       sRAW_WB(0x0062);
1180       fseek(ifp, save1 + (0x0067 << 1), SEEK_SET);
1181       Canon_WBpresets(2, 12);
1182       fseek(ifp, save1 + (0x00bc << 1), SEEK_SET);
1183       Canon_WBCTpresets(0); // BCAT
1184       offsetChannelBlackLevel = save1 + (0x01df << 1);
1185       offsetWhiteLevels = save1 + (0x01e3 << 1);
1186       break;
1187 
1188     case 1312: // 5D Mark III, 650D, 700D, M; ColorDataSubVer: 10
1189     case 1313: // 100D, 6D, 70D, EOS M2; ColorDataSubVer: 10
1190     case 1316: // -1D C, -1D X; ColorDataSubVer: 10
1191     case 1506: // 750D, 760D, 7D Mark II; ColorDataSubVer: 11
1192       imCanon.ColorDataVer = 7;
1193       AsShot_Auto_MeasuredWB(0x003f);
1194       sRAW_WB(0x007b);
1195       fseek(ifp, save1 + (0x0080 << 1), SEEK_SET);
1196       Canon_WBpresets(2, 12);
1197       fseek(ifp, save1 + (0x00d5 << 1), SEEK_SET);
1198       Canon_WBCTpresets(0); // BCAT
1199 
1200       if (imCanon.ColorDataSubVer == 10)
1201       {
1202         offsetChannelBlackLevel = save1 + (0x01f8 << 1);
1203         offsetWhiteLevels = save1 + (0x01fc << 1);
1204       }
1205       else if (imCanon.ColorDataSubVer == 11)
1206       {
1207         offsetChannelBlackLevel = save1 + (0x02d8 << 1);
1208         offsetWhiteLevels = save1 + (0x02dc << 1);
1209       }
1210       break;
1211 
1212     case 1560: // 5DS, 5DS R; ColorDataSubVer: 12
1213     case 1592: // 5D Mark IV, 80D, -1D X Mark II; ColorDataSubVer: 13
1214     case 1353: // 1300D, 1500D, 3000D; ColorDataSubVer: 14
1215     case 1602: // 200D, 6D Mark II, 77D, 800D; ColorDataSubVer: 15
1216       imCanon.ColorDataVer = 8;
1217       AsShot_Auto_MeasuredWB(0x003f);
1218       sRAW_WB(0x0080);
1219       fseek(ifp, save1 + (0x0085 << 1), SEEK_SET);
1220       Canon_WBpresets(2, 12);
1221       fseek(ifp, save1 + (0x0107 << 1), SEEK_SET);
1222       Canon_WBCTpresets(0); // BCAT
1223 
1224       if (imCanon.ColorDataSubVer == 14) // 1300D, 1500D, 3000D
1225       {
1226         offsetChannelBlackLevel = save1 + (0x022c << 1);
1227         offsetWhiteLevels = save1 + (0x0230 << 1);
1228       }
1229       else
1230       {
1231         offsetChannelBlackLevel = save1 + (0x030a << 1);
1232         offsetWhiteLevels = save1 + (0x030e << 1);
1233       }
1234       break;
1235 
1236     case 1820: // M50; ColorDataSubVer: 16
1237     case 1824: // R; ColorDataSubVer: 17
1238     case 1816: // RP, 250D, SX70 HS; ColorDataSubVer: 18
1239                // M6 Mark II, M200, 90D, G5 X Mark II, G7 X Mark III, 850D; ColorDataSubVer: 19
1240       imCanon.ColorDataVer = 9;
1241       AsShot_Auto_MeasuredWB(0x0047);
1242       CR3_ColorData(0x0047);
1243       break;
1244 
1245     case 1770: // R5 CRM
1246     case 2024: // -1D X Mark III; ColorDataSubVer: 32
1247     case 3656: // R5, R6; ColorDataSubVer: 33 
1248       imCanon.ColorDataVer = 10;
1249       AsShot_Auto_MeasuredWB(0x0055);
1250       CR3_ColorData(0x0055);
1251       break;
1252 
1253     case 3973: // R3; ColorDataSubVer: 34
1254     case 3778: // R7, R10; ColorDataSubVer: 48
1255       imCanon.ColorDataVer = 11;
1256       AsShot_Auto_MeasuredWB(0x0069);
1257 
1258       fseek(ifp, save1 + ((0x0069+0x0064) << 1), SEEK_SET);
1259       Canon_WBpresets(2, 12);
1260       fseek(ifp, save1 + ((0x0069+0x00c3) << 1), SEEK_SET);
1261       Canon_WBCTpresets(0);
1262       offsetChannelBlackLevel2 = save1 + ((0x0069+0x0102) << 1);
1263       offsetChannelBlackLevel  = save1 + ((0x0069+0x0213) << 1);
1264       offsetWhiteLevels        = save1 + ((0x0069+0x0217) << 1);
1265       break;
1266 
1267    default:
1268       imCanon.ColorDataSubVer = get2();
1269       break;
1270     }
1271 
1272     if (offsetChannelBlackLevel)
1273     {
1274       fseek(ifp, offsetChannelBlackLevel, SEEK_SET);
1275       FORC4
1276         bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2());
1277       imCanon.AverageBlackLevel = bls / 4;
1278     }
1279     if (offsetWhiteLevels)
1280     {
1281       if ((offsetWhiteLevels - offsetChannelBlackLevel) != 8L)
1282         fseek(ifp, offsetWhiteLevels, SEEK_SET);
1283       imCanon.NormalWhiteLevel = get2();
1284       imCanon.SpecularWhiteLevel = get2();
1285       FORC4
1286         imgdata.color.linear_max[c] = imCanon.SpecularWhiteLevel;
1287     }
1288 
1289     if(!imCanon.AverageBlackLevel && offsetChannelBlackLevel2)
1290     {
1291         fseek(ifp, offsetChannelBlackLevel2, SEEK_SET);
1292         FORC4
1293             bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2());
1294         imCanon.AverageBlackLevel = bls / 4;
1295     }
1296     fseek(ifp, save1, SEEK_SET);
1297 
1298   } else if (tag == 0x4013) {
1299     get4();
1300     imCanon.AFMicroAdjMode = get4();
1301     float a = float(get4());
1302     float b = float(get4());
1303     if (fabsf(b) > 0.001f)
1304       imCanon.AFMicroAdjValue = a / b;
1305 
1306   } else if (tag == 0x4018) {
1307     fseek(ifp, 8, SEEK_CUR);
1308     imCanon.AutoLightingOptimizer = get4();
1309     if ((imCanon.AutoLightingOptimizer > 3) ||
1310         (imCanon.AutoLightingOptimizer < 0))
1311       imCanon.AutoLightingOptimizer = 3;
1312     imCanon.HighlightTonePriority = get4();
1313     if ((imCanon.HighlightTonePriority > 5) ||
1314         (imCanon.HighlightTonePriority < 0))
1315       imCanon.HighlightTonePriority = 0;
1316     if (imCanon.HighlightTonePriority) {
1317       imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority);
1318     }
1319 
1320   } else if ((tag == 0x4021) && (dng_writer == nonDNG) &&
1321              (imCanon.multishot[0] = get4()) &&
1322              (imCanon.multishot[1] = get4())) {
1323     if (len >= 4) {
1324       imCanon.multishot[2] = get4();
1325       imCanon.multishot[3] = get4();
1326     }
1327     FORC4 cam_mul[c] = 1024;
1328   } else if (tag == 0x4026) {
1329     fseek(ifp, 44, SEEK_CUR);
1330     imCanon.CanonLog = get4();
1331   }
1332 #undef CR3_ColorData
1333 #undef sRAW_WB
1334 #undef AsShot_Auto_MeasuredWB
1335 }