init
This commit is contained in:
commit
eca5344c66
10 changed files with 445 additions and 0 deletions
90
encoder/src/main.rs
Normal file
90
encoder/src/main.rs
Normal file
|
@ -0,0 +1,90 @@
|
|||
mod dec;
|
||||
mod enc;
|
||||
mod util;
|
||||
pub use util::*;
|
||||
|
||||
const INTERACTIVE: bool = false;
|
||||
|
||||
fn main() {
|
||||
let frames = get_all_frames("../video/frames/");
|
||||
let encoded = encode(&frames);
|
||||
println!("{} frames, total {} bytes", frames.len(), encoded.len());
|
||||
//
|
||||
}
|
||||
|
||||
fn encode(frames: &[Frame]) -> Vec<u8> {
|
||||
let mut out = Vec::new();
|
||||
let encodings: Vec<(FrameEncoder, FrameDecoder)> = vec![
|
||||
(enc::fill_white, dec::fill_white),
|
||||
(enc::fill_black, dec::fill_black),
|
||||
(enc::rle_horizontal, dec::rle_horizontal),
|
||||
(enc::rle_vertical, dec::rle_vertical),
|
||||
];
|
||||
let max_error = 0;
|
||||
|
||||
let mut last_frame = FRAME_0;
|
||||
for frame in frames {
|
||||
let mut options = Vec::new();
|
||||
for (encode, decode) in &encodings {
|
||||
let encoded = encode(&last_frame, frame);
|
||||
let decoded = decode(&last_frame, &encoded.data);
|
||||
let error = frame_error(frame, &decoded);
|
||||
if error <= max_error {
|
||||
options.push(encoded);
|
||||
}
|
||||
}
|
||||
options.sort_by_key(|b| b.data.len());
|
||||
let best_encoding = options.into_iter().next().unwrap();
|
||||
if INTERACTIVE {
|
||||
println!();
|
||||
println!(
|
||||
"{:?}, {} bytes",
|
||||
best_encoding.encoding,
|
||||
best_encoding.data.len() + 1
|
||||
);
|
||||
render_image(frame);
|
||||
let mut a = String::new();
|
||||
std::io::stdin().read_line(&mut a).unwrap();
|
||||
}
|
||||
let best_encoding = best_encoding.into_bytes();
|
||||
out.extend_from_slice(&best_encoding);
|
||||
last_frame = frame.clone();
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(u8)]
|
||||
enum Encoding {
|
||||
FillWhite,
|
||||
FillBlack,
|
||||
RLEHorizontal,
|
||||
RLEVertical,
|
||||
BGStrips,
|
||||
CellDiff8Horizontal,
|
||||
CellDiff8Vertical,
|
||||
CellDiff4HH,
|
||||
CellDiff4HV,
|
||||
CellDiff4VH,
|
||||
CellDiff4VV,
|
||||
}
|
||||
type FrameEncoder = fn(previous_frame: &Frame, new_frame: &Frame) -> EncodedFrame;
|
||||
type FrameDecoder = fn(previous_frame: &Frame, encoded_bytes: &[u8]) -> Frame;
|
||||
|
||||
struct EncodedFrame {
|
||||
encoding: Encoding,
|
||||
head_u4: u8,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl EncodedFrame {
|
||||
fn into_bytes(self) -> Vec<u8> {
|
||||
let head = (self.encoding as u8) << 4;
|
||||
let head = head | (self.head_u4 & 15);
|
||||
|
||||
let mut out = Vec::with_capacity(self.data.len() + 1);
|
||||
out.push(head);
|
||||
out.extend(self.data.into_iter());
|
||||
out
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue