RLE sequencing and frequency calcs

This commit is contained in:
Muaz Ahmad 2023-11-30 15:13:26 +05:00
parent 6aa84c775f
commit 2dddb9371a

View file

@ -16,6 +16,7 @@ const HuffCode = struct {
const Scan = struct { const Scan = struct {
arena: std.heap.ArenaAllocator, arena: std.heap.ArenaAllocator,
root_alloc: std.mem.Allocator,
dc_diffs: [3]i16, dc_diffs: [3]i16,
rles: [3]RLE_Seq, rles: [3]RLE_Seq,
freqs: [4][]u32, freqs: [4][]u32,
@ -26,10 +27,10 @@ const Scan = struct {
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{ .arena = arena, .dc_diffs = [3]i16{ 0, 0, 0 }, .rles = [3]RLE_Seq{ return Self{ .root_alloc = alloc_root, .arena = arena, .dc_diffs = [3]i16{ 0, 0, 0 }, .rles = [3]RLE_Seq{
RLE_Seq.init(alloc), RLE_Seq.init(alloc_root),
RLE_Seq.init(alloc), RLE_Seq.init(alloc_root),
RLE_Seq.init(alloc), 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{ }, .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),
Huffman.init(alloc), Huffman.init(alloc),
@ -39,6 +40,9 @@ const Scan = struct {
} }
fn deinit(self: *Self) void { fn deinit(self: *Self) void {
self.arena.deinit(); self.arena.deinit();
for (0..3) |i| {
self.rles[i].deinit();
}
} }
fn do_rle_freq_pass(self: *Self, buff: *const util.Buffers) !void { 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 { inline fn get_size(n: i16) u8 {
_ = v; 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 { 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.*; const diff = block[0] - dc_diff.*;
var symbol = get_size(diff);
dc_freqs[symbol] += 1;
try rle.append(RLE_Unit{ try rle.append(RLE_Unit{
.symbol = get_size(diff), .symbol = symbol,
.value = diff, .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 { pub fn generate_jpg(buff: util.Buffers, alloc: std.mem.Allocator) !void {