summaryrefslogtreecommitdiff
path: root/src/jpg/segment.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/jpg/segment.zig')
-rw-r--r--src/jpg/segment.zig69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/jpg/segment.zig b/src/jpg/segment.zig
new file mode 100644
index 0000000..ec1346a
--- /dev/null
+++ b/src/jpg/segment.zig
@@ -0,0 +1,69 @@
+const std = @import("std");
+const jpg = @import("root.zig");
+
+pub const Segment = union(jpg.Marker.Kind) {
+ temporary: void,
+ reset: void,
+ start_of_image: void,
+ end_of_image: void,
+ start_of_frame: void,
+ define_quantization_table: void,
+ define_huffman_table: void,
+ define_restart_interval: void,
+ define_number_of_lines: void,
+ define_hierarchy_progression: void,
+ extend_huffman_table: void,
+ application_segment: void,
+ comment: void,
+ start_of_scan: void,
+
+ const Self = @This();
+
+ pub fn read(gpa: std.mem.Allocator, reader: *std.Io.Reader) !Self {
+ if (try reader.peekByte() != 0xff) {
+ return error.InvalidMarkerHeader;
+ }
+ reader.toss(1);
+
+ const marker = jpg.Marker.from_u8(try reader.peekByte())
+ catch return error.InvalidMarkerByte;
+ reader.toss(1);
+
+ return switch (marker) {
+ .temporary => .{ .temporary = void{} },
+ .reset => .{ .reset = void{} },
+ .start_of_image => .{ .start_of_image = void{} },
+ .end_of_image => .{ .end_of_image = void{} },
+ .start_of_frame => data: {
+ const buffer = try read_data_with_length(gpa, reader);
+ defer gpa.free(buffer);
+ break :data .{ .start_of_frame = void{} };
+ },
+ .application_segment => data: {
+ const buffer = try read_data_with_length(gpa, reader);
+ defer gpa.free(buffer);
+ break :data .{ .application_segment = void{} };
+ },
+ else => {
+ std.debug.panic("unimplemented tag '{s}'\n", .{@tagName(marker)});
+ },
+ };
+ }
+
+ fn read_data_with_length(gpa: std.mem.Allocator, reader: *std.Io.Reader) ![]u8 {
+ const length = try reader.takeInt(u16, .big);
+ return try reader.readAlloc(gpa, @intCast(length));
+ }
+};
+
+
+test "file" {
+ const buffer = @embedFile("../testing/rgb.jpg");
+ var reader: std.Io.Reader = .fixed(buffer);
+
+ var segment: Segment = try .read(std.testing.allocator, &reader);
+ try std.testing.expectEqual(.start_of_image, std.meta.activeTag(segment));
+
+ segment = try .read(std.testing.allocator, &reader);
+ try std.testing.expectEqual(.application_segment, std.meta.activeTag(segment));
+}