Skip to content

Commit bf2c194

Browse files
committed
Merge branch 'master' into portable_simd
2 parents 34d3a86 + f9d3e65 commit bf2c194

File tree

2 files changed

+74
-101
lines changed

2 files changed

+74
-101
lines changed

rustfmt.toml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
max_width = 120

src/lib.rs

+73-101
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,35 @@ where
152152
}
153153
.select(x(), y())
154154
}
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()
155184
}
156185

157186
// ### CONSTS ### {{{
@@ -822,12 +851,7 @@ pub fn convert_space_sliced(from: Space, to: Space, pixels: &mut [f32]) {
822851
///
823852
/// Returns 0 on success, 1 on invalid `from`, 2 on invalid `to`, 3 on invalid `pixels`
824853
#[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 {
831855
let from = unsafe {
832856
if from.is_null() {
833857
return 1;
@@ -873,13 +897,7 @@ pub extern "C" fn convert_space_ffi(
873897

874898
/// Same as `convert_space`, ignores the 4th value in `pixel`.
875899
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()) }
883901
}
884902

885903
// ### Convert Space ### }}}
@@ -924,14 +942,10 @@ pub fn str2col(mut s: &str) -> Option<(Space, [f32; 3])> {
924942
let seps = [',', ':', ';'];
925943

926944
// 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)) {
930946
if let Ok(sp) = Space::try_from(&s[..i]) {
931947
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)));
935949
}
936950
}
937951

@@ -1523,11 +1537,7 @@ mod tests {
15231537
pix_cmp(&input, reference, epsilon, skips);
15241538
}
15251539

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])) {
15311541
func_cmp_full(input, reference, function, 1e-3, &[])
15321542
}
15331543

@@ -1544,20 +1554,8 @@ mod tests {
15441554
pix_cmp(&input, reference, epsilon, skips)
15451555
}
15461556

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])
15611559
}
15621560
// ### Comparison FNs ### }}}
15631561

@@ -1570,8 +1568,7 @@ mod tests {
15701568
#[test]
15711569
fn irgb_from() {
15721570
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);
15751572
assert_eq!([0.2, 0.35, 0.95], srgb)
15761573
}
15771574

@@ -1748,6 +1745,27 @@ mod tests {
17481745
assert_eq!(pixels, smol);
17491746
}
17501747

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+
17511769
#[test]
17521770
fn nan_checks() {
17531771
let it = [1e+3, -1e+3, 1e-3, -1e-3];
@@ -1817,10 +1835,7 @@ mod tests {
18171835
// ### Str2Col ### {{{
18181836
#[test]
18191837
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])))
18241839
}
18251840

18261841
#[test]
@@ -1830,10 +1845,7 @@ mod tests {
18301845

18311846
#[test]
18321847
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])))
18371849
}
18381850

18391851
#[test]
@@ -1843,26 +1855,17 @@ mod tests {
18431855

18441856
#[test]
18451857
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])))
18501859
}
18511860

18521861
#[test]
18531862
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])))
18581864
}
18591865

18601866
#[test]
18611867
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])))
18661869
}
18671870

18681871
#[test]
@@ -1887,50 +1890,32 @@ mod tests {
18871890

18881891
#[test]
18891892
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])))
18941894
}
18951895

18961896
#[test]
18971897
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])))
19021899
}
19031900

19041901
#[test]
19051902
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])))
19101904
}
19111905

19121906
#[test]
19131907
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])))
19181909
}
19191910

19201911
#[test]
19211912
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])))
19261914
}
19271915

19281916
#[test]
19291917
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])))
19341919
}
19351920

19361921
#[test]
@@ -1952,11 +1937,7 @@ mod tests {
19521937
str2col("oklch 100% 100% 100%"),
19531938
Some((
19541939
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]
19601941
))
19611942
)
19621943
}
@@ -1982,11 +1963,7 @@ mod tests {
19821963
str2col("oklch 0% 0% 0%"),
19831964
Some((
19841965
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]
19901967
))
19911968
)
19921969
}
@@ -1997,11 +1974,7 @@ mod tests {
19971974
str2col("oklab 0.5 100.000% 0%"),
19981975
Some((
19991976
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]]
20051978
))
20061979
)
20071980
}
@@ -2023,8 +1996,7 @@ mod tests {
20231996

20241997
#[test]
20251998
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");
20282000
let reference = [1.00000000, 0.00000000, 0.00000000];
20292001
pix_cmp(&[pix], &[reference], 1e-3, &[]);
20302002
}

0 commit comments

Comments
 (0)