add RLEVerticalExt (16 bit run length support)

This commit is contained in:
Crispy 2025-06-16 23:46:01 +02:00
parent 90f648e0b0
commit 62ee8a6efa
8 changed files with 77689 additions and 106875 deletions

View file

@ -1,6 +1,6 @@
use crate::*;
pub fn cell_diff_4_vertical_small(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
pub fn cell_diff_4_vertical(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
const CELLS_X: usize = WIDTH / 4;
const CELLS_Y: usize = HEIGHT / 4;
@ -126,7 +126,6 @@ pub fn bg_strips_horizontal24(_prev_frame: &Frame, encoded: &[u8], reader: &mut
frame
}
pub fn rle_diff_horizontal(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
let (runs, decoded) = rle_255_decode(encoded, FRAME_SIZE);
*reader += runs;
@ -187,6 +186,41 @@ pub fn rle_vertical(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) ->
frame
}
pub fn rle_vertical_ext(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
let mut x = 0;
let mut y = 0;
let mut color = 0;
let mut i = 0;
let mut frame = FRAME_0;
while x < WIDTH {
let byte = encoded[i];
i += 1;
let mut run = byte as u16;
if byte == 0 && encoded[i] == 0 {
// 16 bit run length
let upper = (encoded[i+1] as u16) << 8;
if upper > 0{
let lower = encoded[i + 2] as u16;
i += 3;
run = upper | lower;
}
}
for _ in 0..run {
frame[x][y] = color;
y += 1;
if y == HEIGHT {
y = 0;
x += 1;
}
}
color = 1 - color;
}
*reader += i;
frame
}
pub fn fill_white(_prev_frame: &Frame, _encoded: &[u8], _reader: &mut usize) -> Frame {
FRAME_1
}

View file

@ -1,6 +1,6 @@
use crate::*;
pub fn cell_diff_4_vertical_small(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
pub fn cell_diff_4_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
let loss = loss / 4;
const CELLS_X: usize = WIDTH / 4;
const CELLS_Y: usize = HEIGHT / 4;
@ -48,7 +48,7 @@ pub fn cell_diff_4_vertical_small(prev_frame: &Frame, frame: &Frame, loss: usize
data.extend_from_slice(&rle_255_encode(&changed_pixels));
EncodedFrame {
encoding: Encoding::CellDiff4VV_small,
encoding: Encoding::CellDiff4VV,
data,
}
}
@ -306,6 +306,48 @@ pub fn rle_vertical(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
}
}
pub fn rle_vertical_ext(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
let mut data = Vec::new();
let mut last_pixel = 0;
let mut run: u16 = 0;
let push_run = |data: &mut Vec<u8>, run| {
if run < 256 {
data.push(run as u8);
} else {
// double zero to mark 16 bit run length
// if data.last() != Some(&0) {
// }
data.push(0);
data.push(0);
data.push((run >> 8) as u8);
data.push((run & 0xff) as u8);
}
};
for x in 0..WIDTH {
for y in 0..HEIGHT {
let pixel = frame[x][y];
if pixel != last_pixel || run == 0xffff {
push_run(&mut data, run);
if run == 0xffff && pixel == last_pixel {
// inserting dummy run because we ran out of max len
data.push(0);
}
run = 1;
} else {
run += 1;
}
last_pixel = pixel;
}
}
push_run(&mut data, run);
EncodedFrame {
encoding: Encoding::RLEVerticalExt,
data,
}
}
pub fn fill_white(_prev_frame: &Frame, _frame: &Frame, _loss: usize) -> EncodedFrame {
EncodedFrame {
encoding: Encoding::FillWhite,

View file

@ -16,17 +16,18 @@ const MAX_LOSS: usize = 16; // highest "loss" value tried for all lossy encoding
const LOSSLESS_ENCODINGS: &[FrameEncoder] = &[
enc::rle_horizontal,
enc::rle_vertical,
enc::rle_diff_horizontal,
enc::rle_diff_vertical,
enc::rle_vertical_ext,
// enc::rle_diff_horizontal,
// enc::rle_diff_vertical,
// enc::bg_strips_horizontal_16, // only works for the tiny display
// enc::bg_strips_horizontal_24, // intended for the 240x320 display
];
enc::bg_strips_horizontal_24, // intended for the 240x320 display
];
const LOSSY_ENCODINGS: &[FrameEncoderLossy] = &[
enc::fill_white,
enc::fill_black,
// todo: adapt these for big display
// todo: adapt for big display
// enc::cell_diff_8_vertical,
// enc::cell_diff_4_vertical_small,
// enc::cell_diff_4_vertical,
];
fn main() {
@ -80,6 +81,7 @@ fn main() {
}
export_string += "} Encoding_t;\n\n";
export_string += "const unsigned char video[] = {";
// export_string += &format!("const unsigned char video[{}] = {{", encoded.len());
let mut i = 99;
for byte in encoded {
if i > 15 {
@ -108,7 +110,9 @@ fn encode(frames: &[Frame]) -> Vec<u8> {
options.push(encoded);
} else {
dbg!(&encoded);
eprintln!("{:?}, error: {error}, frame: {_i}", encoded.encoding);
println!("{:?}, error: {error}, frame: {_i}", encoded.encoding);
println!("original | decoded");
render_images(&frame, &decoded);
panic!("error in lossless compression");
}
@ -161,6 +165,7 @@ enum Encoding {
FillWhite,
RLEHorizontal,
RLEVertical,
RLEVerticalExt,
RLEDiffHorizontal,
RLEDiffVertical,
BGStripsH16,
@ -173,7 +178,7 @@ enum Encoding {
// CellDiff4HH,
// CellDiff4HV,
// CellDiff4VH,
CellDiff4VV_small,
CellDiff4VV,
// CellDiff4VV_large,
}
@ -183,6 +188,7 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
Encoding::FillBlack => dec::fill_black,
Encoding::RLEHorizontal => dec::rle_horizontal,
Encoding::RLEVertical => dec::rle_vertical,
Encoding::RLEVerticalExt => dec::rle_vertical_ext,
Encoding::RLEDiffHorizontal => dec::rle_diff_horizontal,
Encoding::RLEDiffVertical => dec::rle_diff_vertical,
Encoding::BGStripsH16 => dec::bg_strips_horizontal16,
@ -195,8 +201,7 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
// Encoding::CellDiff4HH => todo!(),
// Encoding::CellDiff4HV => todo!(),
// Encoding::CellDiff4VH => todo!(),
Encoding::CellDiff4VV_small => dec::cell_diff_4_vertical_small,
// Encoding::CellDiff4VV_large => dec::cell_diff_4_vertical_large,
Encoding::CellDiff4VV => dec::cell_diff_4_vertical,
}
}

View file

@ -1,121 +0,0 @@
BGStripsH24, error: 868, frame: 14
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ▀█████| ▀█████|
| █████| █████|
| █████| █████|
| █████| █████|
| █████| █████|
| █████| █████|
| █████| █████|
| █████| █████|
| █████| █████|
| █████| █████|
| █████| █████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ██████| ██████|
| ███████| ███████|
| ███████| ███████|
| ███████| ███████|
| ███████| ███████|
| ███████| ███████|
| ███████| ███████|
| ███████| ███████|
| ▄███████| ▄███████|
| ████████| ████████|
| ████████| ████████|
| ████████| ████████|
| ████████| ████████|
| ████████| ████████|
| ████████| ████████|
| ▄████████| ▄████████|
| █████████| █████████|
| █████████| █████████|
| █████████| █████████|
| █████████| █████████|
| ██████████| ██████████|
| ██████████| ██████████|
| ███████████| ███████████|
| ███████████| ███████████|
| ▄███████████| ▄███████████|
| ████████████| ████████████|
| ▄████████████| ▄████████████|
| █████████████| █████████████|
| ▄█████████████| ▄█████████████|
| ██████████████| ██████████████|
| ▄██████████████| ▄██████████████|
| ███████████████| ███████████████|
| ▄███████████████| ▄███████████████|
| ████████████████| ████████████████|
| ▄████████████████| ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀|
| █████████████████| |
| ▄█████████████████| |
| ██████████████████| |
| ▄██████████████████| |
| ███████████████████| |
| ███████████████████| |
| ███████████████████| |
| ███████████████████| |
| ▀██████████████████| |
| ██████████████████| |
| ██████████████████| |
| ██████████████████| |
| ██████████████████| |
| ██████████████████| |
| ██████████████████| |
| █ ██████████████████| |
| ██ ██████████████████| |
| ███ ██████████████████| |
| ▀▀█▄ ██████████████████| |
| ██████████████████| |
| ▀█████████████████| |
| ▀██████████████| |
| ▀▀██████████| |
| ▀▀██████| |
| ▀▀██| |
| ▀| |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |