struct RangeDecoder [src]

Fields

range: u32
code: u32

Members

Source

pub const RangeDecoder = struct { range: u32, code: u32, pub fn init(reader: *Reader) !RangeDecoder { var counter: u64 = 0; return initCounting(reader, &counter); } pub fn initCounting(reader: *Reader, n_read: *u64) !RangeDecoder { const reserved = try reader.takeByte(); n_read.* += 1; if (reserved != 0) return error.InvalidRangeCode; const code = try reader.takeInt(u32, .big); n_read.* += 4; return .{ .range = 0xFFFF_FFFF, .code = code, }; } pub fn isFinished(self: RangeDecoder) bool { return self.code == 0; } fn normalize(self: *RangeDecoder, reader: *Reader, n_read: *u64) !void { if (self.range < 0x0100_0000) { self.range <<= 8; self.code = (self.code << 8) ^ @as(u32, try reader.takeByte()); n_read.* += 1; } } fn getBit(self: *RangeDecoder, reader: *Reader, n_read: *u64) !bool { self.range >>= 1; const bit = self.code >= self.range; if (bit) self.code -= self.range; try self.normalize(reader, n_read); return bit; } pub fn get(self: *RangeDecoder, reader: *Reader, count: usize, n_read: *u64) !u32 { var result: u32 = 0; for (0..count) |_| { result = (result << 1) ^ @intFromBool(try self.getBit(reader, n_read)); } return result; } pub fn decodeBit(self: *RangeDecoder, reader: *Reader, prob: *u16, n_read: *u64) !bool { const bound = (self.range >> 11) * prob.*; if (self.code < bound) { prob.* += (0x800 - prob.*) >> 5; self.range = bound; try self.normalize(reader, n_read); return false; } else { prob.* -= prob.* >> 5; self.code -= bound; self.range -= bound; try self.normalize(reader, n_read); return true; } } fn parseBitTree( self: *RangeDecoder, reader: *Reader, num_bits: u5, probs: []u16, n_read: *u64, ) !u32 { var tmp: u32 = 1; var i: @TypeOf(num_bits) = 0; while (i < num_bits) : (i += 1) { const bit = try self.decodeBit(reader, &probs[tmp], n_read); tmp = (tmp << 1) ^ @intFromBool(bit); } return tmp - (@as(u32, 1) << num_bits); } pub fn parseReverseBitTree( self: *RangeDecoder, reader: *Reader, num_bits: u5, probs: []u16, offset: usize, n_read: *u64, ) !u32 { var result: u32 = 0; var tmp: usize = 1; var i: @TypeOf(num_bits) = 0; while (i < num_bits) : (i += 1) { const bit = @intFromBool(try self.decodeBit(reader, &probs[offset + tmp], n_read)); tmp = (tmp << 1) ^ bit; result ^= @as(u32, bit) << i; } return result; } }