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
15unsafe impl<R: Read> Send for Ppmd8Decoder<R> {}
16unsafe impl<R: Read> Sync for Ppmd8Decoder<R> {}
17
18impl<R: Read> Ppmd8Decoder<R> {
19 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 pub fn get_ref(&self) -> &R {
45 self.ppmd.get_ref()
46 }
47
48 pub fn get_mut(&mut self) -> &mut R {
53 self.ppmd.get_mut()
54 }
55
56 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 Ok(decoded)
112 }
113}