1 /* -*- C++ -*-
2  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
3  *
4 
5  LibRaw is free software; you can redistribute it and/or modify
6  it under the terms of the one of two licenses as you choose:
7 
8 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
9    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
10 
11 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
12    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
13 
14  */
15 #include "../../internal/dcraw_defs.h"
16 #include "../../internal/libraw_cameraids.h"
17 
get_CanonArea()18 libraw_area_t LibRaw::get_CanonArea() {
19   libraw_area_t la = {};
20   la.l = get2();
21   la.t = get2();
22   la.r = get2();
23   la.b = get2();
24   return la;
25 }
26 
_CanonConvertAperture(ushort in)27 float LibRaw::_CanonConvertAperture(ushort in)
28 {
29   if ((in == (ushort)0xffe0) || (in == (ushort)0x7fff))
30     return 0.0f;
31   return LibRaw::libraw_powf64l(2.f, float(in) / 64.f);
32 }
33 
_CanonConvertEV(short in)34 static float _CanonConvertEV(short in)
35 {
36   short EV, Sign, Frac;
37   float Frac_f;
38   EV = in;
39   if (EV < 0)
40   {
41     EV = -EV;
42     Sign = -1;
43   }
44   else
45   {
46     Sign = 1;
47   }
48   Frac = EV & 0x1f;
49   EV -= Frac; // remove fraction
50 
51   if (Frac == 0x0c)
52   { // convert 1/3 and 2/3 codes
53     Frac_f = 32.0f / 3.0f;
54   }
55   else if (Frac == 0x14)
56   {
57     Frac_f = 64.0f / 3.0f;
58   }
59   else
60     Frac_f = (float)Frac;
61 
62   return ((float)Sign * ((float)EV + Frac_f)) / 32.0f;
63 }
64 
setCanonBodyFeatures(unsigned long long id)65 void LibRaw::setCanonBodyFeatures(unsigned long long id)
66 {
67 
68   ilm.CamID = id;
69   if ((id == CanonID_EOS_1D)           ||
70       (id == CanonID_EOS_1D_Mark_II)   ||
71       (id == CanonID_EOS_1D_Mark_II_N) ||
72       (id == CanonID_EOS_1D_Mark_III)  ||
73       (id == CanonID_EOS_1D_Mark_IV))
74   {
75     ilm.CameraFormat = LIBRAW_FORMAT_APSH;
76     ilm.CameraMount = LIBRAW_MOUNT_Canon_EF;
77   }
78   else if ((id == CanonID_EOS_1Ds)           ||
79            (id == CanonID_EOS_1Ds_Mark_II)   ||
80            (id == CanonID_EOS_1Ds_Mark_III)  ||
81            (id == CanonID_EOS_1D_X)          ||
82            (id == CanonID_EOS_1D_X_Mark_II)  ||
83            (id == CanonID_EOS_1D_X_Mark_III) ||
84            (id == CanonID_EOS_1D_C)          ||
85            (id == CanonID_EOS_5D)            ||
86            (id == CanonID_EOS_5D_Mark_II)    ||
87            (id == CanonID_EOS_5D_Mark_III)   ||
88            (id == CanonID_EOS_5D_Mark_IV)    ||
89            (id == CanonID_EOS_5DS)           ||
90            (id == CanonID_EOS_5DS_R)         ||
91            (id == CanonID_EOS_6D)            ||
92            (id == CanonID_EOS_6D_Mark_II))
93   {
94     ilm.CameraFormat = LIBRAW_FORMAT_FF;
95     ilm.CameraMount = LIBRAW_MOUNT_Canon_EF;
96   }
97   else if ((id == CanonID_EOS_M)             ||
98            (id == CanonID_EOS_M2)            ||
99            (id == CanonID_EOS_M3)            ||
100            (id == CanonID_EOS_M5)            ||
101            (id == CanonID_EOS_M10)           ||
102            (id == CanonID_EOS_M50)           ||
103            (id == CanonID_EOS_M50_Mark_II)   ||
104            (id == CanonID_EOS_M6)            ||
105            (id == CanonID_EOS_M6_Mark_II)    ||
106            (id == CanonID_EOS_M100))
107   {
108     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
109     ilm.CameraMount = LIBRAW_MOUNT_Canon_EF_M;
110   }
111   else if ((id == CanonID_EOS_R)  ||
112            (id == CanonID_EOS_RP) ||
113            (id == CanonID_EOS_R3) ||
114            (id == CanonID_EOS_R6) ||
115            (id == CanonID_EOS_R5))
116   {
117     ilm.CameraFormat = LIBRAW_FORMAT_FF;
118     ilm.CameraMount = LIBRAW_MOUNT_Canon_RF;
119   }
120   else if ((id == CanonID_EOS_D30) ||
121            (id == CanonID_EOS_D60) ||
122            (id > 0x80000000ULL))
123   {
124     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
125     ilm.CameraMount = LIBRAW_MOUNT_Canon_EF;
126   }
127 }
128 
CanonCameraInfo_checkFirmwareRecordLocation(uchar * offset)129 int CanonCameraInfo_checkFirmwareRecordLocation (uchar *offset) {
130 // firmware record location allows
131 // to determine the subversion of the CameraInfo table
132 // and to adjust offsets accordingly
133   if (isdigit(*offset)   &&
134       isdigit(*offset+2) &&
135       isdigit(*offset+4) &&
136       (*(offset+1) == '.') &&
137       (*(offset+3) == '.') &&
138       (*(offset+5) == 0)) return 1;
139   else return 0; // error
140 }
141 
processCanonCameraInfo(unsigned long long id,uchar * CameraInfo,unsigned maxlen,unsigned type,unsigned dng_writer)142 void LibRaw::processCanonCameraInfo(unsigned long long id, uchar *CameraInfo,
143                                     unsigned maxlen, unsigned type, unsigned dng_writer)
144 {
145   ushort iCanonLensID = 0, iCanonMaxFocal = 0, iCanonMinFocal = 0,
146          iCanonLens = 0, iCanonCurFocal = 0, iCanonFocalType = 0,
147          iMakernotesFlip = 0,
148          iHTP = 0, iALO = 0;
149   short SubVersion_offset = 0;
150   ushort SubVersion = 0, mgck = 0;
151 
152   if (maxlen < 16)
153     return; // too short
154 
155   mgck = sget2(CameraInfo);
156   CameraInfo[0] = 0;
157   CameraInfo[1] = 0;
158   if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) {
159     if ((maxlen == 94)  || (maxlen == 138) || (maxlen == 148) ||
160         (maxlen == 156) || (maxlen == 162) || (maxlen == 167) ||
161         (maxlen == 171) || (maxlen == 264) || (maxlen > 400))
162       imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 3) << 2)));
163     else if (maxlen == 72)
164       imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 1) << 2)));
165     else if ((maxlen == 85) || (maxlen == 93))
166       imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 2) << 2)));
167     else if ((maxlen == 96) || (maxlen == 104))
168       imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 4) << 2)));
169   }
170 
171   switch (id)
172   {
173   case CanonID_EOS_1D:
174   case CanonID_EOS_1Ds:
175     iCanonCurFocal  =  0x0a;
176     iCanonLensID    =  0x0d;
177     iCanonMinFocal  =  0x0e;
178     iCanonMaxFocal  =  0x10;
179     if (!ilm.CurFocal)
180       ilm.CurFocal = sget2(CameraInfo + iCanonCurFocal);
181     if (!ilm.MinFocal)
182       ilm.MinFocal = sget2(CameraInfo + iCanonMinFocal);
183     if (!ilm.MaxFocal)
184       ilm.MaxFocal = sget2(CameraInfo + iCanonMaxFocal);
185     imCommon.CameraTemperature = 0.0f;
186     break;
187 
188   case CanonID_EOS_1D_Mark_II:
189   case CanonID_EOS_1Ds_Mark_II:
190     iCanonCurFocal  =  0x09;
191     iCanonLensID    =  0x0c;
192     iCanonMinFocal  =  0x11;
193     iCanonMaxFocal  =  0x13;
194     iCanonFocalType =  0x2d;
195     break;
196 
197   case CanonID_EOS_1D_Mark_II_N:
198     iCanonCurFocal  =  0x09;
199     iCanonLensID    =  0x0c;
200     iCanonMinFocal  =  0x11;
201     iCanonMaxFocal  =  0x13;
202     break;
203 
204   case CanonID_EOS_1D_Mark_III:
205   case CanonID_EOS_1Ds_Mark_III:
206     iCanonCurFocal  =  0x1d;
207     iMakernotesFlip =  0x30;
208     iCanonLensID    = 0x111;
209     iCanonMinFocal  = 0x113;
210     iCanonMaxFocal  = 0x115;
211     break;
212 
213   case CanonID_EOS_1D_Mark_IV:
214     if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1e8))
215       SubVersion = 1;
216     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1ed))
217       SubVersion = 2;
218 // printf ("==>> CanonID_EOS_1D_Mark_IV, SubVersion: %d\n", SubVersion);
219     iHTP            =  0x07;
220     iCanonCurFocal  =  0x1e;
221     iMakernotesFlip =  0x35;
222 
223     if (!SubVersion)
224       break;
225     else if (SubVersion < 2)
226       SubVersion_offset += -1;
227 
228     iCanonLensID    = 0x14f+SubVersion_offset;
229     iCanonMinFocal  = 0x151+SubVersion_offset;
230     iCanonMaxFocal  = 0x153+SubVersion_offset;
231     break;
232 
233   case CanonID_EOS_1D_X:
234     if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x271))
235       SubVersion = 1;
236     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x279))
237       SubVersion = 2;
238     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x280))
239       SubVersion = 3;
240     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x285))
241       SubVersion = 4;
242 // printf ("==>> CanonID_EOS_1D_X, SubVersion: %d\n", SubVersion);
243 
244     if (SubVersion < 3)
245       SubVersion_offset += -3;
246 
247     iCanonCurFocal  =  0x23+SubVersion_offset;
248     iMakernotesFlip =  0x7d+SubVersion_offset;
249 
250     if (SubVersion < 3)
251       SubVersion_offset += -4;
252     else if (SubVersion == 4)
253       SubVersion_offset += 5;
254 
255     iCanonLensID    = 0x1a7+SubVersion_offset;
256     iCanonMinFocal  = 0x1a9+SubVersion_offset;
257     iCanonMaxFocal  = 0x1ab+SubVersion_offset;
258     break;
259 
260   case CanonID_EOS_5D:
261     iMakernotesFlip =  0x27;
262     iCanonCurFocal  =  0x28;
263     iCanonLensID    =  0x0c;
264     if (!sget2Rev(CameraInfo + iCanonLensID))
265       iCanonLensID  =  0x97;
266     iCanonMinFocal  =  0x93;
267     iCanonMaxFocal  =  0x95;
268     break;
269 
270   case CanonID_EOS_5D_Mark_II:
271     iHTP            =  0x07;
272     iCanonCurFocal  =  0x1e;
273     iMakernotesFlip =  0x31;
274     iALO            =  0xbf;
275     iCanonLensID    =  0xe6;
276     iCanonMinFocal  =  0xe8;
277     iCanonMaxFocal  =  0xea;
278     break;
279 
280   case CanonID_EOS_5D_Mark_III:
281     if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x22c))
282       SubVersion = 1;
283     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x22d))
284       SubVersion = 2;
285     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x23c))
286       SubVersion = 3;
287     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x242))
288       SubVersion = 4;
289     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x247))
290       SubVersion = 5;
291 // printf ("==>> CanonID_EOS_5D_Mark_III, SubVersion: %d\n", SubVersion);
292 
293     if (!SubVersion)
294       break;
295     else if (SubVersion < 3)
296       SubVersion_offset += -1;
297 
298     iCanonCurFocal  =  0x23+SubVersion_offset;
299 
300     if (SubVersion == 1)
301       SubVersion_offset += -3;
302     else if (SubVersion == 2)
303       SubVersion_offset += -2;
304     else if (SubVersion >= 4)
305       SubVersion_offset += 6;
306 
307     iMakernotesFlip =  0x7d+SubVersion_offset;
308 
309     if (SubVersion < 3)
310       SubVersion_offset += -4;
311     else if (SubVersion > 4)
312       SubVersion_offset += 5;
313 
314     iCanonLensID    = 0x153+SubVersion_offset;
315     iCanonMinFocal  = 0x155+SubVersion_offset;
316     iCanonMaxFocal  = 0x157+SubVersion_offset;
317     break;
318 
319   case CanonID_EOS_6D:
320     iCanonCurFocal  =  0x23;
321     iMakernotesFlip =  0x83;
322     iCanonLensID    = 0x161;
323     iCanonMinFocal  = 0x163;
324     iCanonMaxFocal  = 0x165;
325     break;
326 
327   case CanonID_EOS_7D:
328     if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1a8))
329       SubVersion = 1;
330     else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1ac))
331       SubVersion = 2;
332 // printf ("==>> CanonID_EOS_7D, SubVersion: %d\n", SubVersion);
333     iHTP            =  0x07;
334     iCanonCurFocal  =  0x1e;
335 
336     if (!SubVersion)
337       break;
338     else if (SubVersion < 2)
339       SubVersion_offset += -4;
340 
341     iMakernotesFlip =  0x35+SubVersion_offset;
342     iCanonLensID    = 0x112+SubVersion_offset;
343     iCanonMinFocal  = 0x114+SubVersion_offset;
344     iCanonMaxFocal  = 0x116+SubVersion_offset;
345     break;
346 
347   case CanonID_EOS_40D:
348     iCanonCurFocal  =  0x1d;
349     iMakernotesFlip =  0x30;
350     iCanonLensID    =  0xd6;
351     iCanonMinFocal  =  0xd8;
352     iCanonMaxFocal  =  0xda;
353     iCanonLens      = 0x92b;
354     break;
355 
356   case CanonID_EOS_50D:
357     iHTP            =  0x07;
358     iCanonCurFocal  =  0x1e;
359     iMakernotesFlip =  0x31;
360     iALO            =  0xbf;
361     iCanonLensID    =  0xea;
362     iCanonMinFocal  =  0xec;
363     iCanonMaxFocal  =  0xee;
364     break;
365 
366   case CanonID_EOS_60D:
367   case CanonID_EOS_1200D:
368     iCanonCurFocal  =  0x1e;
369     if (id == CanonID_EOS_60D)
370       iMakernotesFlip =  0x36;
371     else
372       iMakernotesFlip =  0x3a;
373     iCanonLensID    =  0xe8;
374     iCanonMinFocal  =  0xea;
375     iCanonMaxFocal  =  0xec;
376     break;
377 
378   case CanonID_EOS_70D:
379     iCanonCurFocal  =  0x23;
380     iMakernotesFlip =  0x84;
381     iCanonLensID    = 0x166;
382     iCanonMinFocal  = 0x168;
383     iCanonMaxFocal  = 0x16a;
384     break;
385 
386   case CanonID_EOS_80D:
387     iCanonCurFocal  =  0x23;
388     iMakernotesFlip =  0x96;
389     iCanonLensID    = 0x189;
390     iCanonMinFocal  = 0x18b;
391     iCanonMaxFocal  = 0x18d;
392     break;
393 
394   case CanonID_EOS_450D:
395     iCanonCurFocal  =  0x1d;
396     iMakernotesFlip =  0x30;
397     iCanonLensID    =  0xde;
398     iCanonLens      = 0x933;
399     break;
400 
401   case CanonID_EOS_500D:
402     iHTP            =  0x07;
403     iCanonCurFocal  =  0x1e;
404     iMakernotesFlip =  0x31;
405     iALO            =  0xbe;
406     iCanonLensID    =  0xf6;
407     iCanonMinFocal  =  0xf8;
408     iCanonMaxFocal  =  0xfa;
409     break;
410 
411   case CanonID_EOS_550D:
412     iHTP            =  0x07;
413     iCanonCurFocal  =  0x1e;
414     iMakernotesFlip =  0x35;
415     iCanonLensID    =  0xff;
416     iCanonMinFocal  = 0x101;
417     iCanonMaxFocal  = 0x103;
418     break;
419 
420   case CanonID_EOS_600D:
421   case CanonID_EOS_1100D:
422     iHTP            =  0x07;
423     iCanonCurFocal  =  0x1e;
424     iMakernotesFlip =  0x38;
425     iCanonLensID    =  0xea;
426     iCanonMinFocal  =  0xec;
427     iCanonMaxFocal  =  0xee;
428     break;
429 
430   case CanonID_EOS_650D:
431   case CanonID_EOS_700D:
432     iCanonCurFocal  =  0x23;
433     iMakernotesFlip =  0x7d;
434     iCanonLensID    = 0x127;
435     iCanonMinFocal  = 0x129;
436     iCanonMaxFocal  = 0x12b;
437     break;
438 
439   case CanonID_EOS_750D:
440   case CanonID_EOS_760D:
441     iCanonCurFocal  =  0x23;
442     iMakernotesFlip =  0x96;
443     iCanonLensID    = 0x184;
444     iCanonMinFocal  = 0x186;
445     iCanonMaxFocal  = 0x188;
446     break;
447 
448   case CanonID_EOS_1000D:
449     iCanonCurFocal  =  0x1d;
450     iMakernotesFlip =  0x30;
451     iCanonLensID    =  0xe2;
452     iCanonMinFocal  =  0xe4;
453     iCanonMaxFocal  =  0xe6;
454     iCanonLens      = 0x937;
455     break;
456   }
457 
458   if (iMakernotesFlip && (CameraInfo[iMakernotesFlip] < 3)) {
459     imCanon.MakernotesFlip = "065"[CameraInfo[iMakernotesFlip]] - '0';
460 // printf ("==>> iMakernotesFlip: 0x%x, flip: %d\n", iMakernotesFlip, imCanon.MakernotesFlip);
461   } else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&
462      (mgck == 0xaaaa) && (dng_writer == nonDNG)) { // CameraOrientation
463     int c, i;
464     for (i = 2; (sget2(CameraInfo+i) != 0xbbbb) && i < (int)maxlen; i++);
465     i+=2;
466     while (i < int(maxlen - 5))
467       if ((sget4(CameraInfo+i) == 257) && ((c = CameraInfo[i+8]) < 3)) {
468         imCanon.MakernotesFlip = "065"[c] - '0';
469 // printf ("==>> MakernotesFlip offset: 0x%x, flip: %d\n", i+8, imCanon.MakernotesFlip);
470         break;
471       } else i+=4;
472   }
473 
474   if (iHTP)
475   {
476     imCanon.HighlightTonePriority = CameraInfo[iHTP];
477     if ((imCanon.HighlightTonePriority > 5) ||
478         (imCanon.HighlightTonePriority < 0))
479       imCanon.HighlightTonePriority = 0;
480     if (imCanon.HighlightTonePriority) {
481       imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority);
482     }
483   }
484   if (iALO)
485   {
486     imCanon.AutoLightingOptimizer = CameraInfo[iALO];
487     if ((imCanon.AutoLightingOptimizer > 3) ||
488         (imCanon.AutoLightingOptimizer < 0))
489       imCanon.AutoLightingOptimizer = 3;
490   }
491   if (iCanonFocalType)
492   {
493     if (iCanonFocalType >= maxlen)
494       return; // broken;
495     ilm.FocalType = CameraInfo[iCanonFocalType];
496     if (!ilm.FocalType) // zero means 'prime' here, replacing with standard '1'
497       ilm.FocalType = LIBRAW_FT_PRIME_LENS;
498   }
499   if (!ilm.CurFocal && iCanonCurFocal)
500   {
501     if (iCanonCurFocal >= maxlen)
502       return; // broken;
503     ilm.CurFocal = sget2Rev(CameraInfo + iCanonCurFocal);
504   }
505   if (!ilm.LensID && iCanonLensID)
506   {
507     if (iCanonLensID >= maxlen)
508       return; // broken;
509     ilm.LensID = sget2Rev(CameraInfo + iCanonLensID);
510   }
511   if (!ilm.MinFocal && iCanonMinFocal)
512   {
513     if (iCanonMinFocal >= maxlen)
514       return; // broken;
515     ilm.MinFocal = sget2Rev(CameraInfo + iCanonMinFocal);
516   }
517   if (!ilm.MaxFocal && iCanonMaxFocal)
518   {
519     if (iCanonMaxFocal >= maxlen)
520       return; // broken;
521     ilm.MaxFocal = sget2Rev(CameraInfo + iCanonMaxFocal);
522   }
523   if (!ilm.Lens[0] && iCanonLens)
524   {
525     if (iCanonLens + 64 >= (int)maxlen) // broken;
526       return;
527 
528     char *pl = (char *)CameraInfo + iCanonLens;
529     if (!strncmp(pl, "EF-S", 4))
530     {
531       memcpy(ilm.Lens, pl, 4);
532       ilm.Lens[4] = ' ';
533       memcpy(ilm.LensFeatures_pre, pl, 4);
534       ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S;
535       ilm.LensFormat = LIBRAW_FORMAT_APSC;
536       memcpy(ilm.Lens + 5, pl + 4, 60);
537     }
538     else if (!strncmp(pl, "EF-M", 4))
539     {
540       memcpy(ilm.Lens, pl, 4);
541       ilm.Lens[4] = ' ';
542       memcpy(ilm.LensFeatures_pre, pl, 4);
543       ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M;
544       ilm.LensFormat = LIBRAW_FORMAT_APSC;
545       memcpy(ilm.Lens + 5, pl + 4, 60);
546     }
547     else if (!strncmp(pl, "EF", 2))
548     {
549       memcpy(ilm.Lens, pl, 2);
550       ilm.Lens[2] = ' ';
551       memcpy(ilm.LensFeatures_pre, pl, 2);
552       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
553       ilm.LensFormat = LIBRAW_FORMAT_FF;
554       memcpy(ilm.Lens + 3, pl + 2, 62);
555     }
556     else if (!strncmp(ilm.Lens, "CN-E", 4))
557     {
558       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
559       ilm.Lens[4] = ' ';
560       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
561       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
562       ilm.LensFormat = LIBRAW_FORMAT_FF;
563     }
564     else if (!strncmp(pl, "TS-E", 4))
565     {
566       memcpy(ilm.Lens, pl, 4);
567       ilm.Lens[4] = ' ';
568       memcpy(ilm.LensFeatures_pre, pl, 4);
569       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
570       ilm.LensFormat = LIBRAW_FORMAT_FF;
571       memcpy(ilm.Lens + 5, pl + 4, 60);
572     }
573     else if (!strncmp(pl, "MP-E", 4))
574     {
575       memcpy(ilm.Lens, pl, 4);
576       ilm.Lens[4] = ' ';
577       memcpy(ilm.LensFeatures_pre, pl, 4);
578       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
579       ilm.LensFormat = LIBRAW_FORMAT_FF;
580       memcpy(ilm.Lens + 5, pl + 4, 60);
581     }
582     else // non-Canon lens
583       memcpy(ilm.Lens, pl, 64);
584   }
585   return;
586 }
587 
Canon_CameraSettings(unsigned len)588 void LibRaw::Canon_CameraSettings(unsigned len)
589 {
590   fseek(ifp, 10, SEEK_CUR);
591   imgdata.shootinginfo.DriveMode = get2(); // 5
592   get2();
593   imgdata.shootinginfo.FocusMode = get2(); // 7
594   imCanon.RecordMode = (get2(), get2());   // 9, format
595   fseek(ifp, 14, SEEK_CUR);
596   imgdata.shootinginfo.MeteringMode = get2(); // 17
597   get2();
598   imgdata.shootinginfo.AFPoint = get2();      // 19
599   imgdata.shootinginfo.ExposureMode = get2(); // 20
600   get2();
601   ilm.LensID = get2();          // 22
602   ilm.MaxFocal = get2();        // 23
603   ilm.MinFocal = get2();        // 24
604   ilm.FocalUnits = get2();      // 25
605   if (ilm.FocalUnits > 1)
606   {
607     ilm.MaxFocal /= (float)ilm.FocalUnits;
608     ilm.MinFocal /= (float)ilm.FocalUnits;
609   }
610   ilm.MaxAp = _CanonConvertAperture(get2()); // 26
611   ilm.MinAp = _CanonConvertAperture(get2()); // 27
612   if (len >= 36)
613   {
614     fseek(ifp, 12, SEEK_CUR);
615     imgdata.shootinginfo.ImageStabilization = get2(); // 34
616   }
617   else
618     return;
619   if (len >= 48)
620   {
621     fseek(ifp, 22, SEEK_CUR);
622     imCanon.SRAWQuality = get2(); // 46
623   }
624 }
625 
Canon_WBpresets(int skip1,int skip2)626 void LibRaw::Canon_WBpresets(int skip1, int skip2)
627 {
628   int c;
629   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][RGGB_2_RGBG(c)] = get2();
630 
631   if (skip1)
632     fseek(ifp, skip1, SEEK_CUR);
633   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][RGGB_2_RGBG(c)] = get2();
634 
635   if (skip1)
636     fseek(ifp, skip1, SEEK_CUR);
637   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][RGGB_2_RGBG(c)] = get2();
638 
639   if (skip1)
640     fseek(ifp, skip1, SEEK_CUR);
641   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][RGGB_2_RGBG(c)] = get2();
642 
643   if (skip1)
644     fseek(ifp, skip1, SEEK_CUR);
645   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][RGGB_2_RGBG(c)] = get2();
646 
647   if (skip2)
648     fseek(ifp, skip2, SEEK_CUR);
649   FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][RGGB_2_RGBG(c)] = get2();
650 
651   return;
652 }
653 
Canon_WBCTpresets(short WBCTversion)654 void LibRaw::Canon_WBCTpresets(short WBCTversion)
655 {
656 
657   int i;
658   float norm;
659 
660   if (WBCTversion == 0)
661   { // tint, as shot R, as shot B, CСT
662     for (i = 0; i < 15; i++)
663     {
664       icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f;
665       fseek(ifp, 2, SEEK_CUR);
666       icWBCCTC[i][1] = 1024.0f / fMAX(get2(), 1.f);
667       icWBCCTC[i][3] = 1024.0f / fMAX(get2(), 1.f);
668       icWBCCTC[i][0] = get2();
669     }
670   }
671   else if (WBCTversion == 1)
672   { // as shot R, as shot B, tint, CСT
673     for (i = 0; i < 15; i++)
674     {
675       icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f;
676       icWBCCTC[i][1] = 1024.0f / fMAX(get2(), 1.f);
677       icWBCCTC[i][3] = 1024.0f / fMAX(get2(), 1.f);
678       fseek(ifp, 2, SEEK_CUR);
679       icWBCCTC[i][0] = get2();
680     }
681   }
682   else if (WBCTversion == 2)
683   { // tint, offset, as shot R, as shot B, CСT
684     if ((unique_id == CanonID_EOS_M3)  ||
685         (unique_id == CanonID_EOS_M10) ||
686         (imCanon.ColorDataSubVer == 0xfffc))
687     {
688       for (i = 0; i < 15; i++)
689       {
690         fseek(ifp, 4, SEEK_CUR);
691         icWBCCTC[i][2] = icWBCCTC[i][4] =
692             1.0f;
693         icWBCCTC[i][1] = 1024.0f / fMAX(1.f, get2());
694         icWBCCTC[i][3] = 1024.0f / fMAX(1.f, get2());
695         icWBCCTC[i][0] = get2();
696       }
697     }
698     else if (imCanon.ColorDataSubVer == 0xfffd)
699     {
700       for (i = 0; i < 15; i++)
701       {
702         fseek(ifp, 2, SEEK_CUR);
703         norm = (signed short)get2();
704         norm = 512.0f + norm / 8.0f;
705         icWBCCTC[i][2] = icWBCCTC[i][4] =
706             1.0f;
707         icWBCCTC[i][1] = (float)get2();
708         if (norm > 0.001f)
709           icWBCCTC[i][1] /= norm;
710         icWBCCTC[i][3] = (float)get2();
711         if (norm > 0.001f)
712           icWBCCTC[i][3] /= norm;
713         icWBCCTC[i][0] = get2();
714       }
715     }
716   }
717   return;
718 }
719 
parseCanonMakernotes(unsigned tag,unsigned type,unsigned len,unsigned dng_writer)720 void LibRaw::parseCanonMakernotes(unsigned tag, unsigned type, unsigned len, unsigned dng_writer)
721 {
722 
723 #define AsShot_Auto_MeasuredWB(offset)                       \
724   imCanon.ColorDataSubVer = get2();                          \
725   fseek(ifp, save1 + (offset << 1), SEEK_SET);               \
726   FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2();             \
727   get2();                                                    \
728   FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();     \
729   get2();                                                    \
730   FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] = get2();
731 
732 #define sRAW_WB(offset)                                      \
733   fseek(ifp, save1 + (offset << 1), SEEK_SET);               \
734   FORC4 {                                                    \
735     sraw_mul[RGGB_2_RGBG(c)] = get2();                       \
736     if ((float)sraw_mul[RGGB_2_RGBG(c)] > sraw_mul_max) {    \
737       sraw_mul_max = (float)sraw_mul[RGGB_2_RGBG(c)];        \
738     }                                                        \
739   }                                                          \
740   sraw_mul_max /= 1024.f;                                    \
741   FORC4 sraw_mul[c] = (ushort)((float)sraw_mul[c] * sraw_mul_max);
742 
743 #define CR3_ColorData(offset)                                \
744   fseek(ifp, save1 + ((offset+0x0041) << 1), SEEK_SET);      \
745   Canon_WBpresets(2, 12);                                    \
746   fseek(ifp, save1 + ((offset+0x00c3) << 1), SEEK_SET);      \
747   Canon_WBCTpresets(0);                                      \
748   offsetChannelBlackLevel2 = save1 + ((offset+0x0102) << 1); \
749   offsetChannelBlackLevel  = save1 + ((offset+0x02d1) << 1); \
750   offsetWhiteLevels        = save1 + ((offset+0x02d5) << 1);
751 
752   int c;
753   unsigned i;
754 
755   if (tag == 0x0001) {
756     Canon_CameraSettings(len);
757 
758   } else if (tag == 0x0002) { // focal length
759     ilm.FocalType = get2();
760     ilm.CurFocal = get2();
761     if (ilm.FocalUnits > 1) {
762       ilm.CurFocal /= (float)ilm.FocalUnits;
763     }
764 
765   } else if (tag == 0x0004) { // subdir, ShotInfo
766     short tempAp;
767     if (dng_writer == nonDNG) {
768       get2();
769       imCanon.ISOgain[0] = get2();
770       imCanon.ISOgain[1] = get2();
771       if (imCanon.ISOgain[1] != 0x7fff) {
772         imCommon.real_ISO = floorf(100.f * libraw_powf64l(2.f, float(imCanon.ISOgain[0]+imCanon.ISOgain[1]) / 32.f - 5.f));
773         if (!iso_speed || (iso_speed == 65535))
774           iso_speed = imCommon.real_ISO;
775       }
776       get4();
777       if (((i = get2()) != 0xffff) && !shutter) {
778         shutter = libraw_powf64l(2.f, float((short)i) / -32.0f);
779       }
780       imCanon.wbi = (get2(), get2());
781       shot_order = (get2(), get2());
782       fseek(ifp, 4, SEEK_CUR);
783     } else
784       fseek(ifp, 24, SEEK_CUR);
785     tempAp = get2();
786     if (tempAp != 0)
787       imCommon.CameraTemperature = (float)(tempAp - 128);
788     tempAp = get2();
789     if (tempAp != -1)
790       imCommon.FlashGN = ((float)tempAp) / 32;
791     get2();
792 
793     imCommon.FlashEC = _CanonConvertEV((signed short)get2());
794     fseek(ifp, 8 - 32, SEEK_CUR);
795     if ((tempAp = get2()) != 0x7fff)
796       ilm.CurAp = _CanonConvertAperture(tempAp);
797     if (ilm.CurAp < 0.7f) {
798       fseek(ifp, 32, SEEK_CUR);
799       ilm.CurAp = _CanonConvertAperture(get2());
800     }
801     if (!aperture)
802       aperture = ilm.CurAp;
803 
804   } else if ((tag == 0x0007) && (dng_writer == nonDNG)) {
805     fgets(model2, 64, ifp);
806 
807   } else if ((tag == 0x0008) && (dng_writer == nonDNG)) {
808     shot_order = get4();
809 
810   } else if ((tag == 0x0009)  && (dng_writer == nonDNG)) {
811     fread(artist, 64, 1, ifp);
812 
813   } else if (tag == 0x000c) {
814     unsigned tS = get4();
815     sprintf(imgdata.shootinginfo.BodySerial, "%d", tS);
816 
817   } else if ((tag == 0x0012) ||
818              (tag == 0x0026) ||
819              (tag == 0x003c)) {
820     if (!imCommon.afcount) {
821       imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
822       imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
823       imCommon.afdata[imCommon.afcount].AFInfoData_length = len;
824       imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length);
825       fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
826       imCommon.afcount = 1;
827     }
828 
829   } else if ((tag == 0x0029) && (dng_writer == nonDNG)) { // PowerShot G9
830     int Got_AsShotWB = 0;
831     fseek(ifp, 8, SEEK_CUR);
832     for (unsigned linenum = 0; linenum < Canon_G9_linenums_2_StdWBi.size(); linenum++) {
833       if (Canon_G9_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown ) {
834         FORC4 icWBC[Canon_G9_linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get4();
835         if (Canon_wbi2std[imCanon.wbi] == Canon_G9_linenums_2_StdWBi[linenum]) {
836           FORC4 cam_mul[c] = float(icWBC[Canon_G9_linenums_2_StdWBi[linenum]][c]);
837           Got_AsShotWB = 1;
838         }
839       }
840       fseek(ifp, 16, SEEK_CUR);
841     }
842     if (!Got_AsShotWB)
843       FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]);
844 
845   } else if ((tag == 0x0081) && (dng_writer == nonDNG)) { // -1D, -1Ds
846     data_offset = get4();
847     fseek(ifp, data_offset + 41, SEEK_SET);
848     raw_height = get2() * 2;
849     raw_width = get2();
850     filters = 0x61616161;
851 
852   } else if (tag == 0x0093) {
853     if (!imCanon.RF_lensID) {
854       fseek(ifp, 0x03d<<1, SEEK_CUR);
855       imCanon.RF_lensID = get2();
856     }
857 
858   } else if (tag == 0x0095 && !ilm.Lens[0])
859   { // lens model tag
860     fread(ilm.Lens, 64, 1, ifp);
861     if (!strncmp(ilm.Lens, "EF-S", 4))
862     {
863       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
864       ilm.Lens[4] = ' ';
865       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
866       ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S;
867       ilm.LensFormat = LIBRAW_FORMAT_APSC;
868     }
869     else if (!strncmp(ilm.Lens, "EF-M", 4))
870     {
871       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
872       ilm.Lens[4] = ' ';
873       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
874       ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M;
875       ilm.LensFormat = LIBRAW_FORMAT_APSC;
876     }
877     else if (!strncmp(ilm.Lens, "EF", 2))
878     {
879       memmove(ilm.Lens + 3, ilm.Lens + 2, 62);
880       ilm.Lens[2] = ' ';
881       memcpy(ilm.LensFeatures_pre, ilm.Lens, 2);
882       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
883       ilm.LensFormat = LIBRAW_FORMAT_FF;
884     }
885     else if (!strncmp(ilm.Lens, "CN-E", 4))
886     {
887       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
888       ilm.Lens[4] = ' ';
889       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
890       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
891       ilm.LensFormat = LIBRAW_FORMAT_FF;
892     }
893     else if (!strncmp(ilm.Lens, "TS-E", 4))
894     {
895       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
896       ilm.Lens[4] = ' ';
897       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
898       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
899       ilm.LensFormat = LIBRAW_FORMAT_FF;
900     }
901     else if (!strncmp(ilm.Lens, "MP-E", 4))
902     {
903       memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
904       ilm.Lens[4] = ' ';
905       memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
906       ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
907       ilm.LensFormat = LIBRAW_FORMAT_FF;
908     }
909     else if (!strncmp(ilm.Lens, "RF", 2))
910     {
911       memmove(ilm.Lens + 3, ilm.Lens + 2, 62);
912       ilm.Lens[2] = ' ';
913       memcpy(ilm.LensFeatures_pre, ilm.Lens, 2);
914       ilm.LensMount = LIBRAW_MOUNT_Canon_RF;
915       ilm.LensFormat = LIBRAW_FORMAT_FF;
916     }
917   }
918   else if (tag == 0x009a)
919   { // AspectInfo
920     i = get4();
921     switch (i)
922     {
923     case 0:
924     case 12: /* APS-H crop */
925     case 13: /* APS-C crop */
926       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
927       break;
928     case 1:
929       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1;
930       break;
931     case 2:
932       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3;
933       break;
934     case 7:
935       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9;
936       break;
937     case 8:
938       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4;
939       break;
940     default:
941       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER;
942       break;
943     }
944     imgdata.sizes.raw_inset_crops[0].cwidth = get4();
945     imgdata.sizes.raw_inset_crops[0].cheight = get4();
946     imgdata.sizes.raw_inset_crops[0].cleft = get4();
947     imgdata.sizes.raw_inset_crops[0].ctop = get4();
948 
949   } else if ((tag == 0x00a4) && (dng_writer == nonDNG)) { // -1D, -1Ds
950     fseek(ifp, imCanon.wbi * 48, SEEK_CUR);
951     FORC3 cam_mul[c] = get2();
952 
953   } else if (tag == 0x00a9) {
954     INT64 save1 = ftell(ifp);
955     fseek(ifp, (0x1 << 1), SEEK_CUR);
956     FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
957     Canon_WBpresets(0, 0);
958     fseek(ifp, save1, SEEK_SET);
959   }
960   else if (tag == 0x00b4)
961   {
962     switch (get2()) {
963     case 1:
964       imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB;
965       break;
966     case 2:
967       imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
968       break;
969     default:
970       imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown;
971       break;
972     }
973   }
974   else if (tag == 0x00e0) // SensorInfo
975   {
976     imCanon.SensorWidth  = (get2(), get2());
977     imCanon.SensorHeight = get2();
978     fseek(ifp, 4, SEEK_CUR);
979     imCanon.DefaultCropAbsolute = get_CanonArea();
980     imCanon.LeftOpticalBlack    = get_CanonArea();
981   }
982   else if (tag == 0x4001 && len > 500)
983   {
984     float sraw_mul_max = 0.f;
985     int bls = 0;
986     INT64 offsetChannelBlackLevel = 0L;
987     INT64 offsetChannelBlackLevel2 = 0L;
988     INT64 offsetWhiteLevels = 0L;
989     INT64 save1 = ftell(ifp);
990 
991     switch (len)
992     {
993 
994     case 582:
995       imCanon.ColorDataVer = 1; // 20D, 350D
996 
997       fseek(ifp, save1 + (0x0019 << 1), SEEK_SET);
998       FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2();
999       fseek(ifp, save1 + (0x001e << 1), SEEK_SET);
1000       FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
1001       fseek(ifp, save1 + (0x0041 << 1), SEEK_SET);
1002       FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2();
1003       fseek(ifp, save1 + (0x0046 << 1), SEEK_SET);
1004       FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2();
1005 
1006       fseek(ifp, save1 + (0x0023 << 1), SEEK_SET);
1007       Canon_WBpresets(2, 2);
1008       fseek(ifp, save1 + (0x004b << 1), SEEK_SET);
1009       Canon_WBCTpresets(1); // ABCT
1010       offsetChannelBlackLevel = save1 + (0x00a6 << 1);
1011       break;
1012 
1013     case 653:
1014       imCanon.ColorDataVer = 2; // -1D Mark II, -1Ds Mark II
1015 
1016       fseek(ifp, save1 + (0x0018 << 1), SEEK_SET);
1017       FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
1018       fseek(ifp, save1 + (0x0022 << 1), SEEK_SET);
1019       FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2();
1020       fseek(ifp, save1 + (0x0090 << 1), SEEK_SET);
1021       FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2();
1022       fseek(ifp, save1 + (0x0095 << 1), SEEK_SET);
1023       FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2();
1024       fseek(ifp, save1 + (0x009a << 1), SEEK_SET);
1025       FORC4 icWBC[LIBRAW_WBI_Custom3][RGGB_2_RGBG(c)] = get2();
1026 
1027       fseek(ifp, save1 + (0x0027 << 1), SEEK_SET);
1028       Canon_WBpresets(2, 12);
1029       fseek(ifp, save1 + (0x00a4 << 1), SEEK_SET);
1030       Canon_WBCTpresets(1); // ABCT
1031       offsetChannelBlackLevel = save1 + (0x011e << 1);
1032       break;
1033 
1034     case 796:
1035       imCanon.ColorDataVer = 3; // -1D Mark II N, 5D, 30D, 400D; ColorDataSubVer: 1
1036       AsShot_Auto_MeasuredWB(0x003f);
1037 
1038       fseek(ifp, save1 + (0x0071 << 1), SEEK_SET);
1039       FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2();
1040       fseek(ifp, save1 + (0x0076 << 1), SEEK_SET);
1041       FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2();
1042       fseek(ifp, save1 + (0x007b << 1), SEEK_SET);
1043       FORC4 icWBC[LIBRAW_WBI_Custom3][RGGB_2_RGBG(c)] = get2();
1044       fseek(ifp, save1 + (0x0080 << 1), SEEK_SET);
1045       FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2();
1046 
1047       fseek(ifp, save1 + (0x004e << 1), SEEK_SET);
1048       Canon_WBpresets(2, 12);
1049       fseek(ifp, save1 + (0x0085 << 1), SEEK_SET);
1050       Canon_WBCTpresets(0); // BCAT
1051       offsetChannelBlackLevel = save1 + (0x00c4 << 1);
1052       break;
1053 
1054     case 674:  // -1D Mark III; ColorDataSubVer: 2
1055     case 692:  // 40D; ColorDataSubVer: 3
1056     case 702:  // -1Ds Mark III; ColorDataSubVer: 4
1057     case 1227: // 450D, 1000D; ColorDataSubVer: 5
1058     case 1250: // 5D Mark II, 50D; ColorDataSubVer: 6
1059     case 1251: // 500D; ColorDataSubVer: 7
1060     case 1337: // -1D Mark IV, 7D; ColorDataSubVer: 7
1061     case 1338: // 550D; ColorDataSubVer: 7
1062     case 1346: // 1100D, 60D; ColorDataSubVer: 9
1063       imCanon.ColorDataVer = 4;
1064       AsShot_Auto_MeasuredWB(0x003f);
1065       sRAW_WB(0x004e);
1066       fseek(ifp, save1 + (0x0053 << 1), SEEK_SET);
1067       Canon_WBpresets(2, 12);
1068       fseek(ifp, save1 + (0x00a8 << 1), SEEK_SET);
1069       Canon_WBCTpresets(0); // BCAT
1070 
1071       if ((imCanon.ColorDataSubVer == 4) ||
1072           (imCanon.ColorDataSubVer == 5))
1073       {
1074         offsetChannelBlackLevel = save1 + (0x02b4 << 1);
1075         offsetWhiteLevels = save1 + (0x02b8 << 1);
1076       }
1077       else if ((imCanon.ColorDataSubVer == 6) ||
1078                (imCanon.ColorDataSubVer == 7))
1079       {
1080         offsetChannelBlackLevel = save1 + (0x02cb << 1);
1081         offsetWhiteLevels = save1 + (0x02cf << 1);
1082       }
1083       else if (imCanon.ColorDataSubVer == 9)
1084       {
1085         offsetChannelBlackLevel = save1 + (0x02cf << 1);
1086         offsetWhiteLevels = save1 + (0x02d3 << 1);
1087       }
1088       else
1089         offsetChannelBlackLevel = save1 + (0x00e7 << 1);
1090       break;
1091 
1092     case 5120: // G10, G11, G12, G15, G16
1093                // G1 X, G1 X Mark II, G1 X Mark III
1094                // G3 X, G5 X
1095                // G7 X, G7 X Mark II
1096                // G9 X, G9 X Mark II
1097                // S90, S95, S100, S100V, S110, S120
1098                // SX1 IS, SX50 HS, SX60 HS
1099                // M3, M5, M6, M10, M100
1100       imCanon.ColorDataVer = 5;
1101       imCanon.ColorDataSubVer = get2();
1102 
1103       fseek(ifp, save1 + (0x0047 << 1), SEEK_SET);
1104       FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2();
1105 
1106       if (imCanon.ColorDataSubVer == 0xfffc) // ColorDataSubVer: 65532 (-4)
1107                                              // G7 X Mark II, G9 X Mark II, G1 X Mark III
1108                                              // M5, M100, M6
1109       {
1110         fseek(ifp, save1 + (0x004f << 1), SEEK_SET);
1111         FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
1112         fseek(ifp, 8, SEEK_CUR);
1113         FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] =
1114             get2();
1115         fseek(ifp, 8, SEEK_CUR);
1116         FORC4 icWBC[LIBRAW_WBI_Other][RGGB_2_RGBG(c)] = get2();
1117         fseek(ifp, 8, SEEK_CUR);
1118         Canon_WBpresets(8, 24);
1119         fseek(ifp, 168, SEEK_CUR);
1120         FORC4 icWBC[LIBRAW_WBI_FL_WW][RGGB_2_RGBG(c)] = get2();
1121         fseek(ifp, 24, SEEK_CUR);
1122         Canon_WBCTpresets(2); // BCADT
1123         offsetChannelBlackLevel = save1 + (0x014d << 1);
1124         offsetWhiteLevels = save1 + (0x0569 << 1);
1125       }
1126       else if (imCanon.ColorDataSubVer == 0xfffd) // ColorDataSubVer: 65533 (-3)
1127                                                   // M10, M3
1128                                                   // G1 X, G1 X Mark II
1129                                                   // G3 X, G5 X, G7 X, G9 X
1130                                                   // G10, G11, G12, G15, G16
1131                                                   // S90, S95, S100, S100V, S110, S120
1132                                                   // SX1 IS, SX50 HS, SX60 HS
1133       {
1134         fseek(ifp, save1 + (0x004c << 1), SEEK_SET);
1135         FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
1136         get2();
1137         FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] =
1138             get2();
1139         get2();
1140         FORC4 icWBC[LIBRAW_WBI_Other][RGGB_2_RGBG(c)] = get2();
1141         get2();
1142         Canon_WBpresets(2, 12);
1143         fseek(ifp, save1 + (0x00ba << 1), SEEK_SET);
1144         Canon_WBCTpresets(2); // BCADT
1145         offsetChannelBlackLevel = save1 + (0x0108 << 1);
1146       }
1147       break;
1148 
1149     case 1273: // 600D; ColorDataSubVer: 10
1150     case 1275: // 1200D; ColorDataSubVer: 10
1151       imCanon.ColorDataVer = 6;
1152       AsShot_Auto_MeasuredWB(0x003f);
1153       sRAW_WB(0x0062);
1154       fseek(ifp, save1 + (0x0067 << 1), SEEK_SET);
1155       Canon_WBpresets(2, 12);
1156       fseek(ifp, save1 + (0x00bc << 1), SEEK_SET);
1157       Canon_WBCTpresets(0); // BCAT
1158       offsetChannelBlackLevel = save1 + (0x01df << 1);
1159       offsetWhiteLevels = save1 + (0x01e3 << 1);
1160       break;
1161 
1162     case 1312: // 5D Mark III, 650D, 700D, M; ColorDataSubVer: 10
1163     case 1313: // 100D, 6D, 70D, EOS M2; ColorDataSubVer: 10
1164     case 1316: // -1D C, -1D X; ColorDataSubVer: 10
1165     case 1506: // 750D, 760D, 7D Mark II; ColorDataSubVer: 11
1166       imCanon.ColorDataVer = 7;
1167       AsShot_Auto_MeasuredWB(0x003f);
1168       sRAW_WB(0x007b);
1169       fseek(ifp, save1 + (0x0080 << 1), SEEK_SET);
1170       Canon_WBpresets(2, 12);
1171       fseek(ifp, save1 + (0x00d5 << 1), SEEK_SET);
1172       Canon_WBCTpresets(0); // BCAT
1173 
1174       if (imCanon.ColorDataSubVer == 10)
1175       {
1176         offsetChannelBlackLevel = save1 + (0x01f8 << 1);
1177         offsetWhiteLevels = save1 + (0x01fc << 1);
1178       }
1179       else if (imCanon.ColorDataSubVer == 11)
1180       {
1181         offsetChannelBlackLevel = save1 + (0x02d8 << 1);
1182         offsetWhiteLevels = save1 + (0x02dc << 1);
1183       }
1184       break;
1185 
1186     case 1560: // 5DS, 5DS R; ColorDataSubVer: 12
1187     case 1592: // 5D Mark IV, 80D, -1D X Mark II; ColorDataSubVer: 13
1188     case 1353: // 1300D, 1500D, 3000D; ColorDataSubVer: 14
1189     case 1602: // 200D, 6D Mark II, 77D, 800D; ColorDataSubVer: 15
1190       imCanon.ColorDataVer = 8;
1191       AsShot_Auto_MeasuredWB(0x003f);
1192       sRAW_WB(0x0080);
1193       fseek(ifp, save1 + (0x0085 << 1), SEEK_SET);
1194       Canon_WBpresets(2, 12);
1195       fseek(ifp, save1 + (0x0107 << 1), SEEK_SET);
1196       Canon_WBCTpresets(0); // BCAT
1197 
1198       if (imCanon.ColorDataSubVer == 14) // 1300D, 1500D, 3000D
1199       {
1200         offsetChannelBlackLevel = save1 + (0x022c << 1);
1201         offsetWhiteLevels = save1 + (0x0230 << 1);
1202       }
1203       else
1204       {
1205         offsetChannelBlackLevel = save1 + (0x030a << 1);
1206         offsetWhiteLevels = save1 + (0x030e << 1);
1207       }
1208       break;
1209 
1210     case 1820: // M50; ColorDataSubVer: 16
1211     case 1824: // R; ColorDataSubVer: 17
1212     case 1816: // RP, 250D, SX70 HS; ColorDataSubVer: 18
1213                // M6 Mark II, M200, 90D, G5 X Mark II, G7 X Mark III, 850D; ColorDataSubVer: 19
1214       imCanon.ColorDataVer = 9;
1215       AsShot_Auto_MeasuredWB(0x0047);
1216       CR3_ColorData(0x0047);
1217       break;
1218 
1219     case 2024: // -1D X Mark III; ColorDataSubVer: 32
1220     case 3656: // R5, R6; ColorDataSubVer: 33
1221       imCanon.ColorDataVer = 10;
1222       AsShot_Auto_MeasuredWB(0x0055);
1223       CR3_ColorData(0x0055);
1224       break;
1225 
1226    default:
1227       imCanon.ColorDataSubVer = get2();
1228       break;
1229     }
1230 
1231     if (offsetChannelBlackLevel)
1232     {
1233       fseek(ifp, offsetChannelBlackLevel, SEEK_SET);
1234       FORC4
1235         bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2());
1236       imCanon.AverageBlackLevel = bls / 4;
1237     }
1238     if (offsetWhiteLevels)
1239     {
1240       if ((offsetWhiteLevels - offsetChannelBlackLevel) != 8L)
1241         fseek(ifp, offsetWhiteLevels, SEEK_SET);
1242       imCanon.NormalWhiteLevel = get2();
1243       imCanon.SpecularWhiteLevel = get2();
1244       FORC4
1245         imgdata.color.linear_max[c] = imCanon.SpecularWhiteLevel;
1246     }
1247 
1248     if(!imCanon.AverageBlackLevel && offsetChannelBlackLevel2)
1249     {
1250         fseek(ifp, offsetChannelBlackLevel2, SEEK_SET);
1251         FORC4
1252             bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2());
1253         imCanon.AverageBlackLevel = bls / 4;
1254     }
1255     fseek(ifp, save1, SEEK_SET);
1256 
1257   } else if (tag == 0x4013) {
1258     get4();
1259     imCanon.AFMicroAdjMode = get4();
1260     float a = float(get4());
1261     float b = float(get4());
1262     if (fabsf(b) > 0.001f)
1263       imCanon.AFMicroAdjValue = a / b;
1264 
1265   } else if (tag == 0x4018) {
1266     fseek(ifp, 8, SEEK_CUR);
1267     imCanon.AutoLightingOptimizer = get4();
1268     if ((imCanon.AutoLightingOptimizer > 3) ||
1269         (imCanon.AutoLightingOptimizer < 0))
1270       imCanon.AutoLightingOptimizer = 3;
1271     imCanon.HighlightTonePriority = get4();
1272     if ((imCanon.HighlightTonePriority > 5) ||
1273         (imCanon.HighlightTonePriority < 0))
1274       imCanon.HighlightTonePriority = 0;
1275     if (imCanon.HighlightTonePriority) {
1276       imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority);
1277     }
1278 
1279   } else if ((tag == 0x4021) && (dng_writer == nonDNG) &&
1280              (imCanon.multishot[0] = get4()) &&
1281              (imCanon.multishot[1] = get4())) {
1282     if (len >= 4) {
1283       imCanon.multishot[2] = get4();
1284       imCanon.multishot[3] = get4();
1285     }
1286     FORC4 cam_mul[c] = 1024;
1287   }
1288 #undef CR3_ColorData
1289 #undef sRAW_WB
1290 #undef AsShot_Auto_MeasuredWB
1291 }
1292