This commit is contained in:
Muaz Ahmad 2023-12-04 14:48:17 +05:00
parent af99b90f9c
commit 10d387e036

View file

@ -9,9 +9,14 @@ const RLE_Unit = struct {
}; };
const Huffman = std.AutoHashMap(u8, HuffCode); const Huffman = std.AutoHashMap(u8, HuffCode);
const HuffCode = struct { // const HuffCode = struct {
n_bits: u8, // n_bits: u8,
value: u16, // value: u16,
// };
const HuffCode = u16;
const HuffmanMeta = struct {
bits: [33]u8,
huffval: [256]u8,
}; };
const Scan = struct { const Scan = struct {
@ -20,23 +25,27 @@ 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();
fn init(alloc_root: std.mem.Allocator) !Self { fn init(alloc_root: std.mem.Allocator) !Self {
var arena = std.heap.ArenaAllocator.init(alloc_root); var arena = std.heap.ArenaAllocator.init(alloc_root);
var alloc = arena.allocator(); var alloc = arena.allocator();
return Self{ .root_alloc = alloc_root, .arena = arena, .dc_diffs = [3]i16{ 0, 0, 0 }, .rles = [3]RLE_Seq{ var self = 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), 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{
Huffman.init(alloc), try alloc.create(Huffman),
Huffman.init(alloc), try alloc.create(Huffman),
Huffman.init(alloc), try alloc.create(Huffman),
Huffman.init(alloc), try alloc.create(Huffman),
} }; } };
for (0..4) |i| {
self.huffs[i].* = Huffman.init(alloc);
}
return self;
} }
fn deinit(self: *Self) void { fn deinit(self: *Self) void {
self.arena.deinit(); self.arena.deinit();
@ -66,8 +75,12 @@ const Scan = struct {
} }
fn generate_huffmans(self: *Self) !void { fn generate_huffmans(self: *Self) !void {
for (0..4) |i| { for (0..4) |i_freq| {
try gen_huffman(&self.huffs[i], self.freqs[i]); const huffman_meta = gen_huffman(self.freqs[i_freq]);
_ = huffman_meta;
var huff = self.huffs[i_freq];
std.debug.print("{any}\n", .{huff});
try huff.put(0, 1);
} }
} }
}; };
@ -110,9 +123,54 @@ inline fn get_idx_min2(freqs: []u32) ?struct { usize, usize } {
} else null; } else null;
} }
inline fn gen_huffman(huff: *Huffman, freqs: []u32) !void { inline fn gen_codes(huff: *Huffman, huffman_meta: HuffmanMeta) !void {
var huffsize = [_]u5{0} ** 256;
var huffcode = [_]u16{0} ** 256;
var k: usize = 0;
var j: usize = 0;
for (0..17) |i| {
while (j <= huffman_meta.bits[i]) {
huffsize[k] = @truncate(i);
k += 1;
j += 1;
}
j = 1;
}
huffsize[k] = 0;
const total_k = k + 1;
k = 0;
var code: usize = 0;
var si = huffsize[0];
while (true) {
huffcode[k] = @truncate(code);
code += 1;
k += 1;
if (huffsize[k] == si) {
continue;
}
if (huffsize[k] == 0) {
break;
}
code <<= 1;
si += 1;
while (huffsize[k] != si) {
code <<= 1;
si += 1;
}
}
for (0..total_k) |x| {
try huff.put(@truncate(x), HuffCode{
.n_bits = huffsize[x],
.value = huffcode[x],
});
}
}
inline fn gen_huffman(freqs: []u32) HuffmanMeta {
freqs[freqs.len - 1] = 1; freqs[freqs.len - 1] = 1;
_ = huff;
var codesizes = [_]u8{0} ** 257; var codesizes = [_]u8{0} ** 257;
var others = [_]u9{0x1ff} ** 257; var others = [_]u9{0x1ff} ** 257;
while (get_idx_min2(freqs)) |tmp| { while (get_idx_min2(freqs)) |tmp| {
@ -166,7 +224,10 @@ inline fn gen_huffman(huff: *Huffman, freqs: []u32) !void {
} }
} }
std.debug.print("{any}\n{any}\n\n", .{ bits, huffval }); return .{
.bits = bits,
.huffval = huffval,
};
} }
inline fn get_size(n: i16) u8 { inline fn get_size(n: i16) u8 {