From f074e99eca3cced4e38197c607feee5234cc8303 Mon Sep 17 00:00:00 2001 From: Muaz Ahmad Date: Wed, 6 Dec 2023 14:27:02 +0500 Subject: [PATCH] huffman gen fix, bitwriter boilerplate --- src/output.zig | 55 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/output.zig b/src/output.zig index e1a872e..54443da 100644 --- a/src/output.zig +++ b/src/output.zig @@ -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,