Implementation:Tencent Ncnn Mat Pixel Rotate
| Knowledge Sources | |
|---|---|
| Domains | Computer Vision, Image Processing |
| Last Updated | 2026-02-09 19:00 GMT |
Overview
Implements pixel-level image rotation operations for the ncnn Mat class, supporting 0/90/180/270 degree rotations and flips across 1-4 channel image formats and YUV420SP, heavily optimized with ARM NEON SIMD.
Description
This file provides a family of kanna_rotate_N_cC internal functions (where N is the rotation type 1-8 and C is the channel count) that perform pixel copying with appropriate coordinate transformations. Each rotation variant handles stride and gap calculations for source and destination buffers.
The 8 rotation types correspond to the 8 EXIF orientation values:
- Type 1: Identity copy (no rotation)
- Type 2: Horizontal flip
- Type 3: 180-degree rotation
- Type 4: Vertical flip
- Type 5: Transpose
- Type 6: 90-degree clockwise rotation
- Type 7: Transpose + horizontal flip
- Type 8: 270-degree clockwise rotation (90 counter-clockwise)
The functions are heavily optimized with ARM NEON SIMD intrinsics and inline assembly for 32-byte vectorized loads and stores, with scalar fallback paths. The public API (kanna_rotate_c1/c2/c3/c4) dispatches to the correct internal function based on rotation type and channel count parameters. A kanna_rotate_yuv420sp variant handles YUV420SP data by rotating the Y and UV planes separately.
The entire file is guarded by the NCNN_PIXEL_ROTATE compile-time flag. At 6106 lines, this is one of the largest source files in ncnn due to the combinatorial expansion of rotation types across channel counts with per-variant SIMD optimization.
Usage
Use these functions for image orientation correction before feeding data into models, particularly on mobile devices where camera images often need EXIF orientation adjustment. The rotation types directly map to EXIF orientation tags for convenient preprocessing.
Code Reference
Source Location
- Repository: Tencent_Ncnn
- File: src/mat_pixel_rotate.cpp
Signature
// Rotate (implicit stride)
void kanna_rotate_c1(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, int type);
void kanna_rotate_c2(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, int type);
void kanna_rotate_c3(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, int type);
void kanna_rotate_c4(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, int type);
// Rotate (explicit stride)
void kanna_rotate_c1(const unsigned char* src, int srcw, int srch, int srcstride,
unsigned char* dst, int w, int h, int stride, int type);
void kanna_rotate_c2(const unsigned char* src, int srcw, int srch, int srcstride,
unsigned char* dst, int w, int h, int stride, int type);
void kanna_rotate_c3(const unsigned char* src, int srcw, int srch, int srcstride,
unsigned char* dst, int w, int h, int stride, int type);
void kanna_rotate_c4(const unsigned char* src, int srcw, int srch, int srcstride,
unsigned char* dst, int w, int h, int stride, int type);
// YUV420SP variant
void kanna_rotate_yuv420sp(const unsigned char* src, int srcw, int srch,
unsigned char* dst, int w, int h, int type);
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 width (may differ from srcw for 90/270 rotations) |
| h | int | Yes | Destination height (may differ from srch for 90/270 rotations) |
| stride | int | No | Destination row stride in bytes (defaults to w * channels) |
| type | int | Yes | Rotation type 1-8 corresponding to EXIF orientation values |
Outputs
| Name | Type | Description |
|---|---|---|
| dst | unsigned char* | Destination buffer filled with the rotated image |
Usage Examples
Correcting Camera Image Orientation
#include "mat.h"
// Rotate a 3-channel image 90 degrees clockwise (EXIF type 6)
// For 90/270 rotation, dst dimensions are swapped
int dst_w = src_h;
int dst_h = src_w;
unsigned char* dst = new unsigned char[dst_w * dst_h * 3];
ncnn::kanna_rotate_c3(src_pixels, src_w, src_h, dst, dst_w, dst_h, 6);
Horizontal Flip
#include "mat.h"
// Horizontal flip (EXIF type 2), dimensions stay the same
unsigned char* flipped = new unsigned char[w * h * 3];
ncnn::kanna_rotate_c3(src_pixels, w, h, flipped, w, h, 2);