Overview
ImageResizer C++ library provides image resizing with SIMD-optimized bicubic interpolation (Keys cubic, a = -0.75). The library implements a two-pass separable filter with platform-specific vectorization: SSSE3 + AVX2 on x86/x64, NEON on ARM64, and a scalar fallback for other architectures. Tile-based processing ensures L2 cache locality for upscale paths, while a row-cache strategy is used for downscale. The library supports multi-threaded row-level parallelism via OpenMP with automatic or user-defined thread count. Input data must be 3-byte-per-pixel interleaved format (BGR24, RGB24 and YUV24). The library uses C++17 standard.
Documentation
Documentation: GO TO DOCUMENATION
Simple interface
namespace cr
{
namespace video
{
/// Image resizer class.
class ImageResizer
{
public:
/// Get the version of the ImageResizer class.
static std::string getVersion();
/// Resize image.
bool resize(uint8_t* src, int srcWidth, int srcHeight,
uint8_t* dst, int dstWidth, int dstHeight,
int numThreads = 0);
};
}
}
Simple example
#include <iostream>
#include <cstdint>
#include <vector>
#include <chrono>
#include "ImageResizer.h"
using namespace std;
using namespace cr::video;
using namespace std::chrono;
int main(void)
{
cout << "ImageResizer v" << ImageResizer::getVersion() << endl;
// Source image size.
const int srcWidth = 640;
const int srcHeight = 512;
// Destination image size.
const int dstWidth = 1920;
const int dstHeight = 1080;
// Create source image with deterministic pattern.
vector<uint8_t> srcImg(srcWidth * srcHeight * 3);
for (int y = 0; y < srcHeight; ++y)
for (int x = 0; x < srcWidth; ++x) {
int idx = (y * srcWidth + x) * 3;
srcImg[idx + 0] = (uint8_t)((x * 37 + y * 13) & 0xFF);
srcImg[idx + 1] = (uint8_t)((x * 59 + y * 7) & 0xFF);
srcImg[idx + 2] = (uint8_t)((x * 23 + y * 41) & 0xFF);
}
// Create destination image buffer.
vector<uint8_t> dstImg(dstWidth * dstHeight * 3);
// Image resizer.
ImageResizer imageResizer;
// Resize image.
auto begin = steady_clock::now();
bool result = imageResizer.resize(srcImg.data(), srcWidth, srcHeight,
dstImg.data(), dstWidth, dstHeight, 0);
auto end = steady_clock::now();
cout << "Result: " << (result ? "OK" : "FAIL") << endl;
cout << "Resize time: " <<
duration_cast<microseconds>(end - begin).count() << " us" << endl;
return 0;
}

