1use super::{Encode, EncodingStrategy};
2use crate::{Incompressible, Small};
3
4#[derive(Clone)]
5pub struct ByteContext([<bool as Encode>::Context; 256]);
6impl Default for ByteContext {
7 #[inline]
8 fn default() -> Self {
9 ByteContext([Default::default(); 256])
10 }
11}
12
13impl Encode for u8 {
14 type Context = ByteContext;
15 #[inline]
16 fn encode<E: super::EntropyCoder>(&self, writer: &mut E, ctx: &mut Self::Context) {
17 let mut filled_up = 0;
18 let mut accumulated_value = 0;
19 for i in 0..8 {
20 let ctx = &mut ctx.0[filled_up + accumulated_value];
21 let bit = (*self >> (7 - i)) & 1 == 1;
22 bit.encode(writer, ctx);
23 filled_up += 1 << i;
24 accumulated_value = 2 * accumulated_value + bit as usize;
25 }
26 }
27 #[inline]
28 fn decode<D: super::EntropyDecoder>(
29 reader: &mut D,
30 ctx: &mut Self::Context,
31 ) -> Result<Self, std::io::Error> {
32 let mut filled_up = 0;
33 let mut accumulated_value = 0;
34 for i in 0..8 {
35 let ctx = &mut ctx.0[filled_up + accumulated_value];
36 let bit = bool::decode(reader, ctx)?;
37 filled_up += 1 << i;
38 accumulated_value = 2 * accumulated_value + bit as usize;
39 }
40 Ok(accumulated_value as u8)
41 }
42}
43
44macro_rules! small_num {
45 ($t:ty, $nbits:literal, $maxval:literal, $doublemax:literal, $testname:ident) => {
46 mod $testname {
47 use super::{Encode, UBits};
48
49 #[derive(Clone)]
50 pub struct Context([<bool as Encode>::Context; $doublemax]);
51
52 impl Default for Context {
53 #[inline]
54 fn default() -> Self {
55 Self([Default::default(); $doublemax])
56 }
57 }
58
59 impl Encode for $t {
60 type Context = Context;
61 #[inline]
62 fn encode<E: super::super::EntropyCoder>(
63 &self,
64 writer: &mut E,
65 ctx: &mut Self::Context,
66 ) {
67 let value = u8::from(*self);
68 let mut filled_up = 0;
69 let mut accumulated_value = 0;
70 for i in 0..$nbits {
71 let ctx = &mut ctx.0[filled_up + accumulated_value];
72 let bit = (value >> ($nbits - 1 - i)) & 1 == 1;
73 bit.encode(writer, ctx);
74 filled_up += 1 << i;
75 accumulated_value = 2 * accumulated_value + bit as usize;
76 }
77 }
78 #[inline]
79 fn decode<D: super::super::EntropyDecoder>(
80 reader: &mut D,
81 ctx: &mut Self::Context,
82 ) -> Result<Self, std::io::Error> {
83 let mut filled_up = 0;
84 let mut accumulated_value = 0;
85 for i in 0..$nbits {
86 let ctx = &mut ctx.0[filled_up + accumulated_value];
87 let bit = bool::decode(reader, ctx)?;
88 filled_up += 1 << i;
89 accumulated_value = 2 * accumulated_value + bit as usize;
90 }
91 Ok((accumulated_value as u8).try_into().unwrap())
92 }
93 }
94
95 #[test]
96 fn test() {
97 for value in 0u8..=$maxval {
98 println!("Testing {value}");
99 let v: $t = value.try_into().unwrap();
100 let encoded = super::super::encode(&v);
101 let decoded = super::super::decode::<$t>(&encoded).unwrap();
102 assert_eq!(v, decoded);
103 assert_eq!(v.millibits(), super::super::Millibits::bits($nbits));
104 }
105 }
106 }
107 };
108}
109
110#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
114pub struct UBits<const N: u8>(u8);
115
116impl<const N: u8> From<UBits<N>> for u8 {
117 fn from(value: UBits<N>) -> u8 {
118 value.0
119 }
120}
121
122impl<const N: u8> TryFrom<u8> for UBits<N> {
123 type Error = ();
124 fn try_from(value: u8) -> Result<Self, Self::Error> {
125 if N == 8 {
126 Ok(Self(value))
127 } else if value >> N == 0 {
128 Ok(Self(value))
129 } else {
130 Err(())
131 }
132 }
133}
134
135small_num!(UBits<1>, 1, 1, 2, ub1);
136small_num!(UBits<2>, 2, 3, 4, ub2);
137small_num!(UBits<3>, 3, 7, 8, ub3);
138small_num!(UBits<4>, 4, 15, 16, ub4);
139small_num!(UBits<5>, 5, 31, 32, ub5);
140small_num!(UBits<6>, 6, 63, 64, ub6);
141small_num!(UBits<7>, 7, 127, 128, ub7);
142small_num!(UBits<8>, 8, 255, 256, ub8);
143
144impl Encode for i8 {
145 type Context = <u8 as Encode>::Context;
146 #[inline]
147 fn encode<E: super::EntropyCoder>(&self, writer: &mut E, ctx: &mut Self::Context) {
148 (*self as u8).encode(writer, ctx)
149 }
150 #[inline]
151 fn decode<D: super::EntropyDecoder>(
152 reader: &mut D,
153 ctx: &mut Self::Context,
154 ) -> Result<Self, std::io::Error> {
155 <u8 as Encode>::decode(reader, ctx).map(|v| v as i8)
156 }
157}
158
159#[derive(Default, Clone)]
160pub struct SmallContext {
161 nonzero: <UBits<3> as Encode>::Context,
162 b1: <UBits<1> as Encode>::Context,
163 b2: <UBits<2> as Encode>::Context,
164 b3: <UBits<3> as Encode>::Context,
165 b4: <UBits<4> as Encode>::Context,
166 b5: <UBits<5> as Encode>::Context,
167 need_seven_bits: <bool as Encode>::Context,
168 b6: <UBits<6> as Encode>::Context,
169 b7: <UBits<7> as Encode>::Context,
170}
171
172impl EncodingStrategy<u8> for Small {
173 type Context = SmallContext;
174 fn encode<E: super::EntropyCoder>(value: &u8, writer: &mut E, ctx: &mut Self::Context) {
175 let nonzero: UBits<3>;
176 match *value {
177 0 => {
178 nonzero = 0.try_into().unwrap();
179 nonzero.encode(writer, &mut ctx.nonzero)
180 }
181 1 => {
182 nonzero = 1.try_into().unwrap();
183 nonzero.encode(writer, &mut ctx.nonzero)
184 }
185 2..4 => {
186 nonzero = 2.try_into().unwrap();
187 nonzero.encode(writer, &mut ctx.nonzero);
188 let b1: UBits<1> = (*value - 2).try_into().unwrap();
189 b1.encode(writer, &mut ctx.b1)
190 }
191 4..8 => {
192 nonzero = 3.try_into().unwrap();
193 nonzero.encode(writer, &mut ctx.nonzero);
194 let b2: UBits<2> = (*value - 4).try_into().unwrap();
195 b2.encode(writer, &mut ctx.b2)
196 }
197 8..16 => {
198 nonzero = 4.try_into().unwrap();
199 nonzero.encode(writer, &mut ctx.nonzero);
200 let b3: UBits<3> = (*value - 8).try_into().unwrap();
201 b3.encode(writer, &mut ctx.b3)
202 }
203 16..32 => {
204 nonzero = 5.try_into().unwrap();
205 nonzero.encode(writer, &mut ctx.nonzero);
206 let b4: UBits<4> = (*value - 16).try_into().unwrap();
207 b4.encode(writer, &mut ctx.b4)
208 }
209 32..64 => {
210 nonzero = 6.try_into().unwrap();
211 nonzero.encode(writer, &mut ctx.nonzero);
212 let b5: UBits<5> = (*value - 32).try_into().unwrap();
213 b5.encode(writer, &mut ctx.b5)
214 }
215 64..128 => {
216 nonzero = 7.try_into().unwrap();
217 nonzero.encode(writer, &mut ctx.nonzero);
218 false.encode(writer, &mut ctx.need_seven_bits);
219 let b6: UBits<6> = (*value - 64).try_into().unwrap();
220 b6.encode(writer, &mut ctx.b6)
221 }
222 128..=255 => {
223 nonzero = 7.try_into().unwrap();
224 nonzero.encode(writer, &mut ctx.nonzero);
225 true.encode(writer, &mut ctx.need_seven_bits);
226 let b7: UBits<7> = (*value - 128).try_into().unwrap();
227 b7.encode(writer, &mut ctx.b7)
228 }
229 }
230 }
231 fn decode<D: super::EntropyDecoder>(
232 reader: &mut D,
233 ctx: &mut Self::Context,
234 ) -> Result<u8, std::io::Error> {
235 let nonzero: u8 = <UBits<3> as Encode>::decode(reader, &mut ctx.nonzero)?.into();
236 match nonzero {
237 0 => Ok(0),
238 1 => Ok(1),
239 2 => {
240 let rest: u8 = <UBits<1> as Encode>::decode(reader, &mut ctx.b1)?.into();
241 Ok(rest + 2)
242 }
243 3 => {
244 let rest: u8 = <UBits<2> as Encode>::decode(reader, &mut ctx.b2)?.into();
245 Ok(rest + 4)
246 }
247 4 => {
248 let rest: u8 = <UBits<3> as Encode>::decode(reader, &mut ctx.b3)?.into();
249 Ok(rest + 8)
250 }
251 5 => {
252 let rest: u8 = <UBits<4> as Encode>::decode(reader, &mut ctx.b4)?.into();
253 Ok(rest + 16)
254 }
255 6 => {
256 let rest: u8 = <UBits<5> as Encode>::decode(reader, &mut ctx.b5)?.into();
257 Ok(rest + 32)
258 }
259 7 => {
260 if <bool as Encode>::decode(reader, &mut ctx.need_seven_bits)? {
261 let rest: u8 = <UBits<7> as Encode>::decode(reader, &mut ctx.b7)?.into();
262 Ok(rest + 128)
263 } else {
264 let rest: u8 = <UBits<6> as Encode>::decode(reader, &mut ctx.b6)?.into();
265 Ok(rest + 64)
266 }
267 }
268 _ => unreachable!(),
269 }
270 }
271}
272
273impl EncodingStrategy<u8> for Incompressible {
274 type Context = ();
275 fn encode<E: super::EntropyCoder>(value: &u8, writer: &mut E, _ctx: &mut Self::Context) {
276 writer.encode_incompressible_bytes(&[*value])
277 }
278 fn decode<D: super::EntropyDecoder>(
279 reader: &mut D,
280 _ctx: &mut Self::Context,
281 ) -> Result<u8, std::io::Error> {
282 let mut byte = [0u8];
283 reader.decode_incompressible_bytes(&mut byte)?;
284 Ok(byte[0])
285 }
286}
287
288#[test]
289fn size() {
290 use super::assert_bits;
291 assert_bits!(u8::MAX, 3);
292 assert_bits!(0_u8, 8);
293 for b in 3_u8..255 {
294 println!("Byte {b}");
295 assert_bits!(b, 8);
296 }
297 assert_bits!(*b"hello", 31);
298 assert_bits!(*b"hello world", 68);
299 assert_bits!(*b"hello world, hello world", 129);
300 assert_bits!(*b"hello hello, hello hello", 111);
301 assert_bits!(*b"hello hello, hello hello, hello hello, hello hello", 195);
302 assert_bits!(*b"hhhhhhhhhhhhhhhhhhhhhhhh", 37);
303 assert_bits!(*b"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", 44);
304 assert_bits!(*b"\0", 8);
305 assert_bits!(*b"\x01", 8);
306 assert_bits!(*b"\x01\x01", 13);
307 assert_bits!(*b"\x01\x01\x01\x01", 19);
308 assert_bits!(*b"\x01\x01\x01\x01\x01", 21);
309 assert_bits!(*b"\x01\x01\x01\x01\x01\x01", 22);
310 assert_bits!(*b"\x01\x02\x03\x04", 25);
311 assert_bits!(*b"\x01\x02\x03\x04\x05", 30);
312 assert_bits!(*b"\x01\x02\x03\x04\x05\x06", 36);
313 assert_bits!(*b"\x01\x02\x03\x04\x05\x06\x07", 40);
314 assert_bits!(*b"\x01\x02\x03\x04\x05\x06\x07\x08", 47);
315
316 assert_bits!(i8::MAX, 8);
317 assert_bits!(0_i8, 8);
318}
319
320#[test]
321fn small() {
322 use super::{assert_bits, Small};
323 use crate::Encoded;
324 fn check_size(v: u8, expected: usize) {
325 println!("Checking {v}");
326 assert_eq!(
327 Encoded::<u8, Small>::new(v).millibits(),
328 super::Millibits::bits(expected)
329 );
330 assert_bits!(Encoded::<u8, Small>::new(v), expected);
331 }
332
333 for x in 0..2 {
334 check_size(x, 3);
335 }
336 for x in 2..4 {
337 check_size(x, 4);
338 }
339 for x in 4..8 {
340 check_size(x, 5);
341 }
342 for x in 8..16 {
343 check_size(x, 6);
344 }
345 for x in 16..32 {
346 check_size(x, 7);
347 }
348 for x in 32..64 {
349 check_size(x, 8);
350 }
351 for x in 64..128 {
352 check_size(x, 10);
353 }
354 for x in 128..255 {
355 check_size(x, 11);
356 }
357 assert_eq!(
358 Encoded::<u8, Small>::new(255u8).millibits(),
359 super::Millibits::bits(11)
360 );
361}