bitwriter reimplemented

This commit is contained in:
Muaz Ahmad 2023-12-12 12:19:53 +05:00
parent 22a63d68bf
commit 6c91c2c228
2 changed files with 45 additions and 11 deletions

View file

@ -48,14 +48,14 @@ const RLEWriter = struct {
fn write_value(self: *Self, huffcode: HuffCode, unit: RLE_Unit) !void { fn write_value(self: *Self, huffcode: HuffCode, unit: RLE_Unit) !void {
try self.bw.write_bits(huffcode.value, huffcode.n_bits); try self.bw.write_bits(huffcode.value, huffcode.n_bits);
const unit_val: u16 = if (unit.value >= 0) @bitCast(unit.value) else @bitCast(unit.value - 1); const unit_val: u16 = if (unit.value >= 0) @bitCast(unit.value) else @bitCast(unit.value - 1);
try self.bw.write_bits(unit_val, @truncate(unit.symbol & 0x0f)); const value_size = unit.symbol & 0x0f;
if (value_size != 0) {
try self.bw.write_bits(unit_val & (try std.math.powi(u16, 2, value_size) - 1), @truncate(value_size));
}
} }
inline fn flush(self: *Self) !void { inline fn flush(self: *Self) !void {
if (self.bw.bits_used != 0) { try self.bw.flush_end();
const bits_left = 8 - self.bw.bits_used;
try self.bw.write_bits(0xf, bits_left);
}
} }
}; };

View file

@ -149,7 +149,7 @@ pub fn gen_qtable(q: f16, step_start_band: usize, step_stop_band: usize) @Vector
pub const BufferedBitWriter = struct { pub const BufferedBitWriter = struct {
byte_buff: u8, byte_buff: u8,
bits_used: u4, bits_used: u4,
buffer: [32]u8, buffer: [8]u8,
buffer_idx: usize, buffer_idx: usize,
f: std.fs.File, f: std.fs.File,
@ -160,18 +160,52 @@ pub const BufferedBitWriter = struct {
.f = f, .f = f,
.byte_buff = 0, .byte_buff = 0,
.bits_used = 0, .bits_used = 0,
.buffer = [_]u8{0x00} ** 32, .buffer = [_]u8{0x00} ** 8,
.buffer_idx = 0, .buffer_idx = 0,
}; };
} }
pub fn write_bits(self: *Self, val: u16, n_bits: u5) !void { pub fn write_bits(self: *Self, val: u16, n_bits: u5) !void {
_ = n_bits; const curr_byte_space = 8 - self.bits_used;
_ = val; if (n_bits <= curr_byte_space) {
_ = self; try self.add_bits(val, @truncate(n_bits));
} else {
try self.add_bits(val >> @truncate(n_bits - curr_byte_space), @truncate(curr_byte_space));
const val_remaining_mask = try std.math.powi(u16, 2, n_bits - curr_byte_space) - 1;
try self.write_bits(val & val_remaining_mask, n_bits - curr_byte_space);
}
}
inline fn add_bits(self: *Self, val: u16, n_bits: u4) !void {
self.byte_buff |= @truncate(val << (8 - self.bits_used - n_bits));
self.bits_used += n_bits;
if (self.bits_used == 8) {
self.buffer[self.buffer_idx] = self.byte_buff;
if (self.byte_buff == 0xff) {
self.buffer_idx += 1;
}
self.buffer_idx += 1;
self.bits_used = 0;
self.byte_buff = 0x00;
if (self.buffer_idx >= self.buffer.len) {
try self.flush();
self.buffer_idx %= self.buffer.len;
}
}
} }
pub fn flush(self: *Self) !void { pub fn flush(self: *Self) !void {
_ = self; _ = try self.f.write(&self.buffer);
@memset(&self.buffer, 0);
}
pub fn flush_end(self: *Self) !void {
if (self.bits_used != 0) {
const stuffing = try std.math.powi(u8, 2, 8 - self.bits_used) - 1;
try self.add_bits(stuffing, 8 - self.bits_used);
}
if (self.buffer_idx != 0) {
_ = try self.f.write(self.buffer[0..self.buffer_idx]);
}
} }
}; };