Coverage Report

Created: 2026-06-30 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/metadata/makernotes.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5
 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6
 LibRaw do not use RESTRICTED code from dcraw.c
7
8
 LibRaw is free software; you can redistribute it and/or modify
9
 it under the terms of the one of two licenses as you choose:
10
11
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17
 */
18
19
#include "../../internal/dcraw_defs.h"
20
21
1.36k
void LibRaw::parseSigmaMakernote (INT64 base, int uptag, unsigned /*dng_writer*/) {
22
1.36k
unsigned wb_table1 [] = {
23
1.36k
  LIBRAW_WBI_Auto, LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy,
24
1.36k
  LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Flash,
25
1.36k
  LIBRAW_WBI_Custom, LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2
26
1.36k
};
27
28
1.36k
  unsigned entries, tag, type, len;
29
1.36k
  INT64 save;
30
1.36k
  unsigned i;
31
32
1.36k
  entries = get2();
33
1.36k
  if (entries > 1000)
34
210
    return;
35
80.6k
  while (entries--) {
36
79.4k
    tiff_get(base, &tag, &type, &len, &save);
37
38
79.4k
  if (callbacks.makernotes_cb)
39
0
    {
40
0
      INT64 _savepos = ifp->tell();
41
0
      callbacks.makernotes_cb(callbacks.makernotesparser_data, tag | (uptag << 16), type, len, order, ifp, base);
42
0
      fseek(ifp, _savepos, SEEK_SET);
43
0
    }
44
45
79.4k
    if (tag == 0x0027) {
46
395
      ilm.LensID = get2();
47
79.0k
    } else if (tag == 0x002a) {
48
450
      ilm.MinFocal = getrealf(type);
49
450
      ilm.MaxFocal = getrealf(type);
50
78.6k
    } else if (tag == 0x002b) {
51
385
      ilm.MaxAp4MinFocal = getrealf(type);
52
385
      ilm.MaxAp4MaxFocal = getrealf(type);
53
78.2k
    } else if (tag == 0x0120) {
54
913
      const unsigned tblsz = (sizeof wb_table1 / sizeof wb_table1[0]);
55
913
      if ((len >= tblsz) && (len%3 == 0) && len/3 <= tblsz) {
56
1.69k
        for (i=0; i<(len/3); i++) {
57
1.49k
          icWBC[wb_table1[i]][0] = (int)(getreal(type)*10000.0);
58
1.49k
          icWBC[wb_table1[i]][1] = icWBC[wb_table1[i]][3] = (int)(getreal(type)*10000.0);
59
1.49k
          icWBC[wb_table1[i]][2] = (int)(getreal(type)*10000.0);
60
1.49k
        }
61
191
      }
62
913
    }
63
79.4k
    fseek(ifp, save, SEEK_SET);
64
79.4k
  }
65
66
1.15k
  return;
67
1.36k
}
68
69
void LibRaw::parse_makernote_0xc634(INT64 base, int uptag, unsigned dng_writer)
70
46.8k
{
71
72
46.8k
  if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
73
2
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
74
75
46.8k
  if (!strncmp(make, "NIKON", 5))
76
549
  {
77
549
    parseNikonMakernote(base, uptag, AdobeDNG);
78
549
    return;
79
549
  }
80
46.2k
  else if (!strncasecmp(make, "LEICA", 5))
81
319
  {
82
319
    parseLeicaMakernote(base, uptag, is_0xc634);
83
319
    return;
84
319
  }
85
86
45.9k
  short morder, sorder = order;
87
45.9k
  char buf[10] = {0,0,0,0,0,0,0,0,0,0};
88
45.9k
  INT64 fsize = ifp->size();
89
90
45.9k
  fread(buf, 1, 10, ifp);
91
45.9k
  buf[9] = 0;
92
93
45.9k
  if (!strcmp(buf, "EPSON"))
94
32
  {
95
32
    parseEpsonMakernote(base, uptag, AdobeDNG);
96
32
    return;
97
32
  }
98
45.9k
  else if (!strcmp(buf, "SIGMA"))
99
58
  {
100
58
    parseSigmaMakernote(base, uptag, AdobeDNG);
101
58
    return;
102
58
  }
103
104
45.8k
  unsigned entries, tag, type, len, c;
105
45.8k
  INT64 save;
106
107
45.8k
  uchar *CanonCameraInfo = NULL;
108
45.8k
  unsigned lenCanonCameraInfo = 0;
109
45.8k
  unsigned typeCanonCameraInfo = 0;
110
111
45.8k
  uchar *table_buf_0x0116;
112
45.8k
  ushort table_buf_0x0116_len = 0;
113
45.8k
  uchar *table_buf_0x2010;
114
45.8k
  ushort table_buf_0x2010_len = 0;
115
45.8k
  uchar *table_buf_0x9050;
116
45.8k
  ushort table_buf_0x9050_len = 0;
117
45.8k
  uchar *table_buf_0x9400;
118
45.8k
  ushort table_buf_0x9400_len = 0;
119
45.8k
  uchar *table_buf_0x9402;
120
45.8k
  ushort table_buf_0x9402_len = 0;
121
45.8k
  uchar *table_buf_0x9403;
122
45.8k
  ushort table_buf_0x9403_len = 0;
123
45.8k
  uchar *table_buf_0x9406;
124
45.8k
  ushort table_buf_0x9406_len = 0;
125
45.8k
  uchar *table_buf_0x940c;
126
45.8k
  ushort table_buf_0x940c_len = 0;
127
45.8k
  uchar *table_buf_0x940e;
128
45.8k
  ushort table_buf_0x940e_len = 0;
129
130
45.8k
  if (!strcmp(buf, "OLYMPUS") || !strcmp(buf, "PENTAX ") || !strncmp(buf,"OM SYS",6)||
131
28.5k
      (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG)))
132
17.7k
  {
133
17.7k
    base = ftell(ifp) - 10;
134
17.7k
    fseek(ifp, -2, SEEK_CUR);
135
17.7k
    order = get2();
136
17.7k
    if (buf[0] == 'O')
137
313
      get2();
138
17.4k
    else if (buf[0] == 'P')
139
17.0k
      is_PentaxRicohMakernotes = 1;
140
17.7k
  }
141
28.1k
  else if (is_PentaxRicohMakernotes && (dng_writer == CameraDNG))
142
11.1k
  {
143
11.1k
    base = ftell(ifp) - 10;
144
11.1k
    fseek(ifp, -4, SEEK_CUR);
145
11.1k
    order = get2();
146
11.1k
  }
147
16.9k
  else if (!strncmp(buf, "SONY", 4) ||
148
16.2k
           !strcmp(buf, "Panasonic"))
149
823
  {
150
823
    order = 0x4949;
151
823
    fseek(ifp, 2, SEEK_CUR);
152
823
  }
153
16.1k
  else if (!strncmp(buf, "FUJIFILM", 8))
154
23
  {
155
23
    base = ftell(ifp) - 10;
156
23
    order = 0x4949;
157
23
    fseek(ifp, 2, SEEK_CUR);
158
23
  }
159
16.1k
  else if (!strcmp(buf, "OLYMP") ||
160
15.9k
           !strcmp(buf, "Ricoh"))
161
236
  {
162
236
    fseek(ifp, -2, SEEK_CUR);
163
236
  }
164
15.8k
  else if (!strcmp(buf, "AOC") || !strcmp(buf, "QVC"))
165
1.07k
  {
166
1.07k
    fseek(ifp, -4, SEEK_CUR);
167
1.07k
  }
168
14.8k
  else
169
14.8k
  {
170
14.8k
    fseek(ifp, -10, SEEK_CUR);
171
14.8k
    if ((!strncmp(make, "SAMSUNG", 7) && (dng_writer == AdobeDNG)))
172
560
      base = ftell(ifp);
173
14.8k
  }
174
175
45.8k
  entries = get2();
176
45.8k
  if (entries > 1000)
177
5.98k
    return;
178
179
39.8k
  if (!strncasecmp(make, "SONY", 4) ||
180
36.4k
      !strncasecmp(make, "Konica", 6) ||
181
36.1k
      !strncasecmp(make, "Minolta", 7) ||
182
34.8k
      (!strncasecmp(make, "Hasselblad", 10) &&
183
2.34k
       (!strncasecmp(model, "Stellar", 7) ||
184
2.19k
        !strncasecmp(model, "Lunar", 5) ||
185
1.57k
        !strncasecmp(model, "Lusso", 5) ||
186
1.48k
        !strncasecmp(model, "HV", 2))))
187
6.01k
    is_Sony = 1;
