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
|
use crate::diff::diff;
use crate::split::split;
use crate::{Block, Frame, Ref, View};
pub fn encode(last_frame: &Frame, frame: &Frame, view: View) -> Block {
if view.size().area() > 1024 {
let [av, bv] = split(view);
return Block::Split([
Box::new(encode(last_frame, frame, av)),
Box::new(encode(last_frame, frame, bv)),
]);
}
let mut rp = Ref::default();
let mut d = diff([last_frame, frame], view, rp);
for _ in 0..500 {
let (nd, nrp) = optimize_ref(last_frame, frame, view, rp);
if nd < d {
rp = nrp;
d = nd;
} else {
break;
}
}
if d < 10000 {
return Block::Ref(rp);
} else {
Block::Lit(frame.export(view))
}
}
pub fn optimize_ref(last_frame: &Frame, frame: &Frame, view: View, rp: Ref) -> (u32, Ref) {
[
rp.apply(|r| r.pos_off.x += 1),
rp.apply(|r| r.pos_off.x -= 1),
rp.apply(|r| r.pos_off.y += 1),
rp.apply(|r| r.pos_off.y -= 1),
rp.apply(|r| r.color_off.r += 10),
rp.apply(|r| r.color_off.r -= 10),
rp.apply(|r| r.color_off.g += 10),
rp.apply(|r| r.color_off.g -= 10),
rp.apply(|r| r.color_off.b += 10),
rp.apply(|r| r.color_off.b -= 10),
]
.map(|p| (diff([last_frame, frame], view, p), p))
.into_iter()
.min_by_key(|x| x.0)
.unwrap()
}
|