linear_srgb/
default.rs

1//! Recommended API for sRGB ↔ linear conversion.
2//!
3//! This module provides the optimal implementation for each use case:
4//!
5//! - **Single values**: Scalar functions (SIMD overhead not worthwhile)
6//! - **Slices**: SIMD-accelerated with runtime CPU dispatch
7//! - **x8 batches**: SIMD with dispatch (`_dispatch`) or inlineable (`_inline`)
8//!
9//! # Quick Start
10//!
11//! ```rust
12//! use linear_srgb::default::{srgb_to_linear, linear_to_srgb};
13//!
14//! // Single value conversion
15//! let linear = srgb_to_linear(0.5);
16//! let srgb = linear_to_srgb(linear);
17//! ```
18//!
19//! # Batch Processing
20//!
21//! ```rust
22//! use linear_srgb::default::{srgb_to_linear_slice, linear_to_srgb_slice};
23//!
24//! let mut values = vec![0.5f32; 10000];
25//! srgb_to_linear_slice(&mut values);  // SIMD-accelerated
26//! linear_to_srgb_slice(&mut values);
27//! ```
28//!
29//! # x8 SIMD Functions
30//!
31//! For manual SIMD control, use the x8 functions:
32//!
33//! - `*_x8` - Default with CPU dispatch (standalone use)
34//! - [`inline`] module - `#[inline(always)]` variants for use inside your own `#[multiversed]` code
35//!
36//! ```rust
37//! use linear_srgb::default::{linear_to_srgb_x8, linear_to_srgb_u8_x8};
38//! use wide::f32x8;
39//!
40//! let linear = f32x8::splat(0.214);
41//! let srgb = linear_to_srgb_x8(linear);  // CPU dispatch
42//! let srgb_u8 = linear_to_srgb_u8_x8(linear);
43//! ```
44//!
45//! For use inside `#[multiversed]` functions (no dispatch overhead):
46//! ```rust,ignore
47//! use linear_srgb::default::inline::*;
48//! ```
49
50// ============================================================================
51// Single-value functions (scalar - best for individual values)
52// ============================================================================
53
54pub use crate::scalar::{
55    // Custom gamma (pure power function)
56    gamma_to_linear,
57    gamma_to_linear_f64,
58    linear_to_gamma,
59    linear_to_gamma_f64,
60    // f32 sRGB
61    linear_to_srgb,
62    linear_to_srgb_extended,
63    // f64 sRGB (high precision)
64    linear_to_srgb_f64,
65    linear_to_srgb_u8,
66    srgb_to_linear,
67    srgb_to_linear_extended,
68    srgb_to_linear_f64,
69};
70
71// u8 → f32 uses LUT (20x faster than scalar powf)
72pub use crate::simd::srgb_u8_to_linear;
73
74// ============================================================================
75// Slice functions (SIMD with dispatch - best for batches)
76// ============================================================================
77
78pub use crate::simd::{
79    // Custom gamma slices
80    gamma_to_linear_slice,
81    // f32x8 slices (for pre-aligned SIMD data)
82    gamma_to_linear_x8_slice,
83    linear_to_gamma_slice,
84    linear_to_gamma_x8_slice,
85    // f32 slices (in-place)
86    linear_to_srgb_slice,
87    // u8 ↔ f32 slices
88    linear_to_srgb_u8_slice,
89    linear_to_srgb_x8_slice,
90    srgb_to_linear_slice,
91    srgb_to_linear_x8_slice,
92    srgb_u8_to_linear_slice,
93};
94
95// ============================================================================
96// x8 SIMD functions with CPU dispatch (default)
97// ============================================================================
98
99pub use crate::simd::{
100    // Custom gamma x8 with dispatch
101    gamma_to_linear_x8_dispatch as gamma_to_linear_x8,
102    linear_to_gamma_x8_dispatch as linear_to_gamma_x8,
103    // sRGB x8 with dispatch
104    linear_to_srgb_u8_x8_dispatch as linear_to_srgb_u8_x8,
105    linear_to_srgb_x8_dispatch as linear_to_srgb_x8,
106    srgb_to_linear_x8_dispatch as srgb_to_linear_x8,
107    // u8 x8 (LUT-based, no dispatch needed)
108    srgb_u8_to_linear_x8,
109};
110
111// ============================================================================
112// LUT converter (zero-cost const tables)
113// ============================================================================
114
115pub use crate::lut::SrgbConverter;
116
117pub mod inline {
118    //! Dispatch-free inline variants for use inside `#[multiversed]` functions.
119    //!
120    //! When building your own SIMD-accelerated functions with `multiversed`,
121    //! use these `_inline` variants to avoid nested dispatch overhead.
122    //! These functions are `#[inline(always)]` and contain no dispatch overhead.
123    //!
124    //! # Example
125    //!
126    //! ```rust,ignore
127    //! use linear_srgb::default::inline::*;
128    //! use multiversed::multiversed;
129    //! use wide::f32x8;
130    //!
131    //! #[multiversed]  // Your function handles dispatch
132    //! pub fn process_pixels(data: &mut [f32]) {
133    //!     for chunk in data.chunks_exact_mut(8) {
134    //!         let v = f32x8::from([
135    //!             chunk[0], chunk[1], chunk[2], chunk[3],
136    //!             chunk[4], chunk[5], chunk[6], chunk[7],
137    //!         ]);
138    //!         // Use inline variants - no dispatch, just raw SIMD
139    //!         let linear = srgb_to_linear_x8(v);
140    //!         let processed = linear * f32x8::splat(1.5);
141    //!         let result = linear_to_srgb_x8(processed);
142    //!         let arr: [f32; 8] = result.into();
143    //!         chunk.copy_from_slice(&arr);
144    //!     }
145    //! }
146    //! ```
147
148    // Re-export inline x8 functions with clean names (no _inline suffix)
149    pub use crate::simd::{
150        gamma_to_linear_x8_inline as gamma_to_linear_x8,
151        linear_to_gamma_x8_inline as linear_to_gamma_x8,
152        linear_to_srgb_u8_x8_inline as linear_to_srgb_u8_x8,
153        linear_to_srgb_x8_inline as linear_to_srgb_x8,
154        srgb_to_linear_x8_inline as srgb_to_linear_x8,
155    };
156
157    // Re-export inline x8 slice functions with clean names (no _inline suffix)
158    pub use crate::simd::{
159        gamma_to_linear_x8_slice_inline as gamma_to_linear_x8_slice,
160        linear_to_gamma_x8_slice_inline as linear_to_gamma_x8_slice,
161        linear_to_srgb_x8_slice_inline as linear_to_srgb_x8_slice,
162        srgb_to_linear_x8_slice_inline as srgb_to_linear_x8_slice,
163    };
164}