Coverage Report

Created: 2025-10-12 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/utils/utils_dcraw.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2024 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
int LibRaw::fcol(int row, int col)
22
686M
{
23
686M
  static const char filter[16][16] = {
24
686M
      {2, 1, 1, 3, 2, 3, 2, 0, 3, 2, 3, 0, 1, 2, 1, 0},
25
686M
      {0, 3, 0, 2, 0, 1, 3, 1, 0, 1, 1, 2, 0, 3, 3, 2},
26
686M
      {2, 3, 3, 2, 3, 1, 1, 3, 3, 1, 2, 1, 2, 0, 0, 3},
27
686M
      {0, 1, 0, 1, 0, 2, 0, 2, 2, 0, 3, 0, 1, 3, 2, 1},
28
686M
      {3, 1, 1, 2, 0, 1, 0, 2, 1, 3, 1, 3, 0, 1, 3, 0},
29
686M
      {2, 0, 0, 3, 3, 2, 3, 1, 2, 0, 2, 0, 3, 2, 2, 1},
30
686M
      {2, 3, 3, 1, 2, 1, 2, 1, 2, 1, 1, 2, 3, 0, 0, 1},
31
686M
      {1, 0, 0, 2, 3, 0, 0, 3, 0, 3, 0, 3, 2, 1, 2, 3},
32
686M
      {2, 3, 3, 1, 1, 2, 1, 0, 3, 2, 3, 0, 2, 3, 1, 3},
33
686M
      {1, 0, 2, 0, 3, 0, 3, 2, 0, 1, 1, 2, 0, 1, 0, 2},
34
686M
      {0, 1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 0, 2, 1, 3, 2},
35
686M
      {2, 3, 2, 0, 0, 1, 3, 0, 2, 0, 1, 2, 3, 0, 1, 0},
36
686M
      {1, 3, 1, 2, 3, 2, 3, 2, 0, 2, 0, 1, 1, 0, 3, 0},
37
686M
      {0, 2, 0, 3, 1, 0, 0, 1, 1, 3, 3, 2, 3, 2, 2, 1},
38
686M
      {2, 1, 3, 2, 3, 1, 2, 1, 0, 3, 0, 2, 0, 2, 0, 2},
39
686M
      {0, 3, 1, 0, 0, 2, 0, 3, 2, 1, 3, 1, 1, 3, 1, 3}};
40
41
686M
  if (filters == 1)
42
148k
    return filter[(row + top_margin) & 15][(col + left_margin) & 15];
43
686M
  if (filters == 9)
44
196M
    return xtrans[(row + 6) % 6][(col + 6) % 6];
45
489M
  return FC(row, col);
46
686M
}
47
48
size_t LibRaw::strnlen(const char *s, size_t n)
49
126k
{
50
126k
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
51
126k
  const char *p = (const char *)memchr(s, 0, n);
52
126k
  return (p ? p - s : n);
53
#else
54
  return ::strnlen(s, n);
55
#endif
56
126k
}
57
58
void *LibRaw::memmem(char *haystack, size_t haystacklen, char *needle,
59
                     size_t needlelen)
60
55.4k
{
61
#if !defined(__GLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
62
  char *c;
63
  for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
64
    if (!memcmp(c, needle, needlelen))
65
      return c;
66
  return 0;
67
#else
68
55.4k
  return ::memmem(haystack, haystacklen, needle, needlelen);
69
55.4k
#endif
70
55.4k
}
71
72
char *LibRaw::strcasestr(char *haystack, const char *needle)
73
1.09M
{
74
1.09M
  char *c;
75
9.90M
  for (c = haystack; *c; c++)
76
8.85M
    if (!strncasecmp(c, needle, strlen(needle)))
77
48.9k
      return c;
78
1.04M
  return 0;
79
1.09M
}
80
81
void LibRaw::initdata()
82
0
{
83
0
  tiff_flip = flip = filters = UINT_MAX; /* unknown */
84
0
  raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
85
0
  maximum = height = width = top_margin = left_margin = 0;
86
0
  cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
87
0
  iso_speed = shutter = aperture = focal_len = 0;
88
0
  unique_id = 0ULL;
89
0
  tiff_nifds = 0;
90
0
  memset(tiff_ifd, 0, sizeof tiff_ifd);
91
0
  for (int i = 0; i < LIBRAW_IFD_MAXCOUNT; i++)
92
0
  {
93
0
    tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant =
94
0
        0xffff;
95
0
    for (int c = 0; c < 4; c++)
96
0
      tiff_ifd[i].dng_levels.analogbalance[c] = 1.0f;
97
0
  }
98
0
  for (int i = 0; i < 0x10000; i++)
99
0
    curve[i] = i;
100
0
  memset(gpsdata, 0, sizeof gpsdata);
101
0
  memset(cblack, 0, sizeof cblack);
102
0
  memset(white, 0, sizeof white);
103
0
  memset(mask, 0, sizeof mask);
104
0
  thumb_offset = thumb_length = thumb_width = thumb_height = 0;
105
0
  load_raw = 0;
106
0
  thumb_format = LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default to JPEG
107
0
  data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
108
0
  kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
109
0
  timestamp = shot_order = tiff_samples = black = is_foveon = 0;
110
0
  mix_green = profile_length = data_error = zero_is_bad = 0;
111
0
  pixel_aspect = is_raw = raw_color = 1;
112
0
  tile_width = tile_length = 0;
113
0
  metadata_blocks = 0;
114
0
  is_NikonTransfer = 0;
115
0
  is_Olympus = 0;
116
0
  OlympusDNG_SubDirOffsetValid = 0;
117
0
  is_Sony = 0;
118
0
  is_pana_raw = 0;
119
0
  maker_index = LIBRAW_CAMERAMAKER_Unknown;
120
0
  FujiCropMode = 0;
121
0
  is_PentaxRicohMakernotes = 0;
122
0
  normalized_model[0] = 0;
123
0
  normalized_make[0] = 0;
124
0
  CM_found = 0;
125
0
}
126
127
void LibRaw::aRGB_coeff(double aRGB_cam[3][3])
128
268
{
129
268
  static const double rgb_aRGB[3][3] = {
130
268
      {1.39828313770000, -0.3982830047, 9.64980900741708E-8},
131
268
      {6.09219200572997E-8, 0.9999999809, 1.33230799934103E-8},
132
268
      {2.17237099975343E-8, -0.0429383201, 1.04293828050000}};
133
134
268
  double cmatrix_tmp[3][3] = {
135
268
      {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
136
268
  int i, j, k;
137
138
1.07k
  for (i = 0; i < 3; i++)
139
3.21k
    for (j = 0; j < 3; j++)
140
2.41k
    {
141
9.64k
      for (k = 0; k < 3; k++)
142
7.23k
        cmatrix_tmp[i][j] += rgb_aRGB[i][k] * aRGB_cam[k][j];
143
2.41k
      cmatrix[i][j] = (float)cmatrix_tmp[i][j];
144
2.41k
    }
145
268
}
146
147
void LibRaw::romm_coeff(float romm_cam[3][3])
148
393
{
149
393
  static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
150
393
      {{2.034193f, -0.727420f, -0.306766f},
151
393
       {-0.228811f, 1.231729f, -0.002922f},
152
393
       {-0.008565f, -0.153273f, 1.161839f}};
153
393
  int i, j, k;
154
155
1.57k
  for (i = 0; i < 3; i++)
156
4.71k
    for (j = 0; j < 3; j++)
157
14.1k
      for (cmatrix[i][j] = 0.f, k = 0; k < 3; k++)
158
10.6k
        cmatrix[i][j] += float(rgb_romm[i][k] * romm_cam[k][j]);
159
393
}
160
161
void LibRaw::remove_zeroes()
162
62
{
163
62
  unsigned row, col, tot, n;
164
62
  int r, c;
165
166
62
  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 0, 2);
167
168
23.2k
  for (row = 0; row < height; row++)
169
6.52M
    for (col = 0; col < width; col++)
170
6.50M
      if (BAYER(row, col) == 0)
171
2.75M
      {
172
2.75M
        tot = n = 0;
173
16.5M
        for (r = (int)row - 2; r <= (int)row + 2; r++)
174
82.6M
          for (c = (int)col - 2; c <= (int)col + 2; c++)
175
68.8M
            if (r >= 0 && r < height && c >= 0 && c < width &&
176
68.8M
                FC(r, c) == FC(row, col) && BAYER(r, c))
177
2.89M
              tot += (n++, BAYER(r, c));
178
2.75M
        if (n)
179
2.75M
          BAYER(row, col) = tot / n;
180
2.75M
      }
181
62
  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 1, 2);
182
62
}
183
void LibRaw::crop_masked_pixels()
184
1.57k
{
185
1.57k
  int row, col;
186
1.57k
  unsigned c, m, zero, val;
187
5.88M
#define mblack imgdata.color.black_stat
188
189
1.57k
  if (mask[0][3] > 0)
190
27
    goto mask_set;
191
1.54k
  if (load_raw == &LibRaw::canon_load_raw ||
192
1.51k
      load_raw == &LibRaw::lossless_jpeg_load_raw ||
193
1.50k
      load_raw == &LibRaw::crxLoadRaw)
194
39
  {
195
39
    mask[0][1] = mask[1][1] += 2;
196
39
    mask[0][3] -= 2;
197
39
    goto sides;
198
39
  }
199
1.50k
  if (load_raw == &LibRaw::canon_600_load_raw ||
200
1.50k
      load_raw == &LibRaw::sony_load_raw ||
201
1.50k
      (load_raw == &LibRaw::eight_bit_load_raw && strncmp(model, "DC2", 3)) ||
202
1.50k
      load_raw == &LibRaw::kodak_262_load_raw ||
203
1.32k
      (load_raw == &LibRaw::packed_load_raw && (load_flags & 32)))
204
182
  {
205
221
  sides:
206
221
    mask[0][0] = mask[1][0] = top_margin;
207
221
    mask[0][2] = mask[1][2] = top_margin + height;
208
221
    mask[0][3] += left_margin;
209
221
    mask[1][1] += left_margin + width;
210
221
    mask[1][3] += raw_width;
211
221
  }
212
1.54k
  if (load_raw == &LibRaw::nokia_load_raw)
213
110
  {
214
110
    mask[0][2] = top_margin;
215
110
    mask[0][3] = width;
216
110
  }
217
1.54k
  if (load_raw == &LibRaw::broadcom_load_raw)
218
0
  {
219
0
    mask[0][2] = top_margin;
220
0
    mask[0][3] = width;
221
0
  }
222
1.57k
mask_set:
223
1.57k
  memset(mblack, 0, sizeof mblack);
224
14.1k
  for (zero = m = 0; m < 8; m++)
225
316k
    for (row = MAX(mask[m][0], 0); row < MIN(mask[m][2], raw_height); row++)
226
3.24M
      for (col = MAX(mask[m][1], 0); col < MIN(mask[m][3], raw_width); col++)
227
2.94M
      {
228
        /* No need to subtract margins because full area and active area filters are the same */
229
2.94M
        c = FC(row, col);
230
2.94M
        mblack[c] += val = raw_image[(row)*raw_pitch / 2 + (col)];
231
2.94M
        mblack[4 + c]++;
232
2.94M
        zero += !val;
233
2.94M
      }
234
1.57k
  if (load_raw == &LibRaw::canon_600_load_raw && width < raw_width)
235
0
  {
236
0
    black = (mblack[0] + mblack[1] + mblack[2] + mblack[3]) /
237
0
                MAX(1, (mblack[4] + mblack[5] + mblack[6] + mblack[7])) -
238
0
            4;
239
0
  }
240
1.57k
  else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7])
241
16
  {
242
64
    FORC4 cblack[c] = mblack[c] / MAX(1, mblack[4 + c]);
243
16
    black = cblack[4] = cblack[5] = cblack[6] = 0;
244
16
  }
245
1.57k
}
246
#undef mblack
247
248
void LibRaw::pseudoinverse(double (*in)[3], double (*out)[3], int size)
249
1.74k
{
250
1.74k
  double work[3][6], num;
251
1.74k
  int i, j, k;
252
253
6.99k
  for (i = 0; i < 3; i++)
254
5.24k
  {
255
36.7k
    for (j = 0; j < 6; j++)
256
31.4k
      work[i][j] = j == i + 3;
257
20.9k
    for (j = 0; j < 3; j++)
258
63.3k
      for (k = 0; k < size && k < 4; k++)
259
47.6k
        work[i][j] += in[k][i] * in[k][j];
260
5.24k
  }
261
6.99k
  for (i = 0; i < 3; i++)
262
5.24k
  {
263
5.24k
    num = work[i][i];
264
36.7k
    for (j = 0; j < 6; j++)
265
31.4k
      if (fabs(num) > 0.00001f)
266
23.6k
        work[i][j] /= num;
267
20.9k
    for (k = 0; k < 3; k++)
268
15.7k
    {
269
15.7k
      if (k == i)
270
5.24k
        continue;
271
10.4k
      num = work[k][i];
272
73.4k
      for (j = 0; j < 6; j++)
273
62.9k
        work[k][j] -= work[i][j] * num;
274
10.4k
    }
275
5.24k
  }
276
7.04k
  for (i = 0; i < size && i < 4; i++)
277
21.1k
    for (j = 0; j < 3; j++)
278
63.5k
      for (out[i][j] = k = 0; k < 3; k++)
279
47.6k
        out[i][j] += work[j][k + 3] * in[i][k];
280
1.74k
}
281
282
void LibRaw::cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3])
283
1.53k
{
284
1.53k
  double cam_rgb[4][3], inverse[4][3], num;
285
1.53k
  int i, j, k;
286
287
6.20k
  for (i = 0; i < colors && i < 4; i++) /* Multiply out XYZ colorspace */
288
18.6k
    for (j = 0; j < 3; j++)
289
55.9k
      for (cam_rgb[i][j] = k = 0; k < 3; k++)
290
41.9k
        cam_rgb[i][j] += cam_xyz[i][k] * LibRaw_constants::xyz_rgb[k][j];
291
292
6.20k
  for (i = 0; i < colors && i < 4; i++)
293
4.66k
  {                               /* Normalize cam_rgb so that */
294
18.6k
    for (num = j = 0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
295
13.9k
      num += cam_rgb[i][j];
296
4.66k
    if (num > 0.00001)
297
3.44k
    {
298
13.7k
      for (j = 0; j < 3; j++)
299
10.3k
        cam_rgb[i][j] /= num;
300
3.44k
      pre_mul[i] = float(1.0 / num);
301
3.44k
    }
302
1.21k
    else
303
1.21k
    {
304
4.87k
      for (j = 0; j < 3; j++)
305
3.65k
        cam_rgb[i][j] = 0.0;
306
1.21k
      pre_mul[i] = 1.0;
307
1.21k
    }
308
4.66k
  }
309
1.53k
  pseudoinverse(cam_rgb, inverse, colors);
310
6.15k
  for (i = 0; i < 3; i++)
311
18.6k
    for (j = 0; j < colors && j < 4; j++)
312
13.9k
      _rgb_cam[i][j] = float(inverse[j][i]);
313
1.53k
}
314
315
void LibRaw::tiff_get(INT64 base, unsigned *tag, unsigned *type,
316
                      unsigned *len, INT64 *save)
317
67.3M
{
318
67.3M
#ifdef LIBRAW_IOSPACE_CHECK
319
67.3M
  INT64 pos = ftell(ifp);
320
67.3M
  INT64 fsize = ifp->size();
321
67.3M
  if (fsize < 12 || (fsize - pos) < 12)
322
11.3k
    throw LIBRAW_EXCEPTION_IO_EOF;
323
67.3M
#endif
324
67.3M
  *tag = get2();
325
67.3M
  *type = get2();
326
67.3M
  *len = get4();
327
67.3M
  *save = ftell(ifp) + 4LL;
328
67.3M
  if (*len * tagtype_dataunit_bytes[(*type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *type : 0] > 4)
329
57.8M
    fseek(ifp, INT64(get4()) + base, SEEK_SET);
330
67.3M
}