MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ interpolate_cubic()

void MayaFlux::Kinesis::Discrete::interpolate_cubic ( std::span< const double >  src,
std::span< double >  dst 
)
noexcept

Catmull-Rom cubic interpolation from src into dst (caller sizes dst) Branchless boundary clamping; Horner evaluation form.

Parameters
srcSource span (read-only, at least 2 samples)
dstDestination span (written in-place)

Definition at line 183 of file Transform.cpp.

184{
185 const size_t dst_n = dst.size();
186 const size_t src_n = src.size();
187
188 if (dst_n == 0 || src_n == 0)
189 return;
190
191 if (dst_n == 1 || src_n == 1) {
192 std::ranges::fill(dst, src[0]);
193 return;
194 }
195
196 const double step = static_cast<double>(src_n - 1) / static_cast<double>(dst_n - 1);
197 const size_t last = src_n - 1;
198
199 Parallel::for_each(Parallel::par_unseq,
200 std::views::iota(size_t { 0 }, dst_n).begin(),
201 std::views::iota(size_t { 0 }, dst_n).end(),
202 [&src, &dst, step, last](size_t i) {
203 const double pos = static_cast<double>(i) * step;
204 const auto idx = static_cast<size_t>(pos);
205 const double f = pos - static_cast<double>(idx);
206
207 const size_t i0 = idx > 0 ? idx - 1 : 0;
208 const size_t i1 = idx;
209 const size_t i2 = std::min(idx + 1, last);
210 const size_t i3 = std::min(idx + 2, last);
211
212 const double y0 = src[i0], y1 = src[i1], y2 = src[i2], y3 = src[i3];
213 const double a = -0.5 * y0 + 1.5 * y1 - 1.5 * y2 + 0.5 * y3;
214 const double b = y0 - 2.5 * y1 + 2.0 * y2 - 0.5 * y3;
215 const double c = -0.5 * y0 + 0.5 * y2;
216 dst[i] = ((a * f + b) * f + c) * f + y1;
217 });
218}
size_t a
size_t b

References a, and b.