Coverage Report

Created: 2026-11-12 07:35

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-2026 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.21k
void LibRaw::parseSigmaMakernote (INT64 base, int uptag, unsigned /*dng_writer*/) {
22
1.21k
unsigned wb_table1 [] = {
23
1.21k
  LIBRAW_WBI_Auto, LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy,
24
1.21k
  LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Flash,
25
1.21k
  LIBRAW_WBI_Custom, LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2
26
1.21k
};
27
28
1.21k
  unsigned entries, tag, type, len;
29
1.21k
  INT64 save;
30
1.21k
  unsigned i;
31
32
1.21k
  entries = get2();
33
1.21k
  if (entries > 1000)
34
314
    return;
35
36.0k
  while (entries--) {
36
35.1k
    tiff_get(base, &tag, &type, &len, &save);
37
38
35.1k
  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
35.1k
    if (tag == 0x0027) {
46
153
      ilm.LensID = get2();
47
35.0k
    } else if (tag == 0x002a) {
48
649
      ilm.MinFocal = getrealf(type);
49
649
      ilm.MaxFocal = getrealf(type);
50
34.3k
    } else if (tag == 0x002b) {
51
349
      ilm.MaxAp4MinFocal = getrealf(type);
52
349
      ilm.MaxAp4MaxFocal = getrealf(type);
53
34.0k
    } else if (tag == 0x0120) {
54
505
      const unsigned tblsz = (sizeof wb_table1 / sizeof wb_table1[0]);
55
505
      if ((len >= tblsz) && (len%3 == 0) && len/3 <= tblsz) {
56
1.11k
        for (i=0; i<(len/3); i++) {
57
979
          icWBC[wb_table1[i]][0] = (int)(getreal(type)*10000.0);
58
979
          icWBC[wb_table1[i]][1] = icWBC[wb_table1[i]][3] = (int)(getreal(type)*10000.0);
59
979
          icWBC[wb_table1[i]][2] = (int)(getreal(type)*10000.0);
60
979
        }
61
139
      }
62
505
    }
63
35.1k
    fseek(ifp, save, SEEK_SET);
64
35.1k
  }
65
66
904
  return;
67
1.21k
}
68
69
void LibRaw::parse_makernote_0xc634(INT64 base, int uptag, unsigned dng_writer)
70
44.9k
{
71
72
44.9k
  if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
73
1
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
74
75
44.9k
  if (!strncmp(make, "NIKON", 5))
76
455
  {
77
455
    parseNikonMakernote(base, uptag, AdobeDNG);
78
455
    return;
79
455
  }
80
44.4k
  else if (!strncasecmp(make, "LEICA", 5))
81
303
  {
82
303
    parseLeicaMakernote(base, uptag, is_0xc634);
83
303
    return;
84
303
  }
85
86
44.1k
  short morder, sorder = order;
87
44.1k
  char buf[10] = {0,0,0,0,0,0,0,0,0,0};
88
44.1k
  INT64 fsize = ifp->size();
89
90
44.1k
  fread(buf, 1, 10, ifp);
91
44.1k
  buf[9] = 0;
92
93
44.1k
  if (!strcmp(buf, "EPSON"))
94
27
  {
95
27
    parseEpsonMakernote(base, uptag, AdobeDNG);
96
27
    return;
97
27
  }
98
44.1k
  else if (!strcmp(buf, "SIGMA"))
99
58
  {
100
58
    parseSigmaMakernote(base, uptag, AdobeDNG);
101
58
    return;
102
58
  }
103
104
44.0k
  unsigned entries, tag, type, len, c;
105
44.0k
  INT64 save;
106
107
44.0k
  uchar *CanonCameraInfo = NULL;
108
44.0k
  unsigned lenCanonCameraInfo = 0;
109
44.0k
  unsigned typeCanonCameraInfo = 0;
110
111
44.0k
  uchar *table_buf_0x0116;
112
44.0k
  ushort table_buf_0x0116_len = 0;
113
44.0k
  uchar *table_buf_0x2010;
114
44.0k
  ushort table_buf_0x2010_len = 0;
115
44.0k
  uchar *table_buf_0x9050;
116
44.0k
  ushort table_buf_0x9050_len = 0;
117
44.0k
  uchar *table_buf_0x9400;
118
44.0k
  ushort table_buf_0x9400_len = 0;
119
44.0k
  uchar *table_buf_0x9402;
120
44.0k
  ushort table_buf_0x9402_len = 0;
121
44.0k
  uchar *table_buf_0x9403;
122
44.0k
  ushort table_buf_0x9403_len = 0;
123
44.0k
  uchar *table_buf_0x9406;
124
44.0k
  ushort table_buf_0x9406_len = 0;
125
44.0k
  uchar *table_buf_0x940c;
126
44.0k
  ushort table_buf_0x940c_len = 0;
127
44.0k
  uchar *table_buf_0x940e;
128
44.0k
  ushort table_buf_0x940e_len = 0;
129
130
44.0k
  if (!strcmp(buf, "OLYMPUS") || !strcmp(buf, "PENTAX ") || !strncmp(buf,"OM SYS",6)||
131
27.2k
      (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG)))