188
189
39.8k
  if (!is_Olympus &&
190
24.1k
      (!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) ||
191
23.2k
      (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) {
192
896
    is_Olympus = 1;
193
896
    OlympusDNG_SubDirOffsetValid =
194
896
          strncmp(model, "E-300", 5) && strncmp(model, "E-330", 5) &&
195
854
          strncmp(model, "E-400", 5) && strncmp(model, "E-500", 5) &&
196
844
          strncmp(model, "E-1", 3);
197
896
  }
198
199
39.8k
  morder = order;
200
7.40M
  while (entries--)
201
7.36M
  {
202
7.36M
    order = morder;
203
204
7.36M
    tiff_get(base, &tag, &type, &len, &save);
205
206
7.36M
    INT64 pos = ifp->tell();
207
7.36M
    if (len > 8 && pos + len > 2 * fsize)
208
6.15M
    {
209
6.15M
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
210
6.15M
      continue;
211
6.15M
    }
212
1.21M
    tag |= uptag << 16;
213
1.21M
    if (len > 100 * 1024 * 1024)
214
0
      goto next; // 100Mb tag? No!
215
216
1.21M
  if (callbacks.makernotes_cb)
217
0
    {
218
0
      INT64 _savepos = ifp->tell();
219
0
      callbacks.makernotes_cb(callbacks.makernotesparser_data, tag, type, len, order, ifp, base);
220
0
      fseek(ifp, _savepos, SEEK_SET);
221
0
    }
222
223
1.21M
    if (!strncmp(make, "Canon", 5))
224
114k
    {
225
114k
      if (tag == 0x000d && len < 256000)
226
1.39k
      { // camera info
227
1.39k
        if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
228
528
        {
229
528
          CanonCameraInfo = (uchar *)calloc(MAX(16, len)+1,1);
230
528
          fread(CanonCameraInfo, len, 1, ifp);
231
528
        }
232
871
        else
233
871
        {
234
871
          CanonCameraInfo = (uchar *)calloc(MAX(16, len * 4)+1,1);
235
871
          fread(CanonCameraInfo, len, 4, ifp);
236
871
        }
237
1.39k
        lenCanonCameraInfo = len;
238
1.39k
        typeCanonCameraInfo = type;
239
1.39k
      }
240
241
112k
      else if (tag == 0x0010) // Canon ModelID
242
1.75k
      {
243
1.75k
        unique_id = get4();
244
1.75k
        setCanonBodyFeatures(unique_id);
245
1.75k
        if (lenCanonCameraInfo)
246
914
        {
247
914
          processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo,
248
914
                                 typeCanonCameraInfo, AdobeDNG);
249
914
          free(CanonCameraInfo);
250
914
          CanonCameraInfo = 0;
251
914
          lenCanonCameraInfo = 0;
252
914
        }
253
1.75k
      }
254
255
110k
      else
256
110k
        parseCanonMakernotes(tag, type, len, AdobeDNG);
257
114k
    }
258
259
1.10M
    else if (!strncmp(make, "FUJI", 4)) {
260
3.57k
      parseFujiMakernotes(tag, type, len, AdobeDNG);
261
262
1.09M
    } else if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) {
263
66.2k
      if (tag == 0x0011) {
264
295
        imHassy.SensorCode = getint(type);
265
65.9k
      } else if ((tag == 0x0015) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) {
266
330
        stmread (imHassy.SensorUnitConnector, len, ifp);
267
2.43k
        for (int i=0; i<(int)len; i++) {
268
2.27k
          if(!isalnum(imHassy.SensorUnitConnector[i]) &&
269
1.34k
             (imHassy.SensorUnitConnector[i]!=' ')    &&
270
1.08k
             (imHassy.SensorUnitConnector[i]!='/')    &&
271
790
             (imHassy.SensorUnitConnector[i]!='-')) {
272
168
            imHassy.SensorUnitConnector[0] = 0;
273
168
            break;
274
168
          }
275
2.27k
        }
276
65.5k
      } else if (tag == 0x0016) {
277
75
        imHassy.CoatingCode = getint(type);
278
65.5k
      } else if ((tag == 0x002a) &&
279
592
                 tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) &&
280
277
                 (len == 12) &&
281
45
                 imHassy.SensorUnitConnector[0]) {
282
304
        FORC4 for (int i = 0; i < 3; i++)
283
228
                imHassy.mnColorMatrix[c][i] = getreal(type);
284
285
65.4k
      } else if ((tag == 0x0031) &&
286
354
                 imHassy.SensorUnitConnector[0]) {
287
43
        imHassy.RecommendedCrop[0] = getint(type);
288
43
        imHassy.RecommendedCrop[1] = getint(type);
289
43
      }
290
291
1.03M
    } else if (is_Olympus) {
292
293
728k
      if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) ||
294
719k
          (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) ||
295
716k
          (tag == 0x3000))
296
12.7k
      {
297
12.7k
        fseek(ifp, save - 4, SEEK_SET);
298
12.7k
        fseek(ifp, base + get4(), SEEK_SET);
299
12.7k
        parse_makernote_0xc634(base, tag, dng_writer);
300
12.7k
      }
301
302
728k
      if (!OlympusDNG_SubDirOffsetValid &&
303
106k
          ((len > 4) ||
304
83.3k
           ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) ||
305
81.8k
            tagtypeIs(LIBRAW_EXIFTAG_TYPE_SSHORT)) && (len > 2)) ||
