From 490a3c95f92c727eed4d60959460b3c9082db67a Mon Sep 17 00:00:00 2001 From: Monty Montgomery Date: Thu, 14 May 2020 03:10:19 -0400 Subject: [PATCH] Widen useful range of BitWriter's write_quniform() The versions of write_quiniform() used by the arithmetic packer and the uncompressed bitwriter vary considerably. For some reason, the BitWriter uses a much 'narrower' implementation that overflows with inputs of more than a few bits. This patch replaces the BitWriter's implementation with one like in the arithmetic packer. This allows its use in coding non-uniform tile header fields. --- src/ec.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ec.rs b/src/ec.rs index 12af200091..5be36dc0a4 100644 --- a/src/ec.rs +++ b/src/ec.rs @@ -804,17 +804,17 @@ impl BCodeWriter for BitWriter { } } fn write_quniform(&mut self, n: u16, v: u16) -> Result<(), std::io::Error> { - /* Encodes a value v in [0, n-1] quasi-uniformly */ - if n <= 1 { - return Ok(()); - }; - let l = 31 ^ ((n - 1) + 1).leading_zeros(); - let m = (1 << l) - n; - if v < m { - self.write(l - 1, v) + if n > 1 { + let l = msb(n as i32) as u8 + 1; + let m = (1 << l) - n; + if v < m { + self.write(l as u32 - 1, v) + } else { + self.write(l as u32 - 1, m + ((v - m) >> 1))?; + self.write(1, (v - m) & 1) + } } else { - self.write(l - 1, m + ((v - m) >> 1))?; - self.write_bit(((v - m) & 1) != 0) + Ok(()) } } fn write_subexpfin(