#![feature(box_patterns)] use anyhow::Context; use clap::Parser; use evc::{ block::{Block, BlockInner}, frame::Frame, header::Header, pixel::Pixel, ser::Source, view::View, }; use std::io::{BufReader, BufWriter}; #[derive(Parser)] #[clap(about, version)] pub struct DecodeArgs { #[arg(long)] debug: bool, } fn main() -> anyhow::Result<()> { let args = DecodeArgs::parse(); let mut input = BufReader::new(std::io::stdin()); let mut output = BufWriter::new(std::io::stdout()); let header = input.get::
().context("reading header")?; eprintln!("{header:?}"); let size = header.resolution; let mut prev = Frame::new(size); for i in 0.. { eprintln!("decode frame {i}"); let block = Block::read(&mut input, size).context("reading encoded frame")?; let mut frame = Frame::new(size); blit_block( &block, frame.view_mut((0, 0), size), prev.view((0, 0), size), ); if args.debug { let mut f2 = frame.clone(); draw_debug(&block, f2.view_mut((0, 0), size)); f2.write(&mut output).context("writing raw frame")?; } else { frame.write(&mut output).context("writing raw frame")?; } prev = frame; } drop(input); Ok(()) } fn blit_block(block: &Block, mut target: View<&mut Frame>, prev: View<&Frame>) { match &block.inner { BlockInner::Literal(pixels) => target.set_pixels(pixels), BlockInner::Split(box [a, b]) => { let [at, bt] = target.split_mut_unsafe(); let [ap, bp] = prev.split(); blit_block(a, at, ap); blit_block(b, bt, bp); } BlockInner::Reference { translation: _ } => target.copy_from(&prev), } } fn draw_debug(block: &Block, mut target: View<&mut Frame>) { match &block.inner { BlockInner::Literal(_) => { target.draw_box(Pixel::GREEN); } BlockInner::Split(box [a, b]) => { let [at, bt] = target.split_mut_unsafe(); draw_debug(a, at); draw_debug(b, bt); } BlockInner::Reference { translation: _ } => { target.draw_box(Pixel::BLUE); } } }