306
83.0k
           ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) ||
307
82.3k
             tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG)) && (len > 1)) ||
308
82.7k
           tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL) ||
309
82.3k
           (type > LIBRAW_EXIFTAG_TYPE_SLONG))) {
310
54.0k
        goto skip_Oly_broken_tags;
311
54.0k
      }
312
674k
      else {
313
674k
        parseOlympusMakernotes(base, tag, type, len, AdobeDNG);
314
674k
      }
315
728k
    skip_Oly_broken_tags:;
316
728k
    }
317
318
303k
    else if (!strncmp(make, "PENTAX", 6)  ||
319
301k
             !strncmp(model, "PENTAX", 6) ||
320
301k
             is_PentaxRicohMakernotes)
321
160k
    {
322
160k
      parsePentaxMakernotes(base, tag, type, len, dng_writer);
323
160k
    }
324
143k
    else if (!strncmp(make, "SAMSUNG", 7))
325
8.15k
    {
326
8.15k
      if (dng_writer == AdobeDNG)
327
6.11k
        parseSamsungMakernotes(base, tag, type, len, dng_writer);
328
2.04k
      else
329
2.04k
        parsePentaxMakernotes(base, tag, type, len, dng_writer);
330
8.15k
    }
331
134k
    else if (is_Sony)
332
91.1k
    {
333
91.1k
      parseSonyMakernotes(
334
91.1k
          base, tag, type, len, AdobeDNG,
335
91.1k
          table_buf_0x0116, table_buf_0x0116_len,
336
91.1k
          table_buf_0x2010, table_buf_0x2010_len,
337
91.1k
          table_buf_0x9050, table_buf_0x9050_len,
338
91.1k
          table_buf_0x9400, table_buf_0x9400_len,
339
91.1k
          table_buf_0x9402, table_buf_0x9402_len,
340
91.1k
          table_buf_0x9403, table_buf_0x9403_len,
341
91.1k
          table_buf_0x9406, table_buf_0x9406_len,
342
91.1k
          table_buf_0x940c, table_buf_0x940c_len,
343
91.1k
          table_buf_0x940e, table_buf_0x940e_len);
344
91.1k
    }
345
1.21M
  next:
346
1.21M
    fseek(ifp, save, SEEK_SET);
347
1.21M
  }
348
349
38.7k
  order = sorder;
