diff --git a/include/lol/private/math/interp.h b/include/lol/private/math/interp.h index 07a8843f..354edd07 100644 --- a/include/lol/private/math/interp.h +++ b/include/lol/private/math/interp.h @@ -2,6 +2,7 @@ // Lol Engine // // Copyright © 2010–2024 Sam Hocevar +// 2024 NuSan // // Lol Engine is free software. It comes without any warranty, to // the extent permitted by applicable law. You can redistribute it @@ -23,41 +24,40 @@ namespace lol::interp { +// Lanczos interpolation +// SIZE: number of lobes of the sinc function that contribute to the interpolation +// PRECISION: number of samples per lobe in the kernel template class lanczos { public: lanczos() { - T const window_center = SIZE / 2; - T const lut_scale = (SIZE * PRECISION - 1) / (window_center + 1); for (size_t k = 0; k < SIZE * PRECISION; ++k) { - T dist = T(k) * F_PI / lut_scale; - m_lut[k] = dist ? window_center * std::sin(dist) * std::sin(dist / window_center) / (dist * dist) : T(1); + T dist = T(k) * F_PI / m_scale; + m_kernel[k] = dist ? m_center * std::sin(dist) * std::sin(dist / m_center) / (dist * dist) : T(1); } } - T get(T *data, size_t stride, T alpha) + T get(T *data, size_t stride, T offset) const { - T const window_center = SIZE / 2; - T const lut_scale = (SIZE * PRECISION - 1) / (window_center + 1); T ret(0); for (size_t k = 0; k < SIZE; ++k) { - float dist = std::abs(k - window_center - alpha); - float lanczos = m_lut[size_t(dist * lut_scale)]; - ret += data[k * stride] * lanczos; + float dist = std::abs(k - m_center - offset); + ret += data[k * stride] * m_kernel[size_t(dist * m_scale)]; } return ret; } - size_t const size() { return SIZE; } + size_t const size() const { return SIZE; } private: - static size_t const center = T(SIZE) / 2; + static inline T const m_center = SIZE / 2; + static inline T const m_scale = (SIZE * PRECISION - 1) / (m_center + 1); - std::array m_lut; + std::array m_kernel; }; } // namespace lol::interp