diff options
Diffstat (limited to 'src/jpg/scan.zig')
| -rw-r--r-- | src/jpg/scan.zig | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/jpg/scan.zig b/src/jpg/scan.zig new file mode 100644 index 0000000..d47b453 --- /dev/null +++ b/src/jpg/scan.zig @@ -0,0 +1,56 @@ +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; +} |