132
17.1k
  {
133
17.1k
    base = ftell(ifp) - 10;
134
17.1k
    fseek(ifp, -2, SEEK_CUR);
135
17.1k
    order = get2();
136
17.1k
    if (buf[0] == 'O')
137
169
      get2();
138
16.9k
    else if (buf[0] == 'P')
139
16.6k
      is_PentaxRicohMakernotes = 1;
140
17.1k
  }
141
26.9k
  else if (is_PentaxRicohMakernotes && (dng_writer == CameraDNG))
142
11.0k
  {
143
11.0k
    base = ftell(ifp) - 10;
144
11.0k
    fseek(ifp, -4, SEEK_CUR);
145
11.0k
    order = get2();
146
11.0k
  }
147
15.8k
  else if (!strncmp(buf, "SONY", 4) ||
148
15.0k
           !strcmp(buf, "Panasonic"))
149
960
  {
150
960
    order = 0x4949;
151
960
    fseek(ifp, 2, SEEK_CUR);
152
960
  }
153
14.9k
  else if (!strncmp(buf, "FUJIFILM", 8))
154
41
  {
155
41
    base = ftell(ifp) - 10;
156
41
    order = 0x4949;
157
41
    fseek(ifp, 2, SEEK_CUR);
158
41
  }
159
14.8k
  else if (!strcmp(buf, "OLYMP") ||
160
14.6k
           !strcmp(buf, "Ricoh"))
161
214
  {
162
214
    fseek(ifp, -2, SEEK_CUR);
163
214
  }
164
14.6k
  else if (!strcmp(buf, "AOC") || !strcmp(buf, "QVC"))
165
920
  {
166
920
    fseek(ifp, -4, SEEK_CUR);
167
920
  }
168
13.7k
  else
169
13.7k
  {
170
13.7k
    fseek(ifp, -10, SEEK_CUR);
171
13.7k
    if ((!strncmp(make, "SAMSUNG", 7) && (dng_writer == AdobeDNG)))
172
438
      base = ftell(ifp);
173
13.7k
  }
174
175
44.0k
  entries = get2();
176
44.0k
  if (entries > 1000)
177
5.45k
    return;
178
179
38.6k
  if (!strncasecmp(make, "SONY", 4) ||
180
35.2k
      !strncasecmp(make, "Konica", 6) ||
181
34.7k
      !strncasecmp(make, "Minolta", 7) ||
182
33.6k
      (!strncasecmp(make, "Hasselblad", 10) &&
183
1.90k
       (!strncasecmp(model, "Stellar", 7) ||
184
1.84k
        !strncasecmp(model, "Lunar", 5) ||
185
1.58k
        !strncasecmp(model, "Lusso", 5) ||
186
1.48k
        !strncasecmp(model, "HV", 2))))
187
5.46k
    is_Sony = 1;
188
189
38.6k
  if (!is_Olympus &&
190
22.7k
      (!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) ||
191
21.9k
      (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) {
192
887
    is_Olympus = 1;
193
887
    OlympusDNG_SubDirOffsetValid =
194
887
          strncmp(model, "E-300", 5) && strncmp(model, "E-330", 5) &&
195
845
          strncmp(model, "E-400", 5) && strncmp(model, "E-500", 5) &&
196
834
          strncmp(model, "E-1", 3);
197
887
  }
198
199
38.6k
  morder = order;
200
7.30M
  while (entries--)
201
7.26M
  {
202
7.26M
    order = morder;
203
204
7.26M
    tiff_get(base, &tag, &type, &len, &save);
205
206
7.26M
    INT64 pos = ifp->tell();
207
7.26M
    if (len > 8 && pos + len > 2 * fsize)
208
6.06M
    {
209
6.06M
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
210
6.06M
      continue;
211
6.06M
    }
212
1.20M
    tag |= uptag << 16;
213
1.20M
    if (len > 100 * 1024 * 1024)
214
0
      goto next; // 100Mb tag? No!
215
216
1.20M
  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.20M
    if (!strncmp(make, "Canon", 5))
224
104k
    {
225
104k
      if (tag == 0x000d && len < 256000)
226
1.70k
      { // camera info
227
1.70k
        if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
228
714
        {
229
714
          CanonCameraInfo = (uchar *)calloc(MAX(16, len)+1,1);
230
714
          fread(CanonCameraInfo, len, 1, ifp);
231
714
        }
232
992
        else
233
992
        {
234
992
          CanonCameraInfo = (uchar *)calloc(MAX(16, len * 4)+1,1);
235
992
          fread(CanonCameraInfo, len, 4, ifp);
236
992
        }
237
1.70k
        lenCanonCameraInfo = len;
238
1.70k
        typeCanonCameraInfo = type;
239
1.70k
      }
240
241
102k
      else if (tag == 0x0010) // Canon ModelID
242
2.22k
      {
243
2.22k
        unique_id = get4();
244
2.22k
        setCanonBodyFeatures(unique_id);
245
2.22k
        if (lenCanonCameraInfo)
246
1.10k
        {
247
1.10k
          processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo,
248
1.10k
                                 typeCanonCameraInfo, AdobeDNG);
249
1.10k
          free(CanonCameraInfo);
250
1.10k
          CanonCameraInfo = 0;
251
1.10k
          lenCanonCameraInfo = 0;
252
1.10k
        }
253
2.22k
      }
254
255
100k
      else
256
100k
        parseCanonMakernotes(tag, type, len, AdobeDNG);
257
104k
    }
258
259
1.10M
    else if (!strncmp(make, "FUJI", 4)) {
260
783
      parseFujiMakernotes(tag, type, len, AdobeDNG);
261
262
1.10M
    } else if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) {
263
66.8k
      if (tag == 0x0011) {
264
292
        imHassy.SensorCode = getint(type);
265
66.5k
      } else if ((tag == 0x0015) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) {
266
366
        stmread (imHassy.SensorUnitConnector, len, ifp);
267
2.26k
        for (int i=0; i<(int)len; i++) {
268
2.09k
          if(!isalnum(imHassy.SensorUnitConnector[i]) &&
269
1.39k
             (imHassy.SensorUnitConnector[i]!=' ')    &&
270
1.05k
             (imHassy.SensorUnitConnector[i]!='/')    &&
271
764
             (imHassy.SensorUnitConnector[i]!='-')) {
272
192
            imHassy.SensorUnitConnector[0] = 0;
273
192
            break;
274
192
          }
275
2.09k
        }
276
66.1k
      } else if (tag == 0x0016) {
277
65
        imHassy.CoatingCode = getint(type);
278
66.1k
      } else if ((tag == 0x002a) &&
279
637
                 tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) &&
280
296
                 (len == 12) &&
281
46
                 imHassy.SensorUnitConnector[0]) {
282
336
        FORC4 for (int i = 0; i < 3; i++)
283
252
                imHassy.mnColorMatrix[c][i] = getreal(type);
284
285
66.1k
      } else if ((tag == 0x0031) &&
286
341
                 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
748k
      if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) ||
294
740k
          (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) ||
295
737k
          (tag == 0x3000))
296
12.5k
      {
297
12.5k
        fseek(ifp, save - 4, SEEK_SET);
298
12.5k
        fseek(ifp, base + get4(), SEEK_SET);
299
12.5k
        parse_makernote_0xc634(base, tag, dng_writer);
300
12.5k
      }
301
302
748k
      if (!OlympusDNG_SubDirOffsetValid &&
303
72.8k
          ((len > 4) ||
304
58.0k
           ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) ||
305
56.3k
            tagtypeIs(LIBRAW_EXIFTAG_TYPE_SSHORT)) && (len > 2)) ||
306
57.5k
           ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) ||
307
56.7k
             tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG)) && (len > 1)) ||
308
57.0k
           tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL) ||
309
56.4k
           (type > LIBRAW_EXIFTAG_TYPE_SLONG))) {
310
37.0k
        goto skip_Oly_broken_tags;
311
37.0k
      }
