huffman gen fix, bitwriter boilerplate
This commit is contained in:
parent
768e428e9a
commit
f074e99eca
1 changed files with 50 additions and 5 deletions
|
@ -19,6 +19,44 @@ const HuffmanMeta = struct {
|
|||
huffval: [256]u8,
|
||||
};
|
||||
|
||||
const BitWriter = struct {
|
||||
f: std.fs.File,
|
||||
buff: [8]u8,
|
||||
curr_buff_idx: usize,
|
||||
curr_bit_used: u4,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
fn init(f: std.fs.File) Self {
|
||||
return Self{
|
||||
.f = f,
|
||||
.buff = [_]u8{0x00} ** 8,
|
||||
.curr_buff_idx = 0,
|
||||
.curr_bit_used = 0,
|
||||
};
|
||||
}
|
||||
|
||||
fn write_until_eob(self: *Self, units: []RLE_Unit, idx_ptr: *usize, dc_huff: *Huffman, ac_huff: *Huffman) !void {
|
||||
var i = idx_ptr.*;
|
||||
defer idx_ptr.* = i;
|
||||
|
||||
try self.write_value(dc_huff.get(units[i].symbol).?, if (units[i].value >= 0) units[i].value else -units[i].value, units[i].symbol & 0x0f);
|
||||
i += 1;
|
||||
while (units[i].symbol != 0x00) : (i += 1) {
|
||||
try self.write_value(ac_huff.get(units[i].symbol).?, units[i].value, units[i].symbol & 0x0f);
|
||||
}
|
||||
try self.write_value(ac_huff.get(units[i].symbol).?, units[i].value, units[i].symbol & 0x0f);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
fn write_value(self: *Self, huffcode: HuffCode, value: i16, val_bits: u8) !void {
|
||||
_ = val_bits;
|
||||
_ = value;
|
||||
_ = huffcode;
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
|
||||
const Scan = struct {
|
||||
arena: std.heap.ArenaAllocator,
|
||||
root_alloc: std.mem.Allocator,
|
||||
|
@ -80,8 +118,16 @@ const Scan = struct {
|
|||
}
|
||||
|
||||
fn dump_scan(self: *Self, f: std.fs.File) !void {
|
||||
_ = self;
|
||||
_ = try f.write(&[_]u8{ 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 });
|
||||
var bw = BitWriter.init(f);
|
||||
var idxs = [3]usize{ 0, 0, 0 };
|
||||
while (idxs[0] < self.rles[0].items.len and idxs[1] < self.rles[1].items.len and idxs[2] < self.rles[2].items.len) {
|
||||
for (0..4) |_| {
|
||||
try bw.write_until_eob(self.rles[0].items, &idxs[0], &self.huffs[0], &self.huffs[1]);
|
||||
}
|
||||
try bw.write_until_eob(self.rles[1].items, &idxs[1], &self.huffs[2], &self.huffs[3]);
|
||||
try bw.write_until_eob(self.rles[2].items, &idxs[2], &self.huffs[2], &self.huffs[3]);
|
||||
}
|
||||
|
||||
_ = try f.write(&[2]u8{ 0xff, 0xd9 });
|
||||
}
|
||||
|
@ -130,8 +176,8 @@ inline fn gen_codes(huff: *Huffman, huffman_meta: HuffmanMeta) !void {
|
|||
var huffcode = [_]u16{0} ** 256;
|
||||
|
||||
var k: usize = 0;
|
||||
var j: usize = 0;
|
||||
for (0..17) |i| {
|
||||
var j: usize = 1;
|
||||
for (1..17) |i| {
|
||||
while (j <= huffman_meta.bits[i]) {
|
||||
huffsize[k] = @truncate(i);
|
||||
k += 1;
|
||||
|
@ -164,7 +210,7 @@ inline fn gen_codes(huff: *Huffman, huffman_meta: HuffmanMeta) !void {
|
|||
}
|
||||
|
||||
for (0..total_k) |x| {
|
||||
try huff.put(@truncate(x), HuffCode{
|
||||
try huff.put(huffman_meta.huffval[x], HuffCode{
|
||||
.n_bits = huffsize[x],
|
||||
.value = huffcode[x],
|
||||
});
|
||||
|
@ -225,7 +271,6 @@ inline fn gen_huffman(freqs: []u32) HuffmanMeta {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return .{
|
||||
.bits = bits,
|
||||
.huffval = huffval,
|
||||
|
|
Loading…
Reference in a new issue