1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! The reconstruction algorithms: features and motion evidence, region and layer learning, tracking, the pose
//! graph, compositing with temporal conflicts, reveal, framing and the preview pyramid, plus the YUV→RGBA and PNG
//! row kernels.
//!
//! Every pixel algorithm lives here, with no FFI and no I/O. The browser reaches it through the `extern "C"`
//! exports of `long-screen-wasm` (rust/wasm), compiled three ways: scalar, SIMD128 and SIMD128 + shared-memory
//! threads (see scripts/build-core.sh). The TypeScript side owns browser APIs only (decoding, storage, UI); it must
//! not reimplement anything this module provides.
//!
//! This is an implementation layer, used by the [`engine`](crate::engine), the driver and the web page; most users
//! want the driver at the crate root. Its API follows what those layers need and may change in minor versions.
//! With the `rayon` feature, `pool::par_for` chunks run on rayon's thread pool; results do not depend on the thread
//! count, and the WebAssembly builds leave it off.
//!
//! Check a candidate motion between two grayscale frames: the second frame is the first one scrolled up by 8
//! pixels, and the retained block error is near zero only for the right displacement.
//!
//! ```
//! use long_screen::kernels::motion::{verify_translation, Gray};
//!
//! let (width, height) = (192, 192);
//! let texture = |x: usize, y: usize| ((x * 37 + y * 101 + (x * y) % 23) % 251) as u8;
//! let a: Vec<u8> = (0..height).flat_map(|y| (0..width).map(move |x| texture(x, y))).collect();
//! let b: Vec<u8> = (0..height).flat_map(|y| (0..width).map(move |x| texture(x, y + 8))).collect();
//! let a = Gray { width, height, data: &a };
//! let b = Gray { width, height, data: &b };
//!
//! let right = verify_translation(a, b, 0.0, 8.0, None);
//! let wrong = verify_translation(a, b, 0.0, 0.0, None);
//! println!("error at the right shift {right:.2}, without it {wrong:.2}");
//! assert!(right < wrong);
//! ```