2023-11-27 14:06:31 +05:00
|
|
|
const std = @import("std");
|
|
|
|
|
|
|
|
const util = @import("util.zig");
|
|
|
|
const threads = @import("threads.zig");
|
2023-11-28 15:29:57 +05:00
|
|
|
const output = @import("output.zig");
|
2023-11-27 14:06:31 +05:00
|
|
|
|
2023-11-27 15:42:01 +05:00
|
|
|
inline fn lum_idxs(i: usize, j: usize) struct { usize, usize, usize } {
|
|
|
|
return .{
|
|
|
|
i / 2,
|
|
|
|
j / 2,
|
|
|
|
2 * (i % 2) + (j % 2),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_lum(f: std.fs.File, source_buff: [][][4]util.Block, target_buff: [][][4]util.BlockQuantized, io_buff: []u8, queue: *util.JobQueue) !void {
|
|
|
|
const block_h = source_buff.len;
|
|
|
|
const block_w = source_buff[0].len;
|
|
|
|
|
|
|
|
for (0..block_h * 2) |i| {
|
|
|
|
_ = try f.read(io_buff);
|
|
|
|
var io_idx: usize = 0;
|
|
|
|
for (0..8) |I| {
|
|
|
|
for (0..block_w * 2) |j| {
|
|
|
|
const idxs = lum_idxs(i, j);
|
|
|
|
@memcpy(source_buff[idxs.@"0"][idxs.@"1"][idxs.@"2"][I * 8 .. (I + 1) * 8], io_buff[io_idx .. io_idx + 8]);
|
|
|
|
io_idx += 8;
|
|
|
|
if (I == 7) {
|
|
|
|
try queue.prepend(util.Job{
|
|
|
|
.source = &source_buff[idxs.@"0"][idxs.@"1"][idxs.@"2"],
|
|
|
|
.target = &target_buff[idxs.@"0"][idxs.@"1"][idxs.@"2"],
|
2023-11-28 13:42:53 +05:00
|
|
|
.is_lum = true,
|
2023-11-27 15:42:01 +05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_chrom(f: std.fs.File, source_buff: [][]util.Block, target_buff: [][]util.BlockQuantized, io_buff: []u8, queue: *util.JobQueue) !void {
|
|
|
|
const block_h = source_buff.len;
|
|
|
|
const block_w = source_buff[0].len;
|
|
|
|
|
|
|
|
for (0..block_h) |i| {
|
|
|
|
_ = try f.read(io_buff);
|
|
|
|
var io_idx: usize = 0;
|
|
|
|
for (0..8) |I| {
|
|
|
|
for (0..block_w) |j| {
|
|
|
|
@memcpy(source_buff[i][j][I * 8 .. (I + 1) * 8], io_buff[io_idx .. io_idx + 8]);
|
|
|
|
io_idx += 8;
|
|
|
|
if (I == 7) {
|
|
|
|
try queue.prepend(util.Job{
|
|
|
|
.source = &source_buff[i][j],
|
|
|
|
.target = &target_buff[i][j],
|
2023-11-28 13:42:53 +05:00
|
|
|
.is_lum = false,
|
2023-11-27 15:42:01 +05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 15:29:57 +05:00
|
|
|
pub fn main_loop(f: std.fs.File, buffs: util.Buffers, thread_mgr: *threads.ThreadManager, alloc: std.mem.Allocator) !void {
|
|
|
|
defer thread_mgr.quit();
|
2023-11-28 15:03:17 +05:00
|
|
|
thread_mgr.unblock();
|
2023-11-27 15:42:01 +05:00
|
|
|
try read_lum(f, buffs.Y, buffs.Y_quant, buffs.input_buff, thread_mgr.queue_wrp.queue);
|
|
|
|
try read_chrom(f, buffs.U, buffs.U_quant, buffs.input_buff[0 .. buffs.input_buff.len / 2], thread_mgr.queue_wrp.queue);
|
|
|
|
try read_chrom(f, buffs.V, buffs.V_quant, buffs.input_buff[0 .. buffs.input_buff.len / 2], thread_mgr.queue_wrp.queue);
|
2023-11-28 13:42:53 +05:00
|
|
|
while (thread_mgr.signals.processed.load(.Acquire) != buffs.num_blocks) : (std.time.sleep(1)) {}
|
2023-11-28 15:03:17 +05:00
|
|
|
thread_mgr.eof();
|
2023-11-28 15:29:57 +05:00
|
|
|
try output.generate_jpg(buffs, alloc);
|
2023-11-27 14:06:31 +05:00
|
|
|
}
|