diff options
Diffstat (limited to 'evc/src/block.rs')
-rw-r--r-- | evc/src/block.rs | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/evc/src/block.rs b/evc/src/block.rs index 24691e8..04ee3d2 100644 --- a/evc/src/block.rs +++ b/evc/src/block.rs @@ -1,10 +1,9 @@ -use anyhow::bail; - use crate::{ - format::ser::{Ser, Sink, Small, Source}, + format::ser::{ConstSizeSerExt, Sink, Small, Source}, helpers::vector::Vec2, helpers::{matrix::Mat2, pixel::Pixel}, }; +use anyhow::bail; #[derive(Clone, Debug)] pub enum Block { @@ -22,16 +21,21 @@ pub struct AdvancedReference { } impl Block { - pub fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { + pub const REFZERO: Block = Block::Reference { + translation: Vec2::<isize>::ZERO, + }; + + pub fn write(&self, sink: &mut impl std::io::Write, size: Vec2<isize>) -> anyhow::Result<()> { match &self { Block::Literal(pixels) => { sink.put(0u8)?; - pixels.write(sink)?; + pixels.write_const_size(sink, size.area() as usize)?; } Block::Split(box [a, b]) => { sink.put(1u8)?; - a.write(sink)?; - b.write(sink)?; + let [asize, bsize] = split_size(size); + a.write(sink, asize)?; + b.write(sink, bsize)?; } Block::Reference { translation } => { sink.put(2u8)?; @@ -51,20 +55,9 @@ impl Block { pub fn read(source: &mut impl std::io::Read, size: Vec2<isize>) -> anyhow::Result<Self> { Ok(match source.get::<u8>()? { - 0 => Block::Literal(source.get()?), + 0 => Block::Literal(Vec::read_const_size(source, size.area() as usize)?), 1 => Block::Split(Box::new({ - let vert = size.x > size.y; - let asize = if vert { - (size.x / 2, size.y).into() - } else { - (size.x, size.y / 2).into() - }; - let bsize = if vert { - (size.x - size.x / 2, size.y).into() - } else { - (size.x, size.y - size.y / 2).into() - }; - + let [asize, bsize] = split_size(size); let a = Block::read(source, asize)?; let b = Block::read(source, bsize)?; [a, b] @@ -82,10 +75,34 @@ impl Block { } } +pub fn split_size(size: Vec2<isize>) -> [Vec2<isize>; 2] { + let vert = size.x > size.y; + [ + if vert { + (size.x / 2, size.y).into() + } else { + (size.x, size.y / 2).into() + }, + if vert { + (size.x - size.x / 2, size.y).into() + } else { + (size.x, size.y - size.y / 2).into() + }, + ] +} + impl Block { pub fn is_literal(&self) -> bool { matches!(self, Block::Literal(..)) } + pub fn is_ref_without_translation(&self) -> bool { + matches!( + self, + Block::Reference { + translation: Vec2::<isize>::ZERO + } + ) + } } impl Default for AdvancedReference { |