312
711k
      else {
313
711k
        parseOlympusMakernotes(base, tag, type, len, AdobeDNG);
314
711k
      }
315
748k
    skip_Oly_broken_tags:;
316
748k
    }
317
318
286k
    else if (!strncmp(make, "PENTAX", 6)  ||
319
283k
             !strncmp(model, "PENTAX", 6) ||
320
282k
             is_PentaxRicohMakernotes)
321
135k
    {
322
135k
      parsePentaxMakernotes(base, tag, type, len, dng_writer);
323
135k
    }
324
151k
    else if (!strncmp(make, "SAMSUNG", 7))
325
12.4k
    {
326
12.4k
      if (dng_writer == AdobeDNG)
327
10.5k
        parseSamsungMakernotes(base, tag, type, len, dng_writer);
328
1.98k
      else
329
1.98k
        parsePentaxMakernotes(base, tag, type, len, dng_writer);
330
12.4k
    }
331
139k
    else if (is_Sony)
332
92.2k
    {
333
92.2k
      parseSonyMakernotes(
334
92.2k
          base, tag, type, len, AdobeDNG,
335
92.2k
          table_buf_0x0116, table_buf_0x0116_len,
336
92.2k
          table_buf_0x2010, table_buf_0x2010_len,
337
92.2k
          table_buf_0x9050, table_buf_0x9050_len,
338
92.2k
          table_buf_0x9400, table_buf_0x9400_len,
339
92.2k
          table_buf_0x9402, table_buf_0x9402_len,
340
92.2k
          table_buf_0x9403, table_buf_0x9403_len,
341
92.2k
          table_buf_0x9406, table_buf_0x9406_len,
342
92.2k
          table_buf_0x940c, table_buf_0x940c_len,
343
92.2k
          table_buf_0x940e, table_buf_0x940e_len);
344
92.2k
    }
345
1.20M
  next:
346
1.20M
    fseek(ifp, save, SEEK_SET);
347
1.20M
  }
348
349
37.4k
  order = sorder;
350
37.4k
}
351
352
void LibRaw::parse_makernote(INT64 base, int uptag)
353
483k
{
354
355
483k
  if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
356
9
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
357
358
483k
  if (!strncmp(make, "NIKON", 5))
359
35.2k
  {
360
35.2k
    parseNikonMakernote(base, uptag, nonDNG);
361
35.2k
    return;
362
35.2k
  }
363
448k
  else if (!strncasecmp(make, "LEICA", 5))
364
19.7k
  {
365
19.7k
    parseLeicaMakernote(base, uptag, is_0x927c);
366
19.7k
    return;
367
19.7k
  }
368
369
428k
  if (!strncmp(make, "Nokia", 5))
370
354
    return;
371
372
428k
  char buf[10];
373
428k
  char another_buf[128];
374
375
428k
  memset(another_buf,0,sizeof(another_buf));
376
428k
  memset(buf,0,sizeof(buf));
377
378
428k
  fseek(ifp, -12, SEEK_CUR);
379
428k
  fread (another_buf, 1, 12, ifp);
380
428k
  if (!strncmp(another_buf, "SONY", 4) ||
381
426k
      !strncmp(another_buf, "VHAB", 4)) { // Sony branded as Hasselblad
382
3.79k
    is_Sony = 1;
383
3.79k
  }
384
385
428k
  fread(buf, 1, 10, ifp);
386
387
428k
  if (!strncmp(buf, "KDK", 3)  || /* these aren't TIFF tables */
388
427k
      !strncmp(buf, "VER", 3)  ||
389
427k
      !strncmp(buf, "IIII", 4) ||
390
426k
      !strncmp(buf, "MMMM", 4))
391
2.00k
    return;
392
393
426k
  if (!strcmp(buf, "EPSON"))
394
1.84k
  {
395
1.84k
    parseEpsonMakernote(base, uptag, nonDNG);
396
1.84k
    return;
397
1.84k
  }
398
424k
  else if (!strcmp(buf, "SIGMA"))
399
1.16k
  {
400
1.16k
    parseSigmaMakernote(base, uptag, CameraDNG);
401
1.16k
    return;
402
1.16k
  }
403
404
405
423k
  unsigned entries, tag, type, len, c;
406
423k
  INT64 save;
407
423k
  unsigned wb[4] = {0, 0, 0, 0};
408
423k
  short morder, sorder = order;
409
410
423k
  uchar *CanonCameraInfo = 0;;
411
423k
  unsigned lenCanonCameraInfo = 0;
412
423k
  unsigned typeCanonCameraInfo = 0;
413
423k
  imCanon.wbi = 0;
414
415
423k
  uchar *table_buf_0x0116;
416
423k
  ushort table_buf_0x0116_len = 0;
417
423k
  uchar *table_buf_0x2010;
418
423k
  ushort table_buf_0x2010_len = 0;
419
423k
  uchar *table_buf_0x9050;
420
423k
  ushort table_buf_0x9050_len = 0;
421
423k
  uchar *table_buf_0x9400;
422
423k
  ushort table_buf_0x9400_len = 0;
423
423k
  uchar *table_buf_0x9402;
424
423k
  ushort table_buf_0x9402_len = 0;
425
423k
  uchar *table_buf_0x9403;
426
423k
  ushort table_buf_0x9403_len = 0;
427
423k
  uchar *table_buf_0x9406;
428
423k
  ushort table_buf_0x9406_len = 0;
429
423k
  uchar *table_buf_0x940c;
430
423k
  ushort table_buf_0x940c_len = 0;
431
423k
  uchar *table_buf_0x940e;
432
423k
  ushort table_buf_0x940e_len = 0;
433
434
423k
  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
423k
  if (!strncmp(buf, "KC", 2) || /* Konica KD-400Z, KD-510Z */
442
422k
      !strncmp(buf, "MLY", 3))  /* Minolta DiMAGE G series */
443
2.61k
  {
444
2.61k
    order = 0x4d4d;
445
2.61k
  INT64 ii;
446
1.78M
    while ((ii = ftell(ifp)) < data_offset && ii < 16384LL)
447
1.78M
    {
448
1.78M
      wb[0] = wb[2];
449
1.78M
      wb[2] = wb[1];
450
1.78M
      wb[1] = wb[3];
451
1.78M
    if (feof(ifp))
452
1.15k
      break;
453
1.78M
      wb[3] = get2();
454
1.78M
      if (wb[1] == 256 && wb[3] == 256 && wb[0] > 256 && wb[0] < 640 &&
455
1.61k
          wb[2] > 256 && wb[2] < 640)
456
2.76k
        FORC4 cam_mul[c] = float(wb[c]);
457
1.78M
    }
458
2.61k
    goto quit;
459
2.61k
  }
460
461
420k
  if (!strcmp(buf, "OLYMPUS") || !strncmp(buf, "OM SYS",6) ||
462
419k
      !strcmp(buf, "PENTAX "))
463
1.06k
  {
464
1.06k
    base = ftell(ifp) - 10;
465
1.06k
    fseek(ifp, -2, SEEK_CUR);
466
1.06k
  if (buf[1] == 'M')
467
519
    get4();
468
1.06k
    order = get2();
469
1.06k
    if (buf[0] == 'O')
470
708
      get2();
471
1.06k
  }
472
419k
  else if (!strncmp(buf, "SONY", 4) || // DSLR-A100
473
415k
           !strcmp(buf, "Panasonic")) {
474
4.69k
    if (buf[0] == 'S')
475
3.93k
      is_Sony = 1;
476
4.69k
    goto nf;
477
4.69k
  }
478
414k
  else if (!strncmp(buf, "FUJIFILM", 8))
479
635
  {
480
635
    base = ftell(ifp) - 10;
481
5.33k
  nf:
482
5.33k
    order = 0x4949;
483
5.33k
    fseek(ifp, 2, SEEK_CUR);
484
5.33k
  }
485
414k
  else if (!strcmp (buf, "OLYMP")    ||
486
413k
           !strncmp(buf, "LEICA", 5) ||
487
412k
           !strcmp (buf, "Ricoh"))
488
2.72k
  {
489
2.72k
    fseek(ifp, -2, SEEK_CUR);
490
2.72k
  }
491
411k
  else if (!strcmp(buf, "AOC") || // Pentax, tribute to Asahi Optical Co.
492
411k
           !strcmp(buf, "QVC"))   // Casio, from "QV-Camera"
493
575
  {
494
575
    fseek(ifp, -4, SEEK_CUR);
495
575
  }
496
410k
  else if (!strncmp(buf, "CMT3", 4))
497
513
  {
498
513
    order = sget2((uchar *)(buf + 4));
499
513
    fseek(ifp, 2L, SEEK_CUR);
500
513
  }
501
410k
  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
410k
  else
507
410k
  {
508
410k
    fseek(ifp, -10, SEEK_CUR);
509
410k
    if (!strncmp(make, "SAMSUNG", 7))
510
24.4k
      base = ftell(ifp);
511
410k
  }
512
513
420k
  if (!is_Olympus &&
514
340k
      (!strncasecmp(make, "Olympus", 7) || !strncmp(make, "OM Digi", 7) ||
515
338k
      (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) {
516
1.63k
    is_Olympus = 1;
517
1.63k
  }
518
519
420k
  if (!is_Sony &&
520
244k
      (!strncasecmp(make, "SONY", 4) ||
521
241k
       !strncasecmp(make, "Konica", 6) ||
522
241k
       !strncasecmp(make, "Minolta", 7) ||
523
241k
       (!strncasecmp(make, "Hasselblad", 10) &&
524
4.60k
        (!strncasecmp(model, "Stellar", 7) ||
525
4.59k
         !strncasecmp(model, "Lunar", 5) ||
526
4.59k
         !strncasecmp(model, "Lusso", 5) ||
527
4.58k
         !strncasecmp(model, "HV", 2))))) {
528
3.71k
    is_Sony = 1;
529
3.71k
  }
530
531
420k
  if (strcasestr(make, "Kodak") &&
532
50.4k
      (sget2((uchar *)buf) > 1) && // check number of entries
533
48.2k
      (sget2((uchar *)buf) < 128) &&
534
39.5k
      (sget2((uchar *)(buf + 4)) > 0) && // check type
535
31.9k
      (sget2((uchar *)(buf + 4)) < 13) &&
536
8.24k
      (sget4((uchar *)(buf + 6)) < 256) // check count
537
420k
  )
538
1.18k
    imKodak.MakerNoteKodak8a = 1; // Kodak P712 / P850 / P880
539
540
420k
  entries = get2();
541
420k
  if (entries > 1000)
542
34.8k
    return;
543
544
385k
  morder = order;
545
30.3M
  while (entries--)
546
29.9M
  {
547
29.9M
    order = morder;
548
29.9M
    tiff_get(base, &tag, &type, &len, &save);
549
29.9M
    tag |= uptag << 16;
550
551
29.9M
    INT64 _pos = ftell(ifp);
552
29.9M
    if (len > 100 * 1024 * 1024)
553
14.9M
  goto next; // 100Mb tag? No!
554
14.9M
    if (len > 8 && _pos + len > 2 * fsize)
555
10.4M
    {
556
10.4M
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
557
10.4M
      continue;
558
10.4M
    }
559
560
4.54M
  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.54M
    if (imKodak.MakerNoteKodak8a)
568
48.7k
    {
569
48.7k
      if ((tag == 0xff00) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) && (len == 1))
570
1.51k
      {
571
1.51k
        INT64 _pos1 = get4();
572
1.51k
        if ((_pos1 < fsize) && (_pos1 > 0))
573
394
        {
574
394
          fseek(ifp, _pos1, SEEK_SET);
575
394
          parse_makernote(base, tag);
576
394
        }
577
1.51k
      }
578
47.2k
      else if (tag == 0xff00f90b)
579
66
      {
580
66
        imKodak.clipBlack = get2();
581
66
      }
582
47.1k
      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
48.7k
    }
589
4.49M
    else if (!strncmp(make, "Canon", 5))
590
1.19M
    {
591
1.19M
      if (tag == 0x000d && len < 256000) // camera info
592
27.7k
      {
593
27.7k
        if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
594
13.6k
        {
595
13.6k
          CanonCameraInfo = (uchar *)calloc(MAX(16, len)+1,1);
596
13.6k
          fread(CanonCameraInfo, len, 1, ifp);
597
13.6k
        }
598
14.0k
        else
599
14.0k
        {
600
14.0k
          CanonCameraInfo = (uchar *)calloc(MAX(16, len * 4)+1,1);
601
14.0k
          fread(CanonCameraInfo, len, 4, ifp);
602
14.0k
        }
603
27.7k
        lenCanonCameraInfo = len;
604
27.7k
        typeCanonCameraInfo = type;
605
27.7k
      }
606
607
1.17M
      else if (tag == 0x0010) // Canon ModelID
608
38.6k
      {
609
38.6k
        unique_id = get4();
610
38.6k
        setCanonBodyFeatures(unique_id);
611
38.6k
        if (lenCanonCameraInfo)
612
20.0k
        {
613
20.0k
          processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo,
614
20.0k
                                 typeCanonCameraInfo, nonDNG);
615
20.0k
    if(CanonCameraInfo)
616
20.0k
            free(CanonCameraInfo);
617
20.0k
          CanonCameraInfo = 0;
618
20.0k
          lenCanonCameraInfo = 0;
619
20.0k
        }
620
38.6k
      }
621
622
1.13M
      else
623
1.13M
        parseCanonMakernotes(tag, type, len, nonDNG);
624
1.19M
    }
625
626
3.29M
    else if (!strncmp(make, "FUJI", 4))
627
186k
      parseFujiMakernotes(tag, type, len, nonDNG);
628
629
3.10M
    else if (!strncasecmp(model, "Hasselblad X1D", 14) ||
630
3.10M
             !strncasecmp(model, "Hasselblad H6D", 14) ||
631
3.10M
             !strncasecmp(model, "Hasselblad A6D", 14))
632
8.67k
    {
633
8.67k
      if (tag == 0x0045)
634
197
      {
635
197
        imHassy.BaseISO = get4();
636
197
      }
637
8.47k
      else if (tag == 0x0046)
638
201
      {
639
201
        imHassy.Gain = getreal(type);
640
201
      }
641
8.67k
    }
642
643
3.10M
    else if (!strncmp(make, "PENTAX", 6) ||
644
2.85M
             !strncmp(make, "RICOH", 5) ||
645
2.56M
             !strncmp(model, "PENTAX", 6))
646
536k
    {
647
536k
      if (!strncmp(model, "GR", 2) ||
648
400k
          !strncmp(model, "GXR", 3))
649
178k
      {
650
178k
        parseRicohMakernotes(base, tag, type, len, CameraDNG);
651
178k
      }
652
358k
      else
653
358k
      {
654
358k
        parsePentaxMakernotes(base, tag, type, len, nonDNG);
655
358k
      }
656
536k
    }
657
658
2.56M
    else if (!strncmp(make, "SAMSUNG", 7))
659
268k
    {
660
268k
      if (!dng_version)
661
109k
        parseSamsungMakernotes(base, tag, type, len, nonDNG);
662
159k
      else
663
159k
        parsePentaxMakernotes(base, tag, type, len, CameraDNG);
664
268k
    }
665
666
2.29M
    else if (is_Sony)
667
1.51M
    {
668
1.51M
      if ((tag == 0xb028) && (len == 1) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) // DSLR-A100
669
775
      {
670
775
        if ((c = get4()))
671
642
        {
672
642
          fseek(ifp, c, SEEK_SET);
673
642
          parse_makernote(base, tag);
674
642
        }
675
775
      }
676
1.51M
      else
677
1.51M
      {
678
1.51M
        parseSonyMakernotes(
679
1.51M
            base, tag, type, len, nonDNG,
680
1.51M
            table_buf_0x0116, table_buf_0x0116_len,
681
1.51M
            table_buf_0x2010, table_buf_0x2010_len,
682
1.51M
            table_buf_0x9050, table_buf_0x9050_len,
683
1.51M
            table_buf_0x9400, table_buf_0x9400_len,
684
1.51M
            table_buf_0x9402, table_buf_0x9402_len,
685
1.51M
            table_buf_0x9403, table_buf_0x9403_len,
686
1.51M
            table_buf_0x9406, table_buf_0x9406_len,
687
1.51M
            table_buf_0x940c, table_buf_0x940c_len,
688
1.51M
            table_buf_0x940e, table_buf_0x940e_len);
689
1.51M
      }
690
1.51M
    }
691
4.54M
    fseek(ifp, _pos, SEEK_SET);
692
693
4.54M
    if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) {
694
51.7k
      if (tag == 0x0011)
695
1.02k
        imHassy.SensorCode = getint(type);
696
50.7k
      else if (tag == 0x0016)
697
264
        imHassy.CoatingCode = getint(type);
698
50.4k
      else if ((tag == 0x002a) &&
699
842
               tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) &&
700
228
               (len == 12)) {
701
1.47k
        FORC4 for (int ii = 0; ii < 3; ii++)
702
1.10k
                imHassy.mnColorMatrix[c][ii] = getreal(type);
703
704
50.3k
      } else if (tag == 0x0031) {
705
513
        imHassy.RecommendedCrop[0] = getint(type);
706
513
        imHassy.RecommendedCrop[1] = getint(type);
707
513
      }
708
51.7k
    }
709
710
4.54M
    if ((tag == 0x0004 || tag == 0x0114) && !strncmp(make, "KONICA", 6))
711
3.00k
    {
712
3.00k
      fseek(ifp, tag == 0x0004 ? 140 : 160, SEEK_CUR);
713
3.00k
      switch (get2())
714
3.00k
      {
715
217
      case 72:
716
217
        flip = 0;
717
217
        break;
718
66
      case 76:
719
66
        flip = 6;
720
66
        break;
721
47
      case 82:
722
47
        flip = 5;
723
47
        break;
724
3.00k
      }
725
3.00k
    }
726
727
4.54M
    if (is_Olympus) {
728
1.00M
      INT64 _pos2 = ftell(ifp);
729
1.00M
      if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) ||
730
993k
          (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) ||
731
978k
          (tag == 0x3000))
732
32.0k
      {
733
32.0k
        if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) {
734
26.7k
          parse_makernote(base, tag);
735
736
26.7k
        } else if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_ifd) ||
737
5.16k
                   tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_int32u)) {
738
526
          fseek(ifp, base + get4(), SEEK_SET);
739
526
          parse_makernote(base, tag);
740
526
        }
741
742
974k
      } else {
743
974k
        parseOlympusMakernotes(base, tag, type, len, nonDNG);
744
974k
      }
