#![allow(clippy::too_many_arguments)]
use std::ffi::c_int;
use crate::{
Android420Image, ArgbImage, ArgbImageMut, Error, I010Image, I010ImageMut, I210Image,
I210ImageMut, I410Image, I410ImageMut, I420Image, I420ImageMut, I422Image, I422ImageMut,
I444Image, I444ImageMut, ImageSize, Nv12Image, RotationMode, checked_buf_size, require_c_int,
sys,
};
pub fn i420_rotate(
src: &I420Image<'_>,
src_size: ImageSize,
dst: &mut I420ImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "I420Rotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"I420Rotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "I420Rotate")?;
let result = unsafe {
sys::I420Rotate(
src.y.as_ptr(),
src.y_stride as c_int,
src.u.as_ptr(),
src.u_stride as c_int,
src.v.as_ptr(),
src.v_stride as c_int,
dst.y.as_mut_ptr(),
dst.y_stride as c_int,
dst.u.as_mut_ptr(),
dst.u_stride as c_int,
dst.v.as_mut_ptr(),
dst.v_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "I420Rotate")
}
pub fn argb_rotate(
src: &ArgbImage<'_>,
src_size: ImageSize,
dst: &mut ArgbImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "ARGBRotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"ARGBRotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "ARGBRotate")?;
let result = unsafe {
sys::ARGBRotate(
src.data.as_ptr(),
src.stride as c_int,
dst.data.as_mut_ptr(),
dst.stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "ARGBRotate")
}
pub fn rotate_plane(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst: &mut [u8],
dst_stride: usize,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"RotatePlane",
"dst_size does not match rotated dimensions",
));
}
require_c_int(src_size.width, "RotatePlane", "width exceeds c_int range")?;
require_c_int(src_size.height, "RotatePlane", "height exceeds c_int range")?;
require_c_int(
src_stride,
"RotatePlane",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride,
"RotatePlane",
"destination stride exceeds c_int range",
)?;
if src_stride < src_size.width {
return Err(Error::with_reason(
-1,
"RotatePlane",
"source stride smaller than width",
));
}
if dst_stride < dst_size.width {
return Err(Error::with_reason(
-1,
"RotatePlane",
"destination stride smaller than width",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"RotatePlane",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"RotatePlane",
"source buffer too small",
));
}
let dst_buf = checked_buf_size(
dst_stride,
dst_size.height,
"RotatePlane",
"destination buffer size overflow",
)?;
if dst.len() < dst_buf {
return Err(Error::with_reason(
-1,
"RotatePlane",
"destination buffer too small",
));
}
let result = unsafe {
sys::RotatePlane(
src.as_ptr(),
src_stride as c_int,
dst.as_mut_ptr(),
dst_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "RotatePlane")
}
pub fn i010_rotate(
src: &I010Image<'_>,
src_size: ImageSize,
dst: &mut I010ImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "I010Rotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"I010Rotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "I010Rotate")?;
let result = unsafe {
sys::I010Rotate(
src.y.as_ptr(),
src.y_stride as c_int,
src.u.as_ptr(),
src.u_stride as c_int,
src.v.as_ptr(),
src.v_stride as c_int,
dst.y.as_mut_ptr(),
dst.y_stride as c_int,
dst.u.as_mut_ptr(),
dst.u_stride as c_int,
dst.v.as_mut_ptr(),
dst.v_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "I010Rotate")
}
pub fn i210_rotate(
src: &I210Image<'_>,
src_size: ImageSize,
dst: &mut I210ImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "I210Rotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"I210Rotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "I210Rotate")?;
let result = unsafe {
sys::I210Rotate(
src.y.as_ptr(),
src.y_stride as c_int,
src.u.as_ptr(),
src.u_stride as c_int,
src.v.as_ptr(),
src.v_stride as c_int,
dst.y.as_mut_ptr(),
dst.y_stride as c_int,
dst.u.as_mut_ptr(),
dst.u_stride as c_int,
dst.v.as_mut_ptr(),
dst.v_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "I210Rotate")
}
pub fn i410_rotate(
src: &I410Image<'_>,
src_size: ImageSize,
dst: &mut I410ImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "I410Rotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"I410Rotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "I410Rotate")?;
let result = unsafe {
sys::I410Rotate(
src.y.as_ptr(),
src.y_stride as c_int,
src.u.as_ptr(),
src.u_stride as c_int,
src.v.as_ptr(),
src.v_stride as c_int,
dst.y.as_mut_ptr(),
dst.y_stride as c_int,
dst.u.as_mut_ptr(),
dst.u_stride as c_int,
dst.v.as_mut_ptr(),
dst.v_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "I410Rotate")
}
pub fn android420_to_i420_rotate(
src: &Android420Image<'_>,
src_size: ImageSize,
pixel_stride_uv: usize,
dst: &mut I420ImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "Android420ToI420Rotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"Android420ToI420Rotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "Android420ToI420Rotate")?;
if pixel_stride_uv != 1 && pixel_stride_uv != 2 {
return Err(Error::with_reason(
-1,
"Android420ToI420Rotate",
"pixel_stride_uv must be 1 or 2",
));
}
let result = unsafe {
sys::Android420ToI420Rotate(
src.y.as_ptr(),
src.y_stride as c_int,
src.u.as_ptr(),
src.u_stride as c_int,
src.v.as_ptr(),
src.v_stride as c_int,
pixel_stride_uv as c_int,
dst.y.as_mut_ptr(),
dst.y_stride as c_int,
dst.u.as_mut_ptr(),
dst.u_stride as c_int,
dst.v.as_mut_ptr(),
dst.v_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "Android420ToI420Rotate")
}
pub fn nv12_to_i420_rotate(
src: &Nv12Image<'_>,
src_size: ImageSize,
dst: &mut I420ImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "NV12ToI420Rotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"NV12ToI420Rotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "NV12ToI420Rotate")?;
let result = unsafe {
sys::NV12ToI420Rotate(
src.y.as_ptr(),
src.y_stride as c_int,
src.uv.as_ptr(),
src.uv_stride as c_int,
dst.y.as_mut_ptr(),
dst.y_stride as c_int,
dst.u.as_mut_ptr(),
dst.u_stride as c_int,
dst.v.as_mut_ptr(),
dst.v_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "NV12ToI420Rotate")
}
pub fn i422_rotate(
src: &I422Image<'_>,
src_size: ImageSize,
dst: &mut I422ImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "I422Rotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"I422Rotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "I422Rotate")?;
let result = unsafe {
sys::I422Rotate(
src.y.as_ptr(),
src.y_stride as c_int,
src.u.as_ptr(),
src.u_stride as c_int,
src.v.as_ptr(),
src.v_stride as c_int,
dst.y.as_mut_ptr(),
dst.y_stride as c_int,
dst.u.as_mut_ptr(),
dst.u_stride as c_int,
dst.v.as_mut_ptr(),
dst.v_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "I422Rotate")
}
pub fn i444_rotate(
src: &I444Image<'_>,
src_size: ImageSize,
dst: &mut I444ImageMut<'_>,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
src.validate(src_size, "I444Rotate")?;
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"I444Rotate",
"dst_size does not match rotated dimensions",
));
}
dst.validate(dst_size, "I444Rotate")?;
let result = unsafe {
sys::I444Rotate(
src.y.as_ptr(),
src.y_stride as c_int,
src.u.as_ptr(),
src.u_stride as c_int,
src.v.as_ptr(),
src.v_stride as c_int,
dst.y.as_mut_ptr(),
dst.y_stride as c_int,
dst.u.as_mut_ptr(),
dst.u_stride as c_int,
dst.v.as_mut_ptr(),
dst.v_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "I444Rotate")
}
pub fn rotate_plane_16(
src: &[u16],
src_stride: usize,
src_size: ImageSize,
dst: &mut [u16],
dst_stride: usize,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"RotatePlane_16",
"dst_size does not match rotated dimensions",
));
}
require_c_int(
src_size.width,
"RotatePlane_16",
"width exceeds c_int range",
)?;
require_c_int(
src_size.height,
"RotatePlane_16",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"RotatePlane_16",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride,
"RotatePlane_16",
"destination stride exceeds c_int range",
)?;
if src_stride < src_size.width {
return Err(Error::with_reason(
-1,
"RotatePlane_16",
"source stride smaller than width",
));
}
if dst_stride < dst_size.width {
return Err(Error::with_reason(
-1,
"RotatePlane_16",
"destination stride smaller than width",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"RotatePlane_16",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"RotatePlane_16",
"source buffer too small",
));
}
let dst_buf = checked_buf_size(
dst_stride,
dst_size.height,
"RotatePlane_16",
"destination buffer size overflow",
)?;
if dst.len() < dst_buf {
return Err(Error::with_reason(
-1,
"RotatePlane_16",
"destination buffer too small",
));
}
let result = unsafe {
sys::RotatePlane_16(
src.as_ptr(),
src_stride as c_int,
dst.as_mut_ptr(),
dst_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "RotatePlane_16")
}
pub fn rotate_plane_90(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst: &mut [u8],
dst_stride: usize,
) -> Result<(), Error> {
require_c_int(src_size.width, "RotatePlane90", "width exceeds c_int range")?;
require_c_int(
src_size.height,
"RotatePlane90",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"RotatePlane90",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride,
"RotatePlane90",
"destination stride exceeds c_int range",
)?;
if src_stride < src_size.width {
return Err(Error::with_reason(
-1,
"RotatePlane90",
"source stride smaller than width",
));
}
if dst_stride < src_size.height {
return Err(Error::with_reason(
-1,
"RotatePlane90",
"destination stride smaller than height",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"RotatePlane90",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"RotatePlane90",
"source buffer too small",
));
}
let dst_buf = checked_buf_size(
dst_stride,
src_size.width,
"RotatePlane90",
"destination buffer size overflow",
)?;
if dst.len() < dst_buf {
return Err(Error::with_reason(
-1,
"RotatePlane90",
"destination buffer too small",
));
}
unsafe {
sys::RotatePlane90(
src.as_ptr(),
src_stride as c_int,
dst.as_mut_ptr(),
dst_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
);
}
Ok(())
}
pub fn rotate_plane_180(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst: &mut [u8],
dst_stride: usize,
) -> Result<(), Error> {
require_c_int(
src_size.width,
"RotatePlane180",
"width exceeds c_int range",
)?;
require_c_int(
src_size.height,
"RotatePlane180",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"RotatePlane180",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride,
"RotatePlane180",
"destination stride exceeds c_int range",
)?;
if src_stride < src_size.width {
return Err(Error::with_reason(
-1,
"RotatePlane180",
"source stride smaller than width",
));
}
if dst_stride < src_size.width {
return Err(Error::with_reason(
-1,
"RotatePlane180",
"destination stride smaller than width",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"RotatePlane180",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"RotatePlane180",
"source buffer too small",
));
}
let dst_buf = checked_buf_size(
dst_stride,
src_size.height,
"RotatePlane180",
"destination buffer size overflow",
)?;
if dst.len() < dst_buf {
return Err(Error::with_reason(
-1,
"RotatePlane180",
"destination buffer too small",
));
}
unsafe {
sys::RotatePlane180(
src.as_ptr(),
src_stride as c_int,
dst.as_mut_ptr(),
dst_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
);
}
Ok(())
}
pub fn rotate_plane_270(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst: &mut [u8],
dst_stride: usize,
) -> Result<(), Error> {
require_c_int(
src_size.width,
"RotatePlane270",
"width exceeds c_int range",
)?;
require_c_int(
src_size.height,
"RotatePlane270",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"RotatePlane270",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride,
"RotatePlane270",
"destination stride exceeds c_int range",
)?;
if src_stride < src_size.width {
return Err(Error::with_reason(
-1,
"RotatePlane270",
"source stride smaller than width",
));
}
if dst_stride < src_size.height {
return Err(Error::with_reason(
-1,
"RotatePlane270",
"destination stride smaller than height",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"RotatePlane270",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"RotatePlane270",
"source buffer too small",
));
}
let dst_buf = checked_buf_size(
dst_stride,
src_size.width,
"RotatePlane270",
"destination buffer size overflow",
)?;
if dst.len() < dst_buf {
return Err(Error::with_reason(
-1,
"RotatePlane270",
"destination buffer too small",
));
}
unsafe {
sys::RotatePlane270(
src.as_ptr(),
src_stride as c_int,
dst.as_mut_ptr(),
dst_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
);
}
Ok(())
}
pub fn split_rotate_uv(
src_uv: &[u8],
src_stride_uv: usize,
src_size: ImageSize,
dst_u: &mut [u8],
dst_stride_u: usize,
dst_v: &mut [u8],
dst_stride_v: usize,
dst_size: ImageSize,
mode: RotationMode,
) -> Result<(), Error> {
let expected = mode.output_size(src_size);
if dst_size.width != expected.width || dst_size.height != expected.height {
return Err(Error::with_reason(
-1,
"SplitRotateUV",
"dst_size does not match rotated dimensions",
));
}
require_c_int(src_size.width, "SplitRotateUV", "width exceeds c_int range")?;
require_c_int(
src_size.height,
"SplitRotateUV",
"height exceeds c_int range",
)?;
require_c_int(
src_stride_uv,
"SplitRotateUV",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride_u,
"SplitRotateUV",
"destination U stride exceeds c_int range",
)?;
require_c_int(
dst_stride_v,
"SplitRotateUV",
"destination V stride exceeds c_int range",
)?;
let src_min_width = src_size
.width
.checked_mul(2)
.ok_or_else(|| Error::with_reason(-1, "SplitRotateUV", "width * 2 overflow"))?;
if src_stride_uv < src_min_width {
return Err(Error::with_reason(
-1,
"SplitRotateUV",
"source stride smaller than width * 2",
));
}
if dst_stride_u < dst_size.width {
return Err(Error::with_reason(
-1,
"SplitRotateUV",
"destination U stride smaller than width",
));
}
if dst_stride_v < dst_size.width {
return Err(Error::with_reason(
-1,
"SplitRotateUV",
"destination V stride smaller than width",
));
}
let src_buf = checked_buf_size(
src_stride_uv,
src_size.height,
"SplitRotateUV",
"source buffer size overflow",
)?;
if src_uv.len() < src_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV",
"source buffer too small",
));
}
let dst_u_buf = checked_buf_size(
dst_stride_u,
dst_size.height,
"SplitRotateUV",
"destination U buffer size overflow",
)?;
if dst_u.len() < dst_u_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV",
"destination U buffer too small",
));
}
let dst_v_buf = checked_buf_size(
dst_stride_v,
dst_size.height,
"SplitRotateUV",
"destination V buffer size overflow",
)?;
if dst_v.len() < dst_v_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV",
"destination V buffer too small",
));
}
let result = unsafe {
sys::SplitRotateUV(
src_uv.as_ptr(),
src_stride_uv as c_int,
dst_u.as_mut_ptr(),
dst_stride_u as c_int,
dst_v.as_mut_ptr(),
dst_stride_v as c_int,
src_size.width as c_int,
src_size.height as c_int,
mode.to_sys(),
)
};
Error::check(result, "SplitRotateUV")
}
pub fn split_rotate_uv_90(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst_a: &mut [u8],
dst_stride_a: usize,
dst_b: &mut [u8],
dst_stride_b: usize,
) -> Result<(), Error> {
require_c_int(
src_size.width,
"SplitRotateUV90",
"width exceeds c_int range",
)?;
require_c_int(
src_size.height,
"SplitRotateUV90",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"SplitRotateUV90",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride_a,
"SplitRotateUV90",
"destination A stride exceeds c_int range",
)?;
require_c_int(
dst_stride_b,
"SplitRotateUV90",
"destination B stride exceeds c_int range",
)?;
let src_min_width = src_size
.width
.checked_mul(2)
.ok_or_else(|| Error::with_reason(-1, "SplitRotateUV90", "width * 2 overflow"))?;
if src_stride < src_min_width {
return Err(Error::with_reason(
-1,
"SplitRotateUV90",
"source stride smaller than width * 2",
));
}
if dst_stride_a < src_size.height {
return Err(Error::with_reason(
-1,
"SplitRotateUV90",
"destination A stride smaller than height",
));
}
if dst_stride_b < src_size.height {
return Err(Error::with_reason(
-1,
"SplitRotateUV90",
"destination B stride smaller than height",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"SplitRotateUV90",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV90",
"source buffer too small",
));
}
let dst_a_buf = checked_buf_size(
dst_stride_a,
src_size.width,
"SplitRotateUV90",
"destination A buffer size overflow",
)?;
if dst_a.len() < dst_a_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV90",
"destination A buffer too small",
));
}
let dst_b_buf = checked_buf_size(
dst_stride_b,
src_size.width,
"SplitRotateUV90",
"destination B buffer size overflow",
)?;
if dst_b.len() < dst_b_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV90",
"destination B buffer too small",
));
}
unsafe {
sys::SplitRotateUV90(
src.as_ptr(),
src_stride as c_int,
dst_a.as_mut_ptr(),
dst_stride_a as c_int,
dst_b.as_mut_ptr(),
dst_stride_b as c_int,
src_size.width as c_int,
src_size.height as c_int,
);
}
Ok(())
}
pub fn split_rotate_uv_180(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst_a: &mut [u8],
dst_stride_a: usize,
dst_b: &mut [u8],
dst_stride_b: usize,
) -> Result<(), Error> {
require_c_int(
src_size.width,
"SplitRotateUV180",
"width exceeds c_int range",
)?;
require_c_int(
src_size.height,
"SplitRotateUV180",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"SplitRotateUV180",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride_a,
"SplitRotateUV180",
"destination A stride exceeds c_int range",
)?;
require_c_int(
dst_stride_b,
"SplitRotateUV180",
"destination B stride exceeds c_int range",
)?;
let src_min_width = src_size
.width
.checked_mul(2)
.ok_or_else(|| Error::with_reason(-1, "SplitRotateUV180", "width * 2 overflow"))?;
if src_stride < src_min_width {
return Err(Error::with_reason(
-1,
"SplitRotateUV180",
"source stride smaller than width * 2",
));
}
if dst_stride_a < src_size.width {
return Err(Error::with_reason(
-1,
"SplitRotateUV180",
"destination A stride smaller than width",
));
}
if dst_stride_b < src_size.width {
return Err(Error::with_reason(
-1,
"SplitRotateUV180",
"destination B stride smaller than width",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"SplitRotateUV180",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV180",
"source buffer too small",
));
}
let dst_a_buf = checked_buf_size(
dst_stride_a,
src_size.height,
"SplitRotateUV180",
"destination A buffer size overflow",
)?;
if dst_a.len() < dst_a_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV180",
"destination A buffer too small",
));
}
let dst_b_buf = checked_buf_size(
dst_stride_b,
src_size.height,
"SplitRotateUV180",
"destination B buffer size overflow",
)?;
if dst_b.len() < dst_b_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV180",
"destination B buffer too small",
));
}
unsafe {
sys::SplitRotateUV180(
src.as_ptr(),
src_stride as c_int,
dst_a.as_mut_ptr(),
dst_stride_a as c_int,
dst_b.as_mut_ptr(),
dst_stride_b as c_int,
src_size.width as c_int,
src_size.height as c_int,
);
}
Ok(())
}
pub fn split_rotate_uv_270(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst_a: &mut [u8],
dst_stride_a: usize,
dst_b: &mut [u8],
dst_stride_b: usize,
) -> Result<(), Error> {
require_c_int(
src_size.width,
"SplitRotateUV270",
"width exceeds c_int range",
)?;
require_c_int(
src_size.height,
"SplitRotateUV270",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"SplitRotateUV270",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride_a,
"SplitRotateUV270",
"destination A stride exceeds c_int range",
)?;
require_c_int(
dst_stride_b,
"SplitRotateUV270",
"destination B stride exceeds c_int range",
)?;
let src_min_width = src_size
.width
.checked_mul(2)
.ok_or_else(|| Error::with_reason(-1, "SplitRotateUV270", "width * 2 overflow"))?;
if src_stride < src_min_width {
return Err(Error::with_reason(
-1,
"SplitRotateUV270",
"source stride smaller than width * 2",
));
}
if dst_stride_a < src_size.height {
return Err(Error::with_reason(
-1,
"SplitRotateUV270",
"destination A stride smaller than height",
));
}
if dst_stride_b < src_size.height {
return Err(Error::with_reason(
-1,
"SplitRotateUV270",
"destination B stride smaller than height",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"SplitRotateUV270",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV270",
"source buffer too small",
));
}
let dst_a_buf = checked_buf_size(
dst_stride_a,
src_size.width,
"SplitRotateUV270",
"destination A buffer size overflow",
)?;
if dst_a.len() < dst_a_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV270",
"destination A buffer too small",
));
}
let dst_b_buf = checked_buf_size(
dst_stride_b,
src_size.width,
"SplitRotateUV270",
"destination B buffer size overflow",
)?;
if dst_b.len() < dst_b_buf {
return Err(Error::with_reason(
-1,
"SplitRotateUV270",
"destination B buffer too small",
));
}
unsafe {
sys::SplitRotateUV270(
src.as_ptr(),
src_stride as c_int,
dst_a.as_mut_ptr(),
dst_stride_a as c_int,
dst_b.as_mut_ptr(),
dst_stride_b as c_int,
src_size.width as c_int,
src_size.height as c_int,
);
}
Ok(())
}
pub fn split_transpose_uv(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst_a: &mut [u8],
dst_stride_a: usize,
dst_b: &mut [u8],
dst_stride_b: usize,
) -> Result<(), Error> {
require_c_int(
src_size.width,
"SplitTransposeUV",
"width exceeds c_int range",
)?;
require_c_int(
src_size.height,
"SplitTransposeUV",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"SplitTransposeUV",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride_a,
"SplitTransposeUV",
"destination A stride exceeds c_int range",
)?;
require_c_int(
dst_stride_b,
"SplitTransposeUV",
"destination B stride exceeds c_int range",
)?;
let src_min_width = src_size
.width
.checked_mul(2)
.ok_or_else(|| Error::with_reason(-1, "SplitTransposeUV", "width * 2 overflow"))?;
if src_stride < src_min_width {
return Err(Error::with_reason(
-1,
"SplitTransposeUV",
"source stride smaller than width * 2",
));
}
if dst_stride_a < src_size.height {
return Err(Error::with_reason(
-1,
"SplitTransposeUV",
"destination A stride smaller than height",
));
}
if dst_stride_b < src_size.height {
return Err(Error::with_reason(
-1,
"SplitTransposeUV",
"destination B stride smaller than height",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"SplitTransposeUV",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"SplitTransposeUV",
"source buffer too small",
));
}
let dst_a_buf = checked_buf_size(
dst_stride_a,
src_size.width,
"SplitTransposeUV",
"destination A buffer size overflow",
)?;
if dst_a.len() < dst_a_buf {
return Err(Error::with_reason(
-1,
"SplitTransposeUV",
"destination A buffer too small",
));
}
let dst_b_buf = checked_buf_size(
dst_stride_b,
src_size.width,
"SplitTransposeUV",
"destination B buffer size overflow",
)?;
if dst_b.len() < dst_b_buf {
return Err(Error::with_reason(
-1,
"SplitTransposeUV",
"destination B buffer too small",
));
}
unsafe {
sys::SplitTransposeUV(
src.as_ptr(),
src_stride as c_int,
dst_a.as_mut_ptr(),
dst_stride_a as c_int,
dst_b.as_mut_ptr(),
dst_stride_b as c_int,
src_size.width as c_int,
src_size.height as c_int,
);
}
Ok(())
}
pub fn transpose_plane(
src: &[u8],
src_stride: usize,
src_size: ImageSize,
dst: &mut [u8],
dst_stride: usize,
) -> Result<(), Error> {
require_c_int(
src_size.width,
"TransposePlane",
"width exceeds c_int range",
)?;
require_c_int(
src_size.height,
"TransposePlane",
"height exceeds c_int range",
)?;
require_c_int(
src_stride,
"TransposePlane",
"source stride exceeds c_int range",
)?;
require_c_int(
dst_stride,
"TransposePlane",
"destination stride exceeds c_int range",
)?;
if src_stride < src_size.width {
return Err(Error::with_reason(
-1,
"TransposePlane",
"source stride smaller than width",
));
}
if dst_stride < src_size.height {
return Err(Error::with_reason(
-1,
"TransposePlane",
"destination stride smaller than height",
));
}
let src_buf = checked_buf_size(
src_stride,
src_size.height,
"TransposePlane",
"source buffer size overflow",
)?;
if src.len() < src_buf {
return Err(Error::with_reason(
-1,
"TransposePlane",
"source buffer too small",
));
}
let dst_buf = checked_buf_size(
dst_stride,
src_size.width,
"TransposePlane",
"destination buffer size overflow",
)?;
if dst.len() < dst_buf {
return Err(Error::with_reason(
-1,
"TransposePlane",
"destination buffer too small",
));
}
unsafe {
sys::TransposePlane(
src.as_ptr(),
src_stride as c_int,
dst.as_mut_ptr(),
dst_stride as c_int,
src_size.width as c_int,
src_size.height as c_int,
);
}
Ok(())
}