1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

use ::{ CumulativeDistributionFrequency };

use opus::imported_encode;

use std;

pub struct Writer<W> where W: std::io::Write {
    state: imported_encode::ec_enc<W>,
}

impl<W> Writer<W> where W: std::io::Write {
    pub fn new(out: W) -> Self {
        Self {
            state: imported_encode::ec_enc {
                out,
                end_window: 0,
                nend_bits: 0,
                nbits_total: 33,
                offs: 0,
                rng: std::u32::MAX / 2 + 1,
                rem: -1,
                val: 0,
                ext: 0,
                end_buffer: vec![],
            }
        }
    }

    /// Encode the next symbol in line.
    pub fn symbol(&mut self, index: usize, icdf: &CumulativeDistributionFrequency) -> Result<(), std::io::Error> {
        let width = icdf.width();
        let segment = icdf.at_index(index).ok_or_else(|| {
            std::io::Error::new(std::io::ErrorKind::InvalidInput, "Invalid symbol")
        })?;
        unsafe {
            imported_encode::ec_encode(&mut self.state, segment.low, segment.next, width)?;
        };
        Ok(())
    }

/*
// FIXME: I actually don't understand `bits()` well enough
// to publish it.    /// Encode a sequence of raw bits, without any frequency information.
    pub fn bits(&mut self, bits: u16, size: usize) -> Result<(), std::io::Error> {
        unsafe {
            imported_encode::ec_enc_bits(&mut self.state,
                bits as u32,
                size as u32);
            self.check_status()?;
        }
        Ok(())
    }
*/

    /// Flush and return the underlying stream.
    pub fn done(mut self) -> Result<W, std::io::Error> {
        unsafe {
            imported_encode::ec_enc_done(&mut self.state)?;
        };
        Ok(self.state.out)
    }
}