ppmd_rust/
decoder_8.rs

1use std::io::Read;
2
3use crate::{
4    internal::ppmd8::{PPMd8, RangeDecoder},
5    Error, RestoreMethod, PPMD8_MAX_MEM_SIZE, PPMD8_MAX_ORDER, PPMD8_MIN_MEM_SIZE, PPMD8_MIN_ORDER,
6    SYM_END,
7};
8
9/// A decoder to decompress data using PPMd8 (PPMdI rev.1).
10pub struct Ppmd8Decoder<R: Read> {
11    ppmd: PPMd8<RangeDecoder<R>>,
12    finished: bool,
13}
14
15unsafe impl<R: Read> Send for Ppmd8Decoder<R> {}
16unsafe impl<R: Read> Sync for Ppmd8Decoder<R> {}
17
18impl<R: Read> Ppmd8Decoder<R> {
19    /// Creates a new [`Ppmd8Decoder`] which provides a reader over the uncompressed data.
20    ///
21    /// The given `order` must be between [`PPMD8_MIN_ORDER`] and [`PPMD8_MAX_ORDER`] (inclusive).
22    /// The given `mem_size` must be between [`PPMD8_MIN_MEM_SIZE`] and [`PPMD8_MAX_MEM_SIZE`] (inclusive).
23    pub fn new(
24        reader: R,
25        order: u32,
26        mem_size: u32,
27        restore_method: RestoreMethod,
28    ) -> crate::Result<Self> {
29        if !(PPMD8_MIN_ORDER..=PPMD8_MAX_ORDER).contains(&order)
30            || !(PPMD8_MIN_MEM_SIZE..=PPMD8_MAX_MEM_SIZE).contains(&mem_size)
31        {
32            return Err(Error::InvalidParameter);
33        }
34
35        let ppmd = PPMd8::new_decoder(reader, order, mem_size, restore_method)?;
36
37        Ok(Self {
38            ppmd,
39            finished: false,
40        })
41    }
42
43    /// Gets a reference to the underlying reader.
44    pub fn get_ref(&self) -> &R {
45        self.ppmd.get_ref()
46    }
47
48    /// Gets a mutable reference to the underlying reader.
49    ///
50    /// Note that mutation of the stream may result in surprising results if
51    /// this decoder is continued to be used.
52    pub fn get_mut(&mut self) -> &mut R {
53        self.ppmd.get_mut()
54    }
55
56    /// Returns the inner reader.
57    pub fn into_inner(self) -> R {
58        self.ppmd.into_inner()
59    }
60}
61
62impl<R: Read> Read for Ppmd8Decoder<R> {
63    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
64        if self.finished {
65            return Ok(0);
66        }
67
68        if buf.is_empty() {
69            return Ok(0);
70        }
71
72        let mut sym = 0;
73        let mut decoded = 0;
74
75        for byte in buf.iter_mut() {
76            match self.ppmd.decode_symbol() {
77                Ok(symbol) => sym = symbol,
78                Err(err) => {
79                    if err.kind() == std::io::ErrorKind::UnexpectedEof {
80                        self.finished = true;
81                        return Ok(decoded);
82                    }
83                    return Err(err);
84                }
85            }
86
87            if sym < 0 {
88                break;
89            }
90
91            *byte = sym as u8;
92            decoded += 1;
93        }
94
95        let code = self.ppmd.range_decoder_code();
96
97        if sym >= 0 {
98            return Ok(decoded);
99        }
100
101        self.finished = true;
102
103        if sym != SYM_END || code != 0 {
104            return Err(std::io::Error::new(
105                std::io::ErrorKind::InvalidData,
106                "Error during PPMd decoding",
107            ));
108        }
109
110        // END_MARKER detected
111        Ok(decoded)
112    }
113}