diff --git a/src/output.zig b/src/output.zig index 76fc9cd..df40b31 100644 --- a/src/output.zig +++ b/src/output.zig @@ -9,9 +9,14 @@ const RLE_Unit = struct { }; const Huffman = std.AutoHashMap(u8, HuffCode); -const HuffCode = struct { - n_bits: u8, - value: u16, +// const HuffCode = struct { +// n_bits: u8, +// value: u16, +// }; +const HuffCode = u16; +const HuffmanMeta = struct { + bits: [33]u8, + huffval: [256]u8, }; const Scan = struct { @@ -20,23 +25,27 @@ const Scan = struct { dc_diffs: [3]i16, rles: [3]RLE_Seq, freqs: [4][]u32, - huffs: [4]Huffman, + huffs: [4]*Huffman, const Self = @This(); fn init(alloc_root: std.mem.Allocator) !Self { var arena = std.heap.ArenaAllocator.init(alloc_root); var alloc = arena.allocator(); - return Self{ .root_alloc = alloc_root, .arena = arena, .dc_diffs = [3]i16{ 0, 0, 0 }, .rles = [3]RLE_Seq{ + var self = Self{ .root_alloc = alloc_root, .arena = arena, .dc_diffs = [3]i16{ 0, 0, 0 }, .rles = [3]RLE_Seq{ RLE_Seq.init(alloc_root), RLE_Seq.init(alloc_root), RLE_Seq.init(alloc_root), - }, .freqs = [4][]u32{ try alloc.alloc(u32, 13), try alloc.alloc(u32, 257), try alloc.alloc(u32, 13), try alloc.alloc(u32, 257) }, .huffs = [4]Huffman{ - Huffman.init(alloc), - Huffman.init(alloc), - Huffman.init(alloc), - Huffman.init(alloc), + }, .freqs = [4][]u32{ try alloc.alloc(u32, 13), try alloc.alloc(u32, 257), try alloc.alloc(u32, 13), try alloc.alloc(u32, 257) }, .huffs = [4]*Huffman{ + try alloc.create(Huffman), + try alloc.create(Huffman), + try alloc.create(Huffman), + try alloc.create(Huffman), } }; + for (0..4) |i| { + self.huffs[i].* = Huffman.init(alloc); + } + return self; } fn deinit(self: *Self) void { self.arena.deinit(); @@ -66,8 +75,12 @@ const Scan = struct { } fn generate_huffmans(self: *Self) !void { - for (0..4) |i| { - try gen_huffman(&self.huffs[i], self.freqs[i]); + for (0..4) |i_freq| { + const huffman_meta = gen_huffman(self.freqs[i_freq]); + _ = huffman_meta; + var huff = self.huffs[i_freq]; + std.debug.print("{any}\n", .{huff}); + try huff.put(0, 1); } } }; @@ -110,9 +123,54 @@ inline fn get_idx_min2(freqs: []u32) ?struct { usize, usize } { } else null; } -inline fn gen_huffman(huff: *Huffman, freqs: []u32) !void { +inline fn gen_codes(huff: *Huffman, huffman_meta: HuffmanMeta) !void { + var huffsize = [_]u5{0} ** 256; + var huffcode = [_]u16{0} ** 256; + + var k: usize = 0; + var j: usize = 0; + for (0..17) |i| { + while (j <= huffman_meta.bits[i]) { + huffsize[k] = @truncate(i); + k += 1; + j += 1; + } + j = 1; + } + huffsize[k] = 0; + const total_k = k + 1; + + k = 0; + var code: usize = 0; + var si = huffsize[0]; + while (true) { + huffcode[k] = @truncate(code); + code += 1; + k += 1; + if (huffsize[k] == si) { + continue; + } + if (huffsize[k] == 0) { + break; + } + code <<= 1; + si += 1; + while (huffsize[k] != si) { + code <<= 1; + si += 1; + } + } + + for (0..total_k) |x| { + try huff.put(@truncate(x), HuffCode{ + .n_bits = huffsize[x], + .value = huffcode[x], + }); + } +} + +inline fn gen_huffman(freqs: []u32) HuffmanMeta { freqs[freqs.len - 1] = 1; - _ = huff; var codesizes = [_]u8{0} ** 257; var others = [_]u9{0x1ff} ** 257; while (get_idx_min2(freqs)) |tmp| { @@ -166,7 +224,10 @@ inline fn gen_huffman(huff: *Huffman, freqs: []u32) !void { } } - std.debug.print("{any}\n{any}\n\n", .{ bits, huffval }); + return .{ + .bits = bits, + .huffval = huffval, + }; } inline fn get_size(n: i16) u8 {