How to correctly resize image with a different linear interpolation scheme

I want to double image with an linear interpolation scheme so that even indices of the new image is copied from indices/2 of the original and odd indices would linearly interpolate from the even indices. Example:

static Mat prepare_img(bool rows_indexed) {
    int rows = 5;
    int columns = 5;
    Mat img(rows, columns, CV_32F);

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < columns; j++) {
            if (rows_indexed) {
                img.at<float>(i, j) = (float)i;
            } else {
                img.at<float>(i, j) = (float)j;
            }
        }
    }
    return img;
}

static void double_linear(Mat& src, Mat& dst) {
    dst.create(Size(src.cols*2, src.rows*2), src.type());

    for (int i = 0; i < dst.rows; i = i + 2) {
        for (int j = 0; j < dst.cols; j = j + 2) {
            dst.at<float>(i, j) = src.at<float>(i/2, j/2);
        }
    }
    for (int i = 0; i < dst.rows; i = i + 2) {
        for (int j = 0; j < dst.cols; j = j + 2) {
            if (i < dst.cols - 2) {
                dst.at<float>(i + 1, j) = (dst.at<float>(i, j) + dst.at<float>(i + 2, j)) / 2;
                if (j < dst.cols - 2) {
                    float a = dst.at<float>(i, j);
                    float b = dst.at<float>(i + 2, j);
                    float c = dst.at<float>(i, j + 2);
                    float d = dst.at<float>(i + 2, j + 2);
                    dst.at<float>(i + 1, j + 1) = (a + b + c + d) / 4;
                }
            }
            if (j < dst.cols - 2) {
                dst.at<float>(i, j + 1) = (dst.at<float>(i, j) + dst.at<float>(i, j + 2)) / 2;
            }

            if (i >= dst.cols - 2) {
                dst.at<float>(i + 1, j) = dst.at<float>(i, j);
                dst.at<float>(i + 1, j + 1) = dst.at<float>(i, j + 1);
            }

            if (j >= dst.cols - 2) {
                dst.at<float>(i, j + 1) = dst.at<float>(i, j);
                dst.at<float>(i + 1, j + 1) = dst.at<float>(i + 1, j);
            }
        }
    }
}

Mat img1 = prepare_img(true);
std::cout << "image = " << std::endl << format(img1, Formatter::FMT_PYTHON) << std::endl << std::endl;

Mat dbl1;
double_linear(img1, dbl1);
std::cout << "double image = " << std::endl << format(dbl1, Formatter::FMT_PYTHON) << std::endl << std::endl;

Mat img2 = prepare_img(false);
std::cout << "image = " << std::endl << format(img2, Formatter::FMT_PYTHON) << std::endl << std::endl;

Mat dbl2;
double_linear(img2, dbl2);
std::cout << "double image = " << std::endl << format(dbl2, Formatter::FMT_PYTHON) << std::endl << std::endl;

Output:

image = 
[[0, 0, 0, 0, 0],
 [1, 1, 1, 1, 1],
 [2, 2, 2, 2, 2],
 [3, 3, 3, 3, 3],
 [4, 4, 4, 4, 4]]

double image = 
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5],
 [2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
 [2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5],
 [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
 [3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5],
 [4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
 [4, 4, 4, 4, 4, 4, 4, 4, 4, 4]]

image = 
[[0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4]]

double image = 
[[0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4],
 [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4]]

Let’s put aside that double_linear is not a template function and it works only for 1 channel - ideally I want to do this as fast as possible using OpenCV infrastructure (e.g. even using private API from within my OpenCV clone. I was looking at and trying resize function (opencv/resize.cpp at 4.x · opencv/opencv · GitHub). It seemed to me that if I used INTER_AREA and changed the coefficients to something like [0.5, 0.5] here:
opencv/resize.cpp at 4.x · opencv/opencv · GitHub
and on line 4030

Is that the way to go? Can you give me advice on how to achieve that as generically and as fast as possible?

Thank you in advance

I will just ignore all that code you posted and recommend that you use warpAffine() with a suitable transformation matrix, and the WARP_INVERSE_MAP flag, so the matrix directly describes the calculation from destination coordinate to source coordinate.

afaik, INTER_AREA only works for resize(), not for any of the warps

if you need a lowpass, do the lowpass explicitly.

or use pyrDown()