Coverage Report

Created: 2026-06-30 07:12

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