1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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;
}
|