745
1.00M
      fseek(ifp, _pos2, SEEK_SET);
746
1.00M
    }
747
748
4.54M
    if ((tag == 0x0015) &&
749
6.38k
        tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII) &&
750
1.85k
        is_raw)
751
1.76k
    { // Hasselblad
752
1.76k
      stmread (imHassy.SensorUnitConnector, len, ifp);
753
1.76k
    }
754
755
4.54M
    if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&
756
69.4k
        ((tag == 0x0081) || // Minolta
757
69.0k
         (tag == 0x0100)))  // Olympus
758
1.05k
    {
759
1.05k
      thumb_offset = ftell(ifp);
760
1.05k
      thumb_length = len;
761
1.05k
    }
762
4.54M
    if ((tag == 0x0088) && // Minolta, possibly Olympus too
763
3.89k
        tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) &&
764
898
        (thumb_offset = get4()))
765
614
      thumb_offset += base;
766
767
4.54M
    if ((tag == 0x0089) && // Minolta, possibly Olympus too
768
1.98k
        tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
769
416
      thumb_length = get4();
770
771
4.54M
    if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&  // Nikon
772
69.4k
        ((tag == 0x008c) ||
773
69.0k
         (tag == 0x0096))) {
774
635
      meta_offset = ftell(ifp);
775
635
    }
