static void linear_coeffs(int w, int outw, int* xofs, float* alpha, int align_corner)
{
double scale = (double)w / outw;
if (align_corner)
{
scale = (double)(w - 1) / (outw - 1);
}
for (int dx = 0; dx < outw; dx++)
{
float fx = (float)((dx + 0.5) * scale - 0.5);
if (align_corner)
{
fx = (float)(dx * scale);
}
int sx = floor(fx);
fx -= sx;
if (sx < 0)
{
sx = 0;
fx = 0.f;
}
if (sx >= w - 1)
{
sx = w - 2;
fx = 1.f;
}
xofs[dx] = sx;
alpha[dx * 2] = 1.f - fx;
alpha[dx * 2 + 1] = fx;
}
}
static void resize_bilinear_image(const Mat& src, Mat& dst, float* alpha, int* xofs, float* beta, int* yofs)
{
int w = dst.w;
int h = dst.h;
Mat rowsbuf0(w);
Mat rowsbuf1(w);
float* rows0 = rowsbuf0;
float* rows1 = rowsbuf1;
int prev_sy1 = -2;
for (int dy = 0; dy < h; dy++)
{
int sy = yofs[dy];
if (sy == prev_sy1)
{
}
else if (sy == prev_sy1 + 1)
{
float* rows0_old = rows0;
rows0 = rows1;
rows1 = rows0_old;
const float* S1 = src.row(sy + 1);
const float* alphap = alpha;
float* rows1p = rows1;
int dx = 0;
for (; dx < w; dx++)
{
int sx = xofs[dx];
const float* S1p = S1 + sx;
float a0 = alphap[0];
float a1 = alphap[1];
rows1p[dx] = S1p[0] * a0 + S1p[1] * a1;
alphap += 2;
}
}
else
{
const float* S0 = src.row(sy);
const float* S1 = src.row(sy + 1);
const float* alphap = alpha;
float* rows0p = rows0;
float* rows1p = rows1;
int dx = 0;
for (; dx < w; dx++)
{
int sx = xofs[dx];
const float* S0p = S0 + sx;
const float* S1p = S1 + sx;
float a0 = alphap[0];
float a1 = alphap[1];
rows0p[dx] = S0p[0] * a0 + S0p[1] * a1;
rows1p[dx] = S1p[0] * a0 + S1p[1] * a1;
alphap += 2;
}
}
prev_sy1 = sy;
float b0 = beta[0];
float b1 = beta[1];
float* rows0p = rows0;
float* rows1p = rows1;
float* Dp = dst.row(dy);
#if __loongarch_sx
int nn = w >> 3;
#else
int nn = 0;
#endif
int remain = w - (nn << 3);
#if __loongarch_sx
__m128 _b0 = __lsx_vreplfr2vr_s(b0);
__m128 _b1 = __lsx_vreplfr2vr_s(b1);
for (; nn > 0; nn--)
{
__m128 _rows0 = (__m128)__lsx_vld(rows0p, 0);
__m128 _rows1 = (__m128)__lsx_vld(rows1p, 0);
__m128 _Dp = __lsx_vfmul_s(_rows0, _b0);
_Dp = __lsx_vfmadd_s(_b1, _rows1, _Dp);
__lsx_vst(_Dp, Dp, 0);
__m128 _rows0n = (__m128)__lsx_vld(rows0p + 4, 0);
__m128 _rows1n = (__m128)__lsx_vld(rows1p + 4, 0);
__m128 _Dpn = __lsx_vfmul_s(_rows0n, _b0);
_Dpn = __lsx_vfmadd_s(_b1, _rows1n, _Dpn);
__lsx_vst(_Dpn, Dp + 4, 0);
Dp += 8;
rows0p += 8;
rows1p += 8;
}
#endif
for (; remain; --remain)
{
*Dp++ = *rows0p++ * b0 + *rows1p++ * b1;
}
beta += 2;
}
}