add 16 wide, 2 deep tree with RLE at the end. turns out to be worse than other algs
This commit is contained in:
parent
a1bcf7d90b
commit
d44e5d9c55
3 changed files with 144 additions and 6 deletions
|
@ -299,6 +299,72 @@ pub fn rle_vertical_16(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize)
|
|||
frame
|
||||
}
|
||||
|
||||
pub fn tree_16(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize) -> Frame {
|
||||
let fg = 1;
|
||||
let mut frame = [[1-fg; HEIGHT]; WIDTH];
|
||||
let top_node = ((encoded[0] as u16) << 8) | encoded[1] as u16;
|
||||
let mut i = 2;
|
||||
let mut nodes = [0u16; 16];
|
||||
for cx in 0..4 {
|
||||
for cy in 0..4 {
|
||||
let index = cy * 4 + cx;
|
||||
let has_node = (top_node & (1 << index)) != 0;
|
||||
if has_node {
|
||||
let node = ((encoded[i] as u16) << 8) | encoded[i + 1] as u16;
|
||||
i += 2;
|
||||
nodes[index] = node;
|
||||
// temp fill for visualisation:
|
||||
// for px in 0..(WIDTH / 4) {
|
||||
// let x = cx * (WIDTH / 4) + px;
|
||||
// for py in 0..(HEIGHT / 4) {
|
||||
// let y = cy * (HEIGHT / 4) + py;
|
||||
// frame[x][y] = 1;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut color = fg;
|
||||
let mut run = 0;
|
||||
for cx in 0..4 {
|
||||
for cy in 0..4 {
|
||||
let index = cy * 4 + cx;
|
||||
let node = nodes[index];
|
||||
if node != 0 {
|
||||
for ccx in 0..4 {
|
||||
for ccy in 0..4 {
|
||||
let x = cx * (WIDTH / 4) + ccx * (WIDTH / 16);
|
||||
let y = cy * (HEIGHT / 4) + ccy * (HEIGHT / 16);
|
||||
|
||||
let lower_index = ccy * 4 + ccx;
|
||||
if node & (1 << lower_index) != 0 {
|
||||
// leaf node exists, fill from RLE
|
||||
let mut px = 0;
|
||||
let mut py = 0;
|
||||
while px < WIDTH / 16 {
|
||||
while run == 0 {
|
||||
run = encoded[i];
|
||||
i += 1;
|
||||
color = 1 - color;
|
||||
}
|
||||
run -= 1;
|
||||
frame[x + px][y + py] = color;
|
||||
py += 1;
|
||||
if py == HEIGHT / 16 {
|
||||
py = 0;
|
||||
px += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*reader += i;
|
||||
|
||||
frame
|
||||
}
|
||||
|
||||
pub fn fill_white(_prev_frame: &Frame, _encoded: &[u8], _reader: &mut usize) -> Frame {
|
||||
FRAME_1
|
||||
|
|
|
@ -293,6 +293,71 @@ pub fn rle_horizontal(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
|
|||
}
|
||||
}
|
||||
|
||||
/// requires WIDTH and HEIGHT to be multiples of 16
|
||||
/// two-level tree with 4x4 branches per level
|
||||
pub fn tree_16(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
|
||||
let mut top_node: u16 = 0;
|
||||
let mut second_nodes = Vec::new();
|
||||
let mut included_pixels = Vec::new();
|
||||
// todo allow using white as bg
|
||||
let fg = 1;
|
||||
for cx in 0..4 {
|
||||
for cy in 0..4 {
|
||||
let mut any_filled_here = false;
|
||||
'a: for px in 0..(WIDTH / 4) {
|
||||
let x = cx * (WIDTH / 4) + px;
|
||||
for py in 0..(HEIGHT / 4) {
|
||||
let y = cy * (HEIGHT / 4) + py;
|
||||
if frame[x][y] == fg{
|
||||
any_filled_here = true;
|
||||
break 'a;
|
||||
}
|
||||
}
|
||||
}
|
||||
if any_filled_here {
|
||||
top_node |= 1 << (cy * 4 + cx);
|
||||
let mut second_node: u16 = 0;
|
||||
for ccx in 0..4 {
|
||||
for ccy in 0..4 {
|
||||
let mut any_filled_here = false;
|
||||
let mut node_pixels = Vec::new();
|
||||
for px in 0..(WIDTH / 16) {
|
||||
for py in 0..(HEIGHT / 16) {
|
||||
let x = cx * (WIDTH / 4) + ccx * (WIDTH / 16) + px;
|
||||
let y = cy * (HEIGHT / 4) + ccy * (HEIGHT / 16) + py;
|
||||
if frame[x][y] == fg {
|
||||
node_pixels.push(fg);
|
||||
any_filled_here = true;
|
||||
}else{
|
||||
node_pixels.push(1-fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if any_filled_here {
|
||||
second_node |= 1 << (ccy * 4 + ccx);
|
||||
included_pixels.extend_from_slice(&node_pixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
second_nodes.push(second_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut data = Vec::new();
|
||||
data.push((top_node >>8) as u8);
|
||||
data.push(top_node as u8);
|
||||
for n in second_nodes{
|
||||
data.push((n>>8)as u8);
|
||||
data.push(n as u8);
|
||||
}
|
||||
data.extend_from_slice(&rle_255_encode(&included_pixels));
|
||||
|
||||
EncodedFrame {
|
||||
encoding: Encoding::Tree16,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rle_vertical(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
|
||||
let mut pixels = Vec::new();
|
||||
for x in 0..WIDTH {
|
||||
|
@ -348,7 +413,6 @@ 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;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{fs::File, io::Write};
|
||||
use std::{fs::File, io::{stdout, Write}};
|
||||
|
||||
use enum_map::{Enum, EnumMap};
|
||||
use num_enum::TryFromPrimitive;
|
||||
|
@ -22,6 +22,7 @@ const LOSSLESS_ENCODINGS: &[FrameEncoder] = &[
|
|||
// 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::tree_16,// turns out to be useless
|
||||
];
|
||||
const LOSSY_ENCODINGS: &[FrameEncoderLossy] = &[
|
||||
enc::fill_white,
|
||||
|
@ -101,7 +102,11 @@ fn main() {
|
|||
fn encode(frames: &[Frame]) -> Vec<u8> {
|
||||
let mut out = Vec::new();
|
||||
let mut last_frame = FRAME_0;
|
||||
print!("encoding frames");
|
||||
let frame_count = frames.len();
|
||||
for (_i, frame) in frames.iter().enumerate() {
|
||||
print!("\rencoding frame {_i} of {frame_count}");
|
||||
stdout().flush().unwrap();
|
||||
let mut options = Vec::new();
|
||||
for encode in LOSSLESS_ENCODINGS.iter() {
|
||||
let encoded = encode(&last_frame, frame);
|
||||
|
@ -157,6 +162,7 @@ fn encode(frames: &[Frame]) -> Vec<u8> {
|
|||
out.extend_from_slice(&best_encoding);
|
||||
last_frame = *frame;
|
||||
}
|
||||
println!();
|
||||
out
|
||||
}
|
||||
|
||||
|
@ -184,6 +190,7 @@ enum Encoding {
|
|||
// CellDiff4VH,
|
||||
CellDiff4VV,
|
||||
// CellDiff4VV_large,
|
||||
Tree16,
|
||||
}
|
||||
|
||||
fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
|
||||
|
@ -208,6 +215,7 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
|
|||
// Encoding::CellDiff4HV => todo!(),
|
||||
// Encoding::CellDiff4VH => todo!(),
|
||||
Encoding::CellDiff4VV => dec::cell_diff_4_vertical,
|
||||
Encoding::Tree16 => dec::tree_16,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue