#[cfg(any(
feature = "rgb",
feature = "v210",
feature = "y2xx",
feature = "yuv-444-packed",
feature = "yuv-packed",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
use core::arch::aarch64::*;
#[allow(unused_imports)]
pub(super) use crate::{ColorMatrix, row::scalar};
#[cfg(any(feature = "gbr", feature = "yuv-444-packed", feature = "yuva"))]
pub(crate) mod alpha_extract;
#[cfg(feature = "yuv-444-packed")]
mod ayuv64;
pub(crate) mod endian;
#[cfg(feature = "gray")]
mod gray;
mod hsv;
#[cfg(feature = "rgb-legacy")]
pub(crate) mod legacy_rgb;
#[cfg(feature = "mono")]
pub(crate) mod mono1bit;
#[cfg(feature = "rgb")]
mod packed_rgb;
#[cfg(feature = "rgb")]
mod packed_rgb_16bit;
#[cfg(feature = "rgb-float")]
mod packed_rgb_float;
#[cfg(feature = "yuv-packed")]
mod packed_yuv_4_1_1;
#[cfg(feature = "yuv-packed")]
mod packed_yuv_8bit;
#[cfg(feature = "mono")]
pub(crate) mod pal8;
#[cfg(feature = "gbr")]
mod planar_gbr;
#[cfg(feature = "gbr")]
mod planar_gbr_float;
#[cfg(feature = "gbr")]
mod planar_gbr_high_bit;
#[cfg(feature = "yuv-semi-planar")]
mod semi_planar_8bit;
#[cfg(all(feature = "yuv-planar", feature = "yuv-semi-planar"))]
mod subsampled_high_bit_pn_4_2_0;
#[cfg(feature = "yuv-semi-planar")]
mod subsampled_high_bit_pn_4_4_4;
#[cfg(feature = "v210")]
mod v210;
#[cfg(feature = "yuv-444-packed")]
mod v30x;
#[cfg(feature = "yuv-444-packed")]
mod v410;
#[cfg(feature = "yuv-444-packed")]
mod vuya;
#[cfg(feature = "yuv-444-packed")]
mod xv36;
#[cfg(all(feature = "xyz", any(feature = "std", feature = "alloc")))]
pub(crate) mod xyz12;
#[cfg(feature = "y2xx")]
mod y216;
#[cfg(feature = "y2xx")]
mod y2xx;
#[cfg(any(
feature = "gray",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
pub(crate) mod y_plane_to_luma_u16;
#[cfg(feature = "yuv-planar")]
mod yuv_planar_16bit;
#[cfg(feature = "yuv-planar")]
mod yuv_planar_8bit;
#[cfg(feature = "yuv-planar")]
mod yuv_planar_high_bit;
#[cfg(any(feature = "gbr", feature = "yuv-444-packed", feature = "yuva"))]
pub(crate) use alpha_extract::*;
#[cfg(feature = "yuv-444-packed")]
pub(crate) use ayuv64::*;
#[cfg(feature = "gray")]
pub(crate) use gray::*;
pub(crate) use hsv::*;
#[cfg(feature = "rgb")]
pub(crate) use packed_rgb::*;
#[cfg(feature = "rgb")]
#[allow(unused_imports)]
pub(crate) use packed_rgb_16bit::*;
#[cfg(feature = "rgb-float")]
pub(crate) use packed_rgb_float::*;
#[cfg(feature = "yuv-packed")]
pub(crate) use packed_yuv_4_1_1::*;
#[cfg(feature = "yuv-packed")]
pub(crate) use packed_yuv_8bit::*;
#[cfg(feature = "gbr")]
pub(crate) use planar_gbr::*;
#[cfg(feature = "gbr")]
pub(crate) use planar_gbr_float::*;
#[cfg(feature = "gbr")]
pub(crate) use planar_gbr_high_bit::*;
#[cfg(feature = "yuv-semi-planar")]
pub(crate) use semi_planar_8bit::*;
#[cfg(all(feature = "yuv-planar", feature = "yuv-semi-planar"))]
pub(crate) use subsampled_high_bit_pn_4_2_0::*;
#[cfg(feature = "yuv-semi-planar")]
pub(crate) use subsampled_high_bit_pn_4_4_4::*;
#[cfg(feature = "yuv-444-packed")]
pub(crate) use v30x::*;
#[cfg(feature = "v210")]
pub(crate) use v210::*;
#[cfg(feature = "yuv-444-packed")]
pub(crate) use v410::*;
#[cfg(feature = "yuv-444-packed")]
pub(crate) use vuya::*;
#[cfg(feature = "yuv-444-packed")]
pub(crate) use xv36::*;
#[cfg(any(
feature = "gray",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
pub(crate) use y_plane_to_luma_u16::*;
#[cfg(feature = "y2xx")]
pub(crate) use y2xx::*;
#[cfg(feature = "y2xx")]
pub(crate) use y216::*;
#[cfg(feature = "yuv-planar")]
pub(crate) use yuv_planar_8bit::*;
#[cfg(feature = "yuv-planar")]
pub(crate) use yuv_planar_16bit::*;
#[cfg(feature = "yuv-planar")]
pub(crate) use yuv_planar_high_bit::*;
#[cfg(any(
feature = "v210",
feature = "y2xx",
feature = "yuv-444-packed",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
#[inline(always)]
pub(super) fn clamp_u16_max(v: int16x8_t, zero_v: int16x8_t, max_v: int16x8_t) -> uint16x8_t {
unsafe { vreinterpretq_u16_s16(vminq_s16(vmaxq_s16(v, zero_v), max_v)) }
}
#[cfg(any(
feature = "v210",
feature = "y2xx",
feature = "yuv-444-packed",
feature = "yuv-packed",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
#[inline(always)]
pub(super) fn q15_shift(v: int32x4_t) -> int32x4_t {
unsafe { vshrq_n_s32::<15>(v) }
}
#[cfg(any(
feature = "v210",
feature = "y2xx",
feature = "yuv-444-packed",
feature = "yuv-packed",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
#[inline(always)]
pub(super) fn chroma_i16x8(
cu: int32x4_t,
cv: int32x4_t,
u_d_lo: int32x4_t,
v_d_lo: int32x4_t,
u_d_hi: int32x4_t,
v_d_hi: int32x4_t,
rnd: int32x4_t,
) -> int16x8_t {
unsafe {
let lo = vshrq_n_s32::<15>(vaddq_s32(
vaddq_s32(vmulq_s32(cu, u_d_lo), vmulq_s32(cv, v_d_lo)),
rnd,
));
let hi = vshrq_n_s32::<15>(vaddq_s32(
vaddq_s32(vmulq_s32(cu, u_d_hi), vmulq_s32(cv, v_d_hi)),
rnd,
));
vcombine_s16(vqmovn_s32(lo), vqmovn_s32(hi))
}
}
#[cfg(any(
feature = "v210",
feature = "y2xx",
feature = "yuv-444-packed",
feature = "yuv-packed",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
#[inline(always)]
pub(super) fn scale_y(
y_i16: int16x8_t,
y_off_v: int16x8_t,
y_scale_v: int32x4_t,
rnd: int32x4_t,
) -> int16x8_t {
unsafe {
let shifted = vsubq_s16(y_i16, y_off_v);
let lo = vshrq_n_s32::<15>(vaddq_s32(
vmulq_s32(vmovl_s16(vget_low_s16(shifted)), y_scale_v),
rnd,
));
let hi = vshrq_n_s32::<15>(vaddq_s32(
vmulq_s32(vmovl_s16(vget_high_s16(shifted)), y_scale_v),
rnd,
));
vcombine_s16(vqmovn_s32(lo), vqmovn_s32(hi))
}
}
#[cfg(any(
feature = "y2xx",
feature = "yuv-444-packed",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
#[inline(always)]
pub(super) fn scale_y_u16_to_i16(
y_vec: uint16x8_t,
y_off_v: int32x4_t,
y_scale_v: int32x4_t,
rnd_v: int32x4_t,
) -> int16x8_t {
unsafe {
let lo = vreinterpretq_s32_u32(vmovl_u16(vget_low_u16(y_vec)));
let hi = vreinterpretq_s32_u32(vmovl_u16(vget_high_u16(y_vec)));
let lo_s = vshrq_n_s32::<15>(vaddq_s32(
vmulq_s32(vsubq_s32(lo, y_off_v), y_scale_v),
rnd_v,
));
let hi_s = vshrq_n_s32::<15>(vaddq_s32(
vmulq_s32(vsubq_s32(hi, y_off_v), y_scale_v),
rnd_v,
));
vcombine_s16(vqmovn_s32(lo_s), vqmovn_s32(hi_s))
}
}
#[cfg(any(
feature = "y2xx",
feature = "yuv-444-packed",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
#[inline(always)]
pub(super) fn chroma_i64x4(
cu: int32x4_t,
cv: int32x4_t,
u_d: int32x4_t,
v_d: int32x4_t,
rnd64: int64x2_t,
) -> int32x4_t {
unsafe {
let sum_lo = vshrq_n_s64::<15>(vaddq_s64(
vaddq_s64(
vmull_s32(vget_low_s32(cu), vget_low_s32(u_d)),
vmull_s32(vget_low_s32(cv), vget_low_s32(v_d)),
),
rnd64,
));
let sum_hi = vshrq_n_s64::<15>(vaddq_s64(
vaddq_s64(
vmull_s32(vget_high_s32(cu), vget_high_s32(u_d)),
vmull_s32(vget_high_s32(cv), vget_high_s32(v_d)),
),
rnd64,
));
vcombine_s32(vmovn_s64(sum_lo), vmovn_s64(sum_hi))
}
}
#[cfg(any(
feature = "y2xx",
feature = "yuv-444-packed",
feature = "yuv-planar",
feature = "yuv-semi-planar",
feature = "yuva",
))]
#[inline(always)]
pub(super) fn scale_y_u16_i64(
y_i32: int32x4_t,
y_off_v: int32x4_t,
y_scale_d: int32x2_t,
rnd64: int64x2_t,
) -> int32x4_t {
unsafe {
let sub = vsubq_s32(y_i32, y_off_v);
let lo = vshrq_n_s64::<15>(vaddq_s64(vmull_s32(vget_low_s32(sub), y_scale_d), rnd64));
let hi = vshrq_n_s64::<15>(vaddq_s64(vmull_s32(vget_high_s32(sub), y_scale_d), rnd64));
vcombine_s32(vmovn_s64(lo), vmovn_s64(hi))
}
}
#[cfg(any(
feature = "rgb",
feature = "yuv-444-packed",
feature = "yuv-semi-planar"
))]
const HOST_NATIVE_BE: bool = cfg!(target_endian = "big");
#[cfg(any(
feature = "rgb",
feature = "yuv-444-packed",
feature = "yuv-semi-planar"
))]
#[inline(always)]
pub(super) unsafe fn bswap_u16x8_if_be<const BE: bool>(v: uint16x8_t) -> uint16x8_t {
if BE != HOST_NATIVE_BE {
unsafe { vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(v))) }
} else {
v
}
}
#[cfg(feature = "yuv-444-packed")]
#[inline(always)]
pub(super) unsafe fn bswap_u32x4_if_be<const BE: bool>(v: uint32x4_t) -> uint32x4_t {
if BE != HOST_NATIVE_BE {
unsafe { vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(v))) }
} else {
v
}
}
#[cfg(all(test, feature = "std"))]
mod tests;