33 #define GLYPH_COORD_VECT_SIZE 16 34 #define PALETTE_SIZE 256 35 #define PALETTE_DELTA 768 38 0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1
42 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2
46 0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0
50 0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1
54 { 0, 0 }, { -1, -43 }, { 6, -43 }, { -9, -42 }, { 13, -41 },
55 { -16, -40 }, { 19, -39 }, { -23, -36 }, { 26, -34 }, { -2, -33 },
56 { 4, -33 }, { -29, -32 }, { -9, -32 }, { 11, -31 }, { -16, -29 },
57 { 32, -29 }, { 18, -28 }, { -34, -26 }, { -22, -25 }, { -1, -25 },
58 { 3, -25 }, { -7, -24 }, { 8, -24 }, { 24, -23 }, { 36, -23 },
59 { -12, -22 }, { 13, -21 }, { -38, -20 }, { 0, -20 }, { -27, -19 },
60 { -4, -19 }, { 4, -19 }, { -17, -18 }, { -8, -17 }, { 8, -17 },
61 { 18, -17 }, { 28, -17 }, { 39, -17 }, { -12, -15 }, { 12, -15 },
62 { -21, -14 }, { -1, -14 }, { 1, -14 }, { -41, -13 }, { -5, -13 },
63 { 5, -13 }, { 21, -13 }, { -31, -12 }, { -15, -11 }, { -8, -11 },
64 { 8, -11 }, { 15, -11 }, { -2, -10 }, { 1, -10 }, { 31, -10 },
65 { -23, -9 }, { -11, -9 }, { -5, -9 }, { 4, -9 }, { 11, -9 },
66 { 42, -9 }, { 6, -8 }, { 24, -8 }, { -18, -7 }, { -7, -7 },
67 { -3, -7 }, { -1, -7 }, { 2, -7 }, { 18, -7 }, { -43, -6 },
68 { -13, -6 }, { -4, -6 }, { 4, -6 }, { 8, -6 }, { -33, -5 },
69 { -9, -5 }, { -2, -5 }, { 0, -5 }, { 2, -5 }, { 5, -5 },
70 { 13, -5 }, { -25, -4 }, { -6, -4 }, { -3, -4 }, { 3, -4 },
71 { 9, -4 }, { -19, -3 }, { -7, -3 }, { -4, -3 }, { -2, -3 },
72 { -1, -3 }, { 0, -3 }, { 1, -3 }, { 2, -3 }, { 4, -3 },
73 { 6, -3 }, { 33, -3 }, { -14, -2 }, { -10, -2 }, { -5, -2 },
74 { -3, -2 }, { -2, -2 }, { -1, -2 }, { 0, -2 }, { 1, -2 },
75 { 2, -2 }, { 3, -2 }, { 5, -2 }, { 7, -2 }, { 14, -2 },
76 { 19, -2 }, { 25, -2 }, { 43, -2 }, { -7, -1 }, { -3, -1 },
77 { -2, -1 }, { -1, -1 }, { 0, -1 }, { 1, -1 }, { 2, -1 },
78 { 3, -1 }, { 10, -1 }, { -5, 0 }, { -3, 0 }, { -2, 0 },
79 { -1, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, { 5, 0 },
80 { 7, 0 }, { -10, 1 }, { -7, 1 }, { -3, 1 }, { -2, 1 },
81 { -1, 1 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 },
82 { -43, 2 }, { -25, 2 }, { -19, 2 }, { -14, 2 }, { -5, 2 },
83 { -3, 2 }, { -2, 2 }, { -1, 2 }, { 0, 2 }, { 1, 2 },
84 { 2, 2 }, { 3, 2 }, { 5, 2 }, { 7, 2 }, { 10, 2 },
85 { 14, 2 }, { -33, 3 }, { -6, 3 }, { -4, 3 }, { -2, 3 },
86 { -1, 3 }, { 0, 3 }, { 1, 3 }, { 2, 3 }, { 4, 3 },
87 { 19, 3 }, { -9, 4 }, { -3, 4 }, { 3, 4 }, { 7, 4 },
88 { 25, 4 }, { -13, 5 }, { -5, 5 }, { -2, 5 }, { 0, 5 },
89 { 2, 5 }, { 5, 5 }, { 9, 5 }, { 33, 5 }, { -8, 6 },
90 { -4, 6 }, { 4, 6 }, { 13, 6 }, { 43, 6 }, { -18, 7 },
91 { -2, 7 }, { 0, 7 }, { 2, 7 }, { 7, 7 }, { 18, 7 },
92 { -24, 8 }, { -6, 8 }, { -42, 9 }, { -11, 9 }, { -4, 9 },
93 { 5, 9 }, { 11, 9 }, { 23, 9 }, { -31, 10 }, { -1, 10 },
94 { 2, 10 }, { -15, 11 }, { -8, 11 }, { 8, 11 }, { 15, 11 },
95 { 31, 12 }, { -21, 13 }, { -5, 13 }, { 5, 13 }, { 41, 13 },
96 { -1, 14 }, { 1, 14 }, { 21, 14 }, { -12, 15 }, { 12, 15 },
97 { -39, 17 }, { -28, 17 }, { -18, 17 }, { -8, 17 }, { 8, 17 },
98 { 17, 18 }, { -4, 19 }, { 0, 19 }, { 4, 19 }, { 27, 19 },
99 { 38, 20 }, { -13, 21 }, { 12, 22 }, { -36, 23 }, { -24, 23 },
100 { -8, 24 }, { 7, 24 }, { -3, 25 }, { 1, 25 }, { 22, 25 },
101 { 34, 26 }, { -18, 28 }, { -32, 29 }, { 16, 29 }, { -11, 31 },
102 { 9, 32 }, { 29, 32 }, { -4, 33 }, { 2, 33 }, { -26, 34 },
103 { 23, 36 }, { -19, 39 }, { 16, 40 }, { -13, 41 }, { 9, 42 },
104 { -6, 43 }, { 1, 43 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
108 0, 0, 1, 0, 2, 0, 3, 0, 5, 0,
109 8, 0, 13, 0, 21, 0, -1, 0, -2, 0,
110 -3, 0, -5, 0, -8, 0, -13, 0, -17, 0,
111 -21, 0, 0, 1, 1, 1, 2, 1, 3, 1,
112 5, 1, 8, 1, 13, 1, 21, 1, -1, 1,
113 -2, 1, -3, 1, -5, 1, -8, 1, -13, 1,
114 -17, 1, -21, 1, 0, 2, 1, 2, 2, 2,
115 3, 2, 5, 2, 8, 2, 13, 2, 21, 2,
116 -1, 2, -2, 2, -3, 2, -5, 2, -8, 2,
117 -13, 2, -17, 2, -21, 2, 0, 3, 1, 3,
118 2, 3, 3, 3, 5, 3, 8, 3, 13, 3,
119 21, 3, -1, 3, -2, 3, -3, 3, -5, 3,
120 -8, 3, -13, 3, -17, 3, -21, 3, 0, 5,
121 1, 5, 2, 5, 3, 5, 5, 5, 8, 5,
122 13, 5, 21, 5, -1, 5, -2, 5, -3, 5,
123 -5, 5, -8, 5, -13, 5, -17, 5, -21, 5,
124 0, 8, 1, 8, 2, 8, 3, 8, 5, 8,
125 8, 8, 13, 8, 21, 8, -1, 8, -2, 8,
126 -3, 8, -5, 8, -8, 8, -13, 8, -17, 8,
127 -21, 8, 0, 13, 1, 13, 2, 13, 3, 13,
128 5, 13, 8, 13, 13, 13, 21, 13, -1, 13,
129 -2, 13, -3, 13, -5, 13, -8, 13, -13, 13,
130 -17, 13, -21, 13, 0, 21, 1, 21, 2, 21,
131 3, 21, 5, 21, 8, 21, 13, 21, 21, 21,
132 -1, 21, -2, 21, -3, 21, -5, 21, -8, 21,
133 -13, 21, -17, 21, -21, 21, 0, -1, 1, -1,
134 2, -1, 3, -1, 5, -1, 8, -1, 13, -1,
135 21, -1, -1, -1, -2, -1, -3, -1, -5, -1,
136 -8, -1, -13, -1, -17, -1, -21, -1, 0, -2,
137 1, -2, 2, -2, 3, -2, 5, -2, 8, -2,
138 13, -2, 21, -2, -1, -2, -2, -2, -3, -2,
139 -5, -2, -8, -2, -13, -2, -17, -2, -21, -2,
140 0, -3, 1, -3, 2, -3, 3, -3, 5, -3,
141 8, -3, 13, -3, 21, -3, -1, -3, -2, -3,
142 -3, -3, -5, -3, -8, -3, -13, -3, -17, -3,
143 -21, -3, 0, -5, 1, -5, 2, -5, 3, -5,
144 5, -5, 8, -5, 13, -5, 21, -5, -1, -5,
145 -2, -5, -3, -5, -5, -5, -8, -5, -13, -5,
146 -17, -5, -21, -5, 0, -8, 1, -8, 2, -8,
147 3, -8, 5, -8, 8, -8, 13, -8, 21, -8,
148 -1, -8, -2, -8, -3, -8, -5, -8, -8, -8,
149 -13, -8, -17, -8, -21, -8, 0, -13, 1, -13,
150 2, -13, 3, -13, 5, -13, 8, -13, 13, -13,
151 21, -13, -1, -13, -2, -13, -3, -13, -5, -13,
152 -8, -13, -13, -13, -17, -13, -21, -13, 0, -17,
153 1, -17, 2, -17, 3, -17, 5, -17, 8, -17,
154 13, -17, 21, -17, -1, -17, -2, -17, -3, -17,
155 -5, -17, -8, -17, -13, -17, -17, -17, -21, -17,
156 0, -21, 1, -21, 2, -21, 3, -21, 5, -21,
157 8, -21, 13, -21, 21, -21, -1, -21, -2, -21,
158 -3, -21, -5, -21, -8, -21, -13, -21, -17, -21,
159 0, 0, -8, -29, 8, -29, -18, -25, 17, -25,
160 0, -23, -6, -22, 6, -22, -13, -19, 12, -19,
161 0, -18, 25, -18, -25, -17, -5, -17, 5, -17,
162 -10, -15, 10, -15, 0, -14, -4, -13, 4, -13,
163 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
164 2, -11, 8, -11, -15, -10, -4, -10, 4, -10,
165 15, -10, -6, -9, -1, -9, 1, -9, 6, -9,
166 -29, -8, -11, -8, -8, -8, -3, -8, 3, -8,
167 8, -8, 11, -8, 29, -8, -5, -7, -2, -7,
168 0, -7, 2, -7, 5, -7, -22, -6, -9, -6,
169 -6, -6, -3, -6, -1, -6, 1, -6, 3, -6,
170 6, -6, 9, -6, 22, -6, -17, -5, -7, -5,
171 -4, -5, -2, -5, 0, -5, 2, -5, 4, -5,
172 7, -5, 17, -5, -13, -4, -10, -4, -5, -4,
173 -3, -4, -1, -4, 0, -4, 1, -4, 3, -4,
174 5, -4, 10, -4, 13, -4, -8, -3, -6, -3,
175 -4, -3, -3, -3, -2, -3, -1, -3, 0, -3,
176 1, -3, 2, -3, 4, -3, 6, -3, 8, -3,
177 -11, -2, -7, -2, -5, -2, -3, -2, -2, -2,
178 -1, -2, 0, -2, 1, -2, 2, -2, 3, -2,
179 5, -2, 7, -2, 11, -2, -9, -1, -6, -1,
180 -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
181 1, -1, 2, -1, 3, -1, 4, -1, 6, -1,
182 9, -1, -31, 0, -23, 0, -18, 0, -14, 0,
183 -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
184 -2, 0, -1, 0, 0, -31, 1, 0, 2, 0,
185 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
186 14, 0, 18, 0, 23, 0, 31, 0, -9, 1,
187 -6, 1, -4, 1, -3, 1, -2, 1, -1, 1,
188 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
189 6, 1, 9, 1, -11, 2, -7, 2, -5, 2,
190 -3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
191 2, 2, 3, 2, 5, 2, 7, 2, 11, 2,
192 -8, 3, -6, 3, -4, 3, -2, 3, -1, 3,
193 0, 3, 1, 3, 2, 3, 3, 3, 4, 3,
194 6, 3, 8, 3, -13, 4, -10, 4, -5, 4,
195 -3, 4, -1, 4, 0, 4, 1, 4, 3, 4,
196 5, 4, 10, 4, 13, 4, -17, 5, -7, 5,
197 -4, 5, -2, 5, 0, 5, 2, 5, 4, 5,
198 7, 5, 17, 5, -22, 6, -9, 6, -6, 6,
199 -3, 6, -1, 6, 1, 6, 3, 6, 6, 6,
200 9, 6, 22, 6, -5, 7, -2, 7, 0, 7,
201 2, 7, 5, 7, -29, 8, -11, 8, -8, 8,
202 -3, 8, 3, 8, 8, 8, 11, 8, 29, 8,
203 -6, 9, -1, 9, 1, 9, 6, 9, -15, 10,
204 -4, 10, 4, 10, 15, 10, -8, 11, -2, 11,
205 0, 11, 2, 11, 8, 11, 19, 12, -19, 13,
206 -4, 13, 4, 13, 0, 14, -10, 15, 10, 15,
207 -5, 17, 5, 17, 25, 17, -25, 18, 0, 18,
208 -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
209 -17, 25, 18, 25, -8, 29, 8, 29, 0, 31,
210 0, 0, -6, -22, 6, -22, -13, -19, 12, -19,
211 0, -18, -5, -17, 5, -17, -10, -15, 10, -15,
212 0, -14, -4, -13, 4, -13, 19, -13, -19, -12,
213 -8, -11, -2, -11, 0, -11, 2, -11, 8, -11,
214 -15, -10, -4, -10, 4, -10, 15, -10, -6, -9,
215 -1, -9, 1, -9, 6, -9, -11, -8, -8, -8,
216 -3, -8, 0, -8, 3, -8, 8, -8, 11, -8,
217 -5, -7, -2, -7, 0, -7, 2, -7, 5, -7,
218 -22, -6, -9, -6, -6, -6, -3, -6, -1, -6,
219 1, -6, 3, -6, 6, -6, 9, -6, 22, -6,
220 -17, -5, -7, -5, -4, -5, -2, -5, -1, -5,
221 0, -5, 1, -5, 2, -5, 4, -5, 7, -5,
222 17, -5, -13, -4, -10, -4, -5, -4, -3, -4,
223 -2, -4, -1, -4, 0, -4, 1, -4, 2, -4,
224 3, -4, 5, -4, 10, -4, 13, -4, -8, -3,
225 -6, -3, -4, -3, -3, -3, -2, -3, -1, -3,
226 0, -3, 1, -3, 2, -3, 3, -3, 4, -3,
227 6, -3, 8, -3, -11, -2, -7, -2, -5, -2,
228 -4, -2, -3, -2, -2, -2, -1, -2, 0, -2,
229 1, -2, 2, -2, 3, -2, 4, -2, 5, -2,
230 7, -2, 11, -2, -9, -1, -6, -1, -5, -1,
231 -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
232 1, -1, 2, -1, 3, -1, 4, -1, 5, -1,
233 6, -1, 9, -1, -23, 0, -18, 0, -14, 0,
234 -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
235 -2, 0, -1, 0, 0, -23, 1, 0, 2, 0,
236 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
237 14, 0, 18, 0, 23, 0, -9, 1, -6, 1,
238 -5, 1, -4, 1, -3, 1, -2, 1, -1, 1,
239 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
240 5, 1, 6, 1, 9, 1, -11, 2, -7, 2,
241 -5, 2, -4, 2, -3, 2, -2, 2, -1, 2,
242 0, 2, 1, 2, 2, 2, 3, 2, 4, 2,
243 5, 2, 7, 2, 11, 2, -8, 3, -6, 3,
244 -4, 3, -3, 3, -2, 3, -1, 3, 0, 3,
245 1, 3, 2, 3, 3, 3, 4, 3, 6, 3,
246 8, 3, -13, 4, -10, 4, -5, 4, -3, 4,
247 -2, 4, -1, 4, 0, 4, 1, 4, 2, 4,
248 3, 4, 5, 4, 10, 4, 13, 4, -17, 5,
249 -7, 5, -4, 5, -2, 5, -1, 5, 0, 5,
250 1, 5, 2, 5, 4, 5, 7, 5, 17, 5,
251 -22, 6, -9, 6, -6, 6, -3, 6, -1, 6,
252 1, 6, 3, 6, 6, 6, 9, 6, 22, 6,
253 -5, 7, -2, 7, 0, 7, 2, 7, 5, 7,
254 -11, 8, -8, 8, -3, 8, 0, 8, 3, 8,
255 8, 8, 11, 8, -6, 9, -1, 9, 1, 9,
256 6, 9, -15, 10, -4, 10, 4, 10, 15, 10,
257 -8, 11, -2, 11, 0, 11, 2, 11, 8, 11,
258 19, 12, -19, 13, -4, 13, 4, 13, 0, 14,
259 -10, 15, 10, 15, -5, 17, 5, 17, 0, 18,
260 -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
328 const int edge_max = edge_size - 1;
332 else if (y == edge_max)
336 else if (x == edge_max)
365 static void interp_point(int8_t *points,
int x0,
int y0,
int x1,
int y1,
366 int pos,
int npoints)
369 points[0] = (x0 * pos + x1 * (npoints -
pos) + (npoints >> 1)) / npoints;
370 points[1] = (y0 * pos + y1 * (npoints -
pos) + (npoints >> 1)) / npoints;
385 static void make_glyphs(int8_t *pglyphs,
const int8_t *xvec,
const int8_t *yvec,
386 const int side_length)
388 const int glyph_size = side_length * side_length;
389 int8_t *pglyph = pglyphs;
405 for (ipoint = 0; ipoint <= npoints; ipoint++) {
413 for (irow = point[1]; irow >= 0; irow--)
414 pglyph[point[0] + irow * side_length] = 1;
418 for (irow = point[1]; irow < side_length; irow++)
419 pglyph[point[0] + irow * side_length] = 1;
423 for (icol = point[0]; icol >= 0; icol--)
424 pglyph[icol + point[1] * side_length] = 1;
428 for (icol = point[0]; icol < side_length; icol++)
429 pglyph[icol + point[1] * side_length] = 1;
483 if (rotate_code == 2)
536 opcode = bytestream2_get_byte(&ctx->
gb);
537 run_len = (opcode >> 1) + 1;
542 color = bytestream2_get_byte(&ctx->
gb);
543 memset(dst, color, run_len);
563 for (i = 0; i <
height; i++) {
569 len = bytestream2_get_le16u(&ctx->
gb);
576 code = bytestream2_get_byteu(&ctx->
gb);
578 code = (code >> 1) + 1;
579 if (pos + code > width)
582 val = bytestream2_get_byteu(&ctx->
gb);
584 memset(dst + pos, val, code);
589 for (j = 0; j <
code; j++) {
590 val = bytestream2_get_byteu(&ctx->
gb);
610 for (j = 0; j < 4; j++) {
611 for (i = 0; i < 4; i++) {
612 if ((pos + i) < 0 || (pos + i) >= height * stride)
630 int compr = bytestream2_get_byte(&ctx->
gb);
631 int mvoff = bytestream2_get_byte(&ctx->
gb);
632 int seq = bytestream2_get_le16(&ctx->
gb);
633 uint32_t decoded_size = bytestream2_get_le32(&ctx->
gb);
637 flags = bytestream2_get_byte(&ctx->
gb);
640 if (decoded_size > ctx->
height * stride - left - top * stride) {
641 decoded_size = ctx->
height * stride - left - top *
stride;
647 if (((seq & 1) || !(flags & 1)) && (compr && compr != 2))
660 for (i = 0; i <
height; i++) {
676 for (j = 0; j <
height; j += 4) {
677 for (i = 0; i <
width; i += 4) {
686 code = bytestream2_get_byteu(&ctx->
gb);
691 for (k = 0; k < 4; k++)
697 for (k = 0; k < 4; k++)
698 memset(dst + i + k * stride, bytestream2_get_byteu(&ctx->
gb), 4);
703 t = bytestream2_get_byteu(&ctx->
gb);
704 for (k = 0; k < 4; k++)
705 memset(dst + i + k * stride, t, 4);
708 if (compr == 4 && !code) {
711 skip_run = bytestream2_get_byteu(&ctx->
gb) + 1;
718 codec37_mv(dst + i, prev + i + mx + my * stride,
719 ctx->
height, stride, i + mx, j + my);
727 for (j = 0; j <
height; j += 4) {
728 for (i = 0; i <
width; i += 4) {
735 code = bytestream2_get_byte(&ctx->
gb);
739 for (k = 0; k < 4; k++)
741 }
else if (compr == 4 && !code) {
744 skip_run = bytestream2_get_byteu(&ctx->
gb) + 1;
751 codec37_mv(dst + i, prev + i + mx + my * stride,
752 ctx->
height, stride, i + mx, j + my);
762 "Subcodec 37 compression %d", compr);
779 code = bytestream2_get_byteu(&ctx->
gb);
786 dst[0] = bytestream2_get_byteu(&ctx->
gb);
787 dst[1] = bytestream2_get_byteu(&ctx->
gb);
788 dst[0 +
stride] = bytestream2_get_byteu(&ctx->
gb);
789 dst[1 +
stride] = bytestream2_get_byteu(&ctx->
gb);
792 if (
process_block(ctx, dst, prev1, prev2, stride, tbl, size))
794 if (
process_block(ctx, dst + size, prev1 + size, prev2 + size,
800 if (
process_block(ctx, dst, prev1, prev2, stride, tbl, size))
802 if (
process_block(ctx, dst + size, prev1 + size, prev2 + size,
811 t = bytestream2_get_byteu(&ctx->
gb);
812 for (k = 0; k <
size; k++)
813 memset(dst + k * stride, t, size);
819 code = bytestream2_get_byteu(&ctx->
gb);
823 for (k = 0; k <
size; k++)
824 for (t = 0; t <
size; t++)
825 dst[t + k * stride] = colors[!*pglyph++];
828 for (k = 0; k <
size; k++)
829 memcpy(dst + k * stride, prev1 + k * stride, size);
834 t = bytestream2_get_byte(&ctx->
gb);
836 for (k = 0; k <
size; k++)
837 memset(dst + k * stride, t, size);
846 if (index < -mx - my * stride ||
847 (ctx->
buf_size >> 1) - index < mx + size + (my + size - 1) * stride) {
852 for (k = 0; k <
size; k++)
853 memcpy(dst + k * stride, prev2 + mx + (my + k) * stride, size);
862 uint32_t decoded_size;
869 int seq = bytestream2_get_le16(&ctx->
gb);
870 int compr = bytestream2_get_byte(&ctx->
gb);
871 int new_rot = bytestream2_get_byte(&ctx->
gb);
872 int skip = bytestream2_get_byte(&ctx->
gb);
875 decoded_size = bytestream2_get_le32(&ctx->
gb);
878 if (decoded_size > ctx->
height * stride - left - top * stride) {
879 decoded_size = ctx->
height * stride - left - top *
stride;
887 memset(prev1, 0, ctx->
height * stride);
888 memset(prev2, 0, ctx->
height * stride);
895 for (j = 0; j <
height; j++) {
903 for (j = 0; j <
height; j += 2) {
904 for (i = 0; i <
width; i += 2) {
908 dst[stride + i + 1] = bytestream2_get_byteu(&ctx->
gb);
915 for (j = 0; j <
height; j += 8) {
916 for (i = 0; i <
width; i += 8)
917 if (
process_block(ctx, dst + i, prev1 + i, prev2 + i, stride,
938 "Subcodec 47 compression %d", compr);
952 uint16_t codec = bytestream2_get_le16u(&ctx->
gb);
953 uint16_t
left = bytestream2_get_le16u(&ctx->
gb);
954 uint16_t top = bytestream2_get_le16u(&ctx->
gb);
955 uint16_t
w = bytestream2_get_le16u(&ctx->
gb);
956 uint16_t
h = bytestream2_get_le16u(&ctx->
gb);
963 if (ctx->
width < left + w || ctx->
height < top + h) {
993 uint16_t *frm = ctx->
frm0;
1000 for (y = 0; y < ctx->
height; y++) {
1001 for (x = 0; x < ctx->
width; x++)
1002 frm[x] = bytestream2_get_le16u(&ctx->
gb);
1018 ptrdiff_t
stride = pitch * 2;
1020 switch (block_size) {
1037 pitch -= block_size;
1038 for (y = 0; y < block_size; y++, pdest +=
pitch)
1039 for (x = 0; x < block_size; x++)
1044 uint16_t fg_color, uint16_t bg_color,
int block_size,
1048 uint16_t colors[2] = { fg_color, bg_color };
1057 pitch -= block_size;
1059 for (y = 0; y < block_size; y++, dst +=
pitch)
1060 for (x = 0; x < block_size; x++)
1061 *dst++ = colors[*pglyph++];
1067 uint16_t *dst = ctx->
frm0 + cx + cy * ctx->
pitch;
1069 if (block_size == 2) {
1075 indices = bytestream2_get_le32u(&ctx->
gb);
1076 dst[0] = ctx->
codebook[indices & 0xFF];
1078 dst[1] = ctx->
codebook[indices & 0xFF];
1082 dst[pitch + 1] = ctx->
codebook[indices & 0xFF];
1084 uint16_t fgcolor, bgcolor;
1090 glyph = bytestream2_get_byteu(&ctx->
gb);
1091 bgcolor = ctx->
codebook[bytestream2_get_byteu(&ctx->
gb)];
1092 fgcolor = ctx->
codebook[bytestream2_get_byteu(&ctx->
gb)];
1094 draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
1101 uint16_t *dst = ctx->
frm0 + cx + cy * ctx->
pitch;
1103 if (block_size == 2) {
1107 dst[0] = bytestream2_get_le16u(&ctx->
gb);
1108 dst[1] = bytestream2_get_le16u(&ctx->
gb);
1109 dst[
pitch] = bytestream2_get_le16u(&ctx->
gb);
1110 dst[pitch + 1] = bytestream2_get_le16u(&ctx->
gb);
1112 uint16_t fgcolor, bgcolor;
1118 glyph = bytestream2_get_byteu(&ctx->
gb);
1119 bgcolor = bytestream2_get_le16u(&ctx->
gb);
1120 fgcolor = bytestream2_get_le16u(&ctx->
gb);
1122 draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
1130 int start_pos = cx + mx + (cy + my) * ctx->
pitch;
1131 int end_pos = start_pos + (block_size - 1) * (ctx->
pitch + 1);
1133 int good = start_pos >= 0 && end_pos < (ctx->
buf_size >> 1);
1137 "Ignoring invalid motion vector (%i, %i)->(%u, %u), block size = %u\n",
1138 cx + mx, cy + my, cx, cy, block_size);
1145 int16_t mx, my,
index;
1151 opcode = bytestream2_get_byteu(&ctx->
gb);
1158 if (
good_mvec(ctx, cx, cy, mx, my, blk_size)) {
1160 ctx->
frm2 + cx + mx + ctx->
pitch * (cy + my),
1161 blk_size, ctx->
pitch);
1167 index = bytestream2_get_le16u(&ctx->
gb);
1169 mx = index % ctx->
width;
1170 my = index / ctx->
width;
1172 if (
good_mvec(ctx, cx, cy, mx, my, blk_size)) {
1174 ctx->
frm2 + cx + mx + ctx->
pitch * (cy + my),
1175 blk_size, ctx->
pitch);
1181 blk_size, ctx->
pitch);
1201 ctx->
codebook[bytestream2_get_byteu(&ctx->
gb)], blk_size, ctx->
pitch);
1207 bytestream2_get_le16u(&ctx->
gb), blk_size, ctx->
pitch);
1210 if (blk_size == 2) {
1278 uint16_t *frm = ctx->
frm0;
1285 *frm++ = ctx->
codebook[bytestream2_get_byteu(&ctx->
gb)];
1292 uint16_t *pdest = ctx->
frm0;
1330 hdr->
width = bytestream2_get_le32u(&ctx->
gb);
1331 hdr->
height = bytestream2_get_le32u(&ctx->
gb);
1338 hdr->
seq_num = bytestream2_get_le16u(&ctx->
gb);
1339 hdr->
codec = bytestream2_get_byteu(&ctx->
gb);
1344 for (i = 0; i < 4; i++)
1346 hdr->
bg_color = bytestream2_get_le16u(&ctx->
gb);
1351 for (i = 0; i < 256; i++)
1352 ctx->
codebook[i] = bytestream2_get_le16u(&ctx->
gb);
1372 ptrdiff_t dstpitch, srcpitch = ctx->
pitch * (hdr ?
sizeof(ctx->
frm0[0]) : 1);
1381 memcpy(dst, src, srcpitch);
1405 sig = bytestream2_get_be32u(&ctx->
gb);
1406 size = bytestream2_get_be32u(&ctx->
gb);
1414 case MKBETAG(
'N',
'P',
'A',
'L'):
1417 "Incorrect palette block size %"PRIu32
".\n", size);
1421 ctx->
pal[i] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->
gb);
1423 case MKBETAG(
'F',
'O',
'B',
'J'):
1429 case MKBETAG(
'X',
'P',
'A',
'L'):
1430 if (size == 6 || size == 4) {
1435 for (j = 0; j < 3; j++) {
1436 int t = (ctx->
pal[
i] >> (16 - j * 8)) & 0xFF;
1437 tmp[j] = av_clip_uint8((t * 129 + ctx->
delta_pal[i * 3 + j]) >> 7);
1444 "Incorrect palette change block size %"PRIu32
".\n",
1450 ctx->
delta_pal[i] = bytestream2_get_le16u(&ctx->
gb);
1451 if (size >= PALETTE_DELTA * 5 + 4) {
1453 ctx->
pal[i] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->
gb);
1455 memset(ctx->
pal, 0,
sizeof(ctx->
pal));
1459 case MKBETAG(
'S',
'T',
'O',
'R'):
1462 case MKBETAG(
'F',
'T',
'C',
'H'):
1468 "Unknown/unsupported chunk %"PRIx32
".\n", sig);
1499 "Subcodec %d: error decoding frame.\n", header.
codec);
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static int process_frame_obj(SANMVideoContext *ctx)
This structure describes decoded (raw) audio or video data.
static int read_frame_header(SANMVideoContext *ctx, SANMFrameHeader *hdr)
int8_t p4x4glyphs[NGLYPHS][16]
ptrdiff_t const GLvoid * data
#define AV_LOG_WARNING
Something somehow does not look correct.
static void fill_frame(uint16_t *pbuf, int buf_size, uint16_t color)
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
static av_cold int init(AVCodecContext *avctx)
#define avpriv_request_sample(...)
uint32_t pal[PALETTE_SIZE]
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *pkt)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static enum GlyphEdge which_edge(int x, int y, int edge_size)
Return enum GlyphEdge of box where point (x, y) lies.
static const int8_t glyph4_x[GLYPH_COORD_VECT_SIZE]
static void copy_block8(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
static const int8_t glyph8_y[GLYPH_COORD_VECT_SIZE]
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
static const uint8_t run_len[7][16]
static av_cold int decode_init(AVCodecContext *avctx)
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
8 bits with AV_PIX_FMT_RGB32 palette
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
static int good_mvec(SANMVideoContext *ctx, int cx, int cy, int mx, int my, int block_size)
static av_cold int end(AVCodecContext *avctx)
static void codec37_mv(uint8_t *dst, const uint8_t *src, int height, int stride, int x, int y)
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
static const int8_t glyph4_y[GLYPH_COORD_VECT_SIZE]
int(* frm_decoder)(SANMVideoContext *ctx)
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
static const int8_t motion_vectors[256][2]
static const uint8_t header[24]
static int decode_5(SANMVideoContext *ctx)
static void fill_block(uint16_t *pdest, uint16_t color, int block_size, ptrdiff_t pitch)
uint16_t small_codebook[4]
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_cold int decode_end(AVCodecContext *avctx)
static void copy_block(uint16_t *pdest, uint16_t *psrc, int block_size, ptrdiff_t pitch)
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
static int rle_decode(SANMVideoContext *ctx, uint8_t *dst, const int out_size)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
simple assert() macros that are a bit more flexible than ISO C assert().
static int decode_3(SANMVideoContext *ctx)
const char * name
Name of the codec implementation.
static enum GlyphDir which_direction(enum GlyphEdge edge0, enum GlyphEdge edge1)
static void make_glyphs(int8_t *pglyphs, const int8_t *xvec, const int8_t *yvec, const int side_length)
Construct glyphs by iterating through vector coordinates.
uint32_t stored_frame_size
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
enum AVPictureType pict_type
Picture type of the frame.
int width
picture width / height.
static void destroy_buffers(SANMVideoContext *ctx)
static void interp_point(int8_t *points, int x0, int y0, int x1, int y1, int pos, int npoints)
static int old_codec47(SANMVideoContext *ctx, int top, int left, int width, int height)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static int copy_output(SANMVideoContext *ctx, SANMFrameHeader *hdr)
static int opcode_0xf7(SANMVideoContext *ctx, int cx, int cy, int block_size, ptrdiff_t pitch)
#define FF_ARRAY_ELEMS(a)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
static av_cold int init_buffers(SANMVideoContext *ctx)
static av_always_inline int bytestream2_tell(GetByteContext *g)
static int draw_glyph(SANMVideoContext *ctx, uint16_t *dst, int index, uint16_t fg_color, uint16_t bg_color, int block_size, ptrdiff_t pitch)
static const int8_t c37_mv[]
Libavcodec external API header.
#define GLYPH_COORD_VECT_SIZE
static int decode_nop(SANMVideoContext *ctx)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
static int decode_6(SANMVideoContext *ctx)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static void copy_block4(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)
main external API structure.
static int codec2subblock(SANMVideoContext *ctx, int cx, int cy, int blk_size)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
static int process_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *prev1, uint8_t *prev2, int stride, int tbl, int size)
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2]...the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so...,+,-,+,-,+,+,-,+,-,+,...hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32-hcoeff[1]-hcoeff[2]-...a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2}an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||.........intra?||||:Block01:yes no||||:Block02:.................||||:Block03::y DC::ref index:||||:Block04::cb DC::motion x:||||.........:cr DC::motion y:||||.................|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------------------------------|||Y subbands||Cb subbands||Cr subbands||||------||------||------|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||------||------||------||||------||------||------|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||------||------||------||||------||------||------|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||------||------||------||||------||------||------|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------------------------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction------------|\Dequantization-------------------\||Reference frames|\IDWT|--------------|Motion\|||Frame 0||Frame 1||Compensation.OBMC v-------|--------------|--------------.\------> Frame n output Frame Frame<----------------------------------/|...|-------------------Range Coder:============Binary Range Coder:-------------------The implemented range coder is an adapted version based upon"Range encoding: an algorithm for removing redundancy from a digitised message."by G.N.N.Martin.The symbols encoded by the Snow range coder are bits(0|1).The associated probabilities are not fix but change depending on the symbol mix seen so far.bit seen|new state---------+-----------------------------------------------0|256-state_transition_table[256-old_state];1|state_transition_table[old_state];state_transition_table={0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:-------------------------FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1.the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
static int decode_2(SANMVideoContext *ctx)
static int decode_8(SANMVideoContext *ctx)
static int decode_0(SANMVideoContext *ctx)
static void rotate_bufs(SANMVideoContext *ctx, int rotate_code)
static void copy_block16(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
#define flags(name, subs,...)
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
static const frm_decoder v1_decoders[]
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
unsigned int rle_buf_size
GLint GLenum GLboolean GLsizei stride
static int old_codec37(SANMVideoContext *ctx, int top, int left, int width, int height)
common internal api header.
static void init_sizes(SANMVideoContext *ctx, int width, int height)
void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_padded_malloc except that buffer will always be 0-initialized after call...
#define MKBETAG(a, b, c, d)
static const int8_t glyph8_x[GLYPH_COORD_VECT_SIZE]
static int decode_4(SANMVideoContext *ctx)
int16_t delta_pal[PALETTE_DELTA]
int key_frame
1 -> keyframe, 0-> not
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
#define AV_PIX_FMT_RGB565
static int old_codec1(SANMVideoContext *ctx, int top, int left, int width, int height)
int8_t p8x8glyphs[NGLYPHS][64]
#define FFSWAP(type, a, b)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
static double val(void *priv, double ch)
This structure stores compressed data.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
static int opcode_0xf8(SANMVideoContext *ctx, int cx, int cy, int block_size, ptrdiff_t pitch)