pub fn encode_scanline(scanline: &[u8]) -> Vec<u8> {
if scanline.is_empty() {
return Vec::new();
}
let mut runs = Vec::new();
let first_val = scanline[0];
let mut current_val: u8 = 0; let mut count: usize = 0;
if first_val == 1 {
runs.push(0u8);
current_val = 1;
}
for &pixel in scanline {
if pixel == current_val {
count += 1;
} else {
flush_run(&mut runs, count);
current_val = pixel;
count = 1;
}
}
flush_run(&mut runs, count);
runs
}
fn flush_run(runs: &mut Vec<u8>, mut count: usize) {
while count > 255 {
runs.push(255);
runs.push(0); count -= 255;
}
if count > 0 {
runs.push(count as u8);
}
}
pub fn decode_scanline(runs: &[u8], width: usize) -> Option<Vec<u8>> {
let mut out = Vec::with_capacity(width);
let mut current_val = 0u8;
for &count in runs {
for _ in 0..count {
out.push(current_val);
}
current_val = if current_val == 0 { 1 } else { 0 };
}
if out.len() != width {
return None;
}
Some(out)
}
pub fn encode_bitmap(bitmap: &[Vec<u8>]) -> Vec<u8> {
let mut out = Vec::new();
let count = bitmap.len() as u16;
out.push((count >> 8) as u8);
out.push((count & 0xFF) as u8);
for scanline in bitmap {
let encoded = encode_scanline(scanline);
let len = encoded.len() as u16;
out.push((len >> 8) as u8);
out.push((len & 0xFF) as u8);
out.extend(encoded);
}
out
}
pub fn decode_bitmap(data: &[u8]) -> Option<Vec<Vec<u8>>> {
if data.len() < 2 {
return None;
}
let count = ((data[0] as u16) << 8) | (data[1] as u16);
let mut bitmap = Vec::with_capacity(count as usize);
let mut pos = 2;
for _ in 0..count {
if pos + 2 > data.len() {
return None;
}
let len = ((data[pos] as u16) << 8) | (data[pos + 1] as u16);
pos += 2;
if pos + len as usize > data.len() {
return None;
}
let encoded = &data[pos..pos + len as usize];
pos += len as usize;
let mut scanline = Vec::new();
let mut current_val = 0u8;
for &run in encoded {
for _ in 0..run {
scanline.push(current_val);
}
current_val = if current_val == 0 { 1 } else { 0 };
}
bitmap.push(scanline);
}
Some(bitmap)
}