lossy compression

This commit is contained in:
Crispy 2024-04-12 18:47:40 +02:00
parent 242724d7fd
commit 8bfeb6d2f3
4 changed files with 194 additions and 37 deletions

View file

@ -1,15 +1,66 @@
use crate::*;
pub fn cell_diff_8_vertical(prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
let cells_x = WIDTH / 8;
let cells_y = HEIGHT / 8;
let loss = 0;
pub fn cell_diff_4_vertical(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,
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;
let mut bitmap: u32 = 0;
let mut changed_pixels = Vec::new();
for cellx in 0..cells_x {
for celly in 0..cells_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 {
@ -23,15 +74,16 @@ pub fn cell_diff_8_vertical(prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
}
}
if changed > loss {
bitmap |= 1 << (cellx + cells_x * celly);
bitmap |= 1 << (cellx + CELLS_X * celly);
}
}
}
let mut changed_pixels = Vec::new();
for x in 0..WIDTH {
for y in 0..HEIGHT {
let cellx = x / 8;
let celly = y / 8;
let bit = 1 << (cellx + cells_x * celly);
let bit = 1 << (cellx + CELLS_X * celly);
if (bitmap & bit) != 0 {
changed_pixels.push(frame[x][y]);
}
@ -150,14 +202,14 @@ pub fn rle_vertical(_prev_frame: &Frame, frame: &Frame) -> EncodedFrame {
}
}
pub fn fill_white(_prev_frame: &Frame, _frame: &Frame) -> EncodedFrame {
pub fn fill_white(_prev_frame: &Frame, _frame: &Frame, _loss: usize) -> EncodedFrame {
EncodedFrame {
encoding: Encoding::FillWhite,
data: Vec::new(),
}
}
pub fn fill_black(_prev_frame: &Frame, _frame: &Frame) -> EncodedFrame {
pub fn fill_black(_prev_frame: &Frame, _frame: &Frame, _loss: usize) -> EncodedFrame {
EncodedFrame {
encoding: Encoding::FillBlack,
data: Vec::new(),