@@ -152,6 +152,35 @@ where
152
152
}
153
153
. select ( x ( ) , y ( ) )
154
154
}
155
+
156
+ /// Create an array of separate channel buffers from a single interwoven buffer.
157
+ /// Copies the data.
158
+ pub fn unweave < const N : usize > ( slice : & [ f32 ] ) -> [ Box < [ f32 ] > ; N ] {
159
+ let len = slice. len ( ) / N ;
160
+ let mut result: [ Vec < f32 > ; N ] = ( 0 ..N )
161
+ . map ( |_| Vec :: with_capacity ( len) )
162
+ . collect :: < Vec < Vec < f32 > > > ( )
163
+ . try_into ( )
164
+ . unwrap ( ) ;
165
+
166
+ slice. chunks_exact ( N ) . for_each ( |chunk| {
167
+ chunk. iter ( ) . zip ( result. iter_mut ( ) ) . for_each ( |( v, arr) | arr. push ( * v) ) ;
168
+ } ) ;
169
+
170
+ result. map ( |v| v. into_boxed_slice ( ) )
171
+ }
172
+
173
+ /// Create a monolithic woven buffer using unwoven independent channel buffers.
174
+ /// Copies the data.
175
+ pub fn weave < const N : usize > ( array : [ Box < [ f32 ] > ; N ] ) -> Box < [ f32 ] > {
176
+ let len = array[ 0 ] . len ( ) ;
177
+ ( 0 ..len)
178
+ . into_iter ( )
179
+ . fold ( Vec :: with_capacity ( len * N ) , |mut acc, it| {
180
+ ( 0 ..N ) . into_iter ( ) . for_each ( |n| acc. push ( array[ n] [ it] ) ) ;
181
+ acc
182
+ } )
183
+ . into_boxed_slice ( )
155
184
}
156
185
157
186
// ### CONSTS ### {{{
@@ -822,12 +851,7 @@ pub fn convert_space_sliced(from: Space, to: Space, pixels: &mut [f32]) {
822
851
///
823
852
/// Returns 0 on success, 1 on invalid `from`, 2 on invalid `to`, 3 on invalid `pixels`
824
853
#[ no_mangle]
825
- pub extern "C" fn convert_space_ffi (
826
- from : * const c_char ,
827
- to : * const c_char ,
828
- pixels : * mut f32 ,
829
- len : usize ,
830
- ) -> i32 {
854
+ pub extern "C" fn convert_space_ffi ( from : * const c_char , to : * const c_char , pixels : * mut f32 , len : usize ) -> i32 {
831
855
let from = unsafe {
832
856
if from. is_null ( ) {
833
857
return 1 ;
@@ -873,13 +897,7 @@ pub extern "C" fn convert_space_ffi(
873
897
874
898
/// Same as `convert_space`, ignores the 4th value in `pixel`.
875
899
pub fn convert_space_alpha ( from : Space , to : Space , pixel : & mut [ f32 ; 4 ] ) {
876
- unsafe {
877
- convert_space (
878
- from,
879
- to,
880
- pixel. get_unchecked_mut ( 0 ..3 ) . try_into ( ) . unwrap_unchecked ( ) ,
881
- )
882
- }
900
+ unsafe { convert_space ( from, to, pixel. get_unchecked_mut ( 0 ..3 ) . try_into ( ) . unwrap_unchecked ( ) ) }
883
901
}
884
902
885
903
// ### Convert Space ### }}}
@@ -924,14 +942,10 @@ pub fn str2col(mut s: &str) -> Option<(Space, [f32; 3])> {
924
942
let seps = [ ',' , ':' , ';' ] ;
925
943
926
944
// Find Space at front then trim
927
- if let Some ( i) =
928
- s. find ( |c : char | c. is_whitespace ( ) || seps. contains ( & c) || [ '(' , '[' , '{' ] . contains ( & c) )
929
- {
945
+ if let Some ( i) = s. find ( |c : char | c. is_whitespace ( ) || seps. contains ( & c) || [ '(' , '[' , '{' ] . contains ( & c) ) {
930
946
if let Ok ( sp) = Space :: try_from ( & s[ ..i] ) {
931
947
space = sp;
932
- s = rm_paren (
933
- s[ i..] . trim_start_matches ( |c : char | c. is_whitespace ( ) || seps. contains ( & c) ) ,
934
- ) ;
948
+ s = rm_paren ( s[ i..] . trim_start_matches ( |c : char | c. is_whitespace ( ) || seps. contains ( & c) ) ) ;
935
949
}
936
950
}
937
951
@@ -1523,11 +1537,7 @@ mod tests {
1523
1537
pix_cmp ( & input, reference, epsilon, skips) ;
1524
1538
}
1525
1539
1526
- fn func_cmp (
1527
- input : & [ [ f32 ; 3 ] ] ,
1528
- reference : & [ [ f32 ; 3 ] ] ,
1529
- function : extern "C" fn ( & mut [ f32 ; 3 ] ) ,
1530
- ) {
1540
+ fn func_cmp ( input : & [ [ f32 ; 3 ] ] , reference : & [ [ f32 ; 3 ] ] , function : extern "C" fn ( & mut [ f32 ; 3 ] ) ) {
1531
1541
func_cmp_full ( input, reference, function, 1e-3 , & [ ] )
1532
1542
}
1533
1543
@@ -1544,20 +1554,8 @@ mod tests {
1544
1554
pix_cmp ( & input, reference, epsilon, skips)
1545
1555
}
1546
1556
1547
- fn conv_cmp (
1548
- input_space : Space ,
1549
- input : & [ [ f32 ; 3 ] ] ,
1550
- reference_space : Space ,
1551
- reference : & [ [ f32 ; 3 ] ] ,
1552
- ) {
1553
- conv_cmp_full (
1554
- input_space,
1555
- input,
1556
- reference_space,
1557
- reference,
1558
- 1e-2 ,
1559
- & [ 0 , 7 ] ,
1560
- )
1557
+ fn conv_cmp ( input_space : Space , input : & [ [ f32 ; 3 ] ] , reference_space : Space , reference : & [ [ f32 ; 3 ] ] ) {
1558
+ conv_cmp_full ( input_space, input, reference_space, reference, 1e-2 , & [ 0 , 7 ] )
1561
1559
}
1562
1560
// ### Comparison FNs ### }}}
1563
1561
@@ -1570,8 +1568,7 @@ mod tests {
1570
1568
#[ test]
1571
1569
fn irgb_from ( ) {
1572
1570
let mut srgb = irgb_to_srgb ( IRGB ) ;
1573
- srgb. iter_mut ( )
1574
- . for_each ( |c| * c = ( * c * 100.0 ) . round ( ) / 100.0 ) ;
1571
+ srgb. iter_mut ( ) . for_each ( |c| * c = ( * c * 100.0 ) . round ( ) / 100.0 ) ;
1575
1572
assert_eq ! ( [ 0.2 , 0.35 , 0.95 ] , srgb)
1576
1573
}
1577
1574
@@ -1748,6 +1745,27 @@ mod tests {
1748
1745
assert_eq ! ( pixels, smol) ;
1749
1746
}
1750
1747
1748
+ #[ test]
1749
+ fn interweave ( ) {
1750
+ let slice: Vec < f32 > = SRGB . iter ( ) . fold ( Vec :: new ( ) , |mut acc, it| {
1751
+ acc. extend_from_slice ( it) ;
1752
+ acc
1753
+ } ) ;
1754
+ let mut new = slice. clone ( ) ;
1755
+ new. push ( 1234.5678 ) ;
1756
+
1757
+ let deinterleaved = unweave :: < 3 > ( & new) ;
1758
+ assert_eq ! ( deinterleaved[ 0 ] . len( ) , deinterleaved[ 1 ] . len( ) ) ;
1759
+ assert_eq ! ( deinterleaved[ 0 ] . len( ) , deinterleaved[ 2 ] . len( ) ) ;
1760
+ let chunked: Vec < [ f32 ; 3 ] > = ( 0 ..deinterleaved[ 0 ] . len ( ) ) . fold ( Vec :: new ( ) , |mut acc, it| {
1761
+ acc. push ( [ deinterleaved[ 0 ] [ it] , deinterleaved[ 1 ] [ it] , deinterleaved[ 2 ] [ it] ] ) ;
1762
+ acc
1763
+ } ) ;
1764
+
1765
+ assert_eq ! ( SRGB , & chunked) ;
1766
+ assert_eq ! ( slice. as_slice( ) , weave( deinterleaved) . as_ref( ) )
1767
+ }
1768
+
1751
1769
#[ test]
1752
1770
fn nan_checks ( ) {
1753
1771
let it = [ 1e+3 , -1e+3 , 1e-3 , -1e-3 ] ;
@@ -1817,10 +1835,7 @@ mod tests {
1817
1835
// ### Str2Col ### {{{
1818
1836
#[ test]
1819
1837
fn str2col_base ( ) {
1820
- assert_eq ! (
1821
- str2col( "0.2, 0.5, 0.6" ) ,
1822
- Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) )
1823
- )
1838
+ assert_eq ! ( str2col( "0.2, 0.5, 0.6" ) , Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) ) )
1824
1839
}
1825
1840
1826
1841
#[ test]
@@ -1830,10 +1845,7 @@ mod tests {
1830
1845
1831
1846
#[ test]
1832
1847
fn str2col_base_lop ( ) {
1833
- assert_eq ! (
1834
- str2col( "0.2,0.5, 0.6" ) ,
1835
- Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) )
1836
- )
1848
+ assert_eq ! ( str2col( "0.2,0.5, 0.6" ) , Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) ) )
1837
1849
}
1838
1850
1839
1851
#[ test]
@@ -1843,26 +1855,17 @@ mod tests {
1843
1855
1844
1856
#[ test]
1845
1857
fn str2col_base_bare_fat ( ) {
1846
- assert_eq ! (
1847
- str2col( " 0.2 0.5 0.6 " ) ,
1848
- Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) )
1849
- )
1858
+ assert_eq ! ( str2col( " 0.2 0.5 0.6 " ) , Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) ) )
1850
1859
}
1851
1860
1852
1861
#[ test]
1853
1862
fn str2col_base_paren ( ) {
1854
- assert_eq ! (
1855
- str2col( "(0.2 0.5 0.6)" ) ,
1856
- Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) )
1857
- )
1863
+ assert_eq ! ( str2col( "(0.2 0.5 0.6)" ) , Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) ) )
1858
1864
}
1859
1865
1860
1866
#[ test]
1861
1867
fn str2col_base_paren2 ( ) {
1862
- assert_eq ! (
1863
- str2col( "{ 0.2 : 0.5 : 0.6 }" ) ,
1864
- Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) )
1865
- )
1868
+ assert_eq ! ( str2col( "{ 0.2 : 0.5 : 0.6 }" ) , Some ( ( Space :: SRGB , [ 0.2 , 0.5 , 0.6 ] ) ) )
1866
1869
}
1867
1870
1868
1871
#[ test]
@@ -1887,50 +1890,32 @@ mod tests {
1887
1890
1888
1891
#[ test]
1889
1892
fn str2col_lch ( ) {
1890
- assert_eq ! (
1891
- str2col( "lch(50, 30, 160)" ) ,
1892
- Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) )
1893
- )
1893
+ assert_eq ! ( str2col( "lch(50, 30, 160)" ) , Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) ) )
1894
1894
}
1895
1895
1896
1896
#[ test]
1897
1897
fn str2col_lch_space ( ) {
1898
- assert_eq ! (
1899
- str2col( "lch 50, 30, 160" ) ,
1900
- Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) )
1901
- )
1898
+ assert_eq ! ( str2col( "lch 50, 30, 160" ) , Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) ) )
1902
1899
}
1903
1900
1904
1901
#[ test]
1905
1902
fn str2col_lch_colon ( ) {
1906
- assert_eq ! (
1907
- str2col( "lch:50:30:160" ) ,
1908
- Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) )
1909
- )
1903
+ assert_eq ! ( str2col( "lch:50:30:160" ) , Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) ) )
1910
1904
}
1911
1905
1912
1906
#[ test]
1913
1907
fn str2col_lch_semicolon ( ) {
1914
- assert_eq ! (
1915
- str2col( "lch;50;30;160" ) ,
1916
- Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) )
1917
- )
1908
+ assert_eq ! ( str2col( "lch;50;30;160" ) , Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) ) )
1918
1909
}
1919
1910
1920
1911
#[ test]
1921
1912
fn str2col_lch_mixed ( ) {
1922
- assert_eq ! (
1923
- str2col( "lch; (50,30,160)" ) ,
1924
- Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) )
1925
- )
1913
+ assert_eq ! ( str2col( "lch; (50,30,160)" ) , Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) ) )
1926
1914
}
1927
1915
1928
1916
#[ test]
1929
1917
fn str2col_lch_mixed2 ( ) {
1930
- assert_eq ! (
1931
- str2col( "lch(50; 30; 160)" ) ,
1932
- Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) )
1933
- )
1918
+ assert_eq ! ( str2col( "lch(50; 30; 160)" ) , Some ( ( Space :: CIELCH , [ 50.0 , 30.0 , 160.0 ] ) ) )
1934
1919
}
1935
1920
1936
1921
#[ test]
@@ -1952,11 +1937,7 @@ mod tests {
1952
1937
str2col( "oklch 100% 100% 100%" ) ,
1953
1938
Some ( (
1954
1939
Space :: OKLCH ,
1955
- [
1956
- Space :: OKLCH . srgb_quant100( ) [ 0 ] ,
1957
- Space :: OKLCH . srgb_quant100( ) [ 1 ] ,
1958
- 360.0 ,
1959
- ]
1940
+ [ Space :: OKLCH . srgb_quant100( ) [ 0 ] , Space :: OKLCH . srgb_quant100( ) [ 1 ] , 360.0 ]
1960
1941
) )
1961
1942
)
1962
1943
}
@@ -1982,11 +1963,7 @@ mod tests {
1982
1963
str2col( "oklch 0% 0% 0%" ) ,
1983
1964
Some ( (
1984
1965
Space :: OKLCH ,
1985
- [
1986
- Space :: OKLCH . srgb_quant0( ) [ 0 ] ,
1987
- Space :: OKLCH . srgb_quant0( ) [ 1 ] ,
1988
- 0.0 ,
1989
- ]
1966
+ [ Space :: OKLCH . srgb_quant0( ) [ 0 ] , Space :: OKLCH . srgb_quant0( ) [ 1 ] , 0.0 ]
1990
1967
) )
1991
1968
)
1992
1969
}
@@ -1997,11 +1974,7 @@ mod tests {
1997
1974
str2col( "oklab 0.5 100.000% 0%" ) ,
1998
1975
Some ( (
1999
1976
Space :: OKLAB ,
2000
- [
2001
- 0.5 ,
2002
- Space :: OKLAB . srgb_quant100( ) [ 1 ] ,
2003
- Space :: OKLAB . srgb_quant0( ) [ 2 ] ,
2004
- ]
1977
+ [ 0.5 , Space :: OKLAB . srgb_quant100( ) [ 1 ] , Space :: OKLAB . srgb_quant0( ) [ 2 ] ]
2005
1978
) )
2006
1979
)
2007
1980
}
@@ -2023,8 +1996,7 @@ mod tests {
2023
1996
2024
1997
#[ test]
2025
1998
fn str2space_base ( ) {
2026
- let pix = str2space ( "oklch : 0.62792590, 0.25768453, 29.22319405" , Space :: SRGB )
2027
- . expect ( "STR2SPACE_BASE FAIL" ) ;
1999
+ let pix = str2space ( "oklch : 0.62792590, 0.25768453, 29.22319405" , Space :: SRGB ) . expect ( "STR2SPACE_BASE FAIL" ) ;
2028
2000
let reference = [ 1.00000000 , 0.00000000 , 0.00000000 ] ;
2029
2001
pix_cmp ( & [ pix] , & [ reference] , 1e-3 , & [ ] ) ;
2030
2002
}
0 commit comments