Coverage Report

Created: 2026-02-14 07:11

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