dsi_bitstream/codes/
zeta.rs1use super::{MinimalBinaryRead, MinimalBinaryWrite, len_minimal_binary, zeta_tables};
36use crate::traits::*;
37
38#[must_use]
40#[inline(always)]
41#[allow(clippy::collapsible_if)]
42pub fn len_zeta_param<const USE_TABLE: bool>(mut n: u64, k: usize) -> usize {
43 debug_assert!(k >= 1);
44 if USE_TABLE {
45 if k == zeta_tables::K {
46 if let Some(idx) = zeta_tables::LEN.get(n as usize) {
47 return *idx as usize;
48 }
49 }
50 }
51 debug_assert!(n < u64::MAX);
52 n += 1;
53 let h = n.ilog2() as usize / k;
54 let l = 1 << (h * k);
55 h + 1 + len_minimal_binary(n - l, (l << k).wrapping_sub(l))
56}
57
58#[inline(always)]
61pub fn len_zeta(n: u64, k: usize) -> usize {
62 len_zeta_param::<true>(n, k)
63}
64
65pub trait ZetaRead<E: Endianness>: BitRead<E> {
69 fn read_zeta(&mut self, k: usize) -> Result<u64, Self::Error>;
70 fn read_zeta3(&mut self) -> Result<u64, Self::Error>;
71}
72
73pub trait ZetaReadParam<E: Endianness>: MinimalBinaryRead<E> {
82 fn read_zeta_param(&mut self, k: usize) -> Result<u64, Self::Error>;
83 fn read_zeta3_param<const USE_TABLE: bool>(&mut self) -> Result<u64, Self::Error>;
84}
85
86impl<B: BitRead<BE>> ZetaReadParam<BE> for B {
87 #[inline(always)]
88 fn read_zeta_param(&mut self, k: usize) -> Result<u64, B::Error> {
89 default_read_zeta(self, k)
90 }
91
92 #[inline(always)]
93 fn read_zeta3_param<const USE_TABLE: bool>(&mut self) -> Result<u64, B::Error> {
94 if USE_TABLE {
95 if let Some((res, _)) = zeta_tables::read_table_be(self) {
96 return Ok(res);
97 }
98 }
99 default_read_zeta(self, 3)
100 }
101}
102
103impl<B: BitRead<LE>> ZetaReadParam<LE> for B {
104 #[inline(always)]
105 fn read_zeta_param(&mut self, k: usize) -> Result<u64, B::Error> {
106 default_read_zeta(self, k)
107 }
108
109 #[inline(always)]
110 fn read_zeta3_param<const USE_TABLE: bool>(&mut self) -> Result<u64, B::Error> {
111 if USE_TABLE {
112 if let Some((res, _)) = zeta_tables::read_table_le(self) {
113 return Ok(res);
114 }
115 }
116 default_read_zeta(self, 3)
117 }
118}
119
120#[inline(always)]
123fn default_read_zeta<BO: Endianness, B: BitRead<BO>>(
124 backend: &mut B,
125 k: usize,
126) -> Result<u64, B::Error> {
127 debug_assert!(k >= 1);
128 let h = backend.read_unary()? as usize;
129 debug_assert!(h * k < 64);
130 let l = 1_u64 << (h * k);
131 let res = backend.read_minimal_binary((l << k).wrapping_sub(l))?;
132 Ok(l + res - 1)
133}
134
135pub trait ZetaWrite<E: Endianness>: BitWrite<E> {
139 fn write_zeta(&mut self, n: u64, k: usize) -> Result<usize, Self::Error>;
140 fn write_zeta3(&mut self, n: u64) -> Result<usize, Self::Error>;
141}
142
143pub trait ZetaWriteParam<E: Endianness>: MinimalBinaryWrite<E> {
152 fn write_zeta_param<const USE_TABLE: bool>(
153 &mut self,
154 n: u64,
155 k: usize,
156 ) -> Result<usize, Self::Error>;
157 fn write_zeta3_param<const USE_TABLE: bool>(&mut self, n: u64) -> Result<usize, Self::Error>;
158}
159
160impl<B: BitWrite<BE>> ZetaWriteParam<BE> for B {
161 #[inline(always)]
162 fn write_zeta_param<const USE_TABLE: bool>(
163 &mut self,
164 n: u64,
165 k: usize,
166 ) -> Result<usize, Self::Error> {
167 default_write_zeta(self, n, k)
168 }
169
170 #[inline(always)]
171 #[allow(clippy::collapsible_if)]
172 fn write_zeta3_param<const USE_TABLE: bool>(&mut self, n: u64) -> Result<usize, Self::Error> {
173 if USE_TABLE {
174 if let Some(len) = zeta_tables::write_table_be(self, n)? {
175 return Ok(len);
176 }
177 }
178 default_write_zeta(self, n, 3)
179 }
180}
181
182impl<B: BitWrite<LE>> ZetaWriteParam<LE> for B {
183 #[inline(always)]
184 fn write_zeta_param<const USE_TABLE: bool>(
185 &mut self,
186 n: u64,
187 k: usize,
188 ) -> Result<usize, Self::Error> {
189 default_write_zeta(self, n, k)
190 }
191
192 #[inline(always)]
193 #[allow(clippy::collapsible_if)]
194 fn write_zeta3_param<const USE_TABLE: bool>(&mut self, n: u64) -> Result<usize, Self::Error> {
195 if USE_TABLE {
196 if let Some(len) = zeta_tables::write_table_le(self, n)? {
197 return Ok(len);
198 }
199 }
200 default_write_zeta(self, n, 3)
201 }
202}
203
204#[inline(always)]
207fn default_write_zeta<E: Endianness, B: BitWrite<E>>(
208 backend: &mut B,
209 mut n: u64,
210 k: usize,
211) -> Result<usize, B::Error> {
212 debug_assert!(k >= 1);
213 debug_assert!(n < u64::MAX);
214 n += 1;
215 let h = n.ilog2() as usize / k;
216 let l = 1 << (h * k);
217
218 debug_assert!(l <= n, "{} <= {}", l, n);
219
220 Ok(backend.write_unary(h as u64)?
222 + backend.write_minimal_binary(n - l, (l << k).wrapping_sub(l))?)
223}