proper init, initial header file write, huffman generation done

This commit is contained in:
Muaz Ahmad 2023-12-04 16:45:30 +05:00
parent 10d387e036
commit 4bc436d92b
3 changed files with 40 additions and 24 deletions

View file

@ -58,7 +58,7 @@ fn get_opts() !util.Options {
pub fn main() !void { pub fn main() !void {
const opts = try get_opts(); 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(); defer buffs.deinit();
var thread_manager = try threads.ThreadManager.init(std.heap.page_allocator, opts.n_quant_jobs, buffs.Q_Lum, buffs.Q_Chrom); var thread_manager = try threads.ThreadManager.init(std.heap.page_allocator, opts.n_quant_jobs, buffs.Q_Lum, buffs.Q_Chrom);

View file

@ -13,9 +13,13 @@ const Huffman = std.AutoHashMap(u8, HuffCode);
// n_bits: u8, // n_bits: u8,
// value: u16, // value: u16,
// }; // };
const HuffCode = u16; const HuffCode = struct {
value: u16,
n_bits: u5,
};
const HuffmanMeta = struct { const HuffmanMeta = struct {
bits: [33]u8, bits: [33]u8,
total_n: usize,
huffval: [256]u8, huffval: [256]u8,
}; };
@ -25,7 +29,7 @@ const Scan = struct {
dc_diffs: [3]i16, dc_diffs: [3]i16,
rles: [3]RLE_Seq, rles: [3]RLE_Seq,
freqs: [4][]u32, freqs: [4][]u32,
huffs: [4]*Huffman, huffs: [4]Huffman,
const Self = @This(); 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), 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{ }, .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), Huffman.init(alloc_root),
try alloc.create(Huffman), Huffman.init(alloc_root),
try alloc.create(Huffman), Huffman.init(alloc_root),
try alloc.create(Huffman), Huffman.init(alloc_root),
} }; } };
for (0..4) |i| {
self.huffs[i].* = Huffman.init(alloc);
}
return self; return self;
} }
fn deinit(self: *Self) void { 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 h = buff.Y_quant.len;
const w = buff.Y_quant[0].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 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 { fn generate_huffmans(self: *Self, f: std.fs.File) !void {
for (0..4) |i_freq| { for (0..4) |i| {
const huffman_meta = gen_huffman(self.freqs[i_freq]); const huff_meta = gen_huffman(self.freqs[i]);
_ = huffman_meta; try gen_codes(&self.huffs[i], huff_meta);
var huff = self.huffs[i_freq]; try dump_huffman(f, huff_meta);
std.debug.print("{any}\n", .{huff});
try huff.put(0, 1);
} }
} }
}; };
@ -227,6 +226,7 @@ inline fn gen_huffman(freqs: []u32) HuffmanMeta {
return .{ return .{
.bits = bits, .bits = bits,
.huffval = huffval, .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 { pub fn generate_jpg(buff: util.Buffers, alloc: std.mem.Allocator) !void {
var scan_data = try Scan.init(alloc); var scan_data = try Scan.init(alloc);
defer scan_data.deinit(); 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 // rle, huffman pass
// file headers // file headers

View file

@ -77,11 +77,10 @@ pub const Buffers = struct {
num_blocks: u32, num_blocks: u32,
input_buff: []u8, input_buff: []u8,
output_buff: []u8,
const Self = @This(); 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 arena = std.heap.ArenaAllocator.init(root_alloc);
var alloc = arena.allocator(); var alloc = arena.allocator();
const block_w = w / 16; const block_w = w / 16;
@ -103,7 +102,6 @@ pub const Buffers = struct {
.num_blocks = @truncate(w * h * 3 / 2 / 64), .num_blocks = @truncate(w * h * 3 / 2 / 64),
.input_buff = try alloc.alloc(u8, w * 8), .input_buff = try alloc.alloc(u8, w * 8),
.output_buff = try alloc.alloc(u8, output_buff_len),
}; };
for (0..block_h) |i| { for (0..block_h) |i| {
buffs.Y[i] = try alloc.alloc([4]Block, block_w); buffs.Y[i] = try alloc.alloc([4]Block, block_w);