-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWEBP.bt
179 lines (160 loc) · 4.13 KB
/
WEBP.bt
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//------------------------------------------------
//--- 010 Editor v13.0.2 Binary Template
//
// File: WEBP.bt
// Authors: saruman9 <rum.274.4 at gmail.com>
// Version: 0.3
// Purpose: Parse WEBP media files (https://developers.google.com/speed/webp/docs/riff_container).
// Category: Image
// File Mask: *.webp
// ID Bytes: 52 49 46 46 //RIFF
// History:
// 0.3 saruman9: Add support of EXIF chunk parsing
// 0.2 saruman9: Add definition for VP8L
// 0.1 saruman9: Initial version.
//------------------------------------------------
#include "TIF_include.bt"
char magic[4];
if (magic != "RIFF") {
Warning("Wrong magic: %s", magic);
Exit(1);
}
uint32 file_size;
char webp[4];
if (webp != "WEBP") {
Warning("Wrong magic: %s", webp);
Exit(1);
}
struct Vp8(uint32 size) {
ubyte data[size];
};
struct Vp8l(uint32 size) {
ubyte magic_2f;
if (magic_2f != 0x2F) {
Warning("Wrong magic byte in VP8L: %X", magic_2f);
Exit(1);
}
int width_minus_one : 14;
int heigth_minus_one : 14;
int alpha_is_used : 1;
int version : 3; // must be 0
ubyte data[size - 5];
};
struct Vp8x {
BitfieldDisablePadding();
int reserved_0 : 2; // must be 0
int icc_profile : 1;
int alpha : 1;
int exif_metadata : 1;
int xmp_metadata : 1;
int animation : 1;
int reserved_1 : 1; // must be 0
int reserved_2 : 24; // must be 0
int canvas_width_minus_one : 24;
int canvas_height_minus_one : 24;
BitfieldEnablePadding();
};
struct Anim {
uint32 background_color;
uint16 loop_count;
};
enum <int> BlendingMethod {
BLENDING_METHOD_ALPHA = 0,
BLENDING_METHOD_NOT = 1,
};
enum <int> DisposalMethod {
DISPOSAL_METHOD_NOT = 0,
DISPOSAL_METHOD_BACKGROUND = 1,
};
struct Anmf(uint32 size) {
BitfieldDisablePadding();
int frame_x : 24;
int frame_y : 24;
int frame_width_minus_one : 24;
int frame_height_minus_one : 24;
BitfieldEnablePadding();
int frame_duration : 24;
int reserved : 6;
BlendingMethod blending_method : 1;
DisposalMethod disposal_method : 1;
ubyte frame_data[size - 16];
};
enum <int> Preprocessing {
PREPROCESSING_NOT = 0,
PREPROCESSING_LEVEL_REDUCTION = 1,
};
enum <int> FilteringMethod {
FILTERING_METHOD_NONE = 0,
FILTERING_METHOD_HORIZONTAL_FILTER = 1,
FILTERING_METHOD_VERTICAL_FILTER = 2,
FILTERING_METHOD_GRADIENT_FILTER = 3,
};
enum <int> CompressionMethod {
COMPRESSION_METHOD_NO = 0,
COMPRESSION_METHOD_LOSSLESS = 1,
};
struct Alph(uint32 size) {
BitfieldDisablePadding();
int reserved : 2;
Preprocessing preprocessing : 2;
FilteringMethod filtering_method : 2;
CompressionMethod compression_method : 2;
BitfieldEnablePadding();
ubyte alpha_bitstream[size - 1];
};
struct Iccp(uint32 size) {
ubyte color_profile[size];
};
struct Exif(uint32 size) {
local uint16 tbom;
tbom = ReadUShort();
if (tbom == 0x4949) {
LittleEndian();
}
else if (tbom == 0x4D4D) {
BigEndian();
}
else {
Warning("Invalid TIFF payload: bad BOM (%X)", tbom);
Exit(1);
}
IFH ifh;
while(nextIFD) {
FSeek(nextIFD);
nextIFD = (quad)0;
IFD ifd;
}
FSeek(file_offset + size);
LittleEndian();
};
struct Xmp(uint32 size) {
ubyte metadata[size];
};
typedef struct {
char name[4];
uint32 size;
switch (name)
{
case "VP8 ": Vp8 payload(size); break;
case "VP8L": Vp8l payload(size); break;
case "VP8X": Vp8x payload; break;
case "ANIM": Anim payload; break;
case "ANMF": Anmf payload(size); break;
case "ALPH": Alph payload(size); break;
case "ICCP": Iccp payload(size); break;
case "EXIF": Exif payload(size); break;
case "XMP ": Xmp payload(size); break;
default: Warning("Unknown chunk: %s", name); Exit(0); break;
}
if (size % 2 != 0) {
ubyte padding; // must be 0
}
} Chunk <read=readChunk>;
string readChunk(Chunk &chunk) {
local string s;
SPrintf(s, "%s (size: %08X)", chunk.name, chunk.size);
return s;
}
while (!FEof()) {
Chunk chunk;
}