https://doi.org/10.5201/ipol.2020.245
Tip revision: 5f23fb0b6e1d50d996ac54daaa7e637e5d8decaf authored by Software Heritage on 05 May 2020, 00:00:00 UTC
ipol: Deposit 1363 in collection ipol
ipol: Deposit 1363 in collection ipol
Tip revision: 5f23fb0
bilinear_interpolation.c
/*
* bilinear_interpolation.c
*
* Copyright (C) 2019, Enric Meinhardt-Llopis, CMLA, ÉNS Paris-Saclay.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
static inline
float evaluate_bilinear_cell(float a, float b, float c, float d,
float x, float y)
{
float r = 0;
r += a * (1-x) * (1-y);
r += b * ( x ) * (1-y);
r += c * (1-x) * ( y );
r += d * ( x ) * ( y );
return r;
}
static inline
float getsamplec(float *fx, int w, int h, int pd, int i, int j, int l)
{
if (i < 0) i = 0;
if (j < 0) j = 0;
if (l < 0) l = 0;
if (i >= w) i = w-1;
if (j >= h) j = h-1;
if (l >= pd) l = pd-1;
return fx[(i+j*w)*pd + l];
}
static inline
void bilinear_interpolation_vec_at(float *result,
float *x, int w, int h, int pd,
float p, float q)
{
int ip = p;
int iq = q;
for (int l = 0; l < pd; l++)
{
float a = getsamplec(x, w, h, pd, ip, iq, l);
float b = getsamplec(x, w, h, pd, ip+1, iq, l);
float c = getsamplec(x, w, h, pd, ip, iq+1, l);
float d = getsamplec(x, w, h, pd, ip+1, iq+1, l);
float r = evaluate_bilinear_cell(a, b, c, d, p-ip, q-iq);
result[l] = r;
}
}
void
bilinear_interpolant_vec(float *y, int yw, int yh, float *x, int xw, int xh, int pd)
{
float wfactor = xw/(float)yw;
float hfactor = xh/(float)yh;
for (int j = 0; j < yh; j++)
for (int i = 0; i < yw; i++)
{
float p = i*wfactor;
float q = j*hfactor;
bilinear_interpolation_vec_at(y + (j*yw+i)*pd, x, xw, xh, pd, p, q);
}
}