add 8x8 cell partial update encoding

This commit is contained in:
Crispy 2024-04-12 17:27:50 +02:00
parent 1f61cebd50
commit b85cb52ce0
3 changed files with 83 additions and 4 deletions

View file

@ -1,5 +1,45 @@
use crate::*; use crate::*;
pub fn cell_diff_8_horizontal(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
let bitmap = {
*reader += 3;
let mut bitmap = (encoded[0] as u32) << 16;
bitmap |= (encoded[1] as u32) << 8;
bitmap | encoded[2] as u32
};
let encoded = &encoded[3..];
let mut frame = *prev_frame;
let changed_pixel_count = bitmap.count_ones() as usize * 8 * 8;
let (runs, new_pixels) = rle_255_decode_until(encoded, changed_pixel_count);
*reader += runs;
let cells_x = WIDTH / 8;
let cells_y = HEIGHT / 8;
let mut index = 0;
for celly in 0..cells_y {
for cellx in 0..cells_x {
let is_changed = (bitmap >> (cellx + cells_x * celly)) & 1;
if is_changed == 1 {
let pixels = &new_pixels[(index * 8 * 8)..((index + 1) * 8 * 8)];
let mut i = 0;
for dx in 0..8 {
for dy in 0..8 {
let x = cellx * 8 + dx;
let y = celly * 8 + dy;
frame[x][y] = pixels[i];
i += 1;
}
}
index += 1;
}
}
}
frame
}
pub fn bg_strips_horizontal(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame { pub fn bg_strips_horizontal(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
*reader += 1; *reader += 1;
let bg = encoded[0] >> 7; let bg = encoded[0] >> 7;

View file

@ -1,5 +1,43 @@
use crate::*; use crate::*;
pub fn cell_diff_8_horizontal(prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
let cells_x = WIDTH / 8;
let cells_y = HEIGHT / 8;
let loss = 0;
let mut bitmap: u32 = 0;
let mut changed_pixels = Vec::new();
for celly in 0..cells_y {
for cellx in 0..cells_x {
let mut changed = 0;
let mut cell_contents = Vec::new();
// todo try encoding the cells in frame space instead of one cell at a time
for dx in 0..8 {
for dy in 0..8 {
let x = cellx * 8 + dx;
let y = celly * 8 + dy;
let pixel = frame[x][y];
cell_contents.push(pixel);
if pixel != prev_frame[x][y] {
changed += 1;
}
}
}
if changed > loss {
bitmap |= 1 << (cellx + cells_x * celly);
changed_pixels.extend_from_slice(&cell_contents);
}
}
}
let mut data = vec![(bitmap >> 16) as u8, (bitmap >> 8) as u8, bitmap as u8];
data.extend_from_slice(&rle_255_encode(&changed_pixels));
EncodedFrame {
encoding: Encoding::CellDiff8H,
data,
}
}
pub fn bg_strips_horizontal(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame { pub fn bg_strips_horizontal(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
let bg = most_common_pixel(frame); let bg = most_common_pixel(frame);
fn pack_strip(x: usize, y: usize, width: usize) -> [u8; 2] { fn pack_strip(x: usize, y: usize, width: usize) -> [u8; 2] {

View file

@ -8,6 +8,7 @@ pub use util::*;
const INSPECT_ENC: bool = false; const INSPECT_ENC: bool = false;
const INSPECT_DEC: bool = false; const INSPECT_DEC: bool = false;
const MAX_ERROR: usize = 0;
fn main() { fn main() {
let frames = get_all_frames("../video/frames/"); let frames = get_all_frames("../video/frames/");
@ -56,8 +57,8 @@ fn encode(frames: &[Frame]) -> Vec<u8> {
enc::rle_diff_horizontal, enc::rle_diff_horizontal,
enc::rle_diff_vertical, enc::rle_diff_vertical,
enc::bg_strips_horizontal, enc::bg_strips_horizontal,
enc::cell_diff_8_horizontal,
]; ];
let max_error = 0;
let mut last_frame = FRAME_0; let mut last_frame = FRAME_0;
for (i, frame) in frames.iter().enumerate() { for (i, frame) in frames.iter().enumerate() {
@ -67,7 +68,7 @@ fn encode(frames: &[Frame]) -> Vec<u8> {
let decode = get_matching_decoder(encoded.encoding); let decode = get_matching_decoder(encoded.encoding);
let decoded = decode(&last_frame, &encoded.data, &mut 0); let decoded = decode(&last_frame, &encoded.data, &mut 0);
let error = frame_error(frame, &decoded); let error = frame_error(frame, &decoded);
if error <= max_error { if error <= MAX_ERROR {
options.push(encoded); options.push(encoded);
} else { } else {
// dbg!(&encoded); // dbg!(&encoded);
@ -108,7 +109,7 @@ enum Encoding {
// BGStripsV, // BGStripsV,
// QuadTree, // QuadTree,
// DrawCommands, // DrawCommands,
// CellDiff8H, CellDiff8H,
// CellDiff8V, // CellDiff8V,
// CellDiff4HH, // CellDiff4HH,
// CellDiff4HV, // CellDiff4HV,
@ -128,7 +129,7 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
// Encoding::BGStripsV => todo!(), // Encoding::BGStripsV => todo!(),
// Encoding::QuadTree => todo!(), // Encoding::QuadTree => todo!(),
// Encoding::DrawCommands => todo!(), // Encoding::DrawCommands => todo!(),
// Encoding::CellDiff8H => todo!(), Encoding::CellDiff8H => dec::cell_diff_8_horizontal,
// Encoding::CellDiff8V => todo!(), // Encoding::CellDiff8V => todo!(),
// Encoding::CellDiff4HH => todo!(), // Encoding::CellDiff4HH => todo!(),
// Encoding::CellDiff4HV => todo!(), // Encoding::CellDiff4HV => todo!(),