From 4bc436d92bd6b963fa6a34a703e66021fdeab502 Mon Sep 17 00:00:00 2001 From: Muaz Ahmad Date: Mon, 4 Dec 2023 16:45:30 +0500 Subject: [PATCH] proper init, initial header file write, huffman generation done --- src/main.zig | 2 +- src/output.zig | 58 +++++++++++++++++++++++++++++++++----------------- src/util.zig | 4 +--- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/main.zig b/src/main.zig index 8209587..de05866 100644 --- a/src/main.zig +++ b/src/main.zig @@ -58,7 +58,7 @@ fn get_opts() !util.Options { pub fn main() !void { const opts = try get_opts(); - var buffs = try util.Buffers.init(std.heap.page_allocator, opts.width, opts.height, 1000, opts.quality); + var buffs = try util.Buffers.init(std.heap.page_allocator, opts.width, opts.height, opts.quality); defer buffs.deinit(); var thread_manager = try threads.ThreadManager.init(std.heap.page_allocator, opts.n_quant_jobs, buffs.Q_Lum, buffs.Q_Chrom); diff --git a/src/output.zig b/src/output.zig index df40b31..e9b1165 100644 --- a/src/output.zig +++ b/src/output.zig @@ -13,9 +13,13 @@ const Huffman = std.AutoHashMap(u8, HuffCode); // n_bits: u8, // value: u16, // }; -const HuffCode = u16; +const HuffCode = struct { + value: u16, + n_bits: u5, +}; const HuffmanMeta = struct { bits: [33]u8, + total_n: usize, huffval: [256]u8, }; @@ -25,7 +29,7 @@ const Scan = struct { dc_diffs: [3]i16, rles: [3]RLE_Seq, freqs: [4][]u32, - huffs: [4]*Huffman, + huffs: [4]Huffman, const Self = @This(); @@ -36,15 +40,12 @@ const Scan = struct { 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{ - try alloc.create(Huffman), - try alloc.create(Huffman), - try alloc.create(Huffman), - try alloc.create(Huffman), + }, .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_root), + Huffman.init(alloc_root), + Huffman.init(alloc_root), + Huffman.init(alloc_root), } }; - for (0..4) |i| { - self.huffs[i].* = Huffman.init(alloc); - } return self; } fn deinit(self: *Self) void { @@ -54,7 +55,7 @@ const Scan = struct { } } - fn do_rle_freq_pass(self: *Self, buff: *const util.Buffers) !void { + fn do_rle_freq_pass(self: *Self, buff: *const util.Buffers, f: std.fs.File) !void { const h = buff.Y_quant.len; const w = buff.Y_quant[0].len; @@ -71,16 +72,14 @@ const Scan = struct { try parse_block(&buff.V_quant[x][y], &self.dc_diffs[2], &self.rles[2], self.freqs[2], self.freqs[3]); } } - try self.generate_huffmans(); + try self.generate_huffmans(f); } - fn generate_huffmans(self: *Self) !void { - 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); + fn generate_huffmans(self: *Self, f: std.fs.File) !void { + for (0..4) |i| { + const huff_meta = gen_huffman(self.freqs[i]); + try gen_codes(&self.huffs[i], huff_meta); + try dump_huffman(f, huff_meta); } } }; @@ -227,6 +226,7 @@ inline fn gen_huffman(freqs: []u32) HuffmanMeta { return .{ .bits = bits, .huffval = huffval, + .total_n = k, }; } @@ -295,11 +295,29 @@ fn parse_block(block: *util.BlockQuantized, dc_diff: *i16, rle: *RLE_Seq, dc_fre }); } +fn write_headers(f: std.fs.File, buff: *const util.Buffers) !void { + var out_buff = [6]u8{ 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84 } ++ [1]u8{0x00} ++ [_]u8{0x00} ** 64 ++ [1]u8{0x01} ++ [_]u8{0x00} ** 64; + for (0..64) |i| { + out_buff[7 + i] = @intFromFloat(buff.Q_Lum[i]); + out_buff[7 + i + 65] = @intFromFloat(buff.Q_Chrom[i]); + } + _ = try f.write(&out_buff); +} + +fn dump_huffman(f: std.fs.File, huff_meta: HuffmanMeta) !void { + _ = huff_meta; + _ = f; +} + pub fn generate_jpg(buff: util.Buffers, alloc: std.mem.Allocator) !void { var scan_data = try Scan.init(alloc); defer scan_data.deinit(); - try scan_data.do_rle_freq_pass(&buff); + var f = try std.fs.cwd().createFile("out.jpg", .{}); + defer f.close(); + try write_headers(f, &buff); + + try scan_data.do_rle_freq_pass(&buff, f); // rle, huffman pass // file headers diff --git a/src/util.zig b/src/util.zig index 9066f9b..78aa388 100644 --- a/src/util.zig +++ b/src/util.zig @@ -77,11 +77,10 @@ pub const Buffers = struct { num_blocks: u32, input_buff: []u8, - output_buff: []u8, const Self = @This(); - pub fn init(root_alloc: std.mem.Allocator, w: usize, h: usize, output_buff_len: usize, q: f16) !Self { + pub fn init(root_alloc: std.mem.Allocator, w: usize, h: usize, q: f16) !Self { var arena = std.heap.ArenaAllocator.init(root_alloc); var alloc = arena.allocator(); const block_w = w / 16; @@ -103,7 +102,6 @@ pub const Buffers = struct { .num_blocks = @truncate(w * h * 3 / 2 / 64), .input_buff = try alloc.alloc(u8, w * 8), - .output_buff = try alloc.alloc(u8, output_buff_len), }; for (0..block_h) |i| { buffs.Y[i] = try alloc.alloc([4]Block, block_w);