kiss2d 0.1.6

KISS 2d graphics engine
Documentation
struct BitFilter {
    accu: u32,
    bits: isize,
}

impl BitFilter {
    pub fn new() -> Self {
        Self {
            bits: 0,
            accu: 0,
        }
    }

    pub fn write<F>(&mut self, mut buf: &[u8], mut nbits: usize, mut shift: usize, mut putc: F)
        where F: FnMut(u8)
    {
        let mut accu = self.accu;
        let mut bits = self.bits;

        buf = &buf[shift / 8..];
        shift %= 8;

        while nbits != 0 || bits >= 8 {
            while bits >= 8 {
                bits -= 8;
                putc((accu >> bits) as u8);
                accu &= (1 << bits) - 1;
            }
            while bits < 8 && nbits != 0 {
                accu = (accu << 1) | (((128 >> shift) & buf[0]) >> (7 - shift)) as u32;
                nbits -= 1;
                bits += 1;
                shift += 1;
                if shift == 8 {
                    shift = 0;
                    buf = &buf[1..];
                }
            }
        }

        self.accu = accu;
        self.bits = bits;
    }

    pub fn read<F>(&mut self, mut buf: &mut [u8], mut nbits: usize, mut shift: usize, mut getc: F)
        where F: FnMut() -> u8
    {
        let mut accu = self.accu;
        let mut bits = self.bits;

        buf = &mut buf[shift / 8..];
        shift %= 8;

        while nbits != 0 {
            while bits != 0 && nbits != 0 {
                let mask = 128 >> shift;
                if accu & (1 << (bits - 1)) != 0 {
                    buf[0] |= mask;
                } else {
                    buf[0] &= !mask;
                }

                nbits -= 1;
                bits -= 1;
                shift += 1;
                if shift >= 8 {
                    shift = 0;
                    buf = &mut buf[1..];
                }
            }

            if nbits == 0 { break }
            accu = (accu << 8) | getc() as u32;
            bits += 8;
        }

        self.accu = accu;
        self.bits = bits;
    }

    pub fn write_end<F>(mut self, mut putc: F)
        where F: FnMut(u8)
    {
        if self.bits != 0 {
            self.accu <<= 8 - self.bits;
            putc(self.accu as u8)
        }
    }
}

#[test]
fn common() {
    let src = b"abcdefghijk";
    let mut dst = [0u8; 11];

    let mut f = Vec::new();
    let mut b = BitFilter::new();
    // for each byte in s, write 7 bits skipping 1
    for i in 0..10 {
        b.write(&src[i..], 7, 1, |c| f.push(c));
    }
    b.write_end(|c| f.push(c));

    // read 7 bits and expand to each byte of s2 skipping 1 bit
    let mut b = BitFilter::new();
    for i in 0..10 {
        b.read(&mut dst[i..], 7, 1, || f.remove(0));
    }

    // should be the same first 10 bytes as in s
    assert_eq!(&src[..10], &dst[..10]);
}