start work on 320x240 screen version using the pi pico

This commit is contained in:
Crispy 2025-06-16 19:39:07 +02:00
parent 8acd684e59
commit 90f648e0b0
13 changed files with 112280 additions and 20 deletions

View file

@ -1,6 +1,6 @@
use crate::*;
pub fn cell_diff_4_vertical(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
pub fn cell_diff_4_vertical_small(prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
const CELLS_X: usize = WIDTH / 4;
const CELLS_Y: usize = HEIGHT / 4;
@ -83,7 +83,7 @@ pub fn cell_diff_8_vertical(prev_frame: &Frame, encoded: &[u8], reader: &mut usi
frame
}
pub fn bg_strips_horizontal(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
pub fn bg_strips_horizontal16(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
*reader += 1;
let bg = encoded[0] >> 7;
let fg = 1 - bg;
@ -104,6 +104,29 @@ pub fn bg_strips_horizontal(_prev_frame: &Frame, encoded: &[u8], reader: &mut us
frame
}
pub fn bg_strips_horizontal24(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
*reader += 2;
let bg = encoded[0] >> 7;
let fg = 1 - bg;
let mut frame = [[bg; HEIGHT]; WIDTH];
let count_upper = (encoded[0] & 0x7f) as usize;
let count = (count_upper << 8) | encoded[1] as usize;
*reader += count * 3;
for i in 0..count {
let y = encoded[i * 3 + 2] as usize;
let x_lower = encoded[i * 3 + 3];
let x_width = encoded[i * 3 + 4];
let x_upper = ((x_width & 0x80) as usize) << 1;
let x_start = x_lower as usize | x_upper;
let width = (x_width & 0x7f) as usize;
for x in x_start..(x_start + width) {
frame[x][y] = fg;
}
}
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;

View file

@ -1,6 +1,6 @@
use crate::*;
pub fn cell_diff_4_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
pub fn cell_diff_4_vertical_small(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,11 +48,64 @@ pub fn cell_diff_4_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> E
data.extend_from_slice(&rle_255_encode(&changed_pixels));
EncodedFrame {
encoding: Encoding::CellDiff4VV,
encoding: Encoding::CellDiff4VV_small,
data,
}
}
// 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;
// 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];
// 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 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,
// }
// }
pub fn cell_diff_8_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> EncodedFrame {
const CELLS_X: usize = WIDTH / 8;
const CELLS_Y: usize = HEIGHT / 8;
@ -97,7 +150,8 @@ pub fn cell_diff_8_vertical(prev_frame: &Frame, frame: &Frame, loss: usize) -> E
}
}
pub fn bg_strips_horizontal(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
// meant for 42x32 mode
pub fn bg_strips_horizontal_16(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
let bg = most_common_pixel(frame);
fn pack_strip(x: usize, y: usize, width: usize) -> [u8; 2] {
// Y is 0..31 so will only need 5 bits
@ -145,7 +199,57 @@ pub fn bg_strips_horizontal(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame
frame_bytes.extend_from_slice(&pack_strip(x, y, width));
}
EncodedFrame {
encoding: Encoding::BGStripsH,
encoding: Encoding::BGStripsH16,
data: frame_bytes,
}
}
// meant for 320x240 mode
pub fn bg_strips_horizontal_24(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
let bg = most_common_pixel(frame);
fn pack_strip(x: usize, y: usize, width: usize) -> [u8; 3] {
// Y is 0..240 so will need 8 bits
// x is 0..320 so needs 9 bits
// 7 bits remain for width
let x_width = ((x >> 1) & 0x80) as u8 | (width as u8);
[y as u8, (x & 0xff) as u8, x_width]
}
let mut strips = Vec::new();
'outer: for y in 0..HEIGHT {
let mut strip_start = 0;
let mut in_strip = false;
for x in 0..WIDTH {
let pixel = frame[x][y];
if !in_strip && pixel != bg {
in_strip = true;
strip_start = x;
}
if in_strip {
if pixel == bg {
strips.push((strip_start, y, x - strip_start));
in_strip = false;
} else if x - strip_start == 127 {
strips.push((strip_start, y, x - strip_start));
strip_start = x;
}
// if strips.len() == MAX_STRIPS {
// break 'outer;
// }
}
}
if in_strip {
strips.push((strip_start, y, WIDTH - strip_start));
}
}
let mut frame_bytes = Vec::with_capacity(2 + strips.len() * 2);
frame_bytes.push(bg << 7 | ((strips.len() >> 8) as u8));
frame_bytes.push(strips.len() as u8);
for (x, y, width) in strips {
frame_bytes.extend_from_slice(&pack_strip(x, y, width));
}
EncodedFrame {
encoding: Encoding::BGStripsH24,
data: frame_bytes,
}
}

View file

@ -16,15 +16,17 @@ 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::bg_strips_horizontal,
];
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
];
const LOSSY_ENCODINGS: &[FrameEncoderLossy] = &[
enc::fill_white,
enc::fill_black,
enc::cell_diff_8_vertical,
// enc::cell_diff_4_vertical,
// todo: adapt these for big display
// enc::cell_diff_8_vertical,
// enc::cell_diff_4_vertical_small,
];
fn main() {
@ -88,7 +90,7 @@ fn main() {
export_string += &format!("{byte},");
}
export_string += "\n};\n";
let mut file = File::create("../ch32_decoder/data.h").unwrap();
let mut file = File::create(format!("../{OUTPUT_DIR}/data.h")).unwrap();
file.write_all(export_string.as_bytes()).unwrap();
}
@ -161,7 +163,8 @@ enum Encoding {
RLEVertical,
RLEDiffHorizontal,
RLEDiffVertical,
BGStripsH,
BGStripsH16,
BGStripsH24,
// BGStripsV,
// QuadTree,
// DrawCommands,
@ -170,7 +173,8 @@ enum Encoding {
// CellDiff4HH,
// CellDiff4HV,
// CellDiff4VH,
CellDiff4VV,
CellDiff4VV_small,
// CellDiff4VV_large,
}
fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
@ -181,7 +185,8 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
Encoding::RLEVertical => dec::rle_vertical,
Encoding::RLEDiffHorizontal => dec::rle_diff_horizontal,
Encoding::RLEDiffVertical => dec::rle_diff_vertical,
Encoding::BGStripsH => dec::bg_strips_horizontal,
Encoding::BGStripsH16 => dec::bg_strips_horizontal16,
Encoding::BGStripsH24 => dec::bg_strips_horizontal24,
// Encoding::BGStripsV => todo!(),
// Encoding::QuadTree => todo!(),
// Encoding::DrawCommands => todo!(),
@ -190,7 +195,8 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
// Encoding::CellDiff4HH => todo!(),
// Encoding::CellDiff4HV => todo!(),
// Encoding::CellDiff4VH => todo!(),
Encoding::CellDiff4VV => dec::cell_diff_4_vertical,
Encoding::CellDiff4VV_small => dec::cell_diff_4_vertical_small,
// Encoding::CellDiff4VV_large => dec::cell_diff_4_vertical_large,
}
}

View file

@ -5,8 +5,10 @@ use std::{
use image::{self, DynamicImage, GenericImageView, ImageFormat, Rgba};
pub const WIDTH: usize = 40;
pub const HEIGHT: usize = 32;
// pub const OUTPUT_DIR: &str = "ch32_decoder";
pub const OUTPUT_DIR: &str = "pico_decoder/src";
pub const WIDTH: usize = 320;
pub const HEIGHT: usize = 240;
pub const FRAME_SIZE: usize = WIDTH * HEIGHT;
pub type Frame = [[u8; HEIGHT]; WIDTH];

121
encoder/temp.txt Normal file
View file

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