Coverage Report

Created: 2021-08-22 09:07

/src/skia/third_party/externals/dng_sdk/source/dng_spline.cpp
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************/
2
// Copyright 2006-2007 Adobe Systems Incorporated
3
// All Rights Reserved.
4
//
5
// NOTICE:  Adobe permits you to use, modify, and distribute this file in
6
// accordance with the terms of the Adobe license agreement accompanying it.
7
/*****************************************************************************/
8
9
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_spline.cpp#1 $ */ 
10
/* $DateTime: 2012/05/30 13:28:51 $ */
11
/* $Change: 832332 $ */
12
/* $Author: tknoll $ */
13
14
/*****************************************************************************/
15
16
#include "dng_spline.h"
17
18
#include "dng_assertions.h"
19
#include "dng_exceptions.h"
20
21
/******************************************************************************/
22
23
dng_spline_solver::dng_spline_solver ()
24
25
  : X ()
26
  , Y ()
27
  , S ()
28
  
29
0
  {
30
  
31
0
  }
32
33
/******************************************************************************/
34
35
dng_spline_solver::~dng_spline_solver ()
36
0
  {
37
  
38
0
  }
39
40
/******************************************************************************/
41
42
void dng_spline_solver::Reset ()
43
0
  {
44
  
45
0
  X.clear ();
46
0
  Y.clear ();
47
  
48
0
  S.clear ();
49
  
50
0
  }
51
52
/******************************************************************************/
53
54
void dng_spline_solver::Add (real64 x, real64 y)
55
0
  {
56
57
0
  X.push_back (x);
58
0
  Y.push_back (y);
59
60
0
  }
61
62
/******************************************************************************/
63
64
void dng_spline_solver::Solve ()
65
0
  {
66
67
  // This code computes the unique curve such that:
68
  //    It is C0, C1, and C2 continuous
69
  //    The second derivative is zero at the end points
70
  
71
0
  int32 count = (int32) X.size ();
72
  
73
0
  DNG_ASSERT (count >= 2, "Too few points");
74
  
75
0
  int32 start = 0;
76
0
  int32 end   = count;
77
  
78
0
  real64 A =  X [start+1] - X [start];
79
0
  real64 B = (Y [start+1] - Y [start]) / A;
80
  
81
0
  S.resize (count);
82
83
0
  S [start] = B;
84
  
85
0
  int32 j;
86
87
  // Slopes here are a weighted average of the slopes
88
  // to each of the adjcent control points.
89
90
0
  for (j = start + 2; j < end; ++j)
91
0
    {
92
93
0
    real64 C = X [j] - X [j-1];
94
0
    real64 D = (Y [j] - Y [j-1]) / C;
95
96
0
    S [j-1] = (B * C + D * A) / (A + C);
97
98
0
    A = C;
99
0
    B = D;
100
101
0
    }
102
103
0
  S [end-1] = 2.0 * B - S [end-2];
104
0
  S [start] = 2.0 * S [start] - S [start+1];
105
106
0
  if ((end - start) > 2)
107
0
    {
108
109
0
    dng_std_vector<real64> E;
110
0
    dng_std_vector<real64> F;
111
0
    dng_std_vector<real64> G;
112
    
113
0
    E.resize (count);
114
0
    F.resize (count);
115
0
    G.resize (count);
116
117
0
    F [start] = 0.5;
118
0
    E [end-1] = 0.5;
119
0
    G [start] = 0.75 * (S [start] + S [start+1]);
120
0
    G [end-1] = 0.75 * (S [end-2] + S [end-1]);
121
122
0
    for (j = start+1; j < end - 1; ++j)
123
0
      {
124
125
0
      A = (X [j+1] - X [j-1]) * 2.0;
126
127
0
      E [j] = (X [j+1] - X [j]) / A;
128
0
      F [j] = (X [j] - X [j-1]) / A;
129
0
      G [j] = 1.5 * S [j];
130
131
0
      }
132
133
0
    for (j = start+1; j < end; ++j)
134
0
      {
135
136
0
      A = 1.0 - F [j-1] * E [j];
137
138
0
      if (j != end-1) F [j] /= A;
139
140
0
      G [j] = (G [j] - G [j-1] * E [j]) / A;
141
142
0
      }
143
144
0
    for (j = end - 2; j >= start; --j)
145
0
      G [j] = G [j] - F [j] * G [j+1];
146
147
0
    for (j = start; j < end; ++j)
148
0
      S [j] = G [j];
149
150
0
    }
151
152
0
  }
153
154
/******************************************************************************/
155
156
bool dng_spline_solver::IsIdentity () const
157
0
  {
158
  
159
0
  int32 count = (int32) X.size ();
160
  
161
0
  if (count != 2)
162
0
    return false;
163
    
164
0
  if (X [0] != 0.0 || X [1] != 1.0 ||
165
0
    Y [0] != 0.0 || Y [1] != 1.0)
166
0
    return false;
167
    
168
0
  return true;
169
  
170
0
  }
171
172
/******************************************************************************/
173
174
real64 dng_spline_solver::Evaluate (real64 x) const
175
0
  {
176
177
0
  int32 count = (int32) X.size ();
178
  
179
  // Check for off each end of point list.
180
  
181
0
  if (x <= X [0])
182
0
    return Y [0];
183
184
0
  if (x >= X [count-1])
185
0
    return Y [count-1];
186
187
  // Binary search for the index.
188
  
189
0
  int32 lower = 1;
190
0
  int32 upper = count - 1;
191
  
192
0
  while (upper > lower)
193
0
    {
194
    
195
0
    int32 mid = (lower + upper) >> 1;
196
    
197
0
    if (x == X [mid])
198
0
      {
199
0
      return Y [mid];
200
0
      }
201
      
202
0
    if (x > X [mid])
203
0
      lower = mid + 1;
204
0
    else
205
0
      upper = mid;
206
    
207
0
    }
208
    
209
0
  DNG_ASSERT (upper == lower, "Binary search error in point list");
210
211
0
  int32 j = lower;
212
    
213
  // X [j - 1] < x <= X [j]
214
  // A is the distance between the X [j] and X [j - 1]
215
  // B and C describe the fractional distance to either side. B + C = 1.
216
217
  // We compute a cubic spline between the two points with slopes
218
  // S[j-1] and S[j] at either end. Specifically, we compute the 1-D Bezier
219
  // with control values:
220
  //
221
  //    Y[j-1], Y[j-1] + S[j-1]*A, Y[j]-S[j]*A, Y[j]
222
  
223
0
  return EvaluateSplineSegment (x,
224
0
                  X [j - 1],
225
0
                  Y [j - 1],
226
0
                  S [j - 1],
227
0
                  X [j    ],
228
0
                  Y [j    ],
229
0
                  S [j    ]);
230
231
0
  }
232
    
233
/*****************************************************************************/