Coverage Report

Created: 2026-09-14 07:15

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