structstd.compress.lzma.decode.rangecoder.RangeDecoder[src]

Fields

range: u32
code: u32

Functions

Functioninit[src]

pub fn init(reader: anytype) !RangeDecoder

Source Code

Source code
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),
    };
}

FunctionfromParts[src]

pub fn fromParts( range: u32, code: u32, ) RangeDecoder

Parameters

range: u32
code: u32

Source Code

Source code
pub fn fromParts(
    range: u32,
    code: u32,
) RangeDecoder {
    return .{
        .range = range,
        .code = code,
    };
}

Functionset[src]

pub fn set(self: *RangeDecoder, range: u32, code: u32) void

Parameters

range: u32
code: u32

Source Code

Source code
pub fn set(self: *RangeDecoder, range: u32, code: u32) void {
    self.range = range;
    self.code = code;
}

FunctionisFinished[src]

pub inline fn isFinished(self: RangeDecoder) bool

Parameters

Source Code

Source code
pub inline fn isFinished(self: RangeDecoder) bool {
    return self.code == 0;
}

Functionget[src]

pub fn get(self: *RangeDecoder, reader: anytype, count: usize) !u32

Parameters

count: usize

Source Code

Source code
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;
}

FunctiondecodeBit[src]

pub inline fn decodeBit(self: *RangeDecoder, reader: anytype, prob: *u16, update: bool) !bool

Parameters

prob: *u16
update: bool

Source Code

Source code
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;
    }
}

FunctionparseReverseBitTree[src]

pub fn parseReverseBitTree( self: *RangeDecoder, reader: anytype, num_bits: u5, probs: []u16, offset: usize, update: bool, ) !u32

Parameters

num_bits: u5
probs: []u16
offset: usize
update: bool

Source Code

Source code
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;
}

Source Code

Source code
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;
    }
}