struct RangeDecoder [src]

Fields

range: u32
code: u32

Members

Source

pub const RangeDecoder = struct { range: u32, code: u32, pub fn init(reader: anytype) !RangeDecoder { const reserved = try reader.readByte(); if (reserved != 0) { return error.CorruptInput; } return RangeDecoder{ .range = 0xFFFF_FFFF, .code = try reader.readInt(u32, .big), }; } pub fn fromParts( range: u32, code: u32, ) RangeDecoder { return .{ .range = range, .code = code, }; } pub fn set(self: *RangeDecoder, range: u32, code: u32) void { self.range = range; self.code = code; } pub inline fn isFinished(self: RangeDecoder) bool { return self.code == 0; } inline fn normalize(self: *RangeDecoder, reader: anytype) !void { if (self.range < 0x0100_0000) { self.range <<= 8; self.code = (self.code << 8) ^ @as(u32, try reader.readByte()); } } inline fn getBit(self: *RangeDecoder, reader: anytype) !bool { self.range >>= 1; const bit = self.code >= self.range; if (bit) self.code -= self.range; try self.normalize(reader); return bit; } pub fn get(self: *RangeDecoder, reader: anytype, count: usize) !u32 { var result: u32 = 0; var i: usize = 0; while (i < count) : (i += 1) result = (result << 1) ^ @intFromBool(try self.getBit(reader)); return result; } pub inline fn decodeBit(self: *RangeDecoder, reader: anytype, prob: *u16, update: bool) !bool { const bound = (self.range >> 11) * prob.*; if (self.code < bound) { if (update) prob.* += (0x800 - prob.*) >> 5; self.range = bound; try self.normalize(reader); return false; } else { if (update) prob.* -= prob.* >> 5; self.code -= bound; self.range -= bound; try self.normalize(reader); return true; } } fn parseBitTree( self: *RangeDecoder, reader: anytype, num_bits: u5, probs: []u16, update: bool, ) !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], update); tmp = (tmp << 1) ^ @intFromBool(bit); } return tmp - (@as(u32, 1) << num_bits); } pub fn parseReverseBitTree( self: *RangeDecoder, reader: anytype, num_bits: u5, probs: []u16, offset: usize, update: bool, ) !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], update)); tmp = (tmp << 1) ^ bit; result ^= @as(u32, bit) << i; } return result; } }