Procházet zdrojové kódy

math: minor tweaks to the Lanczos interpolator

main
Sam Hocevar před 4 měsíci
rodič
revize
366b460766
1 změnil soubory, kde provedl 13 přidání a 13 odebrání
  1. +13
    -13
      include/lol/private/math/interp.h

+ 13
- 13
include/lol/private/math/interp.h Zobrazit soubor

@@ -2,6 +2,7 @@
// Lol Engine
//
// Copyright © 2010–2024 Sam Hocevar <sam@hocevar.net>
// 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<typename T, size_t SIZE = 16, size_t PRECISION = 64>
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<T, SIZE * PRECISION> m_lut;
std::array<T, SIZE * PRECISION> m_kernel;
};

} // namespace lol::interp

Načítá se…
Zrušit
Uložit