const std = @import("std"); const Self = @This(); pub const Component = struct { selector: u8, dc_selector: u4, ac_selector: u4, }; components: []Component, selection_start: u8, selection_end: u8, params: packed union { approximation_bit_position: u8, point_transform: u4, }, data: []u8, pub fn read(gpa: std.mem.Allocator, reader: *std.Io.Reader) !Self { const count = try reader.takeByte(); var self: Self = undefined; self.components = try gpa.alloc(Component, count); errdefer gpa.free(self.components); for (self.components) |*component| { component.selector = try reader.takeByte(); const entropy_selector = try reader.takeByte(); component.dc_selector = @truncate(entropy_selector >> 4); component.ac_selector = @truncate(entropy_selector); } self.selection_start = try reader.takeByte(); self.selection_end = try reader.takeByte(); self.params = @bitCast(try reader.takeByte()); var aw: std.Io.Writer.Allocating = .init(gpa); var size = try reader.streamDelimiter(&aw.writer, 0xff); while ((try reader.peek(2))[1] == 0) { try aw.writer.writeByte(0xff); reader.toss(2); size = try reader.streamDelimiter(&aw.writer, 0xff); } self.data = try aw.toOwnedSlice(); return self; } pub fn deinit(self: *Self, gpa: std.mem.Allocator) void { gpa.free(self.components); gpa.free(self.data); self.* = undefined; }