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
9pub struct Ppmd8Decoder<R: Read> {
11 ppmd: PPMd8<RangeDecoder<R>>,
12 finished: bool,
13}
14
15impl<R: Read> Ppmd8Decoder<R> {
16 pub fn new(
21 reader: R,
22 order: u32,
23 mem_size: u32,
24 restore_method: RestoreMethod,
25 ) -> crate::Result<Self> {
26 if !(PPMD8_MIN_ORDER..=PPMD8_MAX_ORDER).contains(&order)
27 || !(PPMD8_MIN_MEM_SIZE..=PPMD8_MAX_MEM_SIZE).contains(&mem_size)
28 {
29 return Err(Error::InvalidParameter);
30 }
31
32 let ppmd = PPMd8::new_decoder(reader, order, mem_size, restore_method)?;
33
34 Ok(Self {
35 ppmd,
36 finished: false,
37 })
38 }
39
40 pub fn get_ref(&self) -> &R {
42 self.ppmd.get_ref()
43 }
44
45 pub fn get_mut(&mut self) -> &mut R {
50 self.ppmd.get_mut()
51 }
52
53 pub fn into_inner(self) -> R {
55 self.ppmd.into_inner()
56 }
57}
58
59impl<R: Read> Read for Ppmd8Decoder<R> {
60 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
61 if self.finished {
62 return Ok(0);
63 }
64
65 if buf.is_empty() {
66 return Ok(0);
67 }
68
69 let mut sym = 0;
70 let mut decoded = 0;
71
72 for byte in buf.iter_mut() {
73 match self.ppmd.decode_symbol() {
74 Ok(symbol) => sym = symbol,
75 Err(err) => {
76 if err.kind() == std::io::ErrorKind::UnexpectedEof {
77 self.finished = true;
78 return Ok(decoded);
79 }
80 return Err(err);
81 }
82 }
83
84 if sym < 0 {
85 break;
86 }
87
88 *byte = sym as u8;
89 decoded += 1;
90 }
91
92 let code = self.ppmd.range_decoder_code();
93
94 if sym >= 0 {
95 return Ok(decoded);
96 }
97
98 self.finished = true;
99
100 if sym != SYM_END || code != 0 {
101 return Err(std::io::Error::new(
102 std::io::ErrorKind::InvalidData,
103 "Error during PPMd decoding",
104 ));
105 }
106
107 Ok(decoded)
109 }
110}