diff --git a/src/output.zig b/src/output.zig index 7feae3a..76fc9cd 100644 --- a/src/output.zig +++ b/src/output.zig @@ -49,6 +49,10 @@ const Scan = struct { const h = buff.Y_quant.len; const w = buff.Y_quant[0].len; + for (0..4) |i| { + @memset(self.freqs[i], 0); + } + for (0..h) |x| { for (0..w) |y| { for (0..4) |Y_sub_i| { @@ -80,6 +84,7 @@ inline fn get_idx_min2(freqs: []u32) ?struct { usize, usize } { if (!is_init_1) { min1 = freqs[i]; min1_idx = i; + is_init_1 = true; } else if (!is_init_2) { if (freqs[i] < min1) { min2 = min1; @@ -90,6 +95,7 @@ inline fn get_idx_min2(freqs: []u32) ?struct { usize, usize } { min2 = freqs[i]; min2_idx = i; } + is_init_2 = true; } else if (freqs[i] < min1) { min1 = freqs[i]; min1_idx = i; @@ -105,14 +111,15 @@ inline fn get_idx_min2(freqs: []u32) ?struct { usize, usize } { } inline fn gen_huffman(huff: *Huffman, freqs: []u32) !void { + freqs[freqs.len - 1] = 1; _ = huff; var codesizes = [_]u8{0} ** 257; var others = [_]u9{0x1ff} ** 257; - while (get_idx_min2(freqs)) |tmp| { var v1 = tmp.@"0"; var v2 = tmp.@"1"; freqs[v1] += freqs[v2]; + freqs[v2] = 0; codesizes[v1] += 1; while (others[v1] != 0x1ff) : (codesizes[v1] += 1) { v1 = others[v1]; @@ -123,6 +130,43 @@ inline fn gen_huffman(huff: *Huffman, freqs: []u32) !void { v2 = others[v2]; } } + var bits = [_]u8{0} ** 33; + + for (0..freqs.len) |i| { + if (codesizes[i] != 0) { + bits[codesizes[i]] += 1; + } + } + + var i: usize = 32; + while (i > 16) { + if (bits[i] > 0) { + var j = i - 2; + while (bits[j] <= 0) : (j -= 1) { + bits[i] -= 2; + bits[i - 1] += 1; + bits[j + 1] += 2; + bits[j] -= 1; + } + } else { + i -= 1; + } + } + while (bits[i] == 0) : (i -= 1) {} + bits[i] -= 1; + + var k: usize = 0; + var huffval = [_]u8{0} ** 256; + for (1..33) |i_| { + for (0..freqs.len - 1) |j| { + if (codesizes[j] == i_) { + huffval[k] = @truncate(j); + k += 1; + } + } + } + + std.debug.print("{any}\n{any}\n\n", .{ bits, huffval }); } inline fn get_size(n: i16) u8 {