350
38.7k
}
351
352
void LibRaw::parse_makernote(INT64 base, int uptag)
353
492k
{
354
355
492k
  if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
356
12
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
357
358
492k
  if (!strncmp(make, "NIKON", 5))
359
34.3k
  {
360
34.3k
    parseNikonMakernote(base, uptag, nonDNG);
361
34.3k
    return;
362
34.3k
  }
363
458k
  else if (!strncasecmp(make, "LEICA", 5))
364
22.2k
  {
365
22.2k
    parseLeicaMakernote(base, uptag, is_0x927c);
366
22.2k
    return;
367
22.2k
  }
368
369
436k
  if (!strncmp(make, "Nokia", 5))
370
360
    return;
371
372
435k
  char buf[10];
373
435k
  char another_buf[128];
374
375
435k
  memset(another_buf,0,sizeof(another_buf));
376
435k
  memset(buf,0,sizeof(buf));
377
378
435k
  fseek(ifp, -12, SEEK_CUR);
379
435k
  fread (another_buf, 1, 12, ifp);
380
435k
  if (!strncmp(another_buf, "SONY", 4) ||
381
433k
      !strncmp(another_buf, "VHAB", 4)) { // Sony branded as Hasselblad
382
3.90k
    is_Sony = 1;
383
3.90k
  }
384
385
435k
  fread(buf, 1, 10, ifp);
386
387
435k
  if (!strncmp(buf, "KDK", 3)  || /* these aren't TIFF tables */
388
435k
      !strncmp(buf, "VER", 3)  ||
389
434k
      !strncmp(buf, "IIII", 4) ||
390
433k
      !strncmp(buf, "MMMM", 4))
391
2.29k
    return;
392
393
433k
  if (!strcmp(buf, "EPSON"))
394
2.15k
  {
395
2.15k
    parseEpsonMakernote(base, uptag, nonDNG);
396
2.15k
    return;
397
2.15k
  }
398
431k
  else if (!strcmp(buf, "SIGMA"))
399
1.31k
  {
400
1.31k
    parseSigmaMakernote(base, uptag, CameraDNG);
401
1.31k
    return;
402
1.31k
  }
403
404
405
429k
  unsigned entries, tag, type, len, c;
406
429k
  INT64 save;
407
429k
  unsigned wb[4] = {0, 0, 0, 0};
408
429k
  short morder, sorder = order;
409
410
429k
  uchar *CanonCameraInfo = 0;;
411
429k
  unsigned lenCanonCameraInfo = 0;
412
429k
  unsigned typeCanonCameraInfo = 0;
413
429k
  imCanon.wbi = 0;
414
415
429k
  uchar *table_buf_0x0116;
416
429k
  ushort table_buf_0x0116_len = 0;
417
429k
  uchar *table_buf_0x2010;
418
429k
  ushort table_buf_0x2010_len = 0;
419
429k
  uchar *table_buf_0x9050;
420
429k
  ushort table_buf_0x9050_len = 0;
421
429k
  uchar *table_buf_0x9400;
422
429k
  ushort table_buf_0x9400_len = 0;
423
429k
  uchar *table_buf_0x9402;
424
429k
  ushort table_buf_0x9402_len = 0;
425
429k
  uchar *table_buf_0x9403;
426
429k
  ushort table_buf_0x9403_len = 0;
427
429k
  uchar *table_buf_0x9406;
428
429k
  ushort table_buf_0x9406_len = 0;
429
429k
  uchar *table_buf_0x940c;
430
429k
  ushort table_buf_0x940c_len = 0;
431
429k
  uchar *table_buf_0x940e;
432
429k
  ushort table_buf_0x940e_len = 0;
433
434
429k
  INT64 fsize = ifp->size();
435
436
  /*
437
       The MakerNote might have its own TIFF header (possibly with
438
       its own byte-order!), or it might just be a table.
439
  */
440
441
429k
  if (!strncmp(buf, "KC", 2) || /* Konica KD-400Z, KD-510Z */
442
429k
      !strncmp(buf, "MLY", 3))  /* Minolta DiMAGE G series */
443
2.57k
  {
444
2.57k
    order = 0x4d4d;
445
2.57k
  INT64 ii;
446
1.91M
    while ((ii = ftell(ifp)) < data_offset && ii < 16384LL)
447
1.91M
    {
448
1.91M
      wb[0] = wb[2];
449
1.91M
      wb[2] = wb[1];
450
1.91M
      wb[1] = wb[3];
451
1.91M
    if (feof(ifp))
452
1.20k
      break;
453
1.91M
      wb[3] = get2();
454
1.91M
      if (wb[1] == 256 && wb[3] == 256 && wb[0] > 256 && wb[0] < 640 &&
455
1.86k
          wb[2] > 256 && wb[2] < 640)
456
3.42k
        FORC4 cam_mul[c] = float(wb[c]);
457
1.91M
    }
458
2.57k
    goto quit;
459
2.57k
  }
460
461
427k
  if (!strcmp(buf, "OLYMPUS") || !strncmp(buf, "OM SYS",6) ||
462
426k
      !strcmp(buf, "PENTAX "))
463
715
  {
464
715
    base = ftell(ifp) - 10;
465
715
    fseek(ifp, -2, SEEK_CUR);
466
715
  if (buf[1] == 'M')
467
219
    get4();
468
715
    order = get2();
469
715
    if (buf[0] == 'O')
470
397
      get2();
471
715
  }
472
426k
  else if (!strncmp(buf, "SONY", 4) || // DSLR-A100
473
423k
           !strcmp(buf, "Panasonic")) {
474
4.04k
    if (buf[0] == 'S')
475
3.31k
      is_Sony = 1;
476
4.04k
    goto nf;
477
4.04k
  }
478
422k
  else if (!strncmp(buf, "FUJIFILM", 8))
479
516
  {
480
516
    base = ftell(ifp) - 10;
481
4.55k
  nf:
482
4.55k
    order = 0x4949;
483
4.55k
    fseek(ifp, 2, SEEK_CUR);
484
4.55k
  }
485
422k
  else if (!strcmp (buf, "OLYMP")    ||
486
421k
           !strncmp(buf, "LEICA", 5) ||
487
419k
           !strcmp (buf, "Ricoh"))
488
3.46k
  {
489
3.46k
    fseek(ifp, -2, SEEK_CUR);
490
3.46k
  }
491
418k
  else if (!strcmp(buf, "AOC") || // Pentax, tribute to Asahi Optical Co.
492
418k
           !strcmp(buf, "QVC"))   // Casio, from "QV-Camera"
493
488
  {
494
488
    fseek(ifp, -4, SEEK_CUR);
495
488
  }
496
418k
  else if (!strncmp(buf, "CMT3", 4))
497
651
  {
498
651
    order = sget2((uchar *)(buf + 4));
499
651
    fseek(ifp, 2L, SEEK_CUR);
500
651
  }
501
417k
  else if (libraw_internal_data.unpacker_data.CR3_CTMDtag)
502
0
  {
503
0
    order = sget2((uchar *)buf);
504
0
    fseek(ifp, -2L, SEEK_CUR);
505
0
  }
506
417k
  else
507
417k
  {
508
417k
    fseek(ifp, -10, SEEK_CUR);
509
417k
    if (!strncmp(make, "SAMSUNG", 7))
510
32.6k
      base = ftell(ifp);
511
417k
  }
512
513
427k
  if (!is_Olympus &&
514
341k
      (!strncasecmp(make, "Olympus", 7) || !strncmp(make, "OM Digi", 7) ||
515
340k
      (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) {
516
1.67k
    is_Olympus = 1;
517
1.67k
  }
518
519
427k
  if (!is_Sony &&
520
254k
      (!strncasecmp(make, "SONY", 4) ||
521
251k
       !strncasecmp(make, "Konica", 6) ||
522
251k
       !strncasecmp(make, "Minolta", 7) ||
523
250k
       (!strncasecmp(make, "Hasselblad", 10) &&
524
5.58k
        (!strncasecmp(model, "Stellar", 7) ||
525
5.57k
         !strncasecmp(model, "Lunar", 5) ||
526
5.57k
         !strncasecmp(model, "Lusso", 5) ||
527
5.57k
         !strncasecmp(model, "HV", 2))))) {
528
3.84k
    is_Sony = 1;
529
3.84k
  }
530
531
427k
  if (strcasestr(make, "Kodak") &&
532
55.9k
      (sget2((uchar *)buf) > 1) && // check number of entries
533
53.7k
      (sget2((uchar *)buf) < 128) &&
534
44.3k
      (sget2((uchar *)(buf + 4)) > 0) && // check type
535
36.3k
      (sget2((uchar *)(buf + 4)) < 13) &&
536
9.31k
      (sget4((uchar *)(buf + 6)) < 256) // check count
537
427k
  )
538
1.26k
    imKodak.MakerNoteKodak8a = 1; // Kodak P712 / P850 / P880
539
540
427k
  entries = get2();
541
427k
  if (entries > 1000)
542
35.1k
    return;
543
544
392k
  morder = order;
545
31.8M
  while (entries--)
546
31.4M
  {
547
31.4M
    order = morder;
548
31.4M
    tiff_get(base, &tag, &type, &len, &save);
549
31.4M
    tag |= uptag << 16;
550
551
31.4M
    INT64 _pos = ftell(ifp);
552
31.4M
    if (len > 100 * 1024 * 1024)
553
15.7M
  goto next; // 100Mb tag? No!
554
15.7M
    if (len > 8 && _pos + len > 2 * fsize)
555
10.9M
    {
556
10.9M
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
557
10.9M
      continue;
558
10.9M
    }
559
560
4.74M
  if (callbacks.makernotes_cb)
561
0
    {
562
0
      INT64 _savepos = ifp->tell();
563
0
      callbacks.makernotes_cb(callbacks.makernotesparser_data, tag, type, len, order, ifp, base);
564
0
      fseek(ifp, _savepos, SEEK_SET);
565
0
    }
566
567
4.74M
    if (imKodak.MakerNoteKodak8a)
568
51.3k
    {
569
51.3k
      if ((tag == 0xff00) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) && (len == 1))
570
1.48k
      {
571
1.48k
        INT64 _pos1 = get4();
572
1.48k
        if ((_pos1 < fsize) && (_pos1 > 0))
573
360
        {
574
360
          fseek(ifp, _pos1, SEEK_SET);
575
360
          parse_makernote(base, tag);
576
360
        }
577
1.48k
      }
578
49.9k
      else if (tag == 0xff00f90b)
579
63
      {
580
63
        imKodak.clipBlack = get2();
581
63
      }
582
49.8k
      else if (tag == 0xff00f90c)
583
256
      {
584
256
        imKodak.clipWhite = imgdata.color.linear_max[0] =
585
256
            imgdata.color.linear_max[1] = imgdata.color.linear_max[2] =
586
256
                imgdata.color.linear_max[3] = get2();
587
256
      }
588
51.3k
    }
589
4.69M
    else if (!strncmp(make, "Canon", 5))
590
1.19M
    {
591
1.19M
      if (tag == 0x000d && len < 256000) // camera info
592
25.6k
      {
593
25.6k
        if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
594
12.5k
        {
595
12.5k
          CanonCameraInfo = (uchar *)calloc(MAX(16, len)+1,1);
596
12.5k
          fread(CanonCameraInfo, len, 1, ifp);
597
12.5k
        }
598
13.1k
        else
599
13.1k
        {
600
13.1k
          CanonCameraInfo = (uchar *)calloc(MAX(16, len * 4)+1,1);
601
13.1k
          fread(CanonCameraInfo, len, 4, ifp);
602
13.1k
        }
603
25.6k
        lenCanonCameraInfo = len;
604
25.6k
        typeCanonCameraInfo = type;
605
25.6k
      }
606
607
1.16M
      else if (tag == 0x0010) // Canon ModelID
608
37.0k
      {
609
37.0k
        unique_id = get4();
610
37.0k
        setCanonBodyFeatures(unique_id);
611
37.0k
        if (lenCanonCameraInfo)
612
18.4k
        {
613
18.4k
          processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo,
614
18.4k
                                 typeCanonCameraInfo, nonDNG);
615
18.4k
    if(CanonCameraInfo)
616
18.4k
            free(CanonCameraInfo);
617
18.4k
          CanonCameraInfo = 0;
618
18.4k
          lenCanonCameraInfo = 0;
619
18.4k
        }
620
37.0k
      }
621
622
1.12M
      else
623
1.12M
        parseCanonMakernotes(tag, type, len, nonDNG);
624
1.19M
    }
625
626
3.50M
    else if (!strncmp(make, "FUJI", 4))
627
174k
      parseFujiMakernotes(tag, type, len, nonDNG);
628
629
3.32M
    else if (!strncasecmp(model, "Hasselblad X1D", 14) ||
630
3.32M
             !strncasecmp(model, "Hasselblad H6D", 14) ||
631
3.32M
             !strncasecmp(model, "Hasselblad A6D", 14))
632
12.6k
    {
633
12.6k
      if (tag == 0x0045)
634
179
      {
635
179
        imHassy.BaseISO = get4();
636
179
      }
637
12.4k
      else if (tag == 0x0046)
638
314
      {
639
314
        imHassy.Gain = getreal(type);
640
314
      }
641
12.6k
    }
642
643
3.31M
    else if (!strncmp(make, "PENTAX", 6) ||
644
3.05M
             !strncmp(make, "RICOH", 5) ||
645
2.78M
             !strncmp(model, "PENTAX", 6))
646
556k
    {
647
556k
      if (!strncmp(model, "GR", 2) ||
648
391k
          !strncmp(model, "GXR", 3))
649
204k
      {
650
204k
        parseRicohMakernotes(base, tag, type, len, CameraDNG);
651
204k
      }
652
351k
      else
653
351k
      {
654
351k
        parsePentaxMakernotes(base, tag, type, len, nonDNG);
655
351k
      }
656
556k
    }
657
658
2.75M
    else if (!strncmp(make, "SAMSUNG", 7))
659
338k
    {
660
338k
      if (!dng_version)
661
106k
        parseSamsungMakernotes(base, tag, type, len, nonDNG);
662
232k
      else
663
232k
        parsePentaxMakernotes(base, tag, type, len, CameraDNG);
664
338k
    }
665
666
2.42M
    else if (is_Sony)
667
1.55M
    {
668
1.55M
      if ((tag == 0xb028) && (len == 1) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) // DSLR-A100
669
1.75k
      {
670
1.75k
        if ((c = get4()))
671
1.39k
        {
672
1.39k
          fseek(ifp, c, SEEK_SET);
673
1.39k
          parse_makernote(base, tag);
674
1.39k
        }
675
1.75k
      }
676
1.55M
      else
677
1.55M
      {
678
1.55M
        parseSonyMakernotes(
679
1.55M
            base, tag, type, len, nonDNG,
680
1.55M
            table_buf_0x0116, table_buf_0x0116_len,
681
1.55M
            table_buf_0x2010, table_buf_0x2010_len,
682
1.55M
            table_buf_0x9050, table_buf_0x9050_len,
683
1.55M
            table_buf_0x9400, table_buf_0x9400_len,
684
1.55M
            table_buf_0x9402, table_buf_0x9402_len,
685
1.55M
            table_buf_0x9403, table_buf_0x9403_len,
686
1.55M
            table_buf_0x9406, table_buf_0x9406_len,
687
1.55M
            table_buf_0x940c, table_buf_0x940c_len,
688
1.55M
            table_buf_0x940e, table_buf_0x940e_len);
689
1.55M
      }
690
1.55M
    }
691
4.74M
    fseek(ifp, _pos, SEEK_SET);
692
693
4.74M
    if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) {
694
61.8k
      if (tag == 0x0011)
695
866
        imHassy.SensorCode = getint(type);
696
61.0k
      else if (tag == 0x0016)
697
319
        imHassy.CoatingCode = getint(type);
698
60.7k
      else if ((tag == 0x002a) &&
699
860
               tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) &&
700
210
               (len == 12)) {
701
1.55k
        FORC4 for (int ii = 0; ii < 3; ii++)
702
1.16k
                imHassy.mnColorMatrix[c][ii] = getreal(type);
703
704
60.6k
      } else if (tag == 0x0031) {
705
449
        imHassy.RecommendedCrop[0] = getint(type);
706
449
        imHassy.RecommendedCrop[1] = getint(type);
707
449
      }
708
61.8k
    }
