use super::fast_math;
#[allow(unused_imports)]
use num_traits::Float;
const HLG_A: f32 = 0.17883277;
const HLG_B: f32 = 0.28466892; const HLG_C: f32 = 0.55991073; const HLG_A_INV_LOG2E: f32 = HLG_A * core::f32::consts::LN_2; const HLG_INV_A_LOG2E: f32 = core::f32::consts::LOG2_E / HLG_A;
#[inline(always)]
pub fn hlg_to_linear(v: f32) -> f32 {
if v <= 0.0 {
0.0
} else if v <= 0.5 {
(v * v) / 3.0
} else {
(fast_math::fast_pow2f((v - HLG_C) * HLG_INV_A_LOG2E) + HLG_B) / 12.0
}
}
#[inline(always)]
pub fn linear_to_hlg(v: f32) -> f32 {
if v <= 0.0 {
0.0
} else if v <= 1.0 / 12.0 {
(3.0 * v).sqrt()
} else {
HLG_A_INV_LOG2E * fast_math::fast_log2f(12.0 * v - HLG_B) + HLG_C
}
}
use magetypes::simd::backends::F32x4Convert;
use magetypes::simd::generic::f32x4;
#[allow(dead_code)]
#[inline(always)]
pub(crate) fn hlg_to_linear_x4<T: F32x4Convert>(t: T, v: f32x4<T>) -> f32x4<T> {
let zero = f32x4::zero(t);
let half = f32x4::splat(t, 0.5);
let third = f32x4::splat(t, 1.0 / 3.0);
let inv_12 = f32x4::splat(t, 1.0 / 12.0);
let hlg_b = f32x4::splat(t, HLG_B);
let hlg_c = f32x4::splat(t, HLG_C);
let hlg_inv_a_log2e = f32x4::splat(t, HLG_INV_A_LOG2E);
let a = v.max(zero);
let low = (a * a) * third;
let exp_arg = (a - hlg_c) * hlg_inv_a_log2e;
let exp_val = fast_math::fast_pow2f_x4(t, exp_arg);
let high = (exp_val + hlg_b) * inv_12;
let mask = a.simd_le(half);
let result = f32x4::blend(mask, low, high);
let pos_mask = v.simd_gt(zero);
result & pos_mask
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) fn linear_to_hlg_x4<T: F32x4Convert>(t: T, v: f32x4<T>) -> f32x4<T> {
let zero = f32x4::zero(t);
let threshold = f32x4::splat(t, 1.0 / 12.0);
let three = f32x4::splat(t, 3.0);
let twelve = f32x4::splat(t, 12.0);
let hlg_a_ln2 = f32x4::splat(t, HLG_A_INV_LOG2E);
let hlg_b = f32x4::splat(t, HLG_B);
let hlg_c = f32x4::splat(t, HLG_C);
let a = v.max(zero);
let low = (three * a).sqrt();
let arg = twelve * a - hlg_b;
let safe_arg = arg.max(f32x4::splat(t, f32::MIN_POSITIVE));
let log2_val = fast_math::fast_log2f_x4(t, safe_arg);
let high = hlg_a_ln2.mul_add(log2_val, hlg_c);
let mask = a.simd_le(threshold);
let result = f32x4::blend(mask, low, high);
let pos_mask = v.simd_gt(zero);
result & pos_mask
}
use magetypes::simd::backends::F32x8Convert;
use magetypes::simd::generic::f32x8;
#[inline(always)]
pub(crate) fn hlg_to_linear_x8<T: F32x8Convert>(t: T, v: f32x8<T>) -> f32x8<T> {
let zero = f32x8::zero(t);
let half = f32x8::splat(t, 0.5);
let third = f32x8::splat(t, 1.0 / 3.0);
let inv_12 = f32x8::splat(t, 1.0 / 12.0);
let hlg_b = f32x8::splat(t, HLG_B);
let hlg_c = f32x8::splat(t, HLG_C);
let hlg_inv_a_log2e = f32x8::splat(t, HLG_INV_A_LOG2E);
let a = v.max(zero);
let low = (a * a) * third;
let exp_arg = (a - hlg_c) * hlg_inv_a_log2e;
let exp_val = fast_math::fast_pow2f_x8(t, exp_arg);
let high = (exp_val + hlg_b) * inv_12;
let mask = a.simd_le(half);
let result = f32x8::blend(mask, low, high);
let pos_mask = v.simd_gt(zero);
result & pos_mask
}
#[inline(always)]
pub(crate) fn linear_to_hlg_x8<T: F32x8Convert>(t: T, v: f32x8<T>) -> f32x8<T> {
let zero = f32x8::zero(t);
let threshold = f32x8::splat(t, 1.0 / 12.0);
let three = f32x8::splat(t, 3.0);
let twelve = f32x8::splat(t, 12.0);
let hlg_a_ln2 = f32x8::splat(t, HLG_A_INV_LOG2E);
let hlg_b = f32x8::splat(t, HLG_B);
let hlg_c = f32x8::splat(t, HLG_C);
let a = v.max(zero);
let low = (three * a).sqrt();
let arg = twelve * a - hlg_b;
let safe_arg = arg.max(f32x8::splat(t, f32::MIN_POSITIVE));
let log2_val = fast_math::fast_log2f_x8(t, safe_arg);
let high = hlg_a_ln2.mul_add(log2_val, hlg_c);
let mask = a.simd_le(threshold);
let result = f32x8::blend(mask, low, high);
let pos_mask = v.simd_gt(zero);
result & pos_mask
}