add some more compression variations
This commit is contained in:
parent
62ee8a6efa
commit
a1bcf7d90b
4 changed files with 168 additions and 54 deletions
|
@ -51,6 +51,57 @@ pub fn cell_diff_4_vertical(prev_frame: &Frame, encoded: &[u8], reader: &mut usi
|
|||
frame
|
||||
}
|
||||
|
||||
pub fn cell_diff_8_vertical_big(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
|
||||
const CELLS_X: usize = WIDTH / 8;
|
||||
const CELLS_Y: usize = HEIGHT / 8;
|
||||
|
||||
let mut modified_cells = [[false; CELLS_Y]; CELLS_X];
|
||||
|
||||
let (mut cell_runs, modified_cells_flat) =
|
||||
rle_255_decode(&unpack_nybbles(encoded), CELLS_X * CELLS_Y);
|
||||
|
||||
if cell_runs % 2 == 1 {
|
||||
cell_runs += 1;
|
||||
}
|
||||
*reader += cell_runs / 2;
|
||||
let encoded = &encoded[(cell_runs / 2)..];
|
||||
|
||||
let mut changed_cell_count = 0;
|
||||
let mut i = 0;
|
||||
for cellx in 0..CELLS_X {
|
||||
for celly in 0..CELLS_Y {
|
||||
let cell = modified_cells_flat[i] == 1;
|
||||
modified_cells[cellx][celly] = cell;
|
||||
if cell {
|
||||
changed_cell_count += 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mut frame = *prev_frame;
|
||||
|
||||
let changed_pixel_count = changed_cell_count * 8 * 8;
|
||||
let (runs, new_pixels) = rle_255_decode(encoded, changed_pixel_count);
|
||||
*reader += runs;
|
||||
|
||||
let mut index = 0;
|
||||
|
||||
for x in 0..WIDTH {
|
||||
for y in 0..HEIGHT {
|
||||
let cellx = x / 8;
|
||||
let celly = y / 8;
|
||||
let is_changed = modified_cells[cellx][celly];
|
||||
if is_changed {
|
||||
frame[x][y] = new_pixels[index];
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frame
|
||||
}
|
||||
|
||||
pub fn cell_diff_8_vertical(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
|
||||
let bitmap = {
|
||||
*reader += 3;
|
||||
|
@ -83,7 +134,7 @@ pub fn cell_diff_8_vertical(prev_frame: &Frame, encoded: &[u8], reader: &mut usi
|
|||
frame
|
||||
}
|
||||
|
||||
pub fn bg_strips_horizontal16(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
|
||||
pub fn bg_strips_horizontal_16(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
|
||||
*reader += 1;
|
||||
let bg = encoded[0] >> 7;
|
||||
let fg = 1 - bg;
|
||||
|
@ -104,7 +155,7 @@ pub fn bg_strips_horizontal16(_prev_frame: &Frame, encoded: &[u8], reader: &mut
|
|||
frame
|
||||
}
|
||||
|
||||
pub fn bg_strips_horizontal24(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
|
||||
pub fn bg_strips_horizontal_24(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
|
||||
*reader += 2;
|
||||
let bg = encoded[0] >> 7;
|
||||
let fg = 1 - bg;
|
||||
|
@ -221,6 +272,34 @@ pub fn rle_vertical_ext(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize)
|
|||
frame
|
||||
}
|
||||
|
||||
pub fn rle_vertical_16(_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 upper = encoded[i] as u16;
|
||||
let lower = encoded[i+1] as u16;
|
||||
i += 2;
|
||||
|
||||
let run = (upper<<8) | 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
|
||||
}
|
||||
|
|
|
@ -53,58 +53,58 @@ pub fn cell_diff_4_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> E
|
|||
}
|
||||
}
|
||||
|
||||
// pub fn cell_diff_4_vertical_large(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
|
||||
// let loss = loss / 4;
|
||||
// const CELLS_X: usize = WIDTH / 4;
|
||||
// const CELLS_Y: usize = HEIGHT / 4;
|
||||
pub fn cell_diff_8_vertical_big(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
|
||||
let loss = loss / 8;
|
||||
const CELLS_X: usize = WIDTH / 8;
|
||||
const CELLS_Y: usize = HEIGHT / 8;
|
||||
|
||||
// let mut modified_cells = [[0; CELLS_Y]; CELLS_X];
|
||||
let mut modified_cells = [[0; CELLS_Y]; CELLS_X];
|
||||
|
||||
// for cellx in 0..CELLS_X {
|
||||
// for celly in 0..CELLS_Y {
|
||||
// let mut changed = 0;
|
||||
// for dx in 0..4 {
|
||||
// for dy in 0..4 {
|
||||
// let x = cellx * 4 + dx;
|
||||
// let y = celly * 4 + dy;
|
||||
// let pixel = frame[x][y];
|
||||
for cellx in 0..CELLS_X {
|
||||
for celly in 0..CELLS_Y {
|
||||
let mut changed = 0;
|
||||
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];
|
||||
|
||||
// if pixel != prev_frame[x][y] {
|
||||
// changed += 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if changed > loss {
|
||||
// modified_cells[cellx][celly] = 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// let mut changed_pixels = Vec::new();
|
||||
// for x in 0..WIDTH {
|
||||
// for y in 0..HEIGHT {
|
||||
// let cellx = x / 4;
|
||||
// let celly = y / 4;
|
||||
if pixel != prev_frame[x][y] {
|
||||
changed += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if changed > loss {
|
||||
modified_cells[cellx][celly] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut changed_pixels = Vec::new();
|
||||
for x in 0..WIDTH {
|
||||
for y in 0..HEIGHT {
|
||||
let cellx = x / 8;
|
||||
let celly = y / 8;
|
||||
|
||||
// if modified_cells[cellx][celly] != 0 {
|
||||
// changed_pixels.push(frame[x][y]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// let mut modified_cells_flat = Vec::new();
|
||||
// for x in 0..CELLS_X {
|
||||
// for y in 0..CELLS_Y {
|
||||
// modified_cells_flat.push(modified_cells[x][y]);
|
||||
// }
|
||||
// }
|
||||
// let mut data = Vec::new();
|
||||
// data.extend_from_slice(&pack_nybbles(rle_encode(&modified_cells_flat, 15)));
|
||||
// data.extend_from_slice(&rle_255_encode(&changed_pixels));
|
||||
if modified_cells[cellx][celly] != 0 {
|
||||
changed_pixels.push(frame[x][y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut modified_cells_flat = Vec::new();
|
||||
for x in 0..CELLS_X {
|
||||
for y in 0..CELLS_Y {
|
||||
modified_cells_flat.push(modified_cells[x][y]);
|
||||
}
|
||||
}
|
||||
let mut data = Vec::new();
|
||||
data.extend_from_slice(&pack_nybbles(rle_encode(&modified_cells_flat, 15)));
|
||||
data.extend_from_slice(&rle_255_encode(&changed_pixels));
|
||||
|
||||
// EncodedFrame {
|
||||
// encoding: Encoding::CellDiff4VV_large,
|
||||
// data,
|
||||
// }
|
||||
// }
|
||||
EncodedFrame {
|
||||
encoding: Encoding::CellDiff8VBig,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cell_diff_8_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
|
||||
const CELLS_X: usize = WIDTH / 8;
|
||||
|
@ -348,6 +348,37 @@ pub fn rle_vertical_ext(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn rle_vertical_16(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
|
||||
let mut data = Vec::new();
|
||||
let mut last_pixel = 0;
|
||||
let mut run: u16 = 0;
|
||||
for x in 0..WIDTH {
|
||||
for y in 0..HEIGHT {
|
||||
let pixel = frame[x][y];
|
||||
if pixel != last_pixel || run == 0xffff {
|
||||
data.push((run >> 8) as u8);
|
||||
data.push((run & 0xff) as u8);
|
||||
if run == 0xffff && pixel == last_pixel {
|
||||
// inserting dummy run because we ran out of max len
|
||||
data.push(0);
|
||||
data.push(0);
|
||||
}
|
||||
run = 1;
|
||||
} else {
|
||||
run += 1;
|
||||
}
|
||||
last_pixel = pixel;
|
||||
}
|
||||
}
|
||||
data.push((run >> 8) as u8);
|
||||
data.push((run & 0xff) as u8);
|
||||
EncodedFrame {
|
||||
encoding: Encoding::RLEVertical16,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fill_white(_prev_frame: &Frame, _frame: &Frame, _loss: usize) -> EncodedFrame {
|
||||
EncodedFrame {
|
||||
encoding: Encoding::FillWhite,
|
||||
|
|
|
@ -17,6 +17,7 @@ const LOSSLESS_ENCODINGS: &[FrameEncoder] = &[
|
|||
enc::rle_horizontal,
|
||||
enc::rle_vertical,
|
||||
enc::rle_vertical_ext,
|
||||
enc::rle_vertical_16,
|
||||
// enc::rle_diff_horizontal,
|
||||
// enc::rle_diff_vertical,
|
||||
// enc::bg_strips_horizontal_16, // only works for the tiny display
|
||||
|
@ -27,7 +28,8 @@ const LOSSY_ENCODINGS: &[FrameEncoderLossy] = &[
|
|||
enc::fill_black,
|
||||
// todo: adapt for big display
|
||||
// enc::cell_diff_8_vertical,
|
||||
// enc::cell_diff_4_vertical,
|
||||
enc::cell_diff_4_vertical,
|
||||
enc::cell_diff_8_vertical_big,
|
||||
];
|
||||
|
||||
fn main() {
|
||||
|
@ -166,6 +168,7 @@ enum Encoding {
|
|||
RLEHorizontal,
|
||||
RLEVertical,
|
||||
RLEVerticalExt,
|
||||
RLEVertical16,
|
||||
RLEDiffHorizontal,
|
||||
RLEDiffVertical,
|
||||
BGStripsH16,
|
||||
|
@ -175,6 +178,7 @@ enum Encoding {
|
|||
// DrawCommands,
|
||||
// CellDiff8H,
|
||||
CellDiff8V,
|
||||
CellDiff8VBig,
|
||||
// CellDiff4HH,
|
||||
// CellDiff4HV,
|
||||
// CellDiff4VH,
|
||||
|
@ -189,15 +193,17 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
|
|||
Encoding::RLEHorizontal => dec::rle_horizontal,
|
||||
Encoding::RLEVertical => dec::rle_vertical,
|
||||
Encoding::RLEVerticalExt => dec::rle_vertical_ext,
|
||||
Encoding::RLEVertical16 => dec::rle_vertical_16,
|
||||
Encoding::RLEDiffHorizontal => dec::rle_diff_horizontal,
|
||||
Encoding::RLEDiffVertical => dec::rle_diff_vertical,
|
||||
Encoding::BGStripsH16 => dec::bg_strips_horizontal16,
|
||||
Encoding::BGStripsH24 => dec::bg_strips_horizontal24,
|
||||
Encoding::BGStripsH16 => dec::bg_strips_horizontal_16,
|
||||
Encoding::BGStripsH24 => dec::bg_strips_horizontal_24,
|
||||
// Encoding::BGStripsV => todo!(),
|
||||
// Encoding::QuadTree => todo!(),
|
||||
// Encoding::DrawCommands => todo!(),
|
||||
// Encoding::CellDiff8H => todo!(),
|
||||
Encoding::CellDiff8V => dec::cell_diff_8_vertical,
|
||||
Encoding::CellDiff8VBig => dec::cell_diff_8_vertical_big,
|
||||
// Encoding::CellDiff4HH => todo!(),
|
||||
// Encoding::CellDiff4HV => todo!(),
|
||||
// Encoding::CellDiff4VH => todo!(),
|
||||
|
|
|
@ -75,9 +75,7 @@ void draw_num(u16 x, u16 y, u32 num) {
|
|||
int main() {
|
||||
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, 1);
|
||||
tft_init_display(100 * 1000 * 1000); // max is 62.5MHz
|
||||
// tft_fill(0);
|
||||
|
||||
while (!error) {
|
||||
decode_next_frame();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue