diff options
Diffstat (limited to 'lvc/codec/src/decode.rs')
-rw-r--r-- | lvc/codec/src/decode.rs | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/lvc/codec/src/decode.rs b/lvc/codec/src/decode.rs index 771cba9..4830156 100644 --- a/lvc/codec/src/decode.rs +++ b/lvc/codec/src/decode.rs @@ -1,7 +1,42 @@ -use crate::{split::split, Block, Frame, View, P2}; +use crate::{debug::draw_debug, huff::read_huff, split::split, Block, Frame, Pixel, View, P2}; use rayon::join; +use std::io::{BufReader, BufWriter, Read, Result, Write}; -pub fn decode(last_frame: &Frame, frame: &mut Frame, view: View, block: &Block) { +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 frame = Frame::new(size); + let mut last_frame = Frame::new(size); + let mut debug_frame = if debug { Some(Frame::new(size)) } else { None }; + + let huff = true; + loop { + let b = if huff { + let mut buf = vec![]; + read_huff(&mut input, &mut buf)?; + let mut buf = std::io::Cursor::new(&mut buf); + Block::read(&mut buf, View::all(size))? + } else { + Block::read(&mut input, View::all(size))? + }; + + decode_block(&last_frame, &mut frame, View::all(size), &b); + + if let Some(debug_frame) = &mut debug_frame { + debug_frame.pixels.copy_from_slice(&frame.pixels); + draw_debug(debug_frame, View::all(size), &b); + Frame::write(&mut output, &debug_frame)?; + } else { + Frame::write(&mut output, &frame)?; + } + + last_frame.pixels.copy_from_slice(&frame.pixels); // TODO use mem::swap + frame.pixels.iter_mut().for_each(|e| *e = Pixel::BLACK); + } +} + +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) => { @@ -9,8 +44,8 @@ pub fn decode(last_frame: &Frame, frame: &mut Frame, view: View, block: &Block) let (frame1, frame2) = unsafe { (&mut *(frame as *mut Frame), &mut *(frame as *mut Frame)) }; join( - || decode(last_frame, frame1, av, &a), - || decode(last_frame, frame2, bv, &b), + || decode_block(last_frame, frame1, av, &a), + || decode_block(last_frame, frame2, bv, &b), ); } Block::Ref(r) => { |