776
777
4.54M
    if ((tag == 0x00a1) &&
778
973
        tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&
779
407
        strncasecmp(make, "Samsung", 7))
780
292
    {
781
292
      order = 0x4949;
782
292
      fseek(ifp, 140, SEEK_CUR);
783
876
      FORC3 cam_mul[c] = float(get4());
784
292
    }
785
786
4.54M
    if (tag == 0xb001 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) // Sony ModelID
787
629
    {
788
629
      unique_id = get2();
789
629
    }
790
4.54M
    if (tag == 0x0200 && len == 3) // Olympus
791
1.05k
      shot_order = (get4(), get4());
792
793
4.54M
    if (tag == 0x0f00 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED))
794
237
    {
795
237
      if (len == 614)
796
65
        fseek(ifp, 176, SEEK_CUR);
797
172
      else if (len == 734 || len == 1502) // Kodak, Minolta, Olympus
798
42
        fseek(ifp, 148, SEEK_CUR);
799
130
      else
800
130
        goto next;
801
107
      goto get2_256;
802
237
    }
803
804
4.54M
    if (tag == 0x2011 && len == 2) // Casio
805
569
    {
806
676
    get2_256:
807
676
      order = 0x4d4d;
808
676
      cam_mul[0] = float(get2()) / 256.0f;
809
676
      cam_mul[2] = float(get2()) / 256.0f;
810
676
    }
811
812
19.5M
  next:
813
19.5M
    fseek(ifp, save, SEEK_SET);
814
19.5M
  }
815
384k
quit:
816
384k
  order = sorder;
817
384k
}