mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-11 12:46:47 +00:00
Integration: run retouch blur rows serially on wasm, for #5499
photocraft-algo declares rayon only for non-wasm targets; an unconditional rayon import broke the wasm build. Same cfg split as blur.rs.
This commit is contained in:
1 parent
d94c277566
commit
161d707c04
1 file changed
+42
-26
+42
-26
@@ -7,7 +7,6 @@
|
||||
//! "Protect Tones" works on luminance (scaling RGB so hue and saturation are kept, with gamut
|
||||
//! compression instead of per-channel clipping).
|
||||
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Tonal range targeted by Dodge/Burn.
|
||||
@@ -130,35 +129,43 @@ pub fn local_blur(data: &[f32], w: usize, h: usize, ch: usize, alpha: Option<usi
|
||||
let th = oh + 2 * r as usize;
|
||||
let stride = ow * ch;
|
||||
let mut tmp = vec![0.0f32; stride * th];
|
||||
tmp.par_chunks_mut(stride).enumerate().for_each_init(
|
||||
|| vec![0.0f32; (ow + 2 * r as usize) * ch],
|
||||
|row, (ty, dst)| {
|
||||
let y = (y0 as i32 + ty as i32 - r).clamp(0, h as i32 - 1) as usize;
|
||||
// Clamp and premultiply each source pixel once, rather than once for every kernel tap.
|
||||
for (rx, px) in row.chunks_exact_mut(ch).enumerate() {
|
||||
let x = (x0 as i32 + rx as i32 - r).clamp(0, w as i32 - 1) as usize;
|
||||
let i = (y * w + x) * ch;
|
||||
px.copy_from_slice(&data[i..i + ch]);
|
||||
if let Some(a) = alpha {
|
||||
let av = px[a];
|
||||
for (c, v) in px.iter_mut().enumerate() {
|
||||
if c != a {
|
||||
*v *= av;
|
||||
}
|
||||
let scratch = || vec![0.0f32; (ow + 2 * r as usize) * ch];
|
||||
let horizontal = |row: &mut Vec<f32>, (ty, dst): (usize, &mut [f32])| {
|
||||
let y = (y0 as i32 + ty as i32 - r).clamp(0, h as i32 - 1) as usize;
|
||||
// Clamp and premultiply each source pixel once, rather than once for every kernel tap.
|
||||
for (rx, px) in row.chunks_exact_mut(ch).enumerate() {
|
||||
let x = (x0 as i32 + rx as i32 - r).clamp(0, w as i32 - 1) as usize;
|
||||
let i = (y * w + x) * ch;
|
||||
px.copy_from_slice(&data[i..i + ch]);
|
||||
if let Some(a) = alpha {
|
||||
let av = px[a];
|
||||
for (c, v) in px.iter_mut().enumerate() {
|
||||
if c != a {
|
||||
*v *= av;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Contiguous accumulation can be vectorized for any channel layout. Each output still
|
||||
// sums the same products in the same kernel order as the scalar convolution.
|
||||
for (i, kv) in k.iter().enumerate() {
|
||||
for (d, s) in dst.iter_mut().zip(&row[i * ch..i * ch + stride]) {
|
||||
*d += s * kv;
|
||||
}
|
||||
}
|
||||
// Contiguous accumulation can be vectorized for any channel layout. Each output still
|
||||
// sums the same products in the same kernel order as the scalar convolution.
|
||||
for (i, kv) in k.iter().enumerate() {
|
||||
for (d, s) in dst.iter_mut().zip(&row[i * ch..i * ch + stride]) {
|
||||
*d += s * kv;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
use rayon::prelude::*;
|
||||
tmp.par_chunks_mut(stride).enumerate().for_each_init(scratch, horizontal);
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
let mut row = scratch();
|
||||
tmp.chunks_mut(stride).enumerate().for_each(|item| horizontal(&mut row, item));
|
||||
}
|
||||
let mut out = vec![0.0f32; ow * oh * ch];
|
||||
out.par_chunks_mut(stride).enumerate().for_each(|(oy, dst)| {
|
||||
let vertical = |(oy, dst): (usize, &mut [f32])| {
|
||||
for (i, kv) in k.iter().enumerate() {
|
||||
for (d, s) in dst.iter_mut().zip(&tmp[(oy + i) * stride..(oy + i + 1) * stride]) {
|
||||
*d += s * kv;
|
||||
@@ -174,7 +181,16 @@ pub fn local_blur(data: &[f32], w: usize, h: usize, ch: usize, alpha: Option<usi
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
use rayon::prelude::*;
|
||||
out.par_chunks_mut(stride).enumerate().for_each(vertical);
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
out.chunks_mut(stride).enumerate().for_each(vertical);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user