1#![expect(
5    clippy::excessive_precision,
6    missing_docs,
7    reason = "TODO: https://github.com/linebender/fearless_simd/issues/40"
8)]
9
10use fearless_simd::{Level, Select, Simd, SimdInto, dispatch, f32x4};
11
12#[cfg(feature = "safe_wrappers")]
15#[inline(always)]
16fn copy_alpha<S: Simd>(a: f32x4<S>, b: f32x4<S>) -> f32x4<S> {
17    #[cfg(target_arch = "aarch64")]
25    if let Some(neon) = a.simd.level().as_neon() {
26        return neon
27            .neon
28            .vcopyq_laneq_f32::<3, 3>(a.into(), b.into())
29            .simd_into(a.simd);
30    }
31    let mut result = a;
32    result[3] = b[3];
33    result
34}
35
36#[cfg(not(feature = "safe_wrappers"))]
38#[inline(always)]
39fn copy_alpha<S: Simd>(a: f32x4<S>, b: f32x4<S>) -> f32x4<S> {
40    #[cfg(target_arch = "aarch64")]
41    if let Some(_neon) = a.simd.level().as_neon() {
42        unsafe {
43            return core::arch::aarch64::vcopyq_laneq_f32::<3, 3>(a.into(), b.into())
44                .simd_into(a.simd);
45        }
46    }
47    let mut result = a;
48    result[3] = b[3];
49    result
50}
51
52#[inline(always)]
53fn to_srgb<S: Simd>(simd: S, rgba: [f32; 4]) -> [f32; 4] {
54    let v: f32x4<S> = rgba.simd_into(simd);
55    let vabs = v.abs();
56    let x = vabs - 5.35862651e-04;
57    let x2 = x * x;
58    let even1 = x * -9.12795913e-01 + -2.88143143e-02;
59    let even2 = x2 * -7.29192910e-01 + even1;
60    let odd1 = x * 1.06133172e+00 + 1.40194533e+00;
61    let odd2 = x2 * 2.07758287e-01 + odd1;
62    let poly = odd2 * x.sqrt() + even2;
63    let lin = vabs * 12.92;
64    let z = vabs.simd_gt(0.0031308).select(poly, lin);
65    let z_signed = z.copysign(v);
66    let result = copy_alpha(z_signed, v);
67    result.into()
68}
69
70fn main() {
71    let level = Level::new();
72    let rgba = [0.1, -0.2, 0.001, 0.4];
73    let srgb = dispatch!(level, simd=> to_srgb(simd, rgba));
74    println!("{srgb:?}");
75}