Coverage Report

Created: 2026-11-12 07:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/metadata/kodak.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2026 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw is free software; you can redistribute it and/or modify
5
 it under the terms of the one of two licenses as you choose:
6
7
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
8
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
9
10
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
11
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
12
13
 */
14
15
#include "../../internal/dcraw_defs.h"
16
17
void LibRaw::Kodak_KDC_WBtags(int wb, int wbi)
18
4.34k
{
19
4.34k
  int c;
20
13.0k
  FORC3 icWBC[wb][c] = get4();
21
4.34k
  icWBC[wb][3] = icWBC[wb][1];
22
4.34k
  if (wbi == wb)
23
2.75k
    FORC4 cam_mul[c] = float(icWBC[wb][c]);
24
4.34k
  return;
25
4.34k
}
26
27
void LibRaw::Kodak_DCR_WBtags(int wb, unsigned type, int wbi)
28
2.98k
{
29
2.98k
  float mul[3] = {1.0f, 1.0f, 1.0f}, num, mul2;
30
2.98k
  int c;
31
8.94k
  FORC3 mul[c] = (num = getrealf(type)) <= 0.001f ? 1.0f : num;
32
2.98k
  icWBC[wb][1] = icWBC[wb][3] = int(mul[1]);
33
2.98k
  mul2 = mul[1] * mul[1];
34
2.98k
  icWBC[wb][0] = int(mul2 / mul[0]);
35
2.98k
  icWBC[wb][2] = int(mul2 / mul[2]);
36
2.98k
  if (wbi == wb)
37
4.14k
    FORC4 cam_mul[c] = float(icWBC[wb][c]);
38
2.98k
  return;
39
2.98k
}
40
41
short LibRaw::KodakIllumMatrix(unsigned type, float *romm_camIllum)
42
4.72k
{
43
4.72k
  int c, j, romm_camTemp[9], romm_camScale[3];
44
4.72k
  if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL))
45
150
  {
46
1.50k
    for (j = 0; j < 9; j++)
47
1.35k
      ((float *)romm_camIllum)[j] = getrealf(type);
48
150
    return 1;
49
150
  }
50
4.57k
  else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG))
51
2.83k
  {
52
2.83k
    FORC3
53
8.50k
    {
54
8.50k
      romm_camScale[c] = 0;
55
34.0k
      for (j = 0; j < 3; j++)
56
25.5k
      {
57
25.5k
        romm_camTemp[c * 3 + j] = get4();
58
25.5k
        romm_camScale[c] += romm_camTemp[c * 3 + j];
59
25.5k
      }
60
8.50k
    }
61
2.83k
    if ((romm_camScale[0] > 0x1fff) && (romm_camScale[1] > 0x1fff) &&
62
721
        (romm_camScale[2] > 0x1fff))
63
497
    {
64
5.96k
      FORC3 for (j = 0; j < 3; j++)((float *)romm_camIllum)[c * 3 + j] =
65
4.47k
          ((float)romm_camTemp[c * 3 + j]) / ((float)romm_camScale[c]);
66
497
      return 1;
67
497
    }
68
2.83k
  }
69
4.08k
  return 0;
70
4.72k
}
71
72
/* Thanks to Alexey Danilchenko for wb as-shot parsing code */
73
void LibRaw::parse_kodak_ifd(INT64 base)
74
13.6k
{
75
13.6k
  unsigned entries, tag, type, len;
76
13.6k
  INT64 save;
77
13.6k
  int c, wbi = -1;
78
79
13.6k
  static const int wbtag_kdc[] = {
80
13.6k
      LIBRAW_WBI_Auto,        // 64037 / 0xfa25
81
13.6k
      LIBRAW_WBI_Fluorescent, // 64040 / 0xfa28
82
13.6k
      LIBRAW_WBI_Tungsten,    // 64039 / 0xfa27
83
13.6k
      LIBRAW_WBI_Daylight,    // 64041 / 0xfa29
84
13.6k
      -1,
85
13.6k
      -1,
86
13.6k
      LIBRAW_WBI_Shade // 64042 / 0xfa2a
87
13.6k
  };
88
89
13.6k
  static const int wbtag_dcr[] = {
90
13.6k
      LIBRAW_WBI_Daylight,    // 2120 / 0x0848
91
13.6k
      LIBRAW_WBI_Tungsten,    // 2121 / 0x0849
92
13.6k
      LIBRAW_WBI_Fluorescent, // 2122 / 0x084a
93
13.6k
      LIBRAW_WBI_Flash,       // 2123 / 0x084b
94
13.6k
      LIBRAW_WBI_Custom,      // 2124 / 0x084c
95
13.6k
      LIBRAW_WBI_Auto         // 2125 / 0x084d
96
13.6k
  };
97
98
  //  int a_blck = 0;
99
100
13.6k
  entries = get2();
101
13.6k
  if (entries > 1024)
102
4.50k
    return;
103
9.14k
  INT64 fsize = ifp->size();
104
1.22M
  while (entries--)
105
1.21M
  {
106
1.21M
    tiff_get(base, &tag, &type, &len, &save);
107
1.21M
    INT64 savepos = ftell(ifp);
108
1.21M
    if (len > 8 && len + savepos > 2 * fsize)
109
969k
    {
110
969k
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
111
969k
      continue;
112
969k
    }
113
248k
    if (callbacks.exif_cb)
114
0
    {
115
0
      callbacks.exif_cb(callbacks.exifparser_data, tag | 0x20000, type, len,
116
0
                        order, ifp, base);
117
0
      fseek(ifp, savepos, SEEK_SET);
118
0
    }
119
248k
    if (tag == 0x03eb) // 1003
120
279
      imgdata.sizes.raw_inset_crops[0].cleft = get2();
121
248k
    else if (tag == 0x03ec) // 1004
122
302
      imgdata.sizes.raw_inset_crops[0].ctop = get2();
123
247k
    else if (tag == 0x03ed) // 1005
124
78
      imgdata.sizes.raw_inset_crops[0].cwidth = get2();
125
247k
    else if (tag == 0x03ee) // 1006
126
39
      imgdata.sizes.raw_inset_crops[0].cheight = get2();
127
247k
    else if (tag == 0x03ef) // 1007
128
341
    {
129
341
      if (!strcmp(model, "EOS D2000C"))
130
93
        black = get2();
131
248
      else
132
248
        imKodak.BlackLevelTop = get2();
133
341
    }
134
247k
    else if (tag == 0x03f0) // 1008
135
496
    {
136
496
      if (!strcmp(model, "EOS D2000C"))
137
94
      {
138
94
        if (black) // already set by tag 1007 (0x03ef)
139
25
          black = (black + get2()) / 2;
140
69
        else
141
69
          black = get2();
142
94
      }
143
402
      else
144
402
        imKodak.BlackLevelBottom = get2();
145
496
    }
146
147
247k
    else if (tag == 0x03f1)
148
3.14k
    { // 1009 Kodak TextualInfo
149
3.14k
      if (len > 0)
150
2.58k
      {
151
2.58k
        char kti[1024];
152
2.58k
        char *pkti;
153
2.58k
        int nsym = MIN(len, 1023);
154
2.58k
        fread(kti, 1, nsym, ifp);
155
2.58k
        kti[nsym] = 0;
156
#ifdef LIBRAW_WIN32_CALLS
157
        pkti = strtok(kti, "\x0a");
158
#else
159
2.58k
        char *last = 0;
160
2.58k
        pkti = strtok_r(kti, "\x0a", &last);
161
2.58k
#endif
162
5.82k
        while (pkti != NULL)
163
3.24k
        {
164
3.24k
          c = 12;
165
3.24k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Camera body:", c)))
166
206
          {
167
436
            while ((pkti[c] == ' ') && (c < (int)strlen(pkti)))
168
230
            {
169
230
              c++;
170
230
            }
171
206
            strncpy(ilm.body, pkti + c,63);
172
206
      ilm.body[63] = 0;
173
206
          }
174
3.24k
          c = 5;
175
3.24k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Lens:", c)))
176
108
          {
177
108
            ilm.CurFocal = float(atoi(pkti + c));
178
108
          }
179
3.24k
          c = 9;
180
3.24k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Aperture:", c)))
181
275
          {
182
1.00k
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
183
733
            {
184
733
              c++;
185
733
            }
186
275
            ilm.CurAp = float(atof(pkti + c));
187
275
          }
188
3.24k
          c = 10;
189
3.24k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "ISO Speed:", c)))
190
261
          {
191
261
            iso_speed = float(atoi(pkti + c));
192
261
          }
193
3.24k
          c = 13;
194
3.24k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Focal Length:", c)))
195
145
          {
196
145
            ilm.CurFocal = float(atoi(pkti + c));
197
145
          }
198
3.24k
          c = 13;
199
3.24k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Max Aperture:", c)))
200
108
          {
201
753
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
202
645
            {
203
645
              c++;
204
645
            }
205
108
            ilm.MaxAp4CurFocal = float(atof(pkti + c));
206
108
          }
207
3.24k
          c = 13;
208
3.24k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Min Aperture:", c)))
209
203
          {
210
319
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
211
116
            {
212
116
              c++;
213
116
            }
214
203
            ilm.MinAp4CurFocal = float(atof(pkti + c));
215
203
          }
216
#ifdef LIBRAW_WIN32_CALLS
217
          pkti = strtok(NULL, "\x0a");
218
#else
219
3.24k
          pkti = strtok_r(NULL, "\x0a", &last);
220
3.24k
#endif
221
3.24k
        }
222
2.58k
      }
223
3.14k
    }
224
225
243k
    else if (tag == 0x03f3) // 1011
226
137
      imCommon.FlashEC = getrealf(type);
227
228
243k
    else if (tag == 0x03fc) // 1020
229
1.83k
    {
230
1.83k
      wbi = getint(type);
231
1.83k
      if ((wbi >= 0) && (wbi < 6) && (wbi != -2))
232
575
        wbi = wbtag_dcr[wbi];
233
1.83k
    }
234
241k
    else if (tag == 0x03fd && len == 72) // 1021
235
194
    {                                    /* WB set in software */
236
194
      fseek(ifp, 40, SEEK_CUR);
237
582
      FORC3 cam_mul[c] = 2048.0f / fMAX(1.0f, get2());
238
194
      wbi = -2;
239
194
    }
240
241
241k
    else if ((tag == 0x0406) && (len == 1)) // 1030
242
355
      imCommon.CameraTemperature = getrealf(type);
243
241k
    else if ((tag == 0x0413) && (len == 1)) // 1043
244
54
      imCommon.SensorTemperature = getrealf(type);
245
241k
    else if (tag == 0x0848) // 2120
246
576
      Kodak_DCR_WBtags(LIBRAW_WBI_Daylight, type, wbi);
247
240k
    else if (tag == 0x0849) // 2121
248
298
      Kodak_DCR_WBtags(LIBRAW_WBI_Tungsten, type, wbi);
249
240k
    else if (tag == 0x084a) // 2122
250
378
      Kodak_DCR_WBtags(LIBRAW_WBI_Fluorescent, type, wbi);
251
240k
    else if (tag == 0x084b) // 2123
252
516
      Kodak_DCR_WBtags(LIBRAW_WBI_Flash, type, wbi);
253
239k
    else if (tag == 0x084c) // 2124
254
466
      Kodak_DCR_WBtags(LIBRAW_WBI_Custom, type, wbi);
255
239k
    else if (tag == 0x084d) // 2125
256
748
    {
257
748
      if (wbi == -1)
258
352
        wbi = LIBRAW_WBI_Auto;
259
748
      Kodak_DCR_WBtags(LIBRAW_WBI_Auto, type, wbi);
260
748
    }
261
238k
    else if (tag == 0x089f) // 2207
262
88
      imKodak.ISOCalibrationGain = getrealf(type);
263
238k
    else if (tag == 0x0903) // 2307
264
269
      imKodak.AnalogISO = iso_speed = getrealf(type);
265
237k
    else if (tag == 0x090d) // 2317
266
277
      linear_table(len);
267
237k
    else if (tag == 0x09ce) // 2510
268
92
      stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp);
269
237k
    else if (tag == 0x0e92) // 3730
270
71
    {
271
71
      imKodak.val018percent = get2();
272
71
      imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
273
71
          imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
274
71
              (int)(((float)imKodak.val018percent) / 18.0f * 170.0f);
275
71
    }
276
237k
    else if (tag == 0x0e93) // 3731
277
88
      imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
278
88
          imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
279
88
              imKodak.val170percent = get2();
280
237k
    else if (tag == 0x0e94) // 3732
281
277
      imKodak.val100percent = get2();
282
    /*
283
        else if (tag == 0x1784)    // 6020
284
          iso_speed = getint(type);
285
    */
286
237k
    else if (tag == 0xfa00) // 64000
287
754
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
288
236k
    else if (tag == 0xfa0d) // 64013
289
1.55k
    {
290
1.55k
      wbi = fgetc(ifp);
291
1.55k
      if ((wbi >= 0) && (wbi < 7))
292
1.17k
        wbi = wbtag_kdc[wbi];
293
1.55k
    }
294
234k
    else if (tag == 0xfa13) // 64019
295
638
      width = getint(type);
296
234k
    else if (tag == 0xfa14) // 64020
297
324
      height = (getint(type) + 1) & -2;
298
    /*
299
          height = getint(type);
300
301
        else if (tag == 0xfa16)  // 64022
302
          raw_width = get2();
303
        else if (tag == 0xfa17)  // 64023
304
          raw_height = get2();
305
    */
306
233k
    else if (tag == 0xfa18) // 64024
307
182
    {
308
182
      imKodak.offset_left = getint(LIBRAW_EXIFTAG_TYPE_SSHORT);
309
182
      if (type != LIBRAW_EXIFTAG_TYPE_SSHORT)
310
70
        imKodak.offset_left += 1;
311
182
    }
312
233k
    else if (tag == 0xfa19) // 64025
313
698
    {
314
698
      imKodak.offset_top = getint(LIBRAW_EXIFTAG_TYPE_SSHORT);
315
698
      if (type != LIBRAW_EXIFTAG_TYPE_SSHORT)
316
605
        imKodak.offset_top += 1;
317
698
    }
318
319
232k
    else if (tag == 0xfa25) // 64037
320
802
      Kodak_KDC_WBtags(LIBRAW_WBI_Auto, wbi);
321
232k
    else if (tag == 0xfa27) // 64039
322
383
      Kodak_KDC_WBtags(LIBRAW_WBI_Tungsten, wbi);
323
231k
    else if (tag == 0xfa28) // 64040
324
1.43k
      Kodak_KDC_WBtags(LIBRAW_WBI_Fluorescent, wbi);
325
230k
    else if (tag == 0xfa29) // 64041
326
677
      Kodak_KDC_WBtags(LIBRAW_WBI_Daylight, wbi);
327
229k
    else if (tag == 0xfa2a) // 64042
328
1.04k
      Kodak_KDC_WBtags(LIBRAW_WBI_Shade, wbi);
329
330
228k
    else if (tag == 0xfa31) // 64049
331
403
      imgdata.sizes.raw_inset_crops[0].cwidth = get2();
332
228k
    else if (tag == 0xfa32) // 64050
333
447
      imgdata.sizes.raw_inset_crops[0].cheight = get2();
334
227k
    else if (tag == 0xfa3e) // 64062
335
791
      imgdata.sizes.raw_inset_crops[0].cleft = get2();
336
227k
    else if (tag == 0xfa3f) // 64063
337
1.64k
      imgdata.sizes.raw_inset_crops[0].ctop = get2();
338
339
225k
    else if (((tag == 0x07e4) || (tag == 0xfb01)) &&
340
2.19k
             (len == 9)) // 2020 or 64257
341
939
    {
342
939
      if (KodakIllumMatrix(type, (float *)imKodak.romm_camDaylight))
343
171
      {
344
171
        romm_coeff(imKodak.romm_camDaylight);
345
171
      }
346
939
    }
347
224k
    else if (((tag == 0x07e5) || (tag == 0xfb02)) &&
348
753
             (len == 9)) // 2021 or 64258
349
588
      KodakIllumMatrix(type, (float *)imKodak.romm_camTungsten);
350
223k
    else if (((tag == 0x07e6) || (tag == 0xfb03)) &&
351
1.41k
             (len == 9)) // 2022 or 64259
352
907
      KodakIllumMatrix(type, (float *)imKodak.romm_camFluorescent);
353
222k
    else if (((tag == 0x07e7) || (tag == 0xfb04)) &&
354
1.35k
             (len == 9)) // 2023 or 64260
355
757
      KodakIllumMatrix(type, (float *)imKodak.romm_camFlash);
356
222k
    else if (((tag == 0x07e8) || (tag == 0xfb05)) &&
357
1.10k
             (len == 9)) // 2024 or 64261
358
827
      KodakIllumMatrix(type, (float *)imKodak.romm_camCustom);
359
221k
    else if (((tag == 0x07e9) || (tag == 0xfb06)) &&
360
1.59k
             (len == 9)) // 2025 or 64262
361
709
      KodakIllumMatrix(type, (float *)imKodak.romm_camAuto);
362
363
248k
    fseek(ifp, save, SEEK_SET);
364
248k
  }
365
9.14k
}