"""LSB-first bit reader/writer (Vorbis bit packing order).""" class BitReader: def __init__(self, data: bytes, bitpos: int = 0): self.data = data self.pos = bitpos def get(self, n: int) -> int: v = 0 for i in range(n): byte = self.data[(self.pos >> 3)] if (self.pos >> 3) < len(self.data) else 0 v |= ((byte >> (self.pos & 7)) & 1) << i self.pos += 1 return v def bits_left(self) -> int: return len(self.data) * 8 - self.pos class BitWriter: def __init__(self): self.buf = bytearray() self.pos = 0 def put(self, n: int, v: int): for i in range(n): if (self.pos >> 3) >= len(self.buf): self.buf.append(0) if (v >> i) & 1: self.buf[self.pos >> 3] |= 1 << (self.pos & 7) self.pos += 1 def put_bits_from(self, r: BitReader, n: int): """Copy n bits from a reader (fast path in 32-bit chunks).""" while n > 0: k = 32 if n >= 32 else n self.put(k, r.get(k)) n -= k def bytes(self) -> bytes: return bytes(self.buf) def ilog(v: int) -> int: r = 0 while v: r += 1 v >>= 1 return r def book_maptype1_quantvals(entries: int, dims: int) -> int: bits = ilog(entries) vals = entries >> ((bits - 1) * (dims - 1) // dims) while True: acc = 1 acc1 = 1 for _ in range(dims): acc *= vals acc1 *= vals + 1 if acc <= entries < acc1: return vals if acc > entries: vals -= 1 else: vals += 1