summaryrefslogtreecommitdiff
path: root/src/jpg/scan.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/jpg/scan.zig')
-rw-r--r--src/jpg/scan.zig56
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;
+}