Coverage Report

Created: 2025-12-20 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/utils/curves.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
void LibRaw::cubic_spline(const int *x_, const int *y_, const int len)
22
1.47k
{
23
1.47k
  float **A, *b, *c, *d, *x, *y;
24
1.47k
  int i, j;
25
26
1.47k
  A = (float **)calloc(((2 * len + 4) * sizeof **A + sizeof *A), 2 * len);
27
1.47k
  if (!A)
28
0
    return;
29
1.47k
  A[0] = (float *)(A + 2 * len);
30
38.4k
  for (i = 1; i < 2 * len; i++)
31
37.0k
    A[i] = A[0] + 2 * len * i;
32
1.47k
  y = len + (x = i + (d = i + (c = i + (b = A[0] + i * i))));
33
20.7k
  for (i = 0; i < len; i++)
34
19.2k
  {
35
19.2k
    x[i] = float(x_[i]) / 65535.0f;
36
19.2k
    y[i] = float(y_[i]) / 65535.0f;
37
19.2k
  }
38
19.2k
  for (i = len - 1; i > 0; i--)
39
17.7k
  {
40
17.7k
  float _div = x[i] - x[i - 1];
41
17.7k
  if (fabsf(_div) < 1.0e-15f)
42
4.89k
    _div = 1;
43
17.7k
    b[i] = (y[i] - y[i - 1]) / _div;
44
17.7k
    d[i - 1] = _div;
45
17.7k
  }
46
17.7k
  for (i = 1; i < len - 1; i++)
47
16.3k
  {
48
16.3k
    A[i][i] = 2 * (d[i - 1] + d[i]);
49
16.3k
    if (i > 1)
50
14.8k
    {
51
14.8k
      A[i][i - 1] = d[i - 1];
52
14.8k
      A[i - 1][i] = d[i - 1];
53
14.8k
    }
54
16.3k
    A[i][len - 1] = 6 * (b[i + 1] - b[i]);
55
16.3k
  }
56
16.3k
  for (i = 1; i < len - 2; i++)
57
14.8k
  {
58
14.8k
    float v = A[i + 1][i] / A[i][i];
59
229k
    for (j = 1; j <= len - 1; j++)
60
214k
      A[i + 1][j] -= v * A[i][j];
61
14.8k
  }
62
17.7k
  for (i = len - 2; i > 0; i--)
63
16.3k
  {
64
16.3k
    float acc = 0;
65
132k
    for (j = i; j <= len - 2; j++)
66
116k
      acc += A[i][j] * c[j];
67
16.3k
    c[i] = (A[i][len - 1] - acc) / A[i][i];
68
16.3k
  }
69
96.4M
  for (i = 0; i < 0x10000; i++)
70
96.4M
  {
71
96.4M
    float x_out = (float)(i / 65535.0f);
72
96.4M
    float y_out = 0;
73
1.26G
    for (j = 0; j < len - 1; j++)
74
1.16G
    {
75
1.16G
      if (x[j] <= x_out && x_out <= x[j + 1])
76
201M
      {
77
201M
        float v = x_out - x[j];
78
201M
        y_out = y[j] +
79
201M
                ((y[j + 1] - y[j]) / d[j] -
80
201M
                 (2 * d[j] * c[j] + c[j + 1] * d[j]) / 6) *
81
201M
                    v +
82
201M
                (c[j] * 0.5f) * v * v +
83
201M
                ((c[j + 1] - c[j]) / (6.f * d[j])) * v * v * v;
84
201M
      }
85
1.16G
    }
86
96.4M
    curve[i] = y_out < 0.0
87
96.4M
                   ? 0
88
96.4M
                   : (y_out >= 1.0 ? 65535 : (ushort)(y_out * 65535.0f + 0.5f));
89
96.4M
  }
90
1.47k
  free(A);
91
1.47k
}
92
void LibRaw::gamma_curve(double pwr, double ts, int mode, int imax)
93
31.0k
{
94
31.0k
  int i;
95
31.0k
  double g[6], bnd[2] = {0, 0}, r;
96
97
31.0k
  g[0] = pwr;
98
31.0k
  g[1] = ts;
99
31.0k
  g[2] = g[3] = g[4] = 0;
100
31.0k
  bnd[g[1] >= 1] = 1;
101
31.0k
  if (g[1] && (g[1] - 1) * (g[0] - 1) <= 0)
102
11.3k
  {
103
556k
    for (i = 0; i < 48; i++)
104
545k
    {
105
545k
      g[2] = (bnd[0] + bnd[1]) / 2;
106
545k
      if (g[0])
107
528k
        bnd[(pow(g[2] / g[1], -g[0]) - 1) / g[0] - 1 / g[2] > -1] = g[2];
108
17.3k
      else
109
17.3k
        bnd[g[2] / exp(1 - 1 / g[2]) < g[1]] = g[2];
110
545k
    }
111
11.3k
    g[3] = g[2] / g[1];
112
11.3k
    if (g[0])
113
11.0k
      g[4] = g[2] * (1 / g[0] - 1);
114
11.3k
  }
115
31.0k
  if (g[0])
116
30.3k
    g[5] = 1 / (g[1] * SQR(g[3]) / 2 - g[4] * (1 - g[3]) +
117
30.3k
                (1 - pow(g[3], 1 + g[0])) * (1 + g[4]) / (1 + g[0])) -
118
30.3k
           1;
119
663
  else
120
663
    g[5] = 1 / (g[1] * SQR(g[3]) / 2 + 1 - g[2] - g[3] -
121
663
                g[2] * g[3] * (log(g[3]) - 1)) -
122
663
           1;
123
31.0k
  if (!mode--)
124
30.0k
  {
125
30.0k
    memcpy(gamm, g, sizeof gamm);
126
30.0k
    return;
127
30.0k
  }
128
64.4M
  for (i = 0; i < 0x10000; i++)
129
64.4M
  {
130
64.4M
    curve[i] = 0xffff;
131
64.4M
    if ((r = (double)i / imax) < 1)
132
6.81M
      curve[i] =
133
6.81M
    ushort(
134
6.81M
          0x10000 *
135
6.81M
          (mode ? (r < g[3] ? r * g[1]
136
1.04M
                            : (g[0] ? pow(r, g[0]) * (1 + g[4]) - g[4]
137
14
                                    : log(r) * g[2] + 1))
138
6.81M
                : (r < g[2] ? r / g[1]
139
5.76M
                            : (g[0] ? pow((r + g[4]) / (1 + g[4]), 1 / g[0])
140
5.72M
                                    : exp((r - 1) / g[2]))))
141
6.81M
      );
142
64.4M
  }
143
984
}
144
145
void LibRaw::linear_table(unsigned len)
146
4.37k
{
147
4.37k
  int i;
148
4.37k
  if (len > 0x10000)
149
88
    len = 0x10000;
150
4.29k
  else if (len < 1)
151
1.44k
    return;
152
2.93k
  read_shorts(curve, len);
153
184M
  for (i = len; i < 0x10000; i++)
154
184M
    curve[i] = curve[i - 1];
155
2.93k
  maximum = curve[len < 0x1000 ? 0xfff : len - 1];
156
2.93k
}