use crate::color_space::ColorSpace;
use crate::pixel_format::PixelFormat;
use crate::static_assert;
#[doc(hidden)]
#[macro_export]
macro_rules! rgb_to_yuv_converter {
($src_pf:ident, $dst_pf:ident, $dst_cs:ident) => {
paste::paste! {
pub fn [<$src_pf:lower _ $dst_pf:lower _ $dst_cs:lower>](
width: u32,
height: u32,
last_src_plane: u32,
src_strides: &[usize],
src_buffers: &[&[u8]],
last_dst_plane: u32,
dst_strides: &[usize],
dst_buffers: &mut [&mut [u8]],
) -> bool {
[<rgb _ $dst_pf:lower>]::<{ Sampler::$src_pf as usize }, { sampler_to_depth(Sampler::$src_pf) }, { Colorimetry::$dst_cs as usize }>(
width,
height,
last_src_plane as usize,
src_strides,
src_buffers,
last_dst_plane as usize,
dst_strides,
dst_buffers,
)
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! yuv_to_rgb_converter {
($src_pf:ident, $src_cs:ident) => {
paste::paste! {
pub fn [<$src_pf:lower _ $src_cs:lower _bgra>] (
width: u32,
height: u32,
last_src_plane: u32,
src_strides: &[usize],
src_buffers: &[&[u8]],
last_dst_plane: u32,
dst_strides: &[usize],
dst_buffers: &mut [&mut [u8]],
) -> bool {
[<$src_pf:lower _bgra>]::<{ Colorimetry::$src_cs as usize }, { sampler_to_depth(Sampler::Bgra) }>(
width,
height,
last_src_plane as usize,
src_strides,
src_buffers,
last_dst_plane as usize,
dst_strides,
dst_buffers,
)
}
}
};
}
#[cfg(not(tarpaulin_include))]
const fn enum_count(lo: u32, hi: u32) -> u32 {
hi - lo + 1
}
#[cfg(not(tarpaulin_include))]
const fn upper_power_of_two(x: u32) -> u32 {
1 << (32 - (x - 1).leading_zeros())
}
const LO_RGB_PIXEL_FORMAT: u32 = PixelFormat::Argb as u32;
const HI_RGB_PIXEL_FORMAT: u32 = PixelFormat::Rgb as u32;
const LO_YUV_PIXEL_FORMAT: u32 = PixelFormat::I444 as u32;
const HI_YUV_PIXEL_FORMAT: u32 = PixelFormat::Nv12 as u32;
static_assert!(HI_RGB_PIXEL_FORMAT == LO_YUV_PIXEL_FORMAT - 1);
const LO_RGB_COLOR_SPACE: u32 = ColorSpace::Rgb as u32;
const HI_RGB_COLOR_SPACE: u32 = ColorSpace::Rgb as u32;
const LO_YUV_COLOR_SPACE: u32 = ColorSpace::Bt601 as u32;
const HI_YUV_COLOR_SPACE: u32 = ColorSpace::Bt709FR as u32;
static_assert!(HI_RGB_COLOR_SPACE == LO_YUV_COLOR_SPACE - 1);
const RGB_PIXEL_FORMAT_COUNT: u32 = enum_count(LO_RGB_PIXEL_FORMAT, HI_RGB_PIXEL_FORMAT);
const RGB_COLOR_SPACE_COUNT: u32 = enum_count(LO_RGB_COLOR_SPACE, HI_RGB_COLOR_SPACE);
const RGB_COUNT: u32 = RGB_PIXEL_FORMAT_COUNT * RGB_COLOR_SPACE_COUNT;
const YUV_PIXEL_FORMAT_COUNT: u32 = enum_count(LO_YUV_PIXEL_FORMAT, HI_YUV_PIXEL_FORMAT);
const YUV_COLOR_SPACE_COUNT: u32 = enum_count(LO_YUV_COLOR_SPACE, HI_YUV_COLOR_SPACE);
const ROWS: u32 = RGB_COUNT + (YUV_PIXEL_FORMAT_COUNT * YUV_COLOR_SPACE_COUNT);
const COLUMNS: u32 = upper_power_of_two(ROWS);
fn select_mode(a: u32, b: u32, cond: bool) -> u32 {
let c = u32::from(cond);
c * a + (1 - c) * b
}
pub const TABLE_SIZE: usize = (ROWS * COLUMNS) as usize;
pub fn get_pixel_format_mode(pixel_format: u32) -> bool {
pixel_format <= HI_RGB_PIXEL_FORMAT
}
pub fn get_color_space_mode(color_space: u32) -> bool {
static_assert!(HI_RGB_COLOR_SPACE == LO_RGB_COLOR_SPACE);
color_space == HI_RGB_COLOR_SPACE
}
pub fn get_image_index(pixel_format: u32, color_space: u32, pixel_format_mode: bool) -> u32 {
select_mode(
RGB_PIXEL_FORMAT_COUNT * (color_space - LO_RGB_COLOR_SPACE)
+ (pixel_format - LO_RGB_PIXEL_FORMAT),
RGB_COUNT
.wrapping_add(
YUV_PIXEL_FORMAT_COUNT.wrapping_mul(color_space.wrapping_sub(LO_YUV_COLOR_SPACE)),
)
.wrapping_add(pixel_format.wrapping_sub(LO_YUV_PIXEL_FORMAT)),
pixel_format_mode,
)
}
pub fn get_index(src_index: u32, dst_index: u32) -> usize {
(src_index * COLUMNS + dst_index) as usize
}
#[cfg(not(feature = "test_instruction_sets"))]
#[cfg(not(tarpaulin_include))]
#[inline(never)]
pub fn is_pixel_format_valid(pixel_format: u32) -> bool {
pixel_format.wrapping_sub(LO_RGB_PIXEL_FORMAT)
<= HI_YUV_PIXEL_FORMAT.wrapping_sub(LO_RGB_PIXEL_FORMAT)
}
#[cfg(not(feature = "test_instruction_sets"))]
#[cfg(not(tarpaulin_include))]
#[inline(never)]
pub fn is_color_space_valid(color_space: u32) -> bool {
color_space.wrapping_sub(LO_RGB_COLOR_SPACE)
<= HI_YUV_COLOR_SPACE.wrapping_sub(LO_RGB_COLOR_SPACE)
}