709
710
4.74M
    if ((tag == 0x0004 || tag == 0x0114) && !strncmp(make, "KONICA", 6))
711
4.11k
    {
712
4.11k
      fseek(ifp, tag == 0x0004 ? 140 : 160, SEEK_CUR);
713
4.11k
      switch (get2())
714
4.11k
      {
715
218
      case 72:
716
218
        flip = 0;
717
218
        break;
718
62
      case 76:
719
62
        flip = 6;
720
62
        break;
721
88
      case 82:
722
88
        flip = 5;
723
88
        break;
724
4.11k
      }
725
4.11k
    }
726
727
4.74M
    if (is_Olympus) {
728
1.11M
      INT64 _pos2 = ftell(ifp);
729
1.11M
      if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) ||
730
1.09M
          (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) ||
731
1.08M
          (tag == 0x3000))
732
34.6k
      {
733
34.6k
        if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) {
734
28.3k
          parse_makernote(base, tag);
735
736
28.3k
        } else if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_ifd) ||
737
6.07k
                   tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_int32u)) {
738
313
          fseek(ifp, base + get4(), SEEK_SET);
739
313
          parse_makernote(base, tag);
740
313
        }
741
742
1.07M
      } else {
743
1.07M
        parseOlympusMakernotes(base, tag, type, len, nonDNG);
744
1.07M
      }
745
1.11M
      fseek(ifp, _pos2, SEEK_SET);
746
1.11M
    }
747
748
4.74M
    if ((tag == 0x0015) &&
749
7.31k
        tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII) &&
750
1.68k
        is_raw)
751
1.64k
    { // Hasselblad
752
1.64k
      stmread (imHassy.SensorUnitConnector, len, ifp);
753
1.64k
    }
754
755
4.74M
    if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&
756
69.5k
        ((tag == 0x0081) || // Minolta
757
69.2k
         (tag == 0x0100)))  // Olympus
758
1.02k
    {
759
1.02k
      thumb_offset = ftell(ifp);
760
1.02k
      thumb_length = len;
761
1.02k
    }
762
4.74M
    if ((tag == 0x0088) && // Minolta, possibly Olympus too
763
3.15k
        tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) &&
764
912
        (thumb_offset = get4()))
765
618
      thumb_offset += base;
766
767
4.74M
    if ((tag == 0x0089) && // Minolta, possibly Olympus too
768
2.36k
        tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
769
346
      thumb_length = get4();
770
771
4.74M
    if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&  // Nikon
772
69.5k
        ((tag == 0x008c) ||
773
69.0k
         (tag == 0x0096))) {
774
816
      meta_offset = ftell(ifp);
775
816
    }
