1use std::ops::{Add, BitAnd, Not, Shl, Shr, Sub};
2
3use cfg_if::cfg_if;
4use num_traits::One;
5
6cfg_if! {
7 if #[cfg(target_arch = "x86_64")] {
8 #[allow(dead_code)]
9 pub(crate) const DEFAULT_ALIGNMENT: usize = 32;
10 } else if #[cfg(target_arch = "wasm32")] {
11 #[allow(dead_code)]
12 pub(crate) const DEFAULT_ALIGNMENT: usize = 8;
13 } else {
14 #[allow(dead_code)]
15 pub(crate) const DEFAULT_ALIGNMENT: usize = 16;
16 }
17}
18
19#[allow(dead_code)]
20pub fn align_to<T>(value: T, alignment: T) -> T
21where
22 T: Copy + Add<Output = T> + Sub<Output = T> + BitAnd<Output = T> + Not<Output = T> + One,
23{
24 (value + alignment - T::one()) & !(alignment - T::one())
25}
26
27#[allow(dead_code)]
28pub fn ceil_rshift<T>(value: T, shift: T) -> T
29where
30 T: Copy + Add<Output = T> + Sub<Output = T> + Shl<Output = T> + Shr<Output = T> + One,
31{
32 (value + (T::one() << shift) - T::one()) >> shift
33}
34
35#[macro_export]
36macro_rules! fourcc_le {
37 ($a:expr, $b:expr, $c:expr, $d:expr) => {
38 (($a as u8) as u32) | ((($b as u8) as u32) << 8) | ((($c as u8) as u32) << 16) | ((($d as u8) as u32) << 24)
39 };
40
41 ($s:expr) => {{
42 const BYTES: &[u8] = $s;
43 const _: () = assert!(BYTES.len() == 4, "FourCC must be exactly 4 bytes");
44 $crate::fourcc_le!(BYTES[0], BYTES[1], BYTES[2], BYTES[3])
45 }};
46}
47
48#[macro_export]
49macro_rules! fourcc_be {
50 ($a:expr, $b:expr, $c:expr, $d:expr) => {
51 ((($a as u8) as u32) << 24) | ((($b as u8) as u32) << 16) | ((($c as u8) as u32) << 8) | (($d as u8) as u32)
52 };
53
54 ($s:expr) => {{
55 const BYTES: &[u8] = $s;
56 const _: () = assert!(BYTES.len() == 4, "FourCC must be exactly 4 bytes");
57 $crate::fourcc_be!(BYTES[0], BYTES[1], BYTES[2], BYTES[3])
58 }};
59}
60
61#[macro_export]
62macro_rules! fourcc {
63 ($($tt:tt)*) => {
64 $crate::fourcc_le!($($tt)*)
65 };
66}