draco-oxide-core 0.1.0-alpha.7

Shared core for draco-oxide: the geometry/attribute data model, numeric primitives, and the compression algorithms shared between the encoder and decoder.
Documentation
use crate::bit_coder::BitReader;
use crate::bit_coder::ByteReader;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Symbol {
    C,
    S,
    L,
    R,
    E,
}

impl Symbol {
    #[inline]
    /// Returns the symbol as a character together with the metadata if it is a hole or handle.
    #[allow(unused)] // May be used in the future for debugging or logging.
    pub fn as_char(&self) -> (char, Option<usize>) {
        match self {
            Symbol::C => ('C', None),
            Symbol::R => ('R', None),
            Symbol::L => ('L', None),
            Symbol::E => ('E', None),
            Symbol::S => ('S', None),
        }
    }

    /// Returns the symbol id of the symbol.
    /// This id must be compatible with the draco library.
    pub fn get_id(self) -> usize {
        match self {
            Symbol::C => 0,
            Symbol::S => 1,
            Symbol::L => 2,
            Symbol::R => 3,
            Symbol::E => 4,
        }
    }
}

pub trait SymbolEncoder {
    fn encode_symbol(symbol: Symbol) -> (u8, u64);

    #[allow(dead_code)] // TODO: remove this after completing the decoder.
    fn decode_symbol<R>(reader: &mut BitReader<R>) -> Symbol
    where
        R: ByteReader;
}

pub struct CrLight;
impl SymbolEncoder for CrLight {
    fn encode_symbol(symbol: Symbol) -> (u8, u64) {
        match symbol {
            Symbol::C => (1, 0),
            Symbol::S => (3, 0b1),
            Symbol::L => (3, 0b11),
            Symbol::R => (3, 0b101),
            Symbol::E => (3, 0b111),
        }
    }

    fn decode_symbol<R>(reader: &mut BitReader<R>) -> Symbol
    where
        R: ByteReader,
    {
        if reader.read_bits(1).unwrap() == 0 {
            return Symbol::C;
        }

        if reader.read_bits(1).unwrap() == 0 {
            return Symbol::R;
        }

        match reader.read_bits(2).unwrap() {
            0b00 => Symbol::L,
            0b01 => Symbol::E,
            0b10 => Symbol::S,
            _ => panic!("Internal Error: Invalid symbol encoding"),
        }
    }
}