dsi_bitstream/codes/
zeta.rs1use super::{MinimalBinaryRead, MinimalBinaryWrite, len_minimal_binary, zeta_tables};
41use crate::traits::*;
42
43#[must_use]
45#[inline(always)]
46#[allow(clippy::collapsible_if)]
47pub const fn len_zeta_param<const USE_TABLE: bool>(mut n: u64, k: usize) -> usize {
48 debug_assert!(k >= 1);
49 if USE_TABLE {
50 if k == zeta_tables::K {
51 if n < zeta_tables::LEN.len() as u64 {
53 return zeta_tables::LEN[n as usize] as usize;
54 }
55 }
56 }
57 debug_assert!(n < u64::MAX);
58 n += 1;
59 let h = n.ilog2() as usize / k;
60 let l = 1 << (h * k);
61 h + 1 + len_minimal_binary(n - l, (l << k).wrapping_sub(l))
62}
63
64#[must_use]
67#[inline(always)]
68pub const fn len_zeta(n: u64, k: usize) -> usize {
69 len_zeta_param::<true>(n, k)
70}
71
72pub trait ZetaRead<E: Endianness>: BitRead<E> {
76 fn read_zeta(&mut self, k: usize) -> Result<u64, Self::Error>;
77 fn read_zeta3(&mut self) -> Result<u64, Self::Error>;
78}
79
80pub trait ZetaReadParam<E: Endianness>: BitRead<E> {
89 fn read_zeta_param(&mut self, k: usize) -> Result<u64, Self::Error>;
90 fn read_zeta3_param<const USE_TABLE: bool>(&mut self) -> Result<u64, Self::Error>;
91}
92
93impl<B: BitRead<BE>> ZetaReadParam<BE> for B {
94 #[inline(always)]
95 fn read_zeta_param(&mut self, k: usize) -> Result<u64, B::Error> {
96 default_read_zeta(self, k)
97 }
98
99 #[inline(always)]
100 fn read_zeta3_param<const USE_TABLE: bool>(&mut self) -> Result<u64, B::Error> {
101 const {
102 if USE_TABLE {
103 zeta_tables::check_read_table(B::PEEK_BITS)
104 }
105 }
106 if USE_TABLE {
107 if let Some((res, _)) = zeta_tables::read_table_be(self) {
108 return Ok(res);
109 }
110 }
111 default_read_zeta(self, 3)
112 }
113}
114
115impl<B: BitRead<LE>> ZetaReadParam<LE> for B {
116 #[inline(always)]
117 fn read_zeta_param(&mut self, k: usize) -> Result<u64, B::Error> {
118 default_read_zeta(self, k)
119 }
120
121 #[inline(always)]
122 fn read_zeta3_param<const USE_TABLE: bool>(&mut self) -> Result<u64, B::Error> {
123 const {
124 if USE_TABLE {
125 zeta_tables::check_read_table(B::PEEK_BITS)
126 }
127 }
128 if USE_TABLE {
129 if let Some((res, _)) = zeta_tables::read_table_le(self) {
130 return Ok(res);
131 }
132 }
133 default_read_zeta(self, 3)
134 }
135}
136
137#[inline(always)]
140fn default_read_zeta<BO: Endianness, B: BitRead<BO>>(
141 backend: &mut B,
142 k: usize,
143) -> Result<u64, B::Error> {
144 debug_assert!(k >= 1);
145 let h = backend.read_unary()? as usize;
146 debug_assert!(h * k < 64);
147 let l = 1_u64 << (h * k);
148 let res = backend.read_minimal_binary((l << k).wrapping_sub(l))?;
149 Ok(l + res - 1)
150}
151
152pub trait ZetaWrite<E: Endianness>: BitWrite<E> {
156 fn write_zeta(&mut self, n: u64, k: usize) -> Result<usize, Self::Error>;
157 fn write_zeta3(&mut self, n: u64) -> Result<usize, Self::Error>;
158}
159
160pub trait ZetaWriteParam<E: Endianness>: BitWrite<E> {
169 fn write_zeta_param(&mut self, n: u64, k: usize) -> Result<usize, Self::Error>;
170 fn write_zeta3_param<const USE_TABLE: bool>(&mut self, n: u64) -> Result<usize, Self::Error>;
171}
172
173impl<B: BitWrite<BE>> ZetaWriteParam<BE> for B {
174 #[inline(always)]
175 fn write_zeta_param(&mut self, n: u64, k: usize) -> Result<usize, Self::Error> {
176 default_write_zeta(self, n, k)
177 }
178
179 #[inline(always)]
180 #[allow(clippy::collapsible_if)]
181 fn write_zeta3_param<const USE_TABLE: bool>(&mut self, n: u64) -> Result<usize, Self::Error> {
182 if USE_TABLE {
183 if let Some(len) = zeta_tables::write_table_be(self, n)? {
184 return Ok(len);
185 }
186 }
187 default_write_zeta(self, n, 3)
188 }
189}
190
191impl<B: BitWrite<LE>> ZetaWriteParam<LE> for B {
192 #[inline(always)]
193 fn write_zeta_param(&mut self, n: u64, k: usize) -> Result<usize, Self::Error> {
194 default_write_zeta(self, n, k)
195 }
196
197 #[inline(always)]
198 #[allow(clippy::collapsible_if)]
199 fn write_zeta3_param<const USE_TABLE: bool>(&mut self, n: u64) -> Result<usize, Self::Error> {
200 if USE_TABLE {
201 if let Some(len) = zeta_tables::write_table_le(self, n)? {
202 return Ok(len);
203 }
204 }
205 default_write_zeta(self, n, 3)
206 }
207}
208
209#[inline(always)]
212fn default_write_zeta<E: Endianness, B: BitWrite<E>>(
213 backend: &mut B,
214 mut n: u64,
215 k: usize,
216) -> Result<usize, B::Error> {
217 debug_assert!(k >= 1);
218 debug_assert!(n < u64::MAX);
219 n += 1;
220 let h = n.ilog2() as usize / k;
221 let l = 1 << (h * k);
222
223 debug_assert!(l <= n, "{} <= {}", l, n);
224
225 Ok(backend.write_unary(h as u64)?
227 + backend.write_minimal_binary(n - l, (l << k).wrapping_sub(l))?)
228}