diff --git a/src/output.zig b/src/output.zig index 3d1e3ef..7f9abbf 100644 --- a/src/output.zig +++ b/src/output.zig @@ -16,6 +16,7 @@ const HuffCode = struct { const Scan = struct { arena: std.heap.ArenaAllocator, + root_alloc: std.mem.Allocator, dc_diffs: [3]i16, rles: [3]RLE_Seq, freqs: [4][]u32, @@ -26,10 +27,10 @@ const Scan = struct { fn init(alloc_root: std.mem.Allocator) !Self { var arena = std.heap.ArenaAllocator.init(alloc_root); var alloc = arena.allocator(); - return Self{ .arena = arena, .dc_diffs = [3]i16{ 0, 0, 0 }, .rles = [3]RLE_Seq{ - RLE_Seq.init(alloc), - RLE_Seq.init(alloc), - RLE_Seq.init(alloc), + return 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, 257), try alloc.alloc(u32, 257), try alloc.alloc(u32, 257), try alloc.alloc(u32, 257) }, .huffs = [4]Huffman{ Huffman.init(alloc), Huffman.init(alloc), @@ -39,6 +40,9 @@ const Scan = struct { } fn deinit(self: *Self) void { self.arena.deinit(); + for (0..3) |i| { + self.rles[i].deinit(); + } } fn do_rle_freq_pass(self: *Self, buff: *const util.Buffers) !void { @@ -57,18 +61,70 @@ const Scan = struct { } }; -inline fn get_size(v: i16) u8 { - _ = v; +inline fn get_size(n: i16) u8 { + if (n == 0) { + return 0; + } else if (n < 2 and n > -2) { + return 1; + } else if (n < 4 and n > -4) { + return 2; + } else if (n < 8 and n > -8) { + return 3; + } else if (n < 16 and n > -16) { + return 4; + } else if (n < 32 and n > -32) { + return 5; + } else if (n < 64 and n > -64) { + return 6; + } else if (n < 128 and n > -128) { + return 7; + } else if (n < 256 and n > -256) { + return 8; + } else if (n < 512 and n > -512) { + return 9; + } else if (n < 1024 and n > -1024) { + return 10; + } else if (n < 2048 and n > -2048) { + return 11; + } else { + return 12; + } } fn parse_block(block: *util.BlockQuantized, dc_diff: *i16, rle: *RLE_Seq, dc_freqs: []u32, ac_freqs: []u32) !void { - _ = ac_freqs; - _ = dc_freqs; const diff = block[0] - dc_diff.*; + var symbol = get_size(diff); + dc_freqs[symbol] += 1; try rle.append(RLE_Unit{ - .symbol = get_size(diff), + .symbol = symbol, .value = diff, }); + var curr_rlen: u8 = 0; + for (1..64) |i| { + if (block[i] == 0) { + curr_rlen += 1; + continue; + } + while (curr_rlen > 15) : (curr_rlen -= 16) { + ac_freqs[0xf0] += 1; + try rle.append(RLE_Unit{ + .symbol = 0xf0, + .value = 0, + }); + } + symbol = (curr_rlen << 4) + get_size(block[i]); + ac_freqs[symbol] += 1; + try rle.append(RLE_Unit{ + .symbol = symbol, + .value = block[i], + }); + } + ac_freqs[0x00] += 1; + try rle.append(RLE_Unit{ + .symbol = 0x00, + .value = 0, + }); + std.debug.print("{any}\n", .{rle.items}); } pub fn generate_jpg(buff: util.Buffers, alloc: std.mem.Allocator) !void {