Coverage Report

Created: 2025-09-08 07:52

/src/LibRaw/src/utils/curves.cpp
Line
Count
Source (jump to first uncovered line)
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
void LibRaw::cubic_spline(const int *x_, const int *y_, const int len)
22
0
{
23
0
  float **A, *b, *c, *d, *x, *y;
24
0
  int i, j;
25
26
0
  A = (float **)calloc(((2 * len + 4) * sizeof **A + sizeof *A), 2 * len);
27
0
  if (!A)
28
0
    return;
29
0
  A[0] = (float *)(A + 2 * len);
30
0
  for (i = 1; i < 2 * len; i++)
31
0
    A[i] = A[0] + 2 * len * i;
32
0
  y = len + (x = i + (d = i + (c = i + (b = A[0] + i * i))));
33
0
  for (i = 0; i < len; i++)
34
0
  {
35
0
    x[i] = float(x_[i]) / 65535.0f;
36
0
    y[i] = float(y_[i]) / 65535.0f;
37
0
  }
38
0
  for (i = len - 1; i > 0; i--)
39
0
  {
40
0
  float _div = x[i] - x[i - 1];
41
0
  if (fabsf(_div) < 1.0e-15f)
42
0
    _div = 1;
43
0
    b[i] = (y[i] - y[i - 1]) / _div;
44
0
    d[i - 1] = _div;
45
0
  }
46
0
  for (i = 1; i < len - 1; i++)
47
0
  {
48
0
    A[i][i] = 2 * (d[i - 1] + d[i]);
49
0
    if (i > 1)
50
0
    {
51
0
      A[i][i - 1] = d[i - 1];
52
0
      A[i - 1][i] = d[i - 1];
53
0
    }
54
0
    A[i][len - 1] = 6 * (b[i + 1] - b[i]);
55
0
  }
56
0
  for (i = 1; i < len - 2; i++)
57
0
  {
58
0
    float v = A[i + 1][i] / A[i][i];
59
0
    for (j = 1; j <= len - 1; j++)
60
0
      A[i + 1][j] -= v * A[i][j];
61
0
  }
62
0
  for (i = len - 2; i > 0; i--)
63
0
  {
64
0
    float acc = 0;
65
0
    for (j = i; j <= len - 2; j++)
66
0
      acc += A[i][j] * c[j];
67
0
    c[i] = (A[i][len - 1] - acc) / A[i][i];
68
0
  }
69
0
  for (i = 0; i < 0x10000; i++)
70
0
  {
71
0
    float x_out = (float)(i / 65535.0f);
72
0
    float y_out = 0;
73
0
    for (j = 0; j < len - 1; j++)
74
0
    {
75
0
      if (x[j] <= x_out && x_out <= x[j + 1])
76
0
      {
77
0
        float v = x_out - x[j];
78
0
        y_out = y[j] +
79
0
                ((y[j + 1] - y[j]) / d[j] -
80
0
                 (2 * d[j] * c[j] + c[j + 1] * d[j]) / 6) *
81
0
                    v +
82
0
                (c[j] * 0.5f) * v * v +
83
0
                ((c[j + 1] - c[j]) / (6.f * d[j])) * v * v * v;
84
0
      }
85
0
    }
86
0
    curve[i] = y_out < 0.0
87
0
                   ? 0
88
0
                   : (y_out >= 1.0 ? 65535 : (ushort)(y_out * 65535.0f + 0.5f));
89
0
  }
90
0
  free(A);
91
0
}
92
void LibRaw::gamma_curve(double pwr, double ts, int mode, int imax)
93
4.55k
{
94
4.55k
  int i;
95
4.55k
  double g[6], bnd[2] = {0, 0}, r;
96
97
4.55k
  g[0] = pwr;
98
4.55k
  g[1] = ts;
99
4.55k
  g[2] = g[3] = g[4] = 0;
100
4.55k
  bnd[g[1] >= 1] = 1;
101
4.55k
  if (g[1] && (g[1] - 1) * (g[0] - 1) <= 0)
102
4.48k
  {
103
219k
    for (i = 0; i < 48; i++)
104
215k
    {
105
215k
      g[2] = (bnd[0] + bnd[1]) / 2;
106
215k
      if (g[0])
107
205k
        bnd[(pow(g[2] / g[1], -g[0]) - 1) / g[0] - 1 / g[2] > -1] = g[2];
108
9.69k
      else
109
9.69k
        bnd[g[2] / exp(1 - 1 / g[2]) < g[1]] = g[2];
110
215k
    }
111
4.48k
    g[3] = g[2] / g[1];
112
4.48k
    if (g[0])
113
4.28k
      g[4] = g[2] * (1 / g[0] - 1);
114
4.48k
  }
115
4.55k
  if (g[0])
116
4.35k
    g[5] = 1 / (g[1] * SQR(g[3]) / 2 - g[4] * (1 - g[3]) +
117
4.35k
                (1 - pow(g[3], 1 + g[0])) * (1 + g[4]) / (1 + g[0])) -
118
4.35k
           1;
119
202
  else
120
202
    g[5] = 1 / (g[1] * SQR(g[3]) / 2 + 1 - g[2] - g[3] -
121
202
                g[2] * g[3] * (log(g[3]) - 1)) -
122
202
           1;
123
4.55k
  if (!mode--)
124
2.04k
  {
125
2.04k
    memcpy(gamm, g, sizeof gamm);
126
2.04k
    return;
127
2.04k
  }
128
164M
  for (i = 0; i < 0x10000; i++)
129
164M
  {
130
164M
    curve[i] = 0xffff;
131
164M
    if ((r = (double)i / imax) < 1)
132
85.2M
      curve[i] =
133
85.2M
    ushort(
134
85.2M
          0x10000 *
135
85.2M
          (mode ? (r < g[3] ? r * g[1]
136
82.5M
                            : (g[0] ? pow(r, g[0]) * (1 + g[4]) - g[4]
137
81.0M
                                    : log(r) * g[2] + 1))
138
85.2M
                : (r < g[2] ? r / g[1]
139
2.67M
                            : (g[0] ? pow((r + g[4]) / (1 + g[4]), 1 / g[0])
140
2.63M
                                    : exp((r - 1) / g[2]))))
141
85.2M
      );
142
164M
  }
143
2.50k
}
144
145
void LibRaw::linear_table(unsigned len)
146
2.77k
{
147
2.77k
  int i;
148
2.77k
  if (len > 0x10000)
149
32
    len = 0x10000;
150
2.74k
  else if (len < 1)
151
496
    return;
152
2.27k
  read_shorts(curve, len);
153
146M
  for (i = len; i < 0x10000; i++)
154
146M
    curve[i] = curve[i - 1];
155
2.27k
  maximum = curve[len < 0x1000 ? 0xfff : len - 1];
156
2.27k
}