#![feature(box_patterns)] use anyhow::Context; use clap::Parser; use evc::{ block::Block, codec::decode::decode_block, format::{ header::Header, ser::{map_scalar8, Source}, }, frame::Frame, helpers::{matrix::Mat2, pixel::Pixel, vector::Vec2}, view::View, }; use log::info; use std::io::{BufReader, BufWriter}; #[derive(Parser)] #[clap(about, version)] pub struct DecodeArgs { #[arg(long)] debug: bool, } fn main() -> anyhow::Result<()> { env_logger::init_from_env("LOG"); 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")?; info!("{header:?}"); let size = header.resolution; let mut prev = Frame::new(size); for i in 0.. { info!("decode frame {i}"); let block = Block::read(&mut input, size).context("reading encoded frame")?; let mut frame = Frame::new(size); decode_block(&block, frame.view_mut(), prev.view()); if args.debug { let mut f2 = frame.clone(); draw_debug(&block, f2.view_mut()); f2.write(&mut output).context("writing raw frame")?; } else { frame.write(&mut output).context("writing raw frame")?; } prev = frame; } drop(input); Ok(()) } fn draw_debug(block: &Block, mut target: View<&mut Frame>) { match &block { Block::Literal(_) => { target.draw_box(Pixel::GREEN); } Block::Split(box [a, b]) => { let [at, bt] = target.split_mut_unsafe(); draw_debug(a, at); draw_debug(b, bt); } Block::Reference { translation } => { target.draw_box(Pixel::BLUE); target.frame.draw_line( target.center().into(), (target.center() + *translation).into(), Pixel::RED, ) } Block::AdvancedReference(r) => { let mat = Mat2 { a: map_scalar8(r.transform.a), b: map_scalar8(r.transform.b), c: map_scalar8(r.transform.c), d: map_scalar8(r.transform.d), }; let translation = Vec2 { x: map_scalar8(r.translation.x), y: map_scalar8(r.translation.y), }; let tl = mat.transform(target.offset.into()) + translation; let tr = mat.transform((target.offset + target.size.x_only()).into()) + translation; let bl = mat.transform((target.offset + target.size.y_only()).into()) + translation; let br = mat.transform((target.offset + target.size).into()) + translation; target.frame.draw_line(tl, tr, Pixel::MAGENTA); target.frame.draw_line(tr, br, Pixel::MAGENTA); target.frame.draw_line(br, bl, Pixel::MAGENTA); target.frame.draw_line(bl, tl, Pixel::MAGENTA); target.draw_box(Pixel::CYAN); } } }