-
-
Notifications
You must be signed in to change notification settings - Fork 196
/
Copy pathwebp.hexpat
122 lines (102 loc) · 2.52 KB
/
webp.hexpat
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#pragma author applecuckoo
#pragma description Google WebP
#pragma endian little
#pragma MIME image/webp
// based off of ttf.hexpat by Rebuild and wav.hexpat by WerWolv
import std.mem;
import std.core;
import type.magic;
struct RiffHeader {
char ckID[4] [[comment("Container Signature"), name("RIFF Header Signature")]];
u32 ckSize [[comment("Size of RIFF Header"), name("RIFF Chunk Size")]];
char format[4] [[comment("RIFF format"), name("WAVE Header Signature")]];
};
struct WebPChunk {
char chunkId[4];
u32 chunkSize;
};
bitfield VP8XFlags {
padding : 1;
A : 1;
X : 1;
E : 1;
L : 1;
I : 1;
padding : 2;
};
struct OneBase {
u24 value;
} [[sealed, format("format_onebase")]];
fn format_onebase(OneBase onebase) {
return onebase.value + 1;
};
struct WebPVP8XData {
VP8XFlags flags;
padding[3];
OneBase canvasWidth;
OneBase canvasHeight;
};
struct WebPANIMData {
u32 backgroundColor;
u16 loopCount;
};
bitfield ANMFFlags {
D : 1;
B : 1;
padding : 6;
};
bitfield WebPVP8LHeader {
widthMinusOne : 14;
heightMinusOne : 14;
alphaUsed : 1;
version : 3;
};
struct WebPVP8LData {
type::Magic<"\x2f"> id;
WebPVP8LHeader header;
};
u32 frameSize;
struct WebPANMFData {
u24 frameX;
u24 frameY;
OneBase frameWidth;
OneBase frameHeight;
u24 frameDuration;
ANMFFlags flags;
u8 data[parent.chunkHeader.chunkSize - 16]; // lazy fix - can't be bothered implementing subchunks
};
bitfield ALPHFlags {
C : 2;
F : 2;
P : 2;
padding : 2;
};
u32 paddedChunkSize;
struct WebPData {
WebPChunk chunkHeader;
paddedChunkSize = (chunkHeader.chunkSize + 1) >> 1 << 1;
match (chunkHeader.chunkId) {
("VP8X"): WebPVP8XData VP8XData;
("ANIM"): WebPANIMData ANIMData;
("ANMF"): {
WebPANMFData ANMFData;
padding[paddedChunkSize - sizeof(ANMFData)];
}
("VP8L"): {
WebPVP8LHeader VP8LData;
u8 image[chunkHeader.chunkSize-3];
padding[paddedChunkSize - sizeof(VP8LData) - sizeof(image)];
}
("ALPH"): {
ALPHFlags flags;
u8 ALPHData[chunkHeader.chunkSize-1];
padding[paddedChunkSize - sizeof(ALPHData) - sizeof(flags)];
}
(_): {
u8 data[chunkHeader.chunkSize];
padding[paddedChunkSize - sizeof(data)];
}
}
} [[name(std::format("Chunk ({})", chunkHeader.chunkId))]];
RiffHeader header @0x00;
WebPData data[while (!std::mem::eof())] @ $;