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
|
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 {
|
pub fn cell_diff_8_vertical(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
|
||||||
let bitmap = {
|
let bitmap = {
|
||||||
*reader += 3;
|
*reader += 3;
|
||||||
|
@ -83,7 +134,7 @@ pub fn cell_diff_8_vertical(prev_frame: &Frame, encoded: &[u8], reader: &mut usi
|
||||||
frame
|
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;
|
*reader += 1;
|
||||||
let bg = encoded[0] >> 7;
|
let bg = encoded[0] >> 7;
|
||||||
let fg = 1 - bg;
|
let fg = 1 - bg;
|
||||||
|
@ -104,7 +155,7 @@ pub fn bg_strips_horizontal16(_prev_frame: &Frame, encoded: &[u8], reader: &mut
|
||||||
frame
|
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;
|
*reader += 2;
|
||||||
let bg = encoded[0] >> 7;
|
let bg = encoded[0] >> 7;
|
||||||
let fg = 1 - bg;
|
let fg = 1 - bg;
|
||||||
|
@ -221,6 +272,34 @@ pub fn rle_vertical_ext(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize)
|
||||||
frame
|
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 {
|
pub fn fill_white(_prev_frame: &Frame, _encoded: &[u8], _reader: &mut usize) -> Frame {
|
||||||
FRAME_1
|
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 {
|
pub fn cell_diff_8_vertical_big(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
|
||||||
// let loss = loss / 4;
|
let loss = loss / 8;
|
||||||
// const CELLS_X: usize = WIDTH / 4;
|
const CELLS_X: usize = WIDTH / 8;
|
||||||
// const CELLS_Y: usize = HEIGHT / 4;
|
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 cellx in 0..CELLS_X {
|
||||||
// for celly in 0..CELLS_Y {
|
for celly in 0..CELLS_Y {
|
||||||
// let mut changed = 0;
|
let mut changed = 0;
|
||||||
// for dx in 0..4 {
|
for dx in 0..8 {
|
||||||
// for dy in 0..4 {
|
for dy in 0..8 {
|
||||||
// let x = cellx * 4 + dx;
|
let x = cellx * 8 + dx;
|
||||||
// let y = celly * 4 + dy;
|
let y = celly * 8 + dy;
|
||||||
// let pixel = frame[x][y];
|
let pixel = frame[x][y];
|
||||||
|
|
||||||
// if pixel != prev_frame[x][y] {
|
if pixel != prev_frame[x][y] {
|
||||||
// changed += 1;
|
changed += 1;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// if changed > loss {
|
if changed > loss {
|
||||||
// modified_cells[cellx][celly] = 1;
|
modified_cells[cellx][celly] = 1;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// let mut changed_pixels = Vec::new();
|
let mut changed_pixels = Vec::new();
|
||||||
// for x in 0..WIDTH {
|
for x in 0..WIDTH {
|
||||||
// for y in 0..HEIGHT {
|
for y in 0..HEIGHT {
|
||||||
// let cellx = x / 4;
|
let cellx = x / 8;
|
||||||
// let celly = y / 4;
|
let celly = y / 8;
|
||||||
|
|
||||||
// if modified_cells[cellx][celly] != 0 {
|
if modified_cells[cellx][celly] != 0 {
|
||||||
// changed_pixels.push(frame[x][y]);
|
changed_pixels.push(frame[x][y]);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// let mut modified_cells_flat = Vec::new();
|
let mut modified_cells_flat = Vec::new();
|
||||||
// for x in 0..CELLS_X {
|
for x in 0..CELLS_X {
|
||||||
// for y in 0..CELLS_Y {
|
for y in 0..CELLS_Y {
|
||||||
// modified_cells_flat.push(modified_cells[x][y]);
|
modified_cells_flat.push(modified_cells[x][y]);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
// data.extend_from_slice(&pack_nybbles(rle_encode(&modified_cells_flat, 15)));
|
data.extend_from_slice(&pack_nybbles(rle_encode(&modified_cells_flat, 15)));
|
||||||
// data.extend_from_slice(&rle_255_encode(&changed_pixels));
|
data.extend_from_slice(&rle_255_encode(&changed_pixels));
|
||||||
|
|
||||||
// EncodedFrame {
|
EncodedFrame {
|
||||||
// encoding: Encoding::CellDiff4VV_large,
|
encoding: Encoding::CellDiff8VBig,
|
||||||
// data,
|
data,
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
pub fn cell_diff_8_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
|
pub fn cell_diff_8_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
|
||||||
const CELLS_X: usize = WIDTH / 8;
|
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 {
|
pub fn fill_white(_prev_frame: &Frame, _frame: &Frame, _loss: usize) -> EncodedFrame {
|
||||||
EncodedFrame {
|
EncodedFrame {
|
||||||
encoding: Encoding::FillWhite,
|
encoding: Encoding::FillWhite,
|
||||||
|
|
|
@ -17,6 +17,7 @@ const LOSSLESS_ENCODINGS: &[FrameEncoder] = &[
|
||||||
enc::rle_horizontal,
|
enc::rle_horizontal,
|
||||||
enc::rle_vertical,
|
enc::rle_vertical,
|
||||||
enc::rle_vertical_ext,
|
enc::rle_vertical_ext,
|
||||||
|
enc::rle_vertical_16,
|
||||||
// enc::rle_diff_horizontal,
|
// enc::rle_diff_horizontal,
|
||||||
// enc::rle_diff_vertical,
|
// enc::rle_diff_vertical,
|
||||||
// enc::bg_strips_horizontal_16, // only works for the tiny display
|
// enc::bg_strips_horizontal_16, // only works for the tiny display
|
||||||
|
@ -27,7 +28,8 @@ const LOSSY_ENCODINGS: &[FrameEncoderLossy] = &[
|
||||||
enc::fill_black,
|
enc::fill_black,
|
||||||
// todo: adapt for big display
|
// todo: adapt for big display
|
||||||
// enc::cell_diff_8_vertical,
|
// enc::cell_diff_8_vertical,
|
||||||
// enc::cell_diff_4_vertical,
|
enc::cell_diff_4_vertical,
|
||||||
|
enc::cell_diff_8_vertical_big,
|
||||||
];
|
];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -166,6 +168,7 @@ enum Encoding {
|
||||||
RLEHorizontal,
|
RLEHorizontal,
|
||||||
RLEVertical,
|
RLEVertical,
|
||||||
RLEVerticalExt,
|
RLEVerticalExt,
|
||||||
|
RLEVertical16,
|
||||||
RLEDiffHorizontal,
|
RLEDiffHorizontal,
|
||||||
RLEDiffVertical,
|
RLEDiffVertical,
|
||||||
BGStripsH16,
|
BGStripsH16,
|
||||||
|
@ -175,6 +178,7 @@ enum Encoding {
|
||||||
// DrawCommands,
|
// DrawCommands,
|
||||||
// CellDiff8H,
|
// CellDiff8H,
|
||||||
CellDiff8V,
|
CellDiff8V,
|
||||||
|
CellDiff8VBig,
|
||||||
// CellDiff4HH,
|
// CellDiff4HH,
|
||||||
// CellDiff4HV,
|
// CellDiff4HV,
|
||||||
// CellDiff4VH,
|
// CellDiff4VH,
|
||||||
|
@ -189,15 +193,17 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
|
||||||
Encoding::RLEHorizontal => dec::rle_horizontal,
|
Encoding::RLEHorizontal => dec::rle_horizontal,
|
||||||
Encoding::RLEVertical => dec::rle_vertical,
|
Encoding::RLEVertical => dec::rle_vertical,
|
||||||
Encoding::RLEVerticalExt => dec::rle_vertical_ext,
|
Encoding::RLEVerticalExt => dec::rle_vertical_ext,
|
||||||
|
Encoding::RLEVertical16 => dec::rle_vertical_16,
|
||||||
Encoding::RLEDiffHorizontal => dec::rle_diff_horizontal,
|
Encoding::RLEDiffHorizontal => dec::rle_diff_horizontal,
|
||||||
Encoding::RLEDiffVertical => dec::rle_diff_vertical,
|
Encoding::RLEDiffVertical => dec::rle_diff_vertical,
|
||||||
Encoding::BGStripsH16 => dec::bg_strips_horizontal16,
|
Encoding::BGStripsH16 => dec::bg_strips_horizontal_16,
|
||||||
Encoding::BGStripsH24 => dec::bg_strips_horizontal24,
|
Encoding::BGStripsH24 => dec::bg_strips_horizontal_24,
|
||||||
// Encoding::BGStripsV => todo!(),
|
// Encoding::BGStripsV => todo!(),
|
||||||
// Encoding::QuadTree => todo!(),
|
// Encoding::QuadTree => todo!(),
|
||||||
// Encoding::DrawCommands => todo!(),
|
// Encoding::DrawCommands => todo!(),
|
||||||
// Encoding::CellDiff8H => todo!(),
|
// Encoding::CellDiff8H => todo!(),
|
||||||
Encoding::CellDiff8V => dec::cell_diff_8_vertical,
|
Encoding::CellDiff8V => dec::cell_diff_8_vertical,
|
||||||
|
Encoding::CellDiff8VBig => dec::cell_diff_8_vertical_big,
|
||||||
// Encoding::CellDiff4HH => todo!(),
|
// Encoding::CellDiff4HH => todo!(),
|
||||||
// Encoding::CellDiff4HV => todo!(),
|
// Encoding::CellDiff4HV => todo!(),
|
||||||
// Encoding::CellDiff4VH => todo!(),
|
// Encoding::CellDiff4VH => todo!(),
|
||||||
|
|
|
@ -75,9 +75,7 @@ void draw_num(u16 x, u16 y, u32 num) {
|
||||||
int main() {
|
int main() {
|
||||||
gpio_init(PICO_DEFAULT_LED_PIN);
|
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
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_init_display(100 * 1000 * 1000); // max is 62.5MHz
|
||||||
// tft_fill(0);
|
|
||||||
|
|
||||||
while (!error) {
|
while (!error) {
|
||||||
decode_next_frame();
|
decode_next_frame();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue