use crate::{ debug::draw_debug, huff::read_huff, impls::join, split::split, Block, Frame, View, P2, }; use std::io::{BufReader, BufWriter, Read, Result, Write}; pub fn decode(size: P2, debug: bool, input: impl Read, output: impl Write) -> Result<()> { let mut input = BufReader::new(input); let mut output = BufWriter::new(output); let mut d = Decoder::new(size); let mut f = Frame::new(size); loop { d.decode_frame(&mut input, &mut f, debug)?; Frame::write(&mut output, &f)?; } } pub struct Decoder { last_frame: Frame, size: P2, } impl Decoder { pub fn new(size: P2) -> Self { Self { size, last_frame: Frame::new(size), } } pub fn decode_frame( &mut self, mut input: impl Read, output: &mut Frame, debug: bool, ) -> Result<()> { let huff = true; let b = if huff { let mut buf = vec![]; read_huff(&mut input, &mut buf)?; eprintln!("{}", buf.len()); let mut buf = std::io::Cursor::new(&mut buf); Block::read(&mut buf, View::all(self.size))? } else { Block::read(&mut input, View::all(self.size))? }; decode_block(&self.last_frame, output, View::all(self.size), &b); self.last_frame.pixels.copy_from_slice(&output.pixels); // TODO use mem::swap if debug { draw_debug(output, View::all(self.size), &b); } Ok(()) } } pub fn decode_block(last_frame: &Frame, frame: &mut Frame, view: View, block: &Block) { match block { Block::Lit(pxs) => frame.import(view, &pxs), Block::Split(a, b) => { let [av, bv] = split(view); let (frame1, frame2) = unsafe { (&mut *(frame as *mut Frame), &mut *(frame as *mut Frame)) }; join( || decode_block(last_frame, frame1, av, &a), || decode_block(last_frame, frame2, bv, &b), ); } Block::Ref(r) => { for y in view.a.y..view.b.y { for x in view.a.x..view.b.x { let p = P2 { x, y }; frame[p] = last_frame[p + r.pos_off] + r.color_off } } } } }