mod block_functions;
#[cfg(all(target_arch = "x86_64", feature = "avx2"))]
mod cpu;
mod fps;
mod mask;
mod math;
#[cfg(test)]
mod tests;
use semisafe::slice::get as semisafe_get;
use semisafe::slice::get_mut as semisafe_get_mut;
use std::{
fmt::Display,
mem::{ManuallyDrop, MaybeUninit},
};
pub use crate::frame::PlaneSizeTuple;
pub use block_functions::*;
#[cfg(all(target_arch = "x86_64", feature = "avx2"))]
pub use cpu::*;
pub use fps::*;
pub use mask::*;
pub use math::*;
use num_traits::{AsPrimitive, PrimInt};
pub trait Pixel:
Copy
+ Clone
+ Default
+ Send
+ Sync
+ PrimInt
+ Display
+ AsPrimitive<u16>
+ AsPrimitive<u32>
+ AsPrimitive<u64>
+ AsPrimitive<i32>
+ AsPrimitive<i64>
+ 'static
{
#[must_use]
#[allow(dead_code)]
fn from_u16_or_max_value(value: u16) -> Self;
#[must_use]
fn from_u32_or_max_value(value: u32) -> Self;
}
impl<T> Pixel for T
where
T: Copy
+ Clone
+ Default
+ Send
+ Sync
+ PrimInt
+ Display
+ AsPrimitive<u16>
+ AsPrimitive<u32>
+ AsPrimitive<u64>
+ AsPrimitive<i32>
+ AsPrimitive<i64>
+ 'static,
{
#[inline(always)]
fn from_u16_or_max_value(value: u16) -> Self {
Self::from(value).unwrap_or_else(Self::max_value)
}
#[inline(always)]
fn from_u32_or_max_value(value: u32) -> Self {
Self::from(value).unwrap_or_else(Self::max_value)
}
}
#[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
#[inline]
pub fn vs_bitblt<T: Pixel>(
dest: &mut [T],
dest_stride_pixels: std::num::NonZeroUsize,
src: &[T],
src_stride_pixels: std::num::NonZeroUsize,
row_size: std::num::NonZeroUsize,
height: std::num::NonZeroUsize,
) {
let height = height.get();
let row_size = row_size.get();
let src_stride = src_stride_pixels.get();
let dest_stride = dest_stride_pixels.get();
if src_stride == dest_stride && src_stride == row_size {
semisafe_get_mut(dest, ..row_size * height)
.copy_from_slice(semisafe_get(src, ..row_size * height));
} else {
for i in 0..height {
let src_start = i * src_stride;
let dest_start = i * dest_stride;
semisafe_get_mut(semisafe_get_mut(dest, dest_start..), ..row_size)
.copy_from_slice(semisafe_get(semisafe_get(src, src_start..), ..row_size));
}
}
}
#[inline(always)]
#[must_use]
pub fn uninit_vec<T>(len: usize) -> Vec<MaybeUninit<T>> {
let mut values = Vec::with_capacity(len);
unsafe { values.set_len(len) };
values
}
#[inline(always)]
#[must_use]
pub unsafe fn assume_init_vec<T>(values: Vec<MaybeUninit<T>>) -> Vec<T> {
let mut values = ManuallyDrop::new(values);
let ptr = values.as_mut_ptr().cast::<T>();
let len = values.len();
let cap = values.capacity();
unsafe { Vec::from_raw_parts(ptr, len, cap) }
}