#[cfg(any(
target_arch = "aarch64",
target_arch = "x86_64",
target_arch = "wasm32"
))]
use crate::row::arch;
#[cfg(target_arch = "aarch64")]
use crate::row::neon_available;
#[cfg(target_arch = "wasm32")]
use crate::row::simd128_available;
#[cfg(target_arch = "x86_64")]
use crate::row::{avx2_available, avx512_available, sse41_available};
use crate::{
ColorMatrix,
row::{rgb_row_bytes, rgb_row_elems, rgba_row_bytes, rgba_row_elems, scalar, uv_full_row_elems},
};
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub(crate) fn p_n_444_to_rgb_row<const BITS: u32, const BE: bool>(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
let rgb_min = rgb_row_bytes(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgb_out.len() >= rgb_min, "rgb_out row too short");
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
unsafe {
arch::neon::p_n_444_to_rgb_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
unsafe {
arch::x86_avx512::p_n_444_to_rgb_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
if avx2_available() {
unsafe {
arch::x86_avx2::p_n_444_to_rgb_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
if sse41_available() {
unsafe {
arch::x86_sse41::p_n_444_to_rgb_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
unsafe {
arch::wasm_simd128::p_n_444_to_rgb_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
},
_ => {}
}
}
scalar::p_n_444_to_rgb_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub(crate) fn p_n_444_to_rgb_u16_row<const BITS: u32, const BE: bool>(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
let rgb_min = rgb_row_elems(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgb_out.len() >= rgb_min, "rgb_out row too short");
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
unsafe {
arch::neon::p_n_444_to_rgb_u16_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
unsafe {
arch::x86_avx512::p_n_444_to_rgb_u16_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
if avx2_available() {
unsafe {
arch::x86_avx2::p_n_444_to_rgb_u16_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
if sse41_available() {
unsafe {
arch::x86_sse41::p_n_444_to_rgb_u16_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
unsafe {
arch::wasm_simd128::p_n_444_to_rgb_u16_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
return;
}
},
_ => {}
}
}
scalar::p_n_444_to_rgb_u16_row::<BITS, BE>(y, uv_full, rgb_out, width, matrix, full_range);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p416_to_rgb_row_endian(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
let rgb_min = rgb_row_bytes(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgb_out.len() >= rgb_min, "rgb_out row too short");
macro_rules! dispatch_be {
($call_le:expr, $call_be:expr) => {
if big_endian { $call_be } else { $call_le }
};
}
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
dispatch_be!(
unsafe { arch::neon::p_n_444_16_to_rgb_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::neon::p_n_444_16_to_rgb_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
dispatch_be!(
unsafe { arch::x86_avx512::p_n_444_16_to_rgb_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::x86_avx512::p_n_444_16_to_rgb_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
if avx2_available() {
dispatch_be!(
unsafe { arch::x86_avx2::p_n_444_16_to_rgb_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::x86_avx2::p_n_444_16_to_rgb_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
if sse41_available() {
dispatch_be!(
unsafe { arch::x86_sse41::p_n_444_16_to_rgb_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::x86_sse41::p_n_444_16_to_rgb_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
dispatch_be!(
unsafe { arch::wasm_simd128::p_n_444_16_to_rgb_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::wasm_simd128::p_n_444_16_to_rgb_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
},
_ => {}
}
}
dispatch_be!(
scalar::p_n_444_16_to_rgb_row::<false>(y, uv_full, rgb_out, width, matrix, full_range),
scalar::p_n_444_16_to_rgb_row::<true>(y, uv_full, rgb_out, width, matrix, full_range)
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p416_to_rgb_row(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p416_to_rgb_row_endian(
y, uv_full, rgb_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p416_to_rgb_u16_row_endian(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
let rgb_min = rgb_row_elems(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgb_out.len() >= rgb_min, "rgb_out row too short");
macro_rules! dispatch_be {
($call_le:expr, $call_be:expr) => {
if big_endian { $call_be } else { $call_le }
};
}
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
dispatch_be!(
unsafe { arch::neon::p_n_444_16_to_rgb_u16_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::neon::p_n_444_16_to_rgb_u16_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
dispatch_be!(
unsafe { arch::x86_avx512::p_n_444_16_to_rgb_u16_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::x86_avx512::p_n_444_16_to_rgb_u16_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
if avx2_available() {
dispatch_be!(
unsafe { arch::x86_avx2::p_n_444_16_to_rgb_u16_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::x86_avx2::p_n_444_16_to_rgb_u16_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
if sse41_available() {
dispatch_be!(
unsafe { arch::x86_sse41::p_n_444_16_to_rgb_u16_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::x86_sse41::p_n_444_16_to_rgb_u16_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
dispatch_be!(
unsafe { arch::wasm_simd128::p_n_444_16_to_rgb_u16_row::<false>(y, uv_full, rgb_out, width, matrix, full_range); },
unsafe { arch::wasm_simd128::p_n_444_16_to_rgb_u16_row::<true>(y, uv_full, rgb_out, width, matrix, full_range); }
);
return;
}
},
_ => {}
}
}
dispatch_be!(
scalar::p_n_444_16_to_rgb_u16_row::<false>(y, uv_full, rgb_out, width, matrix, full_range),
scalar::p_n_444_16_to_rgb_u16_row::<true>(y, uv_full, rgb_out, width, matrix, full_range)
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p416_to_rgb_u16_row(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p416_to_rgb_u16_row_endian(
y, uv_full, rgb_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p410_to_rgb_row_endian(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
if big_endian {
p_n_444_to_rgb_row::<10, true>(y, uv_full, rgb_out, width, matrix, full_range, use_simd);
} else {
p_n_444_to_rgb_row::<10, false>(y, uv_full, rgb_out, width, matrix, full_range, use_simd);
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p410_to_rgb_row(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p410_to_rgb_row_endian(
y, uv_full, rgb_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p410_to_rgb_u16_row_endian(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
if big_endian {
p_n_444_to_rgb_u16_row::<10, true>(y, uv_full, rgb_out, width, matrix, full_range, use_simd);
} else {
p_n_444_to_rgb_u16_row::<10, false>(y, uv_full, rgb_out, width, matrix, full_range, use_simd);
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p410_to_rgb_u16_row(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p410_to_rgb_u16_row_endian(
y, uv_full, rgb_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p412_to_rgb_row_endian(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
if big_endian {
p_n_444_to_rgb_row::<12, true>(y, uv_full, rgb_out, width, matrix, full_range, use_simd);
} else {
p_n_444_to_rgb_row::<12, false>(y, uv_full, rgb_out, width, matrix, full_range, use_simd);
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p412_to_rgb_row(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p412_to_rgb_row_endian(
y, uv_full, rgb_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p412_to_rgb_u16_row_endian(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
if big_endian {
p_n_444_to_rgb_u16_row::<12, true>(y, uv_full, rgb_out, width, matrix, full_range, use_simd);
} else {
p_n_444_to_rgb_u16_row::<12, false>(y, uv_full, rgb_out, width, matrix, full_range, use_simd);
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p412_to_rgb_u16_row(
y: &[u16],
uv_full: &[u16],
rgb_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p412_to_rgb_u16_row_endian(
y, uv_full, rgb_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p410_to_rgba_row_endian(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
let rgba_min = rgba_row_bytes(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgba_out.len() >= rgba_min, "rgba_out row too short");
macro_rules! dispatch_be {
($call_le:expr, $call_be:expr) => {
if big_endian { $call_be } else { $call_le }
};
}
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
dispatch_be!(
unsafe { arch::neon::p_n_444_to_rgba_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::neon::p_n_444_to_rgba_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
dispatch_be!(
unsafe { arch::x86_avx512::p_n_444_to_rgba_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx512::p_n_444_to_rgba_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if avx2_available() {
dispatch_be!(
unsafe { arch::x86_avx2::p_n_444_to_rgba_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx2::p_n_444_to_rgba_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if sse41_available() {
dispatch_be!(
unsafe { arch::x86_sse41::p_n_444_to_rgba_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_sse41::p_n_444_to_rgba_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
dispatch_be!(
unsafe { arch::wasm_simd128::p_n_444_to_rgba_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::wasm_simd128::p_n_444_to_rgba_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
_ => {}
}
}
dispatch_be!(
scalar::p_n_444_to_rgba_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range),
scalar::p_n_444_to_rgba_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range)
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p410_to_rgba_row(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p410_to_rgba_row_endian(
y, uv_full, rgba_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p410_to_rgba_u16_row_endian(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
let rgba_min = rgba_row_elems(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgba_out.len() >= rgba_min, "rgba_out row too short");
macro_rules! dispatch_be {
($call_le:expr, $call_be:expr) => {
if big_endian { $call_be } else { $call_le }
};
}
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
dispatch_be!(
unsafe { arch::neon::p_n_444_to_rgba_u16_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::neon::p_n_444_to_rgba_u16_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
dispatch_be!(
unsafe { arch::x86_avx512::p_n_444_to_rgba_u16_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx512::p_n_444_to_rgba_u16_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if avx2_available() {
dispatch_be!(
unsafe { arch::x86_avx2::p_n_444_to_rgba_u16_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx2::p_n_444_to_rgba_u16_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if sse41_available() {
dispatch_be!(
unsafe { arch::x86_sse41::p_n_444_to_rgba_u16_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_sse41::p_n_444_to_rgba_u16_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
dispatch_be!(
unsafe { arch::wasm_simd128::p_n_444_to_rgba_u16_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::wasm_simd128::p_n_444_to_rgba_u16_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
_ => {}
}
}
dispatch_be!(
scalar::p_n_444_to_rgba_u16_row::<10, false>(y, uv_full, rgba_out, width, matrix, full_range),
scalar::p_n_444_to_rgba_u16_row::<10, true>(y, uv_full, rgba_out, width, matrix, full_range)
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p410_to_rgba_u16_row(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p410_to_rgba_u16_row_endian(
y, uv_full, rgba_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p412_to_rgba_row_endian(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
let rgba_min = rgba_row_bytes(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgba_out.len() >= rgba_min, "rgba_out row too short");
macro_rules! dispatch_be {
($call_le:expr, $call_be:expr) => {
if big_endian { $call_be } else { $call_le }
};
}
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
dispatch_be!(
unsafe { arch::neon::p_n_444_to_rgba_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::neon::p_n_444_to_rgba_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
dispatch_be!(
unsafe { arch::x86_avx512::p_n_444_to_rgba_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx512::p_n_444_to_rgba_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if avx2_available() {
dispatch_be!(
unsafe { arch::x86_avx2::p_n_444_to_rgba_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx2::p_n_444_to_rgba_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if sse41_available() {
dispatch_be!(
unsafe { arch::x86_sse41::p_n_444_to_rgba_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_sse41::p_n_444_to_rgba_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
dispatch_be!(
unsafe { arch::wasm_simd128::p_n_444_to_rgba_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::wasm_simd128::p_n_444_to_rgba_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
_ => {}
}
}
dispatch_be!(
scalar::p_n_444_to_rgba_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range),
scalar::p_n_444_to_rgba_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range)
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p412_to_rgba_row(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p412_to_rgba_row_endian(
y, uv_full, rgba_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p412_to_rgba_u16_row_endian(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
let rgba_min = rgba_row_elems(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgba_out.len() >= rgba_min, "rgba_out row too short");
macro_rules! dispatch_be {
($call_le:expr, $call_be:expr) => {
if big_endian { $call_be } else { $call_le }
};
}
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
dispatch_be!(
unsafe { arch::neon::p_n_444_to_rgba_u16_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::neon::p_n_444_to_rgba_u16_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
dispatch_be!(
unsafe { arch::x86_avx512::p_n_444_to_rgba_u16_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx512::p_n_444_to_rgba_u16_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if avx2_available() {
dispatch_be!(
unsafe { arch::x86_avx2::p_n_444_to_rgba_u16_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx2::p_n_444_to_rgba_u16_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if sse41_available() {
dispatch_be!(
unsafe { arch::x86_sse41::p_n_444_to_rgba_u16_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_sse41::p_n_444_to_rgba_u16_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
dispatch_be!(
unsafe { arch::wasm_simd128::p_n_444_to_rgba_u16_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::wasm_simd128::p_n_444_to_rgba_u16_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
_ => {}
}
}
dispatch_be!(
scalar::p_n_444_to_rgba_u16_row::<12, false>(y, uv_full, rgba_out, width, matrix, full_range),
scalar::p_n_444_to_rgba_u16_row::<12, true>(y, uv_full, rgba_out, width, matrix, full_range)
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p412_to_rgba_u16_row(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p412_to_rgba_u16_row_endian(
y, uv_full, rgba_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p416_to_rgba_row_endian(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
let rgba_min = rgba_row_bytes(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgba_out.len() >= rgba_min, "rgba_out row too short");
macro_rules! dispatch_be {
($call_le:expr, $call_be:expr) => {
if big_endian { $call_be } else { $call_le }
};
}
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
dispatch_be!(
unsafe { arch::neon::p_n_444_16_to_rgba_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::neon::p_n_444_16_to_rgba_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
dispatch_be!(
unsafe { arch::x86_avx512::p_n_444_16_to_rgba_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx512::p_n_444_16_to_rgba_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if avx2_available() {
dispatch_be!(
unsafe { arch::x86_avx2::p_n_444_16_to_rgba_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx2::p_n_444_16_to_rgba_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if sse41_available() {
dispatch_be!(
unsafe { arch::x86_sse41::p_n_444_16_to_rgba_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_sse41::p_n_444_16_to_rgba_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
dispatch_be!(
unsafe { arch::wasm_simd128::p_n_444_16_to_rgba_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::wasm_simd128::p_n_444_16_to_rgba_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
_ => {}
}
}
dispatch_be!(
scalar::p_n_444_16_to_rgba_row::<false>(y, uv_full, rgba_out, width, matrix, full_range),
scalar::p_n_444_16_to_rgba_row::<true>(y, uv_full, rgba_out, width, matrix, full_range)
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p416_to_rgba_row(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u8],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p416_to_rgba_row_endian(
y, uv_full, rgba_out, width, matrix, full_range, use_simd, false,
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p416_to_rgba_u16_row_endian(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
big_endian: bool,
) {
let rgba_min = rgba_row_elems(width);
let uv_min = uv_full_row_elems(width);
assert!(y.len() >= width, "y row too short");
assert!(uv_full.len() >= uv_min, "uv_full row too short");
assert!(rgba_out.len() >= rgba_min, "rgba_out row too short");
macro_rules! dispatch_be {
($call_le:expr, $call_be:expr) => {
if big_endian { $call_be } else { $call_le }
};
}
if use_simd {
cfg_select! {
target_arch = "aarch64" => {
if neon_available() {
dispatch_be!(
unsafe { arch::neon::p_n_444_16_to_rgba_u16_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::neon::p_n_444_16_to_rgba_u16_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "x86_64" => {
if avx512_available() {
dispatch_be!(
unsafe { arch::x86_avx512::p_n_444_16_to_rgba_u16_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx512::p_n_444_16_to_rgba_u16_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if avx2_available() {
dispatch_be!(
unsafe { arch::x86_avx2::p_n_444_16_to_rgba_u16_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_avx2::p_n_444_16_to_rgba_u16_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
if sse41_available() {
dispatch_be!(
unsafe { arch::x86_sse41::p_n_444_16_to_rgba_u16_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::x86_sse41::p_n_444_16_to_rgba_u16_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
target_arch = "wasm32" => {
if simd128_available() {
dispatch_be!(
unsafe { arch::wasm_simd128::p_n_444_16_to_rgba_u16_row::<false>(y, uv_full, rgba_out, width, matrix, full_range); },
unsafe { arch::wasm_simd128::p_n_444_16_to_rgba_u16_row::<true>(y, uv_full, rgba_out, width, matrix, full_range); }
);
return;
}
},
_ => {}
}
}
dispatch_be!(
scalar::p_n_444_16_to_rgba_u16_row::<false>(y, uv_full, rgba_out, width, matrix, full_range),
scalar::p_n_444_16_to_rgba_u16_row::<true>(y, uv_full, rgba_out, width, matrix, full_range)
);
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::too_many_arguments)]
pub fn p416_to_rgba_u16_row(
y: &[u16],
uv_full: &[u16],
rgba_out: &mut [u16],
width: usize,
matrix: ColorMatrix,
full_range: bool,
use_simd: bool,
) {
p416_to_rgba_u16_row_endian(
y, uv_full, rgba_out, width, matrix, full_range, use_simd, false,
);
}