linear_srgb/default.rs
1//! Recommended API for sRGB ↔ linear conversion.
2//!
3//! This module re-exports the optimal implementation for each use case:
4//!
5//! - **Single f32 values**: Rational polynomial (~14 ULP max, perfectly
6//! monotonic — no `powf`)
7//! - **Single u8/u16 values**: LUT lookup (zero math)
8//! - **Slices**: SIMD-accelerated with runtime CPU dispatch
9//! - **Custom gamma**: Pure power function (f32, slices)
10//!
11//! For exact `powf()` conversions with C0-continuous constants, see [`crate::precise`].
12//!
13//! # Quick Start
14//!
15//! ```rust
16//! use linear_srgb::default::{srgb_to_linear, linear_to_srgb};
17//!
18//! let linear = srgb_to_linear(0.5);
19//! let srgb = linear_to_srgb(linear);
20//! ```
21//!
22//! # Batch Processing
23//!
24//! ```rust
25//! use linear_srgb::default::{srgb_to_linear_slice, linear_to_srgb_slice};
26//!
27//! let mut values = vec![0.5f32; 10000];
28//! srgb_to_linear_slice(&mut values); // SIMD-accelerated
29//! linear_to_srgb_slice(&mut values);
30//! ```
31
32// ============================================================================
33// Single-value sRGB f32 (rational polynomial — fast, ≤14 ULP, monotonic)
34// ============================================================================
35
36pub use crate::rational_poly::{
37 linear_to_srgb_fast as linear_to_srgb, srgb_to_linear_fast as srgb_to_linear,
38};
39
40// ============================================================================
41// Single-value sRGB integer (LUT lookup — zero math)
42// ============================================================================
43
44pub use crate::scalar::{
45 linear_to_srgb_u8, linear_to_srgb_u16, linear_to_srgb_u16_fast, srgb_u8_to_linear,
46 srgb_u16_to_linear,
47};
48
49// ============================================================================
50// Slice functions (SIMD-dispatched)
51// ============================================================================
52
53pub use crate::simd::{
54 // Custom gamma slices
55 gamma_to_linear_slice,
56 linear_to_gamma_slice,
57 // f32 RGBA slices (alpha-preserving)
58 linear_to_srgb_rgba_slice,
59 // f32 slices (in-place)
60 linear_to_srgb_slice,
61 linear_to_srgb_u8_rgba_slice,
62 // u8 slices
63 linear_to_srgb_u8_slice,
64 linear_to_srgb_u16_rgba_slice,
65 linear_to_srgb_u16_rgba_slice_fast,
66 // u16 slices
67 linear_to_srgb_u16_slice,
68 linear_to_srgb_u16_slice_fast,
69 // Fused premultiply/unpremultiply
70 srgb_to_linear_premultiply_rgba_slice,
71 // f32 RGBA slices (alpha-preserving)
72 srgb_to_linear_rgba_slice,
73 // f32 slices (in-place)
74 srgb_to_linear_slice,
75 srgb_u8_to_linear_premultiply_rgba_slice,
76 srgb_u8_to_linear_rgba_slice,
77 // u8 slices
78 srgb_u8_to_linear_slice,
79 srgb_u16_to_linear_rgba_slice,
80 // u16 slices
81 srgb_u16_to_linear_slice,
82 unpremultiply_linear_to_srgb_rgba_slice,
83 unpremultiply_linear_to_srgb_u8_rgba_slice,
84};
85
86// Deprecated gamma premultiply/unpremultiply re-exports
87#[allow(deprecated)]
88pub use crate::simd::{
89 gamma_to_linear_premultiply_rgba_slice, unpremultiply_linear_to_gamma_rgba_slice,
90};
91
92// ============================================================================
93// Custom gamma (scalar)
94// ============================================================================
95
96pub use crate::scalar::{gamma_to_linear, linear_to_gamma};
97
98// ============================================================================
99// Transfer functions (behind `transfer` feature)
100// ============================================================================
101
102#[cfg(feature = "transfer")]
103pub use crate::tf::{
104 bt709_to_linear, hlg_to_linear, linear_to_bt709, linear_to_hlg, linear_to_pq, pq_to_linear,
105};
106
107// ============================================================================
108// Transfer function slice operations (behind `transfer` feature)
109// ============================================================================
110
111/// Convert HLG signal f32 values to linear in-place.
112#[cfg(feature = "transfer")]
113#[archmage::autoversion]
114pub fn hlg_to_linear_slice(values: &mut [f32]) {
115 for v in values.iter_mut() {
116 *v = crate::tf::hlg_to_linear(*v);
117 }
118}
119
120/// Convert linear f32 values to HLG signal in-place.
121#[cfg(feature = "transfer")]
122#[archmage::autoversion]
123pub fn linear_to_hlg_slice(values: &mut [f32]) {
124 for v in values.iter_mut() {
125 *v = crate::tf::linear_to_hlg(*v);
126 }
127}
128
129/// Convert PQ (ST 2084) signal f32 values to linear in-place.
130#[cfg(feature = "transfer")]
131#[archmage::autoversion]
132pub fn pq_to_linear_slice(values: &mut [f32]) {
133 for v in values.iter_mut() {
134 *v = crate::tf::pq_to_linear(*v);
135 }
136}
137
138/// Convert linear f32 values to PQ (ST 2084) signal in-place.
139#[cfg(feature = "transfer")]
140#[archmage::autoversion]
141pub fn linear_to_pq_slice(values: &mut [f32]) {
142 for v in values.iter_mut() {
143 *v = crate::tf::linear_to_pq(*v);
144 }
145}
146
147/// Convert BT.709 signal f32 values to linear in-place.
148#[cfg(feature = "transfer")]
149#[archmage::autoversion]
150pub fn bt709_to_linear_slice(values: &mut [f32]) {
151 for v in values.iter_mut() {
152 *v = crate::tf::bt709_to_linear(*v);
153 }
154}
155
156/// Convert linear f32 values to BT.709 signal in-place.
157#[cfg(feature = "transfer")]
158#[archmage::autoversion]
159pub fn linear_to_bt709_slice(values: &mut [f32]) {
160 for v in values.iter_mut() {
161 *v = crate::tf::linear_to_bt709(*v);
162 }
163}
164
165// ============================================================================
166// LUT converter (zero-cost const tables)
167// ============================================================================
168
169pub use crate::lut::SrgbConverter;