add RLEVerticalExt (16 bit run length support)
This commit is contained in:
parent
90f648e0b0
commit
62ee8a6efa
8 changed files with 77689 additions and 106875 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue