Coverage Report

Created: 2026-07-20 07:19

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-2025 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
5.25k
{
19
5.25k
  int c;
20
15.7k
  FORC3 icWBC[wb][c] = get4();
21
5.25k
  icWBC[wb][3] = icWBC[wb][1];
22
5.25k
  if (wbi == wb)
23
2.97k
    FORC4 cam_mul[c] = float(icWBC[wb][c]);
24
5.25k
  return;
25
5.25k
}
26
27
void LibRaw::Kodak_DCR_WBtags(int wb, unsigned type, int wbi)
28
3.59k
{
29
3.59k
  float mul[3] = {1.0f, 1.0f, 1.0f}, num, mul2;
30
3.59k
  int c;
31
10.7k
  FORC3 mul[c] = (num = getrealf(type)) <= 0.001f ? 1.0f : num;
32
3.59k
  icWBC[wb][1] = icWBC[wb][3] = int(mul[1]);
33
3.59k
  mul2 = mul[1] * mul[1];
34
3.59k
  icWBC[wb][0] = int(mul2 / mul[0]);
35
3.59k
  icWBC[wb][2] = int(mul2 / mul[2]);
36
3.59k
  if (wbi == wb)
37
4.70k
    FORC4 cam_mul[c] = float(icWBC[wb][c]);
38
3.59k
  return;
39
3.59k
}
40
41
short LibRaw::KodakIllumMatrix(unsigned type, float *romm_camIllum)
42
5.81k
{
43
5.81k
  int c, j, romm_camTemp[9], romm_camScale[3];
44
5.81k
  if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL))
45
261
  {
46
2.61k
    for (j = 0; j < 9; j++)
47
2.34k
      ((float *)romm_camIllum)[j] = getrealf(type);
48
261
    return 1;
49
261
  }
50
5.55k
  else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG))
51
3.34k
  {
52
3.34k
    FORC3
53
10.0k
    {
54
10.0k
      romm_camScale[c] = 0;
55
40.1k
      for (j = 0; j < 3; j++)
56
30.1k
      {
57
30.1k
        romm_camTemp[c * 3 + j] = get4();
58
30.1k
        romm_camScale[c] += romm_camTemp[c * 3 + j];
59
30.1k
      }
60
10.0k
    }
61
3.34k
    if ((romm_camScale[0] > 0x1fff) && (romm_camScale[1] > 0x1fff) &&
62
1.44k
        (romm_camScale[2] > 0x1fff))
63
1.20k
    {
64
14.4k
      FORC3 for (j = 0; j < 3; j++)((float *)romm_camIllum)[c * 3 + j] =
65
10.8k
          ((float)romm_camTemp[c * 3 + j]) / ((float)romm_camScale[c]);
66
1.20k
      return 1;
67
1.20k
    }
68
3.34k
  }
69
4.35k
  return 0;
70
5.81k
}
71
72
/* Thanks to Alexey Danilchenko for wb as-shot parsing code */
73
void LibRaw::parse_kodak_ifd(INT64 base)
74
16.5k
{
75
16.5k
  unsigned entries, tag, type, len;
76
16.5k
  INT64 save;
77
16.5k
  int c, wbi = -1;
78
79
16.5k
  static const int wbtag_kdc[] = {
80
16.5k
      LIBRAW_WBI_Auto,        // 64037 / 0xfa25
81
16.5k
      LIBRAW_WBI_Fluorescent, // 64040 / 0xfa28
82
16.5k
      LIBRAW_WBI_Tungsten,    // 64039 / 0xfa27
83
16.5k
      LIBRAW_WBI_Daylight,    // 64041 / 0xfa29
84
16.5k
      -1,
85
16.5k
      -1,
86
16.5k
      LIBRAW_WBI_Shade // 64042 / 0xfa2a
87
16.5k
  };
88
89
16.5k
  static const int wbtag_dcr[] = {
90
16.5k
      LIBRAW_WBI_Daylight,    // 2120 / 0x0848
91
16.5k
      LIBRAW_WBI_Tungsten,    // 2121 / 0x0849
92
16.5k
      LIBRAW_WBI_Fluorescent, // 2122 / 0x084a
93
16.5k
      LIBRAW_WBI_Flash,       // 2123 / 0x084b
94
16.5k
      LIBRAW_WBI_Custom,      // 2124 / 0x084c
95
16.5k
      LIBRAW_WBI_Auto         // 2125 / 0x084d
96
16.5k
  };
97
98
  //  int a_blck = 0;
99
100
16.5k
  entries = get2();
101
16.5k
  if (entries > 1024)
102
5.69k
    return;
103
10.8k
  INT64 fsize = ifp->size();
104
1.71M
  while (entries--)
105
1.70M
  {
106
1.70M
    tiff_get(base, &tag, &type, &len, &save);
107
1.70M
    INT64 savepos = ftell(ifp);
108
1.70M
    if (len > 8 && len + savepos > 2 * fsize)
109
1.35M
    {
110
1.35M
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
111
1.35M
      continue;
112
1.35M
    }
113
345k
    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
345k
    if (tag == 0x03eb) // 1003
120
278
      imgdata.sizes.raw_inset_crops[0].cleft = get2();
121
345k
    else if (tag == 0x03ec) // 1004
122
328
      imgdata.sizes.raw_inset_crops[0].ctop = get2();
123
345k
    else if (tag == 0x03ed) // 1005
124
81
      imgdata.sizes.raw_inset_crops[0].cwidth = get2();
125
345k
    else if (tag == 0x03ee) // 1006
126
66
      imgdata.sizes.raw_inset_crops[0].cheight = get2();
127
345k
    else if (tag == 0x03ef) // 1007
128
349
    {
129
349
      if (!strcmp(model, "EOS D2000C"))
130
96
        black = get2();
131
253
      else
132
253
        imKodak.BlackLevelTop = get2();
133
349
    }
134
344k
    else if (tag == 0x03f0) // 1008
135
666
    {
136
666
      if (!strcmp(model, "EOS D2000C"))
137
177
      {
138
177
        if (black) // already set by tag 1007 (0x03ef)
139
96
          black = (black + get2()) / 2;
140
81
        else
141
81
          black = get2();
142
177
      }
143
489
      else
144
489
        imKodak.BlackLevelBottom = get2();
145
666
    }
146
147
344k
    else if (tag == 0x03f1)
148
3.04k
    { // 1009 Kodak TextualInfo
149
3.04k
      if (len > 0)
150
2.46k
      {
151
2.46k
        char kti[1024];
152
2.46k
        char *pkti;
153
2.46k
        int nsym = MIN(len, 1023);
154
2.46k
        fread(kti, 1, nsym, ifp);
155
2.46k
        kti[nsym] = 0;
156
#ifdef LIBRAW_WIN32_CALLS
157
        pkti = strtok(kti, "\x0a");
158
#else
159
2.46k
        char *last = 0;
160
2.46k
        pkti = strtok_r(kti, "\x0a", &last);
161
2.46k
#endif
162
5.69k
        while (pkti != NULL)
163
3.22k
        {
164
3.22k
          c = 12;
165
3.22k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Camera body:", c)))
166
331
          {
167
601
            while ((pkti[c] == ' ') && (c < (int)strlen(pkti)))
168
270
            {
169
270
              c++;
170
270
            }
171
331
            strcpy(ilm.body, pkti + c);
172
331
          }
173
3.22k
          c = 5;
174
3.22k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Lens:", c)))
175
128
          {
176
128
            ilm.CurFocal = float(atoi(pkti + c));
177
128
          }
178
3.22k
          c = 9;
179
3.22k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Aperture:", c)))
180
274
          {
181
1.00k
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
182
735
            {
183
735
              c++;
184
735
            }
185
274
            ilm.CurAp = float(atof(pkti + c));
186
274
          }
187
3.22k
          c = 10;
188
3.22k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "ISO Speed:", c)))
189
80
          {
190
80
            iso_speed = float(atoi(pkti + c));
191
80
          }
192
3.22k
          c = 13;
193
3.22k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Focal Length:", c)))
194
207
          {
195
207
            ilm.CurFocal = float(atoi(pkti + c));
196
207
          }
197
3.22k
          c = 13;
198
3.22k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Max Aperture:", c)))
199
111
          {
200
759
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
201
648
            {
202
648
              c++;
203
648
            }
204
111
            ilm.MaxAp4CurFocal = float(atof(pkti + c));
205
111
          }
206
3.22k
          c = 13;
207
3.22k
          if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Min Aperture:", c)))
208
192
          {
209
282
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
210
90
            {
211
90
              c++;
212
90
            }
213
192
            ilm.MinAp4CurFocal = float(atof(pkti + c));
214
192
          }
215
#ifdef LIBRAW_WIN32_CALLS
216
          pkti = strtok(NULL, "\x0a");
217
#else
218
3.22k
          pkti = strtok_r(NULL, "\x0a", &last);
219
3.22k
#endif
220
3.22k
        }
221
2.46k
      }
222
3.04k
    }
223
224
341k
    else if (tag == 0x03f3) // 1011
225
165
      imCommon.FlashEC = getrealf(type);
226
227
340k
    else if (tag == 0x03fc) // 1020
228
1.93k
    {
229
1.93k
      wbi = getint(type);
230
1.93k
      if ((wbi >= 0) && (wbi < 6) && (wbi != -2))
231
589
        wbi = wbtag_dcr[wbi];
232
1.93k
    }
233
339k
    else if (tag == 0x03fd && len == 72) // 1021
234
203
    {                                    /* WB set in software */
235
203
      fseek(ifp, 40, SEEK_CUR);
236
609
      FORC3 cam_mul[c] = 2048.0f / fMAX(1.0f, get2());
237
203
      wbi = -2;
238
203
    }
239
240
338k
    else if ((tag == 0x0406) && (len == 1)) // 1030
241
251
      imCommon.CameraTemperature = getrealf(type);
242
338k
    else if ((tag == 0x0413) && (len == 1)) // 1043
243
111
      imCommon.SensorTemperature = getrealf(type);
244
338k
    else if (tag == 0x0848) // 2120
245
200
      Kodak_DCR_WBtags(LIBRAW_WBI_Daylight, type, wbi);
246
338k
    else if (tag == 0x0849) // 2121
247
358
      Kodak_DCR_WBtags(LIBRAW_WBI_Tungsten, type, wbi);
248
337k
    else if (tag == 0x084a) // 2122
249
656
      Kodak_DCR_WBtags(LIBRAW_WBI_Fluorescent, type, wbi);
250
337k
    else if (tag == 0x084b) // 2123
251
766
      Kodak_DCR_WBtags(LIBRAW_WBI_Flash, type, wbi);
252
336k
    else if (tag == 0x084c) // 2124
253
447
      Kodak_DCR_WBtags(LIBRAW_WBI_Custom, type, wbi);
254
336k
    else if (tag == 0x084d) // 2125
255
1.17k
    {
256
1.17k
      if (wbi == -1)
257
480
        wbi = LIBRAW_WBI_Auto;
258
1.17k
      Kodak_DCR_WBtags(LIBRAW_WBI_Auto, type, wbi);
259
1.17k
    }
260
334k
    else if (tag == 0x089f) // 2207
261
109
      imKodak.ISOCalibrationGain = getrealf(type);
262
334k
    else if (tag == 0x0903) // 2307
263
318
      imKodak.AnalogISO = iso_speed = getrealf(type);
264
334k
    else if (tag == 0x090d) // 2317
265
624
      linear_table(len);
266
333k
    else if (tag == 0x09ce) // 2510
267
115
      stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp);
268
333k
    else if (tag == 0x0e92) // 3730
269
121
    {
270
121
      imKodak.val018percent = get2();
271
121
      imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
272
121
          imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
273
121
              (int)(((float)imKodak.val018percent) / 18.0f * 170.0f);
274
121
    }
275
333k
    else if (tag == 0x0e93) // 3731
276
160
      imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
277
160
          imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
278
160
              imKodak.val170percent = get2();
279
333k
    else if (tag == 0x0e94) // 3732
280
322
      imKodak.val100percent = get2();
281
    /*
282
        else if (tag == 0x1784)    // 6020
283
          iso_speed = getint(type);
284
    */
285
333k
    else if (tag == 0xfa00) // 64000
286
1.49k
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
287
331k
    else if (tag == 0xfa0d) // 64013
288
2.02k
    {
289
2.02k
      wbi = fgetc(ifp);
290
2.02k
      if ((wbi >= 0) && (wbi < 7))
291
1.36k
        wbi = wbtag_kdc[wbi];
292
2.02k
    }
293
329k
    else if (tag == 0xfa13) // 64019
294
809
      width = getint(type);
295
328k
    else if (tag == 0xfa14) // 64020
296
410
      height = (getint(type) + 1) & -2;
297
    /*
298
          height = getint(type);
299
300
        else if (tag == 0xfa16)  // 64022
301
          raw_width = get2();
302
        else if (tag == 0xfa17)  // 64023
303
          raw_height = get2();
304
    */
305
328k
    else if (tag == 0xfa18) // 64024
306
232
    {
307
232
      imKodak.offset_left = getint(LIBRAW_EXIFTAG_TYPE_SSHORT);
308
232
      if (type != LIBRAW_EXIFTAG_TYPE_SSHORT)
309
126
        imKodak.offset_left += 1;
310
232
    }
311
328k
    else if (tag == 0xfa19) // 64025
312
762
    {
313
762
      imKodak.offset_top = getint(LIBRAW_EXIFTAG_TYPE_SSHORT);
314
762
      if (type != LIBRAW_EXIFTAG_TYPE_SSHORT)
315
639
        imKodak.offset_top += 1;
316
762
    }
317
318
327k
    else if (tag == 0xfa25) // 64037
319
1.14k
      Kodak_KDC_WBtags(LIBRAW_WBI_Auto, wbi);
320
326k
    else if (tag == 0xfa27) // 64039
321
295
      Kodak_KDC_WBtags(LIBRAW_WBI_Tungsten, wbi);
322
325k
    else if (tag == 0xfa28) // 64040
323
1.73k
      Kodak_KDC_WBtags(LIBRAW_WBI_Fluorescent, wbi);
324
324k
    else if (tag == 0xfa29) // 64041
325
786
      Kodak_KDC_WBtags(LIBRAW_WBI_Daylight, wbi);
326
323k
    else if (tag == 0xfa2a) // 64042
327
1.29k
      Kodak_KDC_WBtags(LIBRAW_WBI_Shade, wbi);
328
329
322k
    else if (tag == 0xfa31) // 64049
330
276
      imgdata.sizes.raw_inset_crops[0].cwidth = get2();
331
321k
    else if (tag == 0xfa32) // 64050
332
533
      imgdata.sizes.raw_inset_crops[0].cheight = get2();
333
321k
    else if (tag == 0xfa3e) // 64062
334
803
      imgdata.sizes.raw_inset_crops[0].cleft = get2();
335
320k
    else if (tag == 0xfa3f) // 64063
336
1.69k
      imgdata.sizes.raw_inset_crops[0].ctop = get2();
337
338
318k
    else if (((tag == 0x07e4) || (tag == 0xfb01)) &&
339
2.87k
             (len == 9)) // 2020 or 64257
340
1.30k
    {
341
1.30k
      if (KodakIllumMatrix(type, (float *)imKodak.romm_camDaylight))
342
698
      {
343
698
        romm_coeff(imKodak.romm_camDaylight);
344
698
      }
345
1.30k
    }
346
317k
    else if (((tag == 0x07e5) || (tag == 0xfb02)) &&
347
944
             (len == 9)) // 2021 or 64258
348
802
      KodakIllumMatrix(type, (float *)imKodak.romm_camTungsten);
349
316k
    else if (((tag == 0x07e6) || (tag == 0xfb03)) &&
350
1.68k
             (len == 9)) // 2022 or 64259
351
1.17k
      KodakIllumMatrix(type, (float *)imKodak.romm_camFluorescent);
352
315k
    else if (((tag == 0x07e7) || (tag == 0xfb04)) &&
353
1.80k
             (len == 9)) // 2023 or 64260
354
902
      KodakIllumMatrix(type, (float *)imKodak.romm_camFlash);
355
314k
    else if (((tag == 0x07e8) || (tag == 0xfb05)) &&
356
1.58k
             (len == 9)) // 2024 or 64261
357
1.03k
      KodakIllumMatrix(type, (float *)imKodak.romm_camCustom);
358
313k
    else if (((tag == 0x07e9) || (tag == 0xfb06)) &&
359
1.12k
             (len == 9)) // 2025 or 64262
360
604
      KodakIllumMatrix(type, (float *)imKodak.romm_camAuto);
361
362
345k
    fseek(ifp, save, SEEK_SET);
363
345k
  }
364
10.8k
}