Skip to main content

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 `#[magetypes]` 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 `#[magetypes]` 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 (exact powf)
61    linear_to_srgb,
62    linear_to_srgb_extended,
63    // f64 sRGB (high precision)
64    linear_to_srgb_f64,
65    // f32 sRGB (fast polynomial, no powf)
66    linear_to_srgb_fast,
67    linear_to_srgb_u8,
68    // u16 sRGB (LUT-based)
69    linear_to_srgb_u16,
70    srgb_to_linear,
71    srgb_to_linear_extended,
72    srgb_to_linear_f64,
73    // f32 sRGB (fast polynomial, no powf)
74    srgb_to_linear_fast,
75    srgb_u16_to_linear,
76};
77
78// u8 → f32 uses LUT (20x faster than scalar powf)
79pub use crate::simd::srgb_u8_to_linear;
80
81// ============================================================================
82// Slice functions (SIMD with dispatch - best for batches)
83// ============================================================================
84
85pub use crate::simd::{
86    // Custom gamma slices
87    gamma_to_linear_slice,
88    // f32x8 slices (for pre-aligned SIMD data)
89    gamma_to_linear_x8_slice,
90    linear_to_gamma_slice,
91    linear_to_gamma_x8_slice,
92    // f32 slices (in-place)
93    linear_to_srgb_slice,
94    // u8 ↔ f32 slices
95    linear_to_srgb_u8_slice,
96    // u16 slices
97    linear_to_srgb_u16_slice,
98    linear_to_srgb_x8_slice,
99    srgb_to_linear_slice,
100    srgb_to_linear_x8_slice,
101    srgb_u8_to_linear_slice,
102    srgb_u16_to_linear_slice,
103};
104
105// ============================================================================
106// x8 SIMD functions with CPU dispatch (default)
107// ============================================================================
108
109pub use crate::simd::{
110    // Custom gamma x8 with dispatch
111    gamma_to_linear_x8_dispatch as gamma_to_linear_x8,
112    linear_to_gamma_x8_dispatch as linear_to_gamma_x8,
113    // sRGB x8 with dispatch
114    linear_to_srgb_u8_x8_dispatch as linear_to_srgb_u8_x8,
115    linear_to_srgb_x8_dispatch as linear_to_srgb_x8,
116    srgb_to_linear_x8_dispatch as srgb_to_linear_x8,
117    // u8 x8 (LUT-based, no dispatch needed)
118    srgb_u8_to_linear_x8,
119};
120
121// ============================================================================
122// LUT converter (zero-cost const tables)
123// ============================================================================
124
125pub use crate::lut::SrgbConverter;
126
127pub mod inline {
128    //! Dispatch-free inline variants for use inside `#[magetypes]` functions.
129    //!
130    //! When building your own SIMD-accelerated functions with `archmage`,
131    //! use these `_inline` variants to avoid nested dispatch overhead.
132    //! These functions are `#[inline(always)]` and contain no dispatch overhead.
133    //!
134    //! # Example
135    //!
136    //! ```rust,ignore
137    //! use linear_srgb::default::inline::*;
138    //! use archmage::magetypes;
139    //! use wide::f32x8;
140    //!
141    //! #[magetypes(v3)]  // Your function handles dispatch
142    //! fn process_pixels(_token: Token, data: &mut [f32]) {
143    //!     for chunk in data.chunks_exact_mut(8) {
144    //!         let v = f32x8::from([
145    //!             chunk[0], chunk[1], chunk[2], chunk[3],
146    //!             chunk[4], chunk[5], chunk[6], chunk[7],
147    //!         ]);
148    //!         // Use inline variants - no dispatch, just raw SIMD
149    //!         let linear = srgb_to_linear_x8(v);
150    //!         let processed = linear * f32x8::splat(1.5);
151    //!         let result = linear_to_srgb_x8(processed);
152    //!         let arr: [f32; 8] = result.into();
153    //!         chunk.copy_from_slice(&arr);
154    //!     }
155    //! }
156    //! ```
157
158    // Re-export inline x8 functions with clean names (no _inline suffix)
159    pub use crate::simd::{
160        gamma_to_linear_x8_inline as gamma_to_linear_x8,
161        linear_to_gamma_x8_inline as linear_to_gamma_x8,
162        linear_to_srgb_u8_x8_inline as linear_to_srgb_u8_x8,
163        linear_to_srgb_x8_inline as linear_to_srgb_x8,
164        srgb_to_linear_x8_inline as srgb_to_linear_x8,
165    };
166
167    // Re-export inline x8 slice functions with clean names (no _inline suffix)
168    pub use crate::simd::{
169        gamma_to_linear_x8_slice_inline as gamma_to_linear_x8_slice,
170        linear_to_gamma_x8_slice_inline as linear_to_gamma_x8_slice,
171        linear_to_srgb_x8_slice_inline as linear_to_srgb_x8_slice,
172        srgb_to_linear_x8_slice_inline as srgb_to_linear_x8_slice,
173    };
174}