有时我们需要从一张NV12图片中裁取一小块图片,下面的算法可以实现此功能。此算法允许裁取的区域越过原图的右边界与底部边界,当越界时,超出部分将填充灰色(0x7F)。
BOOL nv12_copy_area(uint8_t* nv12, int in_w, int in_h, int in_x, int in_y,
uint8_t* out_nv12, int out_w, int out_h)
{
in_x = in_x & (~1);
in_y = in_y & (~1);
int size = out_w * out_h;
memset(out_nv12, 0x7f, size * 3 / 2);
int offset_in = in_y * in_w;
uint8_t* line = &nv12[offset_in + in_x];
uint8_t* line_out = out_nv12;
int cpy_h = in_h - in_y - 1;
if (cpy_h <= 1) {
return TRUE;
}
cpy_h = cpy_h < out_h ? cpy_h : out_h;
int cpy_w = in_w - in_x - 1;
if (cpy_w <= 1) {
return TRUE;
}
cpy_w = cpy_w < out_w ? cpy_w : out_w;
for (int j = 0; j < cpy_h; j++) {
memcpy(line_out, line, cpy_w);
line += in_w;
line_out += out_w;
}
line = &nv12[in_w * in_h + offset_in / 2 + in_x];
line_out = &out_nv12[size];
int cpy_uv_h = cpy_h / 2;
for (int j = 0; j < cpy_uv_h; j++) {
memcpy(line_out, line, cpy_w);
line += in_w;
line_out += out_w;
}
return TRUE;
}