proper init, initial header file write, huffman generation done
This commit is contained in:
parent
10d387e036
commit
4bc436d92b
3 changed files with 40 additions and 24 deletions
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue