Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Tencent Ncnn Mat Pixel Resize

From Leeroopedia


Knowledge Sources
Domains Computer Vision, Image Processing
Last Updated 2026-02-09 19:00 GMT

Overview

Implements bilinear interpolation-based image resizing for raw pixel buffers, supporting 1-4 channel images with SIMD-optimized paths for ARM NEON and x86 SSE2 architectures.

Description

The implementation uses a two-pass approach for bilinear resize. Helper functions vresize_two and vresize_one perform vertical interpolation by blending two source rows using pre-computed weights in fixed-point 16-bit arithmetic.

The main resize_bilinear_c1/c2/c3/c4 functions (with both implicit and explicit stride overloads) compute horizontal and vertical interpolation coefficients, then process the image row by row: first performing horizontal resampling into intermediate short-precision row buffers, then vertically blending pairs of row buffers into the output. The implementation processes two output rows at a time when possible (via vresize_two) to improve cache efficiency, falling back to single-row processing for the last row if needed.

SIMD optimization is extensive: ARM NEON processes 8-16 pixels per iteration using vqdmulhq_s16/vsraq_n_s16 for fixed-point multiply-accumulate and vqrshrun_n_s16 for saturating narrowing; SSE2 uses _mm_mulhi_epi16/_mm_add_epi16 for equivalent operations. Scalar fallbacks handle remaining pixels using 16-bit fixed-point arithmetic.

A resize_bilinear_yuv420sp variant handles YUV420SP formatted data by resizing the Y plane and UV plane separately. The entire file is guarded by the NCNN_PIXEL compile-time flag.

Usage

Use these functions for the most common preprocessing operation in neural network inference pipelines: resizing input images to match model-expected dimensions. These are the backend functions called by Mat::from_pixels_resize() and Mat::to_pixels_resize().

Code Reference

Source Location

Signature

// Bilinear resize (implicit stride)
void resize_bilinear_c1(const unsigned char* src, int srcw, int srch,
    unsigned char* dst, int w, int h);
void resize_bilinear_c2(const unsigned char* src, int srcw, int srch,
    unsigned char* dst, int w, int h);
void resize_bilinear_c3(const unsigned char* src, int srcw, int srch,
    unsigned char* dst, int w, int h);
void resize_bilinear_c4(const unsigned char* src, int srcw, int srch,
    unsigned char* dst, int w, int h);

// Bilinear resize (explicit stride)
void resize_bilinear_c1(const unsigned char* src, int srcw, int srch, int srcstride,
    unsigned char* dst, int w, int h, int stride);
void resize_bilinear_c2(const unsigned char* src, int srcw, int srch, int srcstride,
    unsigned char* dst, int w, int h, int stride);
void resize_bilinear_c3(const unsigned char* src, int srcw, int srch, int srcstride,
    unsigned char* dst, int w, int h, int stride);
void resize_bilinear_c4(const unsigned char* src, int srcw, int srch, int srcstride,
    unsigned char* dst, int w, int h, int stride);

// YUV420SP variant
void resize_bilinear_yuv420sp(const unsigned char* src, int srcw, int srch,
    unsigned char* dst, int w, int h);

Import

#include "mat.h"

I/O Contract

Inputs

Name Type Required Description
src const unsigned char* Yes Source image pixel buffer
srcw int Yes Source image width in pixels
srch int Yes Source image height in pixels
srcstride int No Source row stride in bytes (defaults to srcw * channels)
dst unsigned char* Yes Destination image pixel buffer (pre-allocated)
w int Yes Destination (target) width in pixels
h int Yes Destination (target) height in pixels
stride int No Destination row stride in bytes (defaults to w * channels)

Outputs

Name Type Description
dst unsigned char* Destination buffer filled with the resized image

Usage Examples

Resizing a 3-Channel Image for Model Input

#include "mat.h"

// Resize a 640x480 RGB image to 224x224
unsigned char resized[224 * 224 * 3];
ncnn::resize_bilinear_c3(src_pixels, 640, 480, resized, 224, 224);

Resizing with Explicit Stride

#include "mat.h"

// Source has padding (stride != width * channels)
int src_stride = 1920; // e.g., 640 * 3 = 1920 or padded
int dst_stride = 672;  // e.g., 224 * 3 = 672 or padded
ncnn::resize_bilinear_c3(src_pixels, 640, 480, src_stride,
    dst_pixels, 224, 224, dst_stride);

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment