reading the start of the huffman tree
This commit is contained in:
parent
a80e954aa3
commit
6264dd9e87
@ -262,11 +262,10 @@ const BlockData = struct {
|
|||||||
return error.unsuported_block_type;
|
return error.unsuported_block_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.dynamic_huffman;
|
try self.dynamic_huffman();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dynamic_huffman() !void {
|
fn dynamic_huffman(self: *Self) !void {
|
||||||
var bitw = self.bitw;
|
var bitw = self.bitw;
|
||||||
|
|
||||||
var number_of_literal_codes: u32 = @as(u32, try bitw.walk(5)) + 257;
|
var number_of_literal_codes: u32 = @as(u32, try bitw.walk(5)) + 257;
|
||||||
|
20
src/utils.zig
Normal file
20
src/utils.zig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
const stderr = std.io.getStdErr().writer();
|
||||||
|
|
||||||
|
pub fn print(comptime str: []const u8, params: anytype) void {
|
||||||
|
stdout.print(str ++ "\n", params) catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn printf(comptime str: []const u8, params: anytype) void {
|
||||||
|
stdout.print(str, params) catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pErr(comptime str: []const u8, params: anytype) void {
|
||||||
|
stderr.print(str ++ "\n", params) catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exit(comptime str: []const u8, params: anytype, exitCode: u8) void {
|
||||||
|
pErr(str, params);
|
||||||
|
std.os.exit(exitCode);
|
||||||
|
}
|
153
src/walker.zig
Normal file
153
src/walker.zig
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const utils = @import("utils.zig");
|
||||||
|
|
||||||
|
pub fn BitWalkerUint(comptime T: anytype, comptime reverse: bool) type {
|
||||||
|
const typeInfo = @typeInfo(T);
|
||||||
|
|
||||||
|
if (typeInfo != .Int) {
|
||||||
|
@compileError("This needs to be a int");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeInfo.Int.signedness == .signed) {
|
||||||
|
@compileError("The integer needs to be unsigned");
|
||||||
|
}
|
||||||
|
|
||||||
|
return struct {
|
||||||
|
value: T,
|
||||||
|
mask: T,
|
||||||
|
|
||||||
|
// TODO this is probably wrong
|
||||||
|
in_byte_position: i16,
|
||||||
|
size: u8,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn init(value: T, size: u8) !Self {
|
||||||
|
if (typeInfo.Int.bits < size)
|
||||||
|
return error.invlaid_size;
|
||||||
|
|
||||||
|
var start_value: u8 = 0;
|
||||||
|
if (reverse) {
|
||||||
|
start_value = size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mask: T = 1;
|
||||||
|
var i: u8 = 0;
|
||||||
|
while (i < start_value) : (i += 1) {
|
||||||
|
mask = @shlExact(mask, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Self{
|
||||||
|
.value = value,
|
||||||
|
.in_byte_position = start_value,
|
||||||
|
.size = size,
|
||||||
|
.mask = mask,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walkBit(self: *Self) ?u1 {
|
||||||
|
if (self.mask == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var result = (self.value & self.mask) == self.mask;
|
||||||
|
|
||||||
|
if (reverse) {
|
||||||
|
self.in_byte_position -= 1;
|
||||||
|
if (self.mask == 1) {
|
||||||
|
self.mask = 0;
|
||||||
|
} else {
|
||||||
|
self.mask = @shrExact(self.mask, 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.in_byte_position += 1;
|
||||||
|
self.mask = @shlExact(self.mask, 1);
|
||||||
|
if (self.in_byte_position > self.size) {
|
||||||
|
self.mask = 0;
|
||||||
|
} else {
|
||||||
|
self.mask = @shrExact(self.mask, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return @boolToInt(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const BitWalker = struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
data: *[]u8,
|
||||||
|
position: usize = 0,
|
||||||
|
in_byte_position: u3 = 0,
|
||||||
|
direction: bool = false,
|
||||||
|
|
||||||
|
pub fn init(data: *[]u8, direction: bool) Self {
|
||||||
|
return Self{
|
||||||
|
.data = data,
|
||||||
|
.direction = direction,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bitWalk(self: *Self) !u1 {
|
||||||
|
return @intCast(u1, try self.walk(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO direction
|
||||||
|
pub fn walk(self: *Self, bits: u3) !u8 {
|
||||||
|
if (bits > 8 or bits == 0) return error.invalid_bit_number;
|
||||||
|
|
||||||
|
var byte = self.data.ptr[self.position];
|
||||||
|
|
||||||
|
// jumps over bytes
|
||||||
|
if (self.in_byte_position + @as(u4, bits) > 8) {
|
||||||
|
// Generate a mast that covers the last part of the old byte
|
||||||
|
var old_mask: u8 = 0;
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < 8 - @as(u4, self.in_byte_position)) : (i += 1) {
|
||||||
|
old_mask = @shlExact(old_mask, 1) + 1;
|
||||||
|
}
|
||||||
|
old_mask = @shlExact(old_mask, self.in_byte_position);
|
||||||
|
|
||||||
|
var next_byte = self.data.ptr[self.position + 1];
|
||||||
|
var new_byte_pos: u3 = @intCast(u3, @as(u4, bits) - (8 - @as(u4, self.in_byte_position)));
|
||||||
|
|
||||||
|
var new_mask: u8 = 0;
|
||||||
|
var j: usize = 0;
|
||||||
|
while (j < new_byte_pos) : (j += 1) {
|
||||||
|
new_mask = @shlExact(new_mask, 1) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = @shrExact(byte & old_mask, self.in_byte_position) + @shlExact(next_byte & new_mask, @intCast(u3, 8 - @as(u4, self.in_byte_position)));
|
||||||
|
|
||||||
|
//print("mask: {b}, new_mask: {b}", .{ old_mask, new_mask });
|
||||||
|
//print("here {b} {b}", .{ byte, old_mask });
|
||||||
|
//print("here_new {b} {b}", .{ next_byte, new_mask });
|
||||||
|
//print("result {}", .{result});
|
||||||
|
|
||||||
|
self.position += 1;
|
||||||
|
self.in_byte_position = new_byte_pos;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a mast that covers the last part of the old byte
|
||||||
|
var old_mask: u8 = 0;
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < bits) : (i += 1) {
|
||||||
|
old_mask = @shlExact(old_mask, 1) + 1;
|
||||||
|
}
|
||||||
|
old_mask = @shlExact(old_mask, self.in_byte_position);
|
||||||
|
|
||||||
|
const result = @shrExact(byte & old_mask, self.in_byte_position);
|
||||||
|
|
||||||
|
const sum = @intCast(u4, self.in_byte_position) + @intCast(u4, bits);
|
||||||
|
if (sum == 8) {
|
||||||
|
self.position += 1;
|
||||||
|
self.in_byte_position = 0;
|
||||||
|
} else {
|
||||||
|
self.in_byte_position += bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user