add huffman boiler, Code_size impl
This commit is contained in:
parent
03e986b5d6
commit
a25213fa2d
1 changed files with 64 additions and 0 deletions
|
@ -58,9 +58,73 @@ 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_huffmans(self: *Self) !void {
|
||||||
|
for (0..4) |i| {
|
||||||
|
try gen_huffman(&self.huffs[i], self.freqs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline fn get_idx_min2(freqs: []u32) ?struct { usize, usize } {
|
||||||
|
var min1: u32 = undefined;
|
||||||
|
var min1_idx: usize = undefined;
|
||||||
|
var min2: u32 = undefined;
|
||||||
|
var min2_idx: usize = undefined;
|
||||||
|
var is_init_1 = false;
|
||||||
|
var is_init_2 = false;
|
||||||
|
for (0..freqs.len) |i| {
|
||||||
|
if (freqs[i] == 0) continue;
|
||||||
|
if (!is_init_1) {
|
||||||
|
min1 = freqs[i];
|
||||||
|
min1_idx = i;
|
||||||
|
} else if (!is_init_2) {
|
||||||
|
if (freqs[i] < min1) {
|
||||||
|
min2 = min1;
|
||||||
|
min2_idx = min1_idx;
|
||||||
|
min1 = freqs[i];
|
||||||
|
min1_idx = i;
|
||||||
|
} else {
|
||||||
|
min2 = freqs[i];
|
||||||
|
min2_idx = i;
|
||||||
|
}
|
||||||
|
} else if (freqs[i] < min1) {
|
||||||
|
min1 = freqs[i];
|
||||||
|
min1_idx = i;
|
||||||
|
} else if (freqs[i] < min2) {
|
||||||
|
min2 = freqs[i];
|
||||||
|
min2_idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return if (is_init_2) .{
|
||||||
|
min1_idx,
|
||||||
|
min2_idx,
|
||||||
|
} else null;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn gen_huffman(huff: *Huffman, freqs: []u32) !void {
|
||||||
|
_ = 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];
|
||||||
|
codesizes[v1] += 1;
|
||||||
|
while (others[v1] != 0x1ff) : (codesizes[v1] += 1) {
|
||||||
|
v1 = others[v1];
|
||||||
|
}
|
||||||
|
others[v1] = @truncate(v2);
|
||||||
|
codesizes[v2] += 1;
|
||||||
|
while (others[v2] != 0x1ff) : (codesizes[v2] += 1) {
|
||||||
|
v2 = others[v2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline fn get_size(n: i16) u8 {
|
inline fn get_size(n: i16) u8 {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue