@@ -14,6 +14,39 @@ fn spowf(n: f32, power: f32) -> f32 {
14
14
n. abs ( ) . powf ( power) . copysign ( n)
15
15
}
16
16
17
+ /// Create an array of separate channel buffers from a single interwoven buffer.
18
+ /// Copies the data.
19
+ pub fn unweave < const N : usize > ( slice : & [ f32 ] ) -> [ Box < [ f32 ] > ; N ] {
20
+ let len = slice. len ( ) / N ;
21
+ let mut result: [ Vec < f32 > ; N ] = ( 0 ..N )
22
+ . map ( |_| Vec :: with_capacity ( len) )
23
+ . collect :: < Vec < Vec < f32 > > > ( )
24
+ . try_into ( )
25
+ . unwrap ( ) ;
26
+
27
+ slice. chunks_exact ( N ) . for_each ( |chunk| {
28
+ chunk
29
+ . iter ( )
30
+ . zip ( result. iter_mut ( ) )
31
+ . for_each ( |( v, arr) | arr. push ( * v) ) ;
32
+ } ) ;
33
+
34
+ result. map ( |v| v. into_boxed_slice ( ) )
35
+ }
36
+
37
+ /// Create a monolithic woven buffer using unwoven independent channel buffers.
38
+ /// Copies the data.
39
+ pub fn weave < const N : usize > ( array : [ Box < [ f32 ] > ; N ] ) -> Box < [ f32 ] > {
40
+ let len = array[ 0 ] . len ( ) ;
41
+ ( 0 ..len)
42
+ . into_iter ( )
43
+ . fold ( Vec :: with_capacity ( len * N ) , |mut acc, it| {
44
+ ( 0 ..N ) . into_iter ( ) . for_each ( |n| acc. push ( array[ n] [ it] ) ) ;
45
+ acc
46
+ } )
47
+ . into_boxed_slice ( )
48
+ }
49
+
17
50
// ### CONSTS ### {{{
18
51
19
52
/// Standard Illuminant D65.
@@ -1592,6 +1625,31 @@ mod tests {
1592
1625
assert_eq ! ( pixels, smol) ;
1593
1626
}
1594
1627
1628
+ #[ test]
1629
+ fn interweave ( ) {
1630
+ let slice: Vec < f32 > = SRGB . iter ( ) . fold ( Vec :: new ( ) , |mut acc, it| {
1631
+ acc. extend_from_slice ( it) ;
1632
+ acc
1633
+ } ) ;
1634
+ let mut new = slice. clone ( ) ;
1635
+ new. push ( 1234.5678 ) ;
1636
+
1637
+ let deinterleaved = unweave :: < 3 > ( & new) ;
1638
+ assert_eq ! ( deinterleaved[ 0 ] . len( ) , deinterleaved[ 1 ] . len( ) ) ;
1639
+ assert_eq ! ( deinterleaved[ 0 ] . len( ) , deinterleaved[ 2 ] . len( ) ) ;
1640
+ let chunked: Vec < [ f32 ; 3 ] > = ( 0 ..deinterleaved[ 0 ] . len ( ) ) . fold ( Vec :: new ( ) , |mut acc, it| {
1641
+ acc. push ( [
1642
+ deinterleaved[ 0 ] [ it] ,
1643
+ deinterleaved[ 1 ] [ it] ,
1644
+ deinterleaved[ 2 ] [ it] ,
1645
+ ] ) ;
1646
+ acc
1647
+ } ) ;
1648
+
1649
+ assert_eq ! ( SRGB , & chunked) ;
1650
+ assert_eq ! ( slice. as_slice( ) , weave( deinterleaved) . as_ref( ) )
1651
+ }
1652
+
1595
1653
#[ test]
1596
1654
fn nan_checks ( ) {
1597
1655
let it = [ 1e+3 , -1e+3 , 1e-3 , -1e-3 ] ;
0 commit comments