aboutsummaryrefslogtreecommitdiff
path: root/lvc/src/diff.rs
blob: 5c65c290d360b9e270954c241bb4d460d635d45b (plain)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use crate::{Frame, Ref, View, P2};
use std::simd::{i32x16, SimdInt};

// 4ms
pub fn diff([frame1, frame2]: [&Frame; 2], view: View, rp: Ref) -> u32 {
    let mut k = 0;
    for y in view.a.y..view.b.y {
        for x in view.a.x..view.b.x {
            let p1 = frame1[P2 { x, y }] + rp.color_off;
            let p2 = frame2[P2 { x, y }];
            k += p1.r.abs_diff(p2.r) as u32
                + p1.g.abs_diff(p2.g) as u32
                + p1.b.abs_diff(p2.b) as u32;
        }
    }
    k
}

pub fn fast_diff([frame1, frame2]: [&Frame; 2], view: View, rp: Ref) -> u32 {
    let mut k = 0;

    let mut diff_lanes = i32x16::from_array([0; 16]);
    let mut k1 = [0; 16];
    let mut k2 = [0; 16];

    let next_line = frame1.size.x as usize - view.size().x as usize;
    let index_start = view.a.x as usize + view.a.y as usize * frame1.size.x as usize;
    let index_end = view.b.x as usize + (view.b.y as usize - 1) * frame1.size.x as usize;

    let mut i = index_start;
    let mut x = view.a.x;
    let mut kfill = 0;

    while i < index_end {
        k1[kfill] = frame1.pixels[i].r as i32;
        k2[kfill] = frame2.pixels[i].r as i32;
        kfill += 1;
        k1[kfill] = frame1.pixels[i].g as i32;
        k2[kfill] = frame2.pixels[i].g as i32;
        kfill += 1;
        k1[kfill] = frame1.pixels[i].b as i32;
        k2[kfill] = frame2.pixels[i].b as i32;
        kfill += 1;

        i += 1;
        x += 1;
        if x > view.b.x {
            i += next_line;
            x = view.a.x
        }

        if kfill == 15 {
            let pl1 = i32x16::from_array(k1);
            let pl2 = i32x16::from_array(k2);
            diff_lanes += (pl1 - pl2).abs();
            kfill = 0;
        }
    }

    return diff_lanes.reduce_sum() as u32;
}

// pub fn fast_diff([frame1, frame2]: [&Frame; 2], view: View, rp: Ref) -> u32 {
//     let mut k = 0;

//     let mut diff_lanes = i32x16::from_array([0; 16]);
//     let mut k1 = [0; 16];
//     let mut k2 = [0; 16];

//     let next_line = frame1.size.x as usize - view.size().x as usize;
//     let index_start = view.a.x as usize + view.a.y as usize * frame1.size.x as usize;
//     let index_end = view.b.x as usize + (view.b.y as usize - 1) * frame1.size.x as usize;

//     let mut i = index_start;
//     let mut x = view.a.x;
//     let mut kfill = 0;

//     while i < index_end {
//         k1[kfill] = frame1.pixels[i].r as i32;
//         k2[kfill] = frame2.pixels[i].r as i32;
//         kfill += 1;
//         k1[kfill] = frame1.pixels[i].g as i32;
//         k2[kfill] = frame2.pixels[i].g as i32;
//         kfill += 1;
//         k1[kfill] = frame1.pixels[i].b as i32;
//         k2[kfill] = frame2.pixels[i].b as i32;
//         kfill += 1;

//         i += 1;
//         x += 1;
//         if x > view.b.x {
//             i += next_line;
//             x = view.a.x
//         }

//         if kfill == 15 {
//             let pl1 = i32x16::from_array(k1);
//             let pl2 = i32x16::from_array(k2);
//             diff_lanes += (pl1 - pl2).abs();
//             kfill = 0;
//         }
//     }

//     return diff_lanes.reduce_sum() as u32;
// }