776
777
4.74M
    if ((tag == 0x00a1) &&
778
910
        tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&
779
237
        strncasecmp(make, "Samsung", 7))
780
122
    {
781
122
      order = 0x4949;
782
122
      fseek(ifp, 140, SEEK_CUR);
783
366
      FORC3 cam_mul[c] = float(get4());
784
122
    }
785
786
4.74M
    if (tag == 0xb001 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) // Sony ModelID
787
438
    {
788
438
      unique_id = get2();
789
438
    }
790
4.74M
    if (tag == 0x0200 && len == 3) // Olympus
791
864
      shot_order = (get4(), get4());
792
793
4.74M
    if (tag == 0x0f00 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED))
794
688
    {
795
688
      if (len == 614)
796
196
        fseek(ifp, 176, SEEK_CUR);
797
492
      else if (len == 734 || len == 1502) // Kodak, Minolta, Olympus
798
50
        fseek(ifp, 148, SEEK_CUR);
799
442
      else
800
442
        goto next;
801
246
      goto get2_256;
802
688
    }
803
804
4.74M
    if (tag == 0x2011 && len == 2) // Casio
805
573
    {
806
819
    get2_256:
807
819
      order = 0x4d4d;
808
819
      cam_mul[0] = float(get2()) / 256.0f;
809
819
      cam_mul[2] = float(get2()) / 256.0f;
810
819
    }
811
812
20.4M
  next:
813
20.4M
    fseek(ifp, save, SEEK_SET);
814
20.4M
  }
815
391k
quit:
816
391k
  order = sorder;
817
391k
}