Skip to content

Commit 9db9a05

Browse files
committed
Faster blur
1 parent 2d9fe0b commit 9db9a05

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

src/denoise.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,31 @@ macro_rules! median_channel {
270270
if $top.next.a > 0 { $top.next.$chan } else { $mid.curr.$chan },
271271
if $mid.prev.a > 0 { $mid.prev.$chan } else { $mid.curr.$chan },
272272
$mid.curr.$chan, // if the center pixel is transparent, the result won't be used
273-
$mid.curr.$chan, // more weight on the center
274273
if $mid.next.a > 0 { $mid.next.$chan } else { $mid.curr.$chan },
275274
if $bot.prev.a > 0 { $bot.prev.$chan } else { $mid.curr.$chan },
276275
if $bot.curr.a > 0 { $bot.curr.$chan } else { $mid.curr.$chan },
277276
if $bot.next.a > 0 { $bot.next.$chan } else { $mid.curr.$chan },
278-
].select_nth_unstable(5).1
277+
].select_nth_unstable(4).1
279278
}
280279
}
281280

281+
/// Average of 9 neighboring pixels
282+
macro_rules! blur_channel {
283+
($top:expr, $mid:expr, $bot:expr, $chan:ident) => {{
284+
let mut tmp = 0u16;
285+
tmp += u16::from(if $top.prev.a > 0 { $top.prev.$chan } else { $mid.curr.$chan });
286+
tmp += u16::from(if $top.curr.a > 0 { $top.curr.$chan } else { $mid.curr.$chan });
287+
tmp += u16::from(if $top.next.a > 0 { $top.next.$chan } else { $mid.curr.$chan });
288+
tmp += u16::from(if $mid.prev.a > 0 { $mid.prev.$chan } else { $mid.curr.$chan });
289+
tmp += u16::from($mid.curr.$chan); // if the center pixel is transparent, the result won't be used
290+
tmp += u16::from(if $mid.next.a > 0 { $mid.next.$chan } else { $mid.curr.$chan });
291+
tmp += u16::from(if $bot.prev.a > 0 { $bot.prev.$chan } else { $mid.curr.$chan });
292+
tmp += u16::from(if $bot.curr.a > 0 { $bot.curr.$chan } else { $mid.curr.$chan });
293+
tmp += u16::from(if $bot.next.a > 0 { $bot.next.$chan } else { $mid.curr.$chan });
294+
(tmp / 9) as u8
295+
}}
296+
}
297+
282298
pub(crate) fn smart_blur(frame: ImgRef<RGBA8>) -> ImgVec<RGB8> {
283299
let mut out = Vec::with_capacity(frame.width() * frame.height());
284300
loop9_img(frame, |_,_, top, mid, bot| {
@@ -288,7 +304,25 @@ pub(crate) fn smart_blur(frame: ImgRef<RGBA8>) -> ImgVec<RGB8> {
288304
let median_b = median_channel!(top, mid, bot, b);
289305

290306
let blurred = RGB8::new(median_r, median_g, median_b);
291-
// diff limit, because median removes thin lines too
307+
if color_diff(mid.curr.rgb(), blurred) < 16*16*6 {
308+
blurred
309+
} else {
310+
mid.curr.rgb()
311+
}
312+
} else { RGB8::new(255,0,255) });
313+
});
314+
ImgVec::new(out, frame.width(), frame.height())
315+
}
316+
317+
pub(crate) fn less_smart_blur(frame: ImgRef<RGBA8>) -> ImgVec<RGB8> {
318+
let mut out = Vec::with_capacity(frame.width() * frame.height());
319+
loop9_img(frame, |_,_, top, mid, bot| {
320+
out.push_in_cap(if mid.curr.a > 0 {
321+
let median_r = blur_channel!(top, mid, bot, r);
322+
let median_g = blur_channel!(top, mid, bot, g);
323+
let median_b = blur_channel!(top, mid, bot, b);
324+
325+
let blurred = RGB8::new(median_r, median_g, median_b);
292326
if color_diff(mid.curr.rgb(), blurred) < 16*16*6 {
293327
blurred
294328
} else {

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,14 +514,14 @@ impl Writer {
514514
}
515515

516516
fn make_resize(inputs: Receiver<CatResult<InputFrameUnresized>>, diff_queue: OrdQueue<InputFrame>, settings: &SettingsExt) -> CatResult<()> {
517-
minipool::new(settings.max_threads.min(if settings.s.fast { 6 } else { 4 }.try_into().unwrap()), "resize", move |to_remap| {
517+
minipool::new(settings.max_threads.min(if settings.s.fast || settings.extra_effort { 6 } else { 4 }.try_into().unwrap()), "resize", move |to_remap| {
518518
for frame in inputs {
519519
to_remap.send(frame?)?;
520520
}
521521
Ok(())
522522
}, move |frame| {
523523
let resized = resized_binary_alpha(frame.frame, settings.s.width, settings.s.height)?;
524-
let frame_blurred = smart_blur(resized.as_ref());
524+
let frame_blurred = if settings.extra_effort { smart_blur(resized.as_ref()) } else { less_smart_blur(resized.as_ref()) };
525525
diff_queue.push(frame.frame_index, InputFrame {
526526
frame: resized,
527527
frame_blurred,

0 commit comments

Comments
 (0)