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
|
@ -251,8 +251,8 @@ pub fn rle_vertical_ext(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize)
|
||||||
let mut run = byte as u16;
|
let mut run = byte as u16;
|
||||||
if byte == 0 && encoded[i] == 0 {
|
if byte == 0 && encoded[i] == 0 {
|
||||||
// 16 bit run length
|
// 16 bit run length
|
||||||
let upper = (encoded[i+1] as u16) << 8;
|
let upper = (encoded[i + 1] as u16) << 8;
|
||||||
if upper > 0{
|
if upper > 0 {
|
||||||
let lower = encoded[i + 2] as u16;
|
let lower = encoded[i + 2] as u16;
|
||||||
i += 3;
|
i += 3;
|
||||||
run = upper | lower;
|
run = upper | lower;
|
||||||
|
@ -281,10 +281,10 @@ pub fn rle_vertical_16(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize)
|
||||||
|
|
||||||
while x < WIDTH {
|
while x < WIDTH {
|
||||||
let upper = encoded[i] as u16;
|
let upper = encoded[i] as u16;
|
||||||
let lower = encoded[i+1] as u16;
|
let lower = encoded[i + 1] as u16;
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
let run = (upper<<8) | lower;
|
let run = (upper << 8) | lower;
|
||||||
for _ in 0..run {
|
for _ in 0..run {
|
||||||
frame[x][y] = color;
|
frame[x][y] = color;
|
||||||
y += 1;
|
y += 1;
|
||||||
|
@ -299,6 +299,72 @@ pub fn rle_vertical_16(_prev_frame: &Frame, encoded: &[u8], reader: &mut usize)
|
||||||
frame
|
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 {
|
pub fn fill_white(_prev_frame: &Frame, _encoded: &[u8], _reader: &mut usize) -> Frame {
|
||||||
FRAME_1
|
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 {
|
pub fn rle_vertical(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
|
||||||
let mut pixels = Vec::new();
|
let mut pixels = Vec::new();
|
||||||
for x in 0..WIDTH {
|
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 {
|
pub fn rle_vertical_16(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
let mut last_pixel = 0;
|
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 enum_map::{Enum, EnumMap};
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
|
@ -22,6 +22,7 @@ const LOSSLESS_ENCODINGS: &[FrameEncoder] = &[
|
||||||
// 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
|
||||||
enc::bg_strips_horizontal_24, // intended for the 240x320 display
|
enc::bg_strips_horizontal_24, // intended for the 240x320 display
|
||||||
|
// enc::tree_16,// turns out to be useless
|
||||||
];
|
];
|
||||||
const LOSSY_ENCODINGS: &[FrameEncoderLossy] = &[
|
const LOSSY_ENCODINGS: &[FrameEncoderLossy] = &[
|
||||||
enc::fill_white,
|
enc::fill_white,
|
||||||
|
@ -101,7 +102,11 @@ fn main() {
|
||||||
fn encode(frames: &[Frame]) -> Vec<u8> {
|
fn encode(frames: &[Frame]) -> Vec<u8> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
let mut last_frame = FRAME_0;
|
let mut last_frame = FRAME_0;
|
||||||
|
print!("encoding frames");
|
||||||
|
let frame_count = frames.len();
|
||||||
for (_i, frame) in frames.iter().enumerate() {
|
for (_i, frame) in frames.iter().enumerate() {
|
||||||
|
print!("\rencoding frame {_i} of {frame_count}");
|
||||||
|
stdout().flush().unwrap();
|
||||||
let mut options = Vec::new();
|
let mut options = Vec::new();
|
||||||
for encode in LOSSLESS_ENCODINGS.iter() {
|
for encode in LOSSLESS_ENCODINGS.iter() {
|
||||||
let encoded = encode(&last_frame, frame);
|
let encoded = encode(&last_frame, frame);
|
||||||
|
@ -157,6 +162,7 @@ fn encode(frames: &[Frame]) -> Vec<u8> {
|
||||||
out.extend_from_slice(&best_encoding);
|
out.extend_from_slice(&best_encoding);
|
||||||
last_frame = *frame;
|
last_frame = *frame;
|
||||||
}
|
}
|
||||||
|
println!();
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +190,7 @@ enum Encoding {
|
||||||
// CellDiff4VH,
|
// CellDiff4VH,
|
||||||
CellDiff4VV,
|
CellDiff4VV,
|
||||||
// CellDiff4VV_large,
|
// CellDiff4VV_large,
|
||||||
|
Tree16,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
|
fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
|
||||||
|
@ -208,6 +215,7 @@ fn get_matching_decoder(encoding: Encoding) -> FrameDecoder {
|
||||||
// Encoding::CellDiff4HV => todo!(),
|
// Encoding::CellDiff4HV => todo!(),
|
||||||
// Encoding::CellDiff4VH => todo!(),
|
// Encoding::CellDiff4VH => todo!(),
|
||||||
Encoding::CellDiff4VV => dec::cell_diff_4_vertical,
|
Encoding::CellDiff4VV => dec::cell_diff_4_vertical,
|
||||||
|
Encoding::Tree16 => dec::tree_16,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue