]> git.nihav.org Git - nihav.git/blob - nihav-duck/src/codecs/truemotion1.rs
vp7: skip DC transform for empty block
[nihav.git] / nihav-duck / src / codecs / truemotion1.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3
4 struct MaskState<'a> {
5 is_intra: bool,
6 pos: usize,
7 row_pos: usize,
8 row_size: usize,
9 mask: u8,
10 src: &'a [u8],
11 }
12
13 impl<'a> MaskState<'a> {
14 fn new(is_intra: bool, src: &'a [u8], row_size: usize) -> Self {
15 Self { is_intra, src, pos: 0, row_pos: 0, row_size, mask: 0x01 }
16 }
17 fn get_next(&mut self) -> bool {
18 if self.is_intra {
19 true
20 } else {
21 let res = (self.src[self.pos] & self.mask) == 0;
22 self.mask <<= 1;
23 if self.mask == 0 {
24 self.pos += 1;
25 self.mask = 0x01;
26 }
27 res
28 }
29 }
30 fn reset_row(&mut self) {
31 self.pos = self.row_pos;
32 self.mask = 0x01;
33 }
34 fn next_row(&mut self) {
35 self.row_pos += self.row_size;
36 self.reset_row();
37 }
38 }
39
40 struct IndexState<'a> {
41 src: &'a [u8],
42 pos: usize,
43 vec_idx: usize,
44 vec_subidx: usize,
45 }
46
47 impl<'a> IndexState<'a> {
48 fn new(src: &'a [u8]) -> Self {
49 Self { src, pos: 0, vec_idx: 0, vec_subidx: 0 }
50 }
51 fn get_next(&mut self) -> DecoderResult<()> {
52 validate!(self.pos < self.src.len());
53 self.vec_idx = self.src[self.pos] as usize;
54 self.vec_subidx = 0;
55 self.pos += 1;
56 Ok(())
57 }
58 fn get_pred(&self, dtab: &[[u32; 4]; 256]) -> u32 { dtab[self.vec_idx][self.vec_subidx] }
59 fn get_diff16(&mut self, dtab: &[[u32; 4]; 256]) -> DecoderResult<u32> {
60 let pred1 = self.get_pred(dtab);
61 let mut pred = pred1 >> 1;
62 if (pred1 & 1) != 0 {
63 self.get_next()?;
64 if self.vec_idx == 0 {
65 self.get_next()?;
66 let pred2 = self.get_pred(dtab);
67 pred = pred.wrapping_add((pred2 >> 1).wrapping_mul(5));
68 if (pred2 & 1) != 0 {
69 self.get_next()?;
70 } else {
71 self.vec_subidx += 1;
72 }
73 }
74 } else {
75 self.vec_subidx += 1;
76 }
77 Ok(pred)
78 }
79 fn get_diff16_noesc(&mut self, dtab: &[[u32; 4]; 256]) -> DecoderResult<u32> {
80 let pred1 = self.get_pred(dtab);
81 let pred = pred1 >> 1;
82 if (pred1 & 1) != 0 {
83 self.get_next()?;
84 } else {
85 self.vec_subidx += 1;
86 }
87 Ok(pred)
88 }
89 fn get_diff24(&mut self, dtab: &[[u32; 4]; 256], esctab: &[[u32; 4]; 256]) -> DecoderResult<u32> {
90 let pred1 = self.get_pred(dtab);
91 let mut pred = pred1 >> 1;
92 if (pred1 & 1) != 0 {
93 self.get_next()?;
94 if self.vec_idx == 0 {
95 self.get_next()?;
96 let pred2 = self.get_pred(esctab);
97 pred = pred.wrapping_add(pred2 >> 1);
98 if (pred2 & 1) != 0 {
99 self.get_next()?;
100 } else {
101 self.vec_subidx += 1;
102 }
103 }
104 } else {
105 self.vec_subidx += 1;
106 }
107 Ok(pred)
108 }
109 }
110
111 struct DeltaTables {
112 ydt: [[u32; 4]; 256],
113 cdt: [[u32; 4]; 256],
114 fat_ydt: [[u32; 4]; 256],
115 fat_cdt: [[u32; 4]; 256],
116 adt: [[u32; 4]; 256],
117 }
118
119 impl Default for DeltaTables {
120 fn default() -> Self {
121 Self {
122 ydt: [[0; 4]; 256],
123 cdt: [[0; 4]; 256],
124 fat_ydt: [[0; 4]; 256],
125 fat_cdt: [[0; 4]; 256],
126 adt: [[0; 4]; 256],
127 }
128 }
129 }
130
131 struct FrameBuf {
132 last16: Option<NAVideoBufferRef<u16>>,
133 last24: Option<NAVideoBufferRef<u8>>,
134 }
135
136 impl FrameBuf {
137 fn set16(&mut self, buf: NAVideoBufferRef<u16>) { self.last16 = Some(buf); }
138 fn set24(&mut self, buf: NAVideoBufferRef<u8>) { self.last24 = Some(buf); }
139 fn get16(&mut self) -> Option<NAVideoBufferRef<u16>> {
140 if let Some(ref mut frm) = self.last16 {
141 let newfrm = frm.copy_buffer();
142 *frm = newfrm.clone().into_ref();
143 Some(newfrm.into_ref())
144 } else {
145 None
146 }
147 }
148 fn get24(&mut self) -> Option<NAVideoBufferRef<u8>> {
149 if let Some(ref mut frm) = self.last24 {
150 let newfrm = frm.copy_buffer();
151 *frm = newfrm.clone().into_ref();
152 Some(newfrm.into_ref())
153 } else {
154 None
155 }
156 }
157 fn reset(&mut self) {
158 self.last16 = None;
159 self.last24 = None;
160 }
161 }
162
163 impl Default for FrameBuf {
164 fn default() -> Self {
165 Self { last16: None, last24: None }
166 }
167 }
168
169 #[derive(Default)]
170 struct TM1Decoder {
171 info: NACodecInfoRef,
172 last_delta_set: usize,
173 last_table_idx: usize,
174 delta_tables: DeltaTables,
175 blk_w: usize,
176 blk_h: usize,
177 vert_pred: Vec<u32>,
178 lastframe: FrameBuf,
179 }
180
181 const RGB555_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
182 comp_info: [
183 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 10, comp_offs: 0, next_elem: 2 }),
184 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 5, comp_offs: 0, next_elem: 2 }),
185 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 0, comp_offs: 0, next_elem: 2 }),
186 None, None],
187 elem_size: 2, be: false, alpha: false, palette: false };
188 const BGR0_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
189 comp_info: [
190 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 2, next_elem: 4 }),
191 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 1, next_elem: 4 }),
192 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 0, next_elem: 4 }),
193 None, None],
194 elem_size: 4, be: false, alpha: false, palette: false };
195
196 impl TM1Decoder {
197 fn new() -> Self { Self::default() }
198 fn set_delta_tables(&mut self, delta_set: usize, table_idx: usize, is_24bit: bool) {
199 if (self.last_delta_set == delta_set) && (self.last_table_idx == table_idx) { return; }
200 let ydt = &DUCK_Y_DELTAS[delta_set];
201 let yfdt = DUCK_Y_FAT_DELTAS[delta_set];
202 let cdt = &DUCK_C_DELTAS[delta_set];
203 let cfdt = DUCK_C_FAT_DELTAS[delta_set];
204 let vec = DUCK_VECTABLES[table_idx - 1];
205
206 let mut vec_iter = vec.iter();
207 for i in 0..256 {
208 let len = (*vec_iter.next().unwrap() as usize) >> 1;
209 for j in 0..len {
210 let pair = vec_iter.next().unwrap();
211 let lo = (pair >> 4) as usize;
212 let hi = (pair & 0xF) as usize;
213 if !is_24bit {
214 let d_lo = ydt[lo] + (ydt[lo] << 5) + (ydt[lo] << 10);
215 let d_hi = ydt[hi] + (ydt[hi] << 5) + (ydt[hi] << 10);
216 self.delta_tables.ydt[i][j] = ((d_lo + (d_hi << 16)) << 1) as u32;
217 let d_c = cdt[hi] + (cdt[lo] << 10);
218 self.delta_tables.cdt[i][j] = ((d_c + (d_c << 16)) << 1) as u32;
219 let d_a = lo + hi * 5;
220 self.delta_tables.adt[i][j] = ((d_a << 16) << 1) as u32;
221 } else {
222 self.delta_tables.ydt[i][j] = ((ydt [lo] + (ydt [hi] << 8) + (ydt [hi] << 16)) << 1) as u32;
223 self.delta_tables.fat_ydt[i][j] = ((yfdt[lo] + (yfdt[hi] << 8) + (yfdt[hi] << 16)) << 1) as u32;
224 self.delta_tables.cdt[i][j] = ((cdt [hi] + (cdt [lo] << 16)) << 1) as u32;
225 self.delta_tables.fat_cdt[i][j] = ((cfdt[hi] + (cfdt[lo] << 16)) << 1) as u32;
226 }
227 }
228 self.delta_tables.ydt[i][len - 1] |= 1;
229 self.delta_tables.cdt[i][len - 1] |= 1;
230 self.delta_tables.adt[i][len - 1] |= 1;
231 self.delta_tables.fat_ydt[i][len - 1] |= 1;
232 self.delta_tables.fat_cdt[i][len - 1] |= 1;
233 }
234
235 self.last_delta_set = delta_set;
236 self.last_table_idx = table_idx;
237 }
238 fn decode_16bit(&mut self, dst: &mut [u16], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
239 let mut off = 0;
240 index.get_next()?;
241 for y in 0..height {
242 let mut hor_pred: u32 = 0;
243 for x in (0..width).step_by(4) {
244 if mask.get_next() {
245 match y & 3 {
246 0 => {
247 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
248 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
249 hor_pred = hor_pred.wrapping_add(dc0);
250 hor_pred = hor_pred.wrapping_add(dy0);
251 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
252 self.vert_pred[(x >> 1) + 0] = cur;
253 dst[off + x + 0] = cur as u16;
254 dst[off + x + 1] = (cur >> 16) as u16;
255 if self.blk_w == 2 {
256 let dc1 = index.get_diff16(&self.delta_tables.cdt)?;
257 hor_pred = hor_pred.wrapping_add(dc1);
258 }
259 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
260 hor_pred = hor_pred.wrapping_add(dy1);
261 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
262 self.vert_pred[(x >> 1) + 1] = cur;
263 dst[off + x + 2] = cur as u16;
264 dst[off + x + 3] = (cur >> 16) as u16;
265 },
266 1 | 3 => {
267 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
268 hor_pred = hor_pred.wrapping_add(dy0);
269 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
270 self.vert_pred[(x >> 1) + 0] = cur;
271 dst[off + x + 0] = cur as u16;
272 dst[off + x + 1] = (cur >> 16) as u16;
273 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
274 hor_pred = hor_pred.wrapping_add(dy1);
275 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
276 self.vert_pred[(x >> 1) + 1] = cur;
277 dst[off + x + 2] = cur as u16;
278 dst[off + x + 3] = (cur >> 16) as u16;
279 },
280 2 => {
281 if self.blk_h == 2 {
282 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
283 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
284 hor_pred = hor_pred.wrapping_add(dc0);
285 hor_pred = hor_pred.wrapping_add(dy0);
286 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
287 self.vert_pred[(x >> 1) + 0] = cur;
288 dst[off + x + 0] = cur as u16;
289 dst[off + x + 1] = (cur >> 16) as u16;
290 if self.blk_w == 2 {
291 let dc1 = index.get_diff16(&self.delta_tables.cdt)?;
292 hor_pred = hor_pred.wrapping_add(dc1);
293 }
294 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
295 hor_pred = hor_pred.wrapping_add(dy1);
296 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
297 self.vert_pred[(x >> 1) + 1] = cur;
298 dst[off + x + 2] = cur as u16;
299 dst[off + x + 3] = (cur >> 16) as u16;
300 } else {
301 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
302 hor_pred = hor_pred.wrapping_add(dy0);
303 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
304 self.vert_pred[(x >> 1) + 0] = cur;
305 dst[off + x + 0] = cur as u16;
306 dst[off + x + 1] = (cur >> 16) as u16;
307 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
308 hor_pred = hor_pred.wrapping_add(dy1);
309 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
310 self.vert_pred[(x >> 1) + 1] = cur;
311 dst[off + x + 2] = cur as u16;
312 dst[off + x + 3] = (cur >> 16) as u16;
313 }
314 },
315 _ => unreachable!(),
316 };
317 } else {
318 let cur = u32::from(dst[off + x + 0]) | (u32::from(dst[off + x + 1]) << 16);
319 self.vert_pred[(x >> 1) + 0] = cur;
320 let cur = u32::from(dst[off + x + 2]) | (u32::from(dst[off + x + 3]) << 16);
321 hor_pred = cur.wrapping_sub(self.vert_pred[(x >> 1) + 1]);
322 self.vert_pred[(x >> 1) + 1] = cur;
323 }
324 }
325 if (y & 3) != 3 {
326 mask.reset_row();
327 } else {
328 mask.next_row();
329 }
330 off += stride;
331 }
332 Ok(())
333 }
334 fn decode_sprite(&mut self, dst: &mut [u16], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
335 let mut off = 0;
336 let _ = index.get_next();
337 for y in 0..height {
338 let mut hor_pred: u32 = 0;
339 for x in (0..width).step_by(4) {
340 let is_tm = !mask.get_next();
341 let is_sprite = !mask.get_next();
342 if is_tm {
343 if (y & 3) == 0 {
344 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
345 hor_pred = hor_pred.wrapping_add(dc0);
346 }
347 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
348 hor_pred = hor_pred.wrapping_add(dy0);
349 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
350 self.vert_pred[(x >> 1) + 0] = cur;
351 dst[off + x + 0] = cur as u16;
352 dst[off + x + 1] = (cur >> 16) as u16;
353 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
354 hor_pred = hor_pred.wrapping_add(dy1);
355 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
356 self.vert_pred[(x >> 1) + 1] = cur;
357 dst[off + x + 2] = cur as u16;
358 dst[off + x + 3] = (cur >> 16) as u16;
359 } else if is_sprite {
360 if (y & 3) == 0 {
361 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
362 hor_pred = hor_pred.wrapping_add(dc0);
363 }
364 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
365 hor_pred = hor_pred.wrapping_add(dy0);
366 let _da0 = index.get_diff16_noesc(&self.delta_tables.adt)?;
367 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
368 self.vert_pred[(x >> 1) + 0] = cur;
369 dst[off + x + 0] = cur as u16;
370 dst[off + x + 1] = (cur >> 16) as u16;
371 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
372 hor_pred = hor_pred.wrapping_add(dy1);
373 let _da1 = index.get_diff16_noesc(&self.delta_tables.adt)?;
374 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
375 self.vert_pred[(x >> 1) + 1] = cur;
376 dst[off + x + 2] = cur as u16;
377 dst[off + x + 3] = (cur >> 16) as u16;
378 } else {
379 hor_pred = 0;
380 dst[off + x + 0] = 0;
381 dst[off + x + 1] = 0;
382 dst[off + x + 2] = 0;
383 dst[off + x + 3] = 0;
384 self.vert_pred[(x >> 1) + 0] = 0;
385 self.vert_pred[(x >> 1) + 1] = 0;
386 }
387 }
388 if (y & 3) != 3 {
389 mask.reset_row();
390 } else {
391 mask.next_row();
392 }
393 off += stride;
394 }
395 Ok(())
396 }
397 fn decode_24bit(&mut self, dst: &mut [u8], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
398 let mut off = 0;
399 index.get_next()?;
400 for y in 0..height {
401 let mut hor_pred: u32 = 0;
402 for x in (0..width).step_by(2) {
403 if mask.get_next() {
404 match y & 3 {
405 0 => {
406 let dc0 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
407 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
408 hor_pred = hor_pred.wrapping_add(dc0);
409 hor_pred = hor_pred.wrapping_add(dy0);
410 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
411 self.vert_pred[x + 0] = cur;
412 dst[off + x*4 + 0] = cur as u8;
413 dst[off + x*4 + 1] = (cur >> 8) as u8;
414 dst[off + x*4 + 2] = (cur >> 16) as u8;
415 dst[off + x*4 + 3] = 0;
416 if self.blk_w == 2 {
417 let dc1 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
418 hor_pred = hor_pred.wrapping_add(dc1);
419 }
420 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
421 hor_pred = hor_pred.wrapping_add(dy1);
422 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
423 self.vert_pred[x + 1] = cur;
424 dst[off + x*4 + 4] = cur as u8;
425 dst[off + x*4 + 5] = (cur >> 8) as u8;
426 dst[off + x*4 + 6] = (cur >> 16) as u8;
427 dst[off + x*4 + 7] = 0;
428 },
429 1 | 3 => {
430 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
431 hor_pred = hor_pred.wrapping_add(dy0);
432 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
433 self.vert_pred[x + 0] = cur;
434 dst[off + x*4 + 0] = cur as u8;
435 dst[off + x*4 + 1] = (cur >> 8) as u8;
436 dst[off + x*4 + 2] = (cur >> 16) as u8;
437 dst[off + x*4 + 3] = 0;
438 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
439 hor_pred = hor_pred.wrapping_add(dy1);
440 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
441 self.vert_pred[x + 1] = cur;
442 dst[off + x*4 + 4] = cur as u8;
443 dst[off + x*4 + 5] = (cur >> 8) as u8;
444 dst[off + x*4 + 6] = (cur >> 16) as u8;
445 dst[off + x*4 + 7] = 0;
446 },
447 2 => {
448 if self.blk_h == 2 {
449 let dc0 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
450 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
451 hor_pred = hor_pred.wrapping_add(dc0);
452 hor_pred = hor_pred.wrapping_add(dy0);
453 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
454 self.vert_pred[x + 0] = cur;
455 dst[off + x*4 + 0] = cur as u8;
456 dst[off + x*4 + 1] = (cur >> 8) as u8;
457 dst[off + x*4 + 2] = (cur >> 16) as u8;
458 dst[off + x*4 + 3] = 0;
459 if self.blk_w == 2 {
460 let dc1 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
461 hor_pred = hor_pred.wrapping_add(dc1);
462 }
463 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
464 hor_pred = hor_pred.wrapping_add(dy1);
465 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
466 self.vert_pred[x + 1] = cur;
467 dst[off + x*4 + 4] = cur as u8;
468 dst[off + x*4 + 5] = (cur >> 8) as u8;
469 dst[off + x*4 + 6] = (cur >> 16) as u8;
470 dst[off + x*4 + 7] = 0;
471 } else {
472 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
473 hor_pred = hor_pred.wrapping_add(dy0);
474 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
475 self.vert_pred[x + 0] = cur;
476 dst[off + x*4 + 0] = cur as u8;
477 dst[off + x*4 + 1] = (cur >> 8) as u8;
478 dst[off + x*4 + 2] = (cur >> 16) as u8;
479 dst[off + x*4 + 3] = 0;
480 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
481 hor_pred = hor_pred.wrapping_add(dy1);
482 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
483 self.vert_pred[x + 1] = cur;
484 dst[off + x*4 + 4] = cur as u8;
485 dst[off + x*4 + 5] = (cur >> 8) as u8;
486 dst[off + x*4 + 6] = (cur >> 16) as u8;
487 dst[off + x*4 + 7] = 0;
488 }
489 },
490 _ => unreachable!(),
491 };
492 } else {
493 let cur = u32::from(dst[off + x*4 + 0])
494 | (u32::from(dst[off + x*4 + 1]) << 8)
495 | (u32::from(dst[off + x*4 + 2]) << 16)
496 | (u32::from(dst[off + x*4 + 3]) << 24);
497 self.vert_pred[x + 0] = cur;
498 let cur = u32::from(dst[off + x*4 + 4])
499 | (u32::from(dst[off + x*4 + 5]) << 8)
500 | (u32::from(dst[off + x*4 + 6]) << 16)
501 | (u32::from(dst[off + x*4 + 7]) << 24);
502 hor_pred = cur.wrapping_sub(self.vert_pred[x + 1]);
503 self.vert_pred[x + 1] = cur;
504 }
505 }
506 if (y & 3) != 3 {
507 mask.reset_row();
508 } else {
509 mask.next_row();
510 }
511 off += stride;
512 }
513 Ok(())
514 }
515 }
516
517 impl NADecoder for TM1Decoder {
518 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
519 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
520 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, YUV410_FORMAT));
521 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
522 Ok(())
523 } else {
524 Err(DecoderError::InvalidData)
525 }
526 }
527 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
528 let src = pkt.get_buffer();
529 validate!(src.len() > 10);
530 let hdr_size = (src[0].rotate_left(3) & 0x7F) as usize;
531 validate!(hdr_size >= 12 && hdr_size < src.len());
532 let mut hdr: [u8; 127] = [0; 127];
533 for i in 1..hdr_size {
534 hdr[i - 1] = src[i] ^ src[i + 1];
535 }
536 let mut mr = MemoryReader::new_read(&hdr[0..hdr_size-1]);
537 let mut br = ByteReader::new(&mut mr);
538
539 let tm1type = br.read_byte()? as usize;
540 let delta_set = br.read_byte()? as usize;
541 let table_idx = br.read_byte()? as usize;
542 let height = br.read_u16le()? as usize;
543 let width = br.read_u16le()? as usize;
544 let _frameno = br.read_u16le()? as usize;
545 let version = br.read_byte()?;
546 let meta_type = br.read_byte()?;
547 validate!(width > 0 && height > 0);
548 let is_intra;
549 let mut is_sprite = false;
550 let mut spr_xoff = 0;
551 let mut spr_yoff = 0;
552 let mut spr_width = 0;
553 let mut spr_height = 0;
554 if version >= 2 {
555 validate!(meta_type <= 3);
556 if meta_type >= 2 {
557 let frameinfo = br.read_byte()?;
558 let _control = br.read_byte()?;
559
560 is_intra = ((frameinfo & 0x10) != 0) || ((frameinfo & 0x08) == 0);
561 } else {
562 is_intra = true;
563 }
564 if meta_type == 3 {
565 spr_xoff = br.read_u16le()? as usize;
566 spr_yoff = br.read_u16le()? as usize;
567 spr_width = br.read_u16le()? as usize;
568 spr_height = br.read_u16le()? as usize;
569 is_sprite = true;
570 }
571 } else {
572 is_intra = true;
573 }
574 validate!(tm1type < TM1_COMPR_TYPES.len());
575 let cinfo = TM1_COMPR_TYPES[tm1type];
576 if cinfo.is_none() {
577 //check for missing ref
578 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
579 frm.set_keyframe(false);
580 frm.set_frame_type(FrameType::Skip);
581 return Ok(frm.into_ref());
582 }
583 let compr_info = cinfo.unwrap();
584 let is_24bit = !is_sprite && compr_info.is_24bit;
585
586 let vec_idx = if ((tm1type & 1) != 0) && (meta_type > 0) { 1 } else { table_idx };
587 validate!((delta_set < DUCK_Y_DELTAS.len()) && (vec_idx > 0) && (vec_idx <= DUCK_VECTABLES.len()));
588 self.set_delta_tables(delta_set, vec_idx, is_24bit);
589
590 let out_width = if is_24bit { width >> 1 } else { width };
591 let mask_row_size = if is_sprite {
592 ((spr_width >> 2) + 3) >> 2
593 } else if is_intra {
594 0
595 } else {
596 ((width >> 2) + 7) >> 3
597 };
598 let mask_size = mask_row_size * (if is_sprite { spr_height >> 2 } else { height >> 2 });
599 let mask_bits = &src[hdr_size..][..mask_size];
600 let index_bytes = &src[hdr_size+mask_size..];
601 validate!(src.len() >= hdr_size + mask_size);
602 self.vert_pred.truncate(0);
603 self.vert_pred.resize(out_width, 0);
604
605 if is_intra || is_sprite {
606 let fmt = if is_24bit { BGR0_FORMAT } else { RGB555_FORMAT };
607 let myinfo = NAVideoInfo::new(out_width, height, false, fmt);
608 let bufinfo = alloc_video_buffer(myinfo, 2)?;
609 self.lastframe.reset();
610 if !is_24bit {
611 self.lastframe.set16(bufinfo.get_vbuf16().unwrap());
612 } else {
613 self.lastframe.set24(bufinfo.get_vbuf().unwrap());
614 }
615 }
616
617 self.blk_w = compr_info.block_w;
618 self.blk_h = compr_info.block_h;
619 let mut mask = MaskState::new(is_intra && !is_sprite, &mask_bits, mask_row_size);
620 let mut index = IndexState::new(&index_bytes);
621 let bufinfo;
622 if !is_24bit {
623 if let Some(mut buf) = self.lastframe.get16() {
624 let stride = buf.get_stride(0);
625 {
626 let data = buf.get_data_mut().unwrap();
627 if !is_sprite {
628 self.decode_16bit(data.as_mut_slice(), stride, out_width, height, &mut mask, &mut index)?;
629 } else {
630 validate!(spr_xoff + spr_width <= out_width);
631 validate!(spr_yoff + spr_height <= height);
632 for el in data.iter_mut() { *el = 0; }
633 let dst = &mut data[spr_xoff + spr_yoff * stride..];
634 self.decode_sprite(dst, stride, spr_width, spr_height, &mut mask, &mut index)?;
635 }
636 }
637 bufinfo = NABufferType::Video16(buf);
638 } else {
639 return Err(DecoderError::MissingReference);
640 }
641 } else if let Some(mut buf) = self.lastframe.get24() {
642 let stride = buf.get_stride(0);
643 {
644 let data = buf.get_data_mut().unwrap();
645 self.decode_24bit(data.as_mut_slice(), stride, out_width, height, &mut mask, &mut index)?;
646 }
647 bufinfo = NABufferType::VideoPacked(buf);
648 } else {
649 return Err(DecoderError::MissingReference);
650 }
651
652 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
653 frm.set_keyframe(is_intra || is_sprite);
654 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
655 Ok(frm.into_ref())
656 }
657 fn flush(&mut self) {
658 self.lastframe.reset();
659 }
660 }
661
662 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
663 Box::new(TM1Decoder::new())
664 }
665
666 #[cfg(test)]
667 mod test {
668 use nihav_core::codecs::RegisteredDecoders;
669 use nihav_core::demuxers::RegisteredDemuxers;
670 use nihav_core::test::dec_video::*;
671 use crate::codecs::duck_register_all_codecs;
672 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
673 #[test]
674 fn test_tm1() {
675 let mut dmx_reg = RegisteredDemuxers::new();
676 generic_register_all_demuxers(&mut dmx_reg);
677 let mut dec_reg = RegisteredDecoders::new();
678 duck_register_all_codecs(&mut dec_reg);
679
680 test_decoding("avi", "truemotion1", "assets/Duck/phant2-940.duk", Some(12), &dmx_reg, &dec_reg,
681 ExpectedTestResult::MD5Frames(vec![
682 [0x989e62b8, 0x5d85c23c, 0x1cffba6d, 0xe599f1c4],
683 [0xc4231321, 0x25561487, 0x9db11f57, 0x4faeb9a5],
684 [0x36e3a831, 0xdbd21f89, 0x0a446071, 0xf6d31ee7],
685 [0x0af640af, 0x64bc2bac, 0x0e95dd72, 0x9e55360b],
686 [0xbc9c5f8b, 0x6c06f2bc, 0x216f4129, 0x3a421337],
687 [0xd8ea7297, 0xce5f79fc, 0x46071f4c, 0xaed7fb7a],
688 [0x87617060, 0x72ce8df8, 0xde42eaa6, 0x804a6f45],
689 [0xfd8c45b3, 0xf424b683, 0xb4d6a9bd, 0xc622d0b9],
690 [0x6c233746, 0xba8ed68e, 0xc0ed0e85, 0xc99e1dc0],
691 [0x5842aac0, 0xd3d78242, 0x5da21218, 0xea1ed0ad],
692 [0xdea0db20, 0xe2ce3586, 0xf7386649, 0xecc374f9],
693 [0xb80ae9cb, 0x04eb938e, 0xd8a337ee, 0x0054b5ed],
694 [0xf8b80e1d, 0xd8eb3d6c, 0xa99b23ff, 0x562851a1]]));
695 test_decoding("avi", "truemotion1", "assets/Duck/SPRITES.AVI", Some(2), &dmx_reg, &dec_reg,
696 ExpectedTestResult::MD5([0xb89a4275, 0xf9797f5f, 0xe53c1ccd, 0xfa163e02]));
697 //let file = "assets/Duck/AVI-DUCK-dk3.duk";
698 //let file = "assets/Duck/phant2-940.duk";
699 //let file = "assets/Duck/bugsampler-m01-16bit.avi";
700 //let file = "assets/Duck/sonic3dblast_intro.avi";
701 //let file = "assets/Duck/BUTTONS.AVI";
702 //let file = "assets/Duck/SPRITES.AVI";
703 //let file = "assets/Duck/TRICORD.AVI";
704 //test_file_decoding("avi", file, Some(42), true, false, None/*Some("tm1-")*/, &dmx_reg, &dec_reg);
705 }
706 }
707
708 #[derive(Clone,Copy)]
709 struct TM1ComprInfo {
710 is_24bit: bool,
711 block_w: usize,
712 block_h: usize,
713 }
714
715 const TM1_COMPR_TYPES: [Option<TM1ComprInfo>; 17] = [
716 None,
717 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 4 }),
718 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 4 }),
719 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 2 }),
720 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 2 }),
721 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 4 }),
722 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 4 }),
723 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 2 }),
724 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 2 }),
725 None,
726 Some(TM1ComprInfo { is_24bit: true, block_w: 4, block_h: 4 }),
727 None,
728 Some(TM1ComprInfo { is_24bit: true, block_w: 4, block_h: 2 }),
729 None,
730 Some(TM1ComprInfo { is_24bit: true, block_w: 2, block_h: 4 }),
731 None,
732 Some(TM1ComprInfo { is_24bit: true, block_w: 2, block_h: 2 }),
733 ];
734
735 const DUCK_Y_DELTAS: [[i32; 8]; 4] = [
736 [ 0, -1, 1, -3, 3, -6, 6, -6 ],
737 [ 0, -1, 2, -3, 4, -6, 6, -6 ],
738 [ 2, -3, 10, -10, 23, -23, 47, -47 ],
739 [ 0, -2, 2, -8, 8, -18, 18, -40 ]
740 ];
741 const DUCK_Y_FAT_DELTA3: [i32; 8] = [ 0, -15, 50, -50, 115, -115, 235, -235 ];
742 const DUCK_Y_FAT_DELTA4: [i32; 8] = [ 0, 40, 80, -76, 160, -154, 236, -236 ];
743 const DUCK_Y_FAT_DELTAS: [&[i32]; 4] = [
744 &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA4
745 ];
746
747 const DUCK_C_DELTAS: [[i32; 8]; 4] = [
748 [ 0, -1, 1, -2, 3, -4, 5, -4 ],
749 [ 0, -1, 1, -2, 3, -4, 5, -4 ],
750 [ 0, -4, 3, -16, 20, -32, 36, -32 ],
751 [ 0, -2, 2, -8, 8, -18, 18, -40 ]
752 ];
753 const DUCK_C_FAT_DELTA3: [i32; 8] = [ 0, -20, 15, -80, 100, -160, 180, -160 ];
754 const DUCK_C_FAT_DELTAS: [&[i32]; 4] = [
755 &DUCK_C_FAT_DELTA3, &DUCK_C_FAT_DELTA3, &DUCK_C_FAT_DELTA3, &DUCK_Y_FAT_DELTA4
756 ];
757
758 const DUCK_VECTBL2: &[u8] = &[
759 0x8,0x00,0x00,0x00,0x00,
760 0x8,0x00,0x00,0x00,0x00,
761 0x8,0x10,0x00,0x00,0x00,
762 0x8,0x01,0x00,0x00,0x00,
763 0x8,0x00,0x10,0x00,0x00,
764 0x8,0x00,0x01,0x00,0x00,
765 0x8,0x00,0x00,0x10,0x00,
766 0x8,0x00,0x00,0x01,0x00,
767 0x8,0x00,0x00,0x00,0x10,
768 0x8,0x00,0x00,0x00,0x01,
769 0x6,0x00,0x00,0x00,
770 0x6,0x10,0x00,0x00,
771 0x6,0x01,0x00,0x00,
772 0x6,0x00,0x10,0x00,
773 0x6,0x00,0x01,0x00,
774 0x6,0x00,0x00,0x01,
775 0x6,0x00,0x00,0x10,
776 0x6,0x00,0x00,0x02,
777 0x6,0x00,0x00,0x20,
778 0x6,0x20,0x10,0x00,
779 0x6,0x00,0x02,0x01,
780 0x6,0x00,0x20,0x10,
781 0x6,0x02,0x01,0x00,
782 0x6,0x11,0x00,0x00,
783 0x6,0x00,0x20,0x00,
784 0x6,0x00,0x02,0x00,
785 0x6,0x20,0x00,0x00,
786 0x6,0x01,0x10,0x00,
787 0x6,0x02,0x00,0x00,
788 0x6,0x01,0x00,0x02,
789 0x6,0x10,0x00,0x20,
790 0x6,0x00,0x01,0x02,
791 0x6,0x10,0x01,0x00,
792 0x6,0x00,0x10,0x20,
793 0x6,0x10,0x10,0x00,
794 0x6,0x10,0x00,0x01,
795 0x6,0x20,0x00,0x10,
796 0x6,0x02,0x00,0x01,
797 0x6,0x01,0x01,0x00,
798 0x6,0x01,0x00,0x10,
799 0x6,0x00,0x11,0x00,
800 0x6,0x10,0x00,0x02,
801 0x6,0x00,0x01,0x10,
802 0x6,0x00,0x00,0x11,
803 0x6,0x10,0x00,0x10,
804 0x6,0x01,0x00,0x01,
805 0x6,0x00,0x00,0x22,
806 0x6,0x02,0x01,0x01,
807 0x6,0x10,0x20,0x10,
808 0x6,0x01,0x02,0x01,
809 0x6,0x20,0x10,0x10,
810 0x6,0x01,0x00,0x20,
811 0x6,0x00,0x10,0x01,
812 0x6,0x21,0x10,0x00,
813 0x6,0x10,0x02,0x01,
814 0x6,0x12,0x01,0x00,
815 0x6,0x01,0x20,0x10,
816 0x6,0x01,0x02,0x00,
817 0x6,0x10,0x20,0x00,
818 0x6,0x00,0x10,0x02,
819 0x6,0x00,0x01,0x20,
820 0x6,0x00,0x02,0x21,
821 0x6,0x00,0x02,0x20,
822 0x6,0x00,0x00,0x12,
823 0x6,0x00,0x00,0x21,
824 0x6,0x20,0x11,0x00,
825 0x6,0x00,0x01,0x01,
826 0x6,0x11,0x10,0x00,
827 0x6,0x00,0x20,0x12,
828 0x6,0x00,0x20,0x11,
829 0x6,0x20,0x10,0x02,
830 0x6,0x02,0x01,0x20,
831 0x6,0x00,0x22,0x11,
832 0x6,0x00,0x10,0x10,
833 0x6,0x02,0x11,0x00,
834 0x6,0x00,0x21,0x10,
835 0x6,0x00,0x02,0x03,
836 0x6,0x20,0x10,0x01,
837 0x6,0x00,0x12,0x01,
838 0x4,0x11,0x00,
839 0x4,0x00,0x22,
840 0x4,0x20,0x00,
841 0x4,0x01,0x10,
842 0x4,0x02,0x20,
843 0x4,0x00,0x20,
844 0x4,0x02,0x00,
845 0x4,0x10,0x01,
846 0x4,0x00,0x11,
847 0x4,0x02,0x01,
848 0x4,0x02,0x21,
849 0x4,0x00,0x02,
850 0x4,0x20,0x02,
851 0x4,0x01,0x01,
852 0x4,0x10,0x10,
853 0x4,0x10,0x02,
854 0x4,0x22,0x00,
855 0x4,0x10,0x00,
856 0x4,0x01,0x00,
857 0x4,0x21,0x00,
858 0x4,0x12,0x00,
859 0x4,0x00,0x10,
860 0x4,0x20,0x12,
861 0x4,0x01,0x11,
862 0x4,0x00,0x01,
863 0x4,0x01,0x02,
864 0x4,0x11,0x02,
865 0x4,0x11,0x01,
866 0x4,0x10,0x20,
867 0x4,0x20,0x01,
868 0x4,0x22,0x11,
869 0x4,0x00,0x12,
870 0x4,0x20,0x10,
871 0x4,0x22,0x01,
872 0x4,0x01,0x20,
873 0x4,0x00,0x21,
874 0x4,0x10,0x11,
875 0x4,0x21,0x10,
876 0x4,0x10,0x22,
877 0x4,0x02,0x03,
878 0x4,0x12,0x01,
879 0x4,0x20,0x11,
880 0x4,0x11,0x10,
881 0x4,0x20,0x30,
882 0x4,0x11,0x20,
883 0x4,0x02,0x10,
884 0x4,0x22,0x10,
885 0x4,0x11,0x11,
886 0x4,0x30,0x20,
887 0x4,0x30,0x00,
888 0x4,0x01,0x22,
889 0x4,0x01,0x12,
890 0x4,0x02,0x11,
891 0x4,0x03,0x02,
892 0x4,0x03,0x00,
893 0x4,0x10,0x21,
894 0x4,0x12,0x20,
895 0x4,0x00,0x00,
896 0x4,0x12,0x21,
897 0x4,0x21,0x11,
898 0x4,0x02,0x22,
899 0x4,0x10,0x12,
900 0x4,0x31,0x00,
901 0x4,0x20,0x20,
902 0x4,0x00,0x03,
903 0x4,0x02,0x02,
904 0x4,0x22,0x20,
905 0x4,0x01,0x21,
906 0x4,0x21,0x02,
907 0x4,0x21,0x12,
908 0x4,0x11,0x22,
909 0x4,0x00,0x30,
910 0x4,0x12,0x11,
911 0x4,0x20,0x22,
912 0x4,0x31,0x20,
913 0x4,0x21,0x30,
914 0x4,0x22,0x02,
915 0x4,0x22,0x22,
916 0x4,0x20,0x31,
917 0x4,0x13,0x02,
918 0x4,0x03,0x10,
919 0x4,0x11,0x12,
920 0x4,0x00,0x13,
921 0x4,0x21,0x01,
922 0x4,0x12,0x03,
923 0x4,0x13,0x00,
924 0x4,0x13,0x10,
925 0x4,0x02,0x13,
926 0x4,0x30,0x01,
927 0x4,0x12,0x10,
928 0x4,0x22,0x13,
929 0x4,0x03,0x12,
930 0x4,0x31,0x01,
931 0x4,0x30,0x22,
932 0x4,0x00,0x31,
933 0x4,0x01,0x31,
934 0x4,0x02,0x23,
935 0x4,0x01,0x30,
936 0x4,0x11,0x21,
937 0x4,0x22,0x21,
938 0x4,0x01,0x13,
939 0x4,0x10,0x03,
940 0x4,0x22,0x03,
941 0x4,0x30,0x21,
942 0x4,0x21,0x31,
943 0x4,0x33,0x00,
944 0x4,0x13,0x12,
945 0x4,0x11,0x31,
946 0x4,0x30,0x02,
947 0x4,0x12,0x02,
948 0x4,0x11,0x13,
949 0x4,0x12,0x22,
950 0x4,0x20,0x32,
951 0x4,0x10,0x13,
952 0x4,0x22,0x31,
953 0x4,0x21,0x20,
954 0x4,0x01,0x33,
955 0x4,0x33,0x10,
956 0x4,0x20,0x13,
957 0x4,0x31,0x22,
958 0x4,0x13,0x30,
959 0x4,0x01,0x03,
960 0x4,0x11,0x33,
961 0x4,0x20,0x21,
962 0x4,0x13,0x31,
963 0x4,0x03,0x22,
964 0x4,0x31,0x02,
965 0x4,0x00,0x24,
966 0x2,0x00,
967 0x2,0x10,
968 0x2,0x20,
969 0x2,0x30,
970 0x2,0x40,
971 0x2,0x50,
972 0x2,0x60,
973 0x2,0x01,
974 0x2,0x11,
975 0x2,0x21,
976 0x2,0x31,
977 0x2,0x41,
978 0x2,0x51,
979 0x2,0x61,
980 0x2,0x02,
981 0x2,0x12,
982 0x2,0x22,
983 0x2,0x32,
984 0x2,0x42,
985 0x2,0x52,
986 0x2,0x62,
987 0x2,0x03,
988 0x2,0x13,
989 0x2,0x23,
990 0x2,0x33,
991 0x2,0x43,
992 0x2,0x53,
993 0x2,0x63,
994 0x2,0x04,
995 0x2,0x14,
996 0x2,0x24,
997 0x2,0x34,
998 0x2,0x44,
999 0x2,0x54,
1000 0x2,0x64,
1001 0x2,0x05,
1002 0x2,0x15,
1003 0x2,0x25,
1004 0x2,0x35,
1005 0x2,0x45,
1006 0x2,0x55,
1007 0x2,0x65,
1008 0x2,0x06,
1009 0x2,0x16,
1010 0x2,0x26,
1011 0x2,0x36,
1012 0x2,0x46,
1013 0x2,0x56,
1014 0x2,0x66
1015 ];
1016
1017 const DUCK_VECTBL3: &[u8] = &[
1018 0x6,0x00,0x00,0x00,
1019 0x6,0x00,0x00,0x00,
1020 0x6,0x00,0x00,0x01,
1021 0x6,0x00,0x00,0x10,
1022 0x6,0x00,0x00,0x11,
1023 0x6,0x00,0x01,0x00,
1024 0x6,0x00,0x01,0x01,
1025 0x6,0x00,0x01,0x10,
1026 0x6,0x00,0x01,0x11,
1027 0x6,0x00,0x10,0x00,
1028 0x6,0x00,0x10,0x01,
1029 0x6,0x00,0x10,0x10,
1030 0x6,0x00,0x10,0x11,
1031 0x6,0x00,0x11,0x00,
1032 0x6,0x00,0x11,0x01,
1033 0x6,0x00,0x11,0x10,
1034 0x6,0x00,0x11,0x11,
1035 0x6,0x01,0x00,0x00,
1036 0x6,0x01,0x00,0x01,
1037 0x6,0x01,0x00,0x10,
1038 0x6,0x01,0x00,0x11,
1039 0x6,0x01,0x01,0x00,
1040 0x6,0x01,0x01,0x01,
1041 0x6,0x01,0x01,0x10,
1042 0x6,0x01,0x01,0x11,
1043 0x6,0x01,0x10,0x00,
1044 0x6,0x01,0x10,0x01,
1045 0x6,0x01,0x10,0x10,
1046 0x6,0x01,0x10,0x11,
1047 0x6,0x01,0x11,0x00,
1048 0x6,0x01,0x11,0x01,
1049 0x6,0x01,0x11,0x10,
1050 0x6,0x01,0x11,0x11,
1051 0x6,0x10,0x00,0x00,
1052 0x6,0x10,0x00,0x01,
1053 0x6,0x10,0x00,0x10,
1054 0x6,0x10,0x00,0x11,
1055 0x6,0x10,0x01,0x00,
1056 0x6,0x10,0x01,0x01,
1057 0x6,0x10,0x01,0x10,
1058 0x6,0x10,0x01,0x11,
1059 0x6,0x10,0x10,0x00,
1060 0x6,0x10,0x10,0x01,
1061 0x6,0x10,0x10,0x10,
1062 0x6,0x10,0x10,0x11,
1063 0x6,0x10,0x11,0x00,
1064 0x6,0x10,0x11,0x01,
1065 0x6,0x10,0x11,0x10,
1066 0x6,0x10,0x11,0x11,
1067 0x6,0x11,0x00,0x00,
1068 0x6,0x11,0x00,0x01,
1069 0x6,0x11,0x00,0x10,
1070 0x6,0x11,0x00,0x11,
1071 0x6,0x11,0x01,0x00,
1072 0x6,0x11,0x01,0x01,
1073 0x6,0x11,0x01,0x10,
1074 0x6,0x11,0x01,0x11,
1075 0x6,0x11,0x10,0x00,
1076 0x6,0x11,0x10,0x01,
1077 0x6,0x11,0x10,0x10,
1078 0x6,0x11,0x10,0x11,
1079 0x6,0x11,0x11,0x00,
1080 0x6,0x11,0x11,0x01,
1081 0x6,0x11,0x11,0x10,
1082 0x4,0x00,0x00,
1083 0x4,0x00,0x01,
1084 0x4,0x00,0x02,
1085 0x4,0x00,0x03,
1086 0x4,0x00,0x10,
1087 0x4,0x00,0x11,
1088 0x4,0x00,0x12,
1089 0x4,0x00,0x13,
1090 0x4,0x00,0x20,
1091 0x4,0x00,0x21,
1092 0x4,0x00,0x22,
1093 0x4,0x00,0x23,
1094 0x4,0x00,0x30,
1095 0x4,0x00,0x31,
1096 0x4,0x00,0x32,
1097 0x4,0x00,0x33,
1098 0x4,0x01,0x00,
1099 0x4,0x01,0x01,
1100 0x4,0x01,0x02,
1101 0x4,0x01,0x03,
1102 0x4,0x01,0x10,
1103 0x4,0x01,0x11,
1104 0x4,0x01,0x12,
1105 0x4,0x01,0x13,
1106 0x4,0x01,0x20,
1107 0x4,0x01,0x21,
1108 0x4,0x01,0x22,
1109 0x4,0x01,0x23,
1110 0x4,0x01,0x30,
1111 0x4,0x01,0x31,
1112 0x4,0x01,0x32,
1113 0x4,0x01,0x33,
1114 0x4,0x02,0x00,
1115 0x4,0x02,0x01,
1116 0x4,0x02,0x02,
1117 0x4,0x02,0x03,
1118 0x4,0x02,0x10,
1119 0x4,0x02,0x11,
1120 0x4,0x02,0x12,
1121 0x4,0x02,0x13,
1122 0x4,0x02,0x20,
1123 0x4,0x02,0x21,
1124 0x4,0x02,0x22,
1125 0x4,0x02,0x23,
1126 0x4,0x02,0x30,
1127 0x4,0x02,0x31,
1128 0x4,0x02,0x32,
1129 0x4,0x02,0x33,
1130 0x4,0x03,0x00,
1131 0x4,0x03,0x01,
1132 0x4,0x03,0x02,
1133 0x4,0x03,0x03,
1134 0x4,0x03,0x10,
1135 0x4,0x03,0x11,
1136 0x4,0x03,0x12,
1137 0x4,0x03,0x13,
1138 0x4,0x03,0x20,
1139 0x4,0x03,0x21,
1140 0x4,0x03,0x22,
1141 0x4,0x03,0x23,
1142 0x4,0x03,0x30,
1143 0x4,0x03,0x31,
1144 0x4,0x03,0x32,
1145 0x4,0x03,0x33,
1146 0x4,0x10,0x00,
1147 0x4,0x10,0x01,
1148 0x4,0x10,0x02,
1149 0x4,0x10,0x03,
1150 0x4,0x10,0x10,
1151 0x4,0x10,0x11,
1152 0x4,0x10,0x12,
1153 0x4,0x10,0x13,
1154 0x4,0x10,0x20,
1155 0x4,0x10,0x21,
1156 0x4,0x10,0x22,
1157 0x4,0x10,0x23,
1158 0x4,0x10,0x30,
1159 0x4,0x10,0x31,
1160 0x4,0x10,0x32,
1161 0x4,0x10,0x33,
1162 0x4,0x11,0x00,
1163 0x4,0x11,0x01,
1164 0x4,0x11,0x02,
1165 0x4,0x11,0x03,
1166 0x4,0x11,0x10,
1167 0x4,0x11,0x11,
1168 0x4,0x11,0x12,
1169 0x4,0x11,0x13,
1170 0x4,0x11,0x20,
1171 0x4,0x11,0x21,
1172 0x4,0x11,0x22,
1173 0x4,0x11,0x23,
1174 0x4,0x11,0x30,
1175 0x4,0x11,0x31,
1176 0x4,0x11,0x32,
1177 0x4,0x11,0x33,
1178 0x4,0x12,0x00,
1179 0x4,0x12,0x01,
1180 0x4,0x12,0x02,
1181 0x4,0x12,0x03,
1182 0x4,0x12,0x10,
1183 0x4,0x12,0x11,
1184 0x4,0x12,0x12,
1185 0x4,0x12,0x13,
1186 0x4,0x12,0x20,
1187 0x4,0x12,0x21,
1188 0x4,0x12,0x22,
1189 0x4,0x12,0x23,
1190 0x4,0x12,0x30,
1191 0x4,0x12,0x31,
1192 0x4,0x12,0x32,
1193 0x4,0x12,0x33,
1194 0x4,0x13,0x00,
1195 0x4,0x13,0x01,
1196 0x4,0x13,0x02,
1197 0x4,0x13,0x03,
1198 0x4,0x13,0x10,
1199 0x4,0x13,0x11,
1200 0x4,0x13,0x12,
1201 0x4,0x13,0x13,
1202 0x4,0x13,0x20,
1203 0x4,0x13,0x21,
1204 0x4,0x13,0x22,
1205 0x4,0x13,0x23,
1206 0x4,0x13,0x30,
1207 0x4,0x13,0x31,
1208 0x4,0x13,0x32,
1209 0x4,0x13,0x33,
1210 0x2,0x00,
1211 0x2,0x10,
1212 0x2,0x20,
1213 0x2,0x30,
1214 0x2,0x40,
1215 0x2,0x50,
1216 0x2,0x60,
1217 0x2,0x70,
1218 0x2,0x01,
1219 0x2,0x11,
1220 0x2,0x21,
1221 0x2,0x31,
1222 0x2,0x41,
1223 0x2,0x51,
1224 0x2,0x61,
1225 0x2,0x71,
1226 0x2,0x02,
1227 0x2,0x12,
1228 0x2,0x22,
1229 0x2,0x32,
1230 0x2,0x42,
1231 0x2,0x52,
1232 0x2,0x62,
1233 0x2,0x72,
1234 0x2,0x03,
1235 0x2,0x13,
1236 0x2,0x23,
1237 0x2,0x33,
1238 0x2,0x43,
1239 0x2,0x53,
1240 0x2,0x63,
1241 0x2,0x73,
1242 0x2,0x04,
1243 0x2,0x14,
1244 0x2,0x24,
1245 0x2,0x34,
1246 0x2,0x44,
1247 0x2,0x54,
1248 0x2,0x64,
1249 0x2,0x74,
1250 0x2,0x05,
1251 0x2,0x15,
1252 0x2,0x25,
1253 0x2,0x35,
1254 0x2,0x45,
1255 0x2,0x55,
1256 0x2,0x65,
1257 0x2,0x75,
1258 0x2,0x06,
1259 0x2,0x16,
1260 0x2,0x26,
1261 0x2,0x36,
1262 0x2,0x46,
1263 0x2,0x56,
1264 0x2,0x66,
1265 0x2,0x76,
1266 0x2,0x07,
1267 0x2,0x17,
1268 0x2,0x27,
1269 0x2,0x37,
1270 0x2,0x47,
1271 0x2,0x57,
1272 0x2,0x67,
1273 0x2,0x77
1274 ];
1275
1276 const DUCK_VECTBL4: &[u8] = &[
1277 0x8,0x00,0x00,0x00,0x00,
1278 0x8,0x00,0x00,0x00,0x00,
1279 0x8,0x20,0x00,0x00,0x00,
1280 0x8,0x00,0x00,0x00,0x01,
1281 0x8,0x10,0x00,0x00,0x00,
1282 0x8,0x00,0x00,0x00,0x02,
1283 0x8,0x01,0x00,0x00,0x00,
1284 0x8,0x00,0x00,0x00,0x10,
1285 0x8,0x02,0x00,0x00,0x00,
1286 0x6,0x00,0x00,0x00,
1287 0x6,0x20,0x00,0x00,
1288 0x6,0x00,0x00,0x01,
1289 0x6,0x10,0x00,0x00,
1290 0x6,0x00,0x00,0x02,
1291 0x6,0x00,0x10,0x00,
1292 0x6,0x00,0x20,0x00,
1293 0x6,0x00,0x02,0x00,
1294 0x6,0x00,0x01,0x00,
1295 0x6,0x01,0x00,0x00,
1296 0x6,0x00,0x00,0x20,
1297 0x6,0x02,0x00,0x00,
1298 0x6,0x00,0x00,0x10,
1299 0x6,0x10,0x00,0x20,
1300 0x6,0x01,0x00,0x02,
1301 0x6,0x20,0x00,0x10,
1302 0x6,0x02,0x00,0x01,
1303 0x6,0x20,0x10,0x00,
1304 0x6,0x00,0x12,0x00,
1305 0x6,0x00,0x02,0x01,
1306 0x6,0x02,0x01,0x00,
1307 0x6,0x00,0x21,0x00,
1308 0x6,0x00,0x01,0x02,
1309 0x6,0x00,0x20,0x10,
1310 0x6,0x00,0x00,0x21,
1311 0x6,0x00,0x00,0x12,
1312 0x6,0x00,0x01,0x20,
1313 0x6,0x12,0x00,0x00,
1314 0x6,0x00,0x10,0x20,
1315 0x6,0x01,0x20,0x00,
1316 0x6,0x02,0x10,0x00,
1317 0x6,0x10,0x20,0x00,
1318 0x6,0x01,0x02,0x00,
1319 0x6,0x21,0x00,0x00,
1320 0x6,0x00,0x02,0x10,
1321 0x6,0x20,0x01,0x00,
1322 0x6,0x00,0x22,0x00,
1323 0x6,0x10,0x02,0x00,
1324 0x6,0x00,0x10,0x02,
1325 0x6,0x11,0x00,0x00,
1326 0x6,0x00,0x11,0x00,
1327 0x6,0x22,0x00,0x00,
1328 0x6,0x20,0x00,0x02,
1329 0x6,0x10,0x00,0x01,
1330 0x6,0x00,0x20,0x01,
1331 0x6,0x02,0x20,0x00,
1332 0x6,0x01,0x10,0x00,
1333 0x6,0x01,0x00,0x20,
1334 0x6,0x00,0x20,0x02,
1335 0x6,0x01,0x20,0x02,
1336 0x6,0x10,0x01,0x00,
1337 0x6,0x02,0x00,0x10,
1338 0x6,0x00,0x10,0x01,
1339 0x6,0x10,0x01,0x20,
1340 0x6,0x20,0x02,0x10,
1341 0x6,0x00,0x00,0x22,
1342 0x6,0x10,0x00,0x02,
1343 0x6,0x00,0x02,0x20,
1344 0x6,0x20,0x02,0x00,
1345 0x6,0x00,0x00,0x11,
1346 0x6,0x02,0x10,0x01,
1347 0x6,0x00,0x01,0x10,
1348 0x6,0x00,0x02,0x11,
1349 0x4,0x01,0x02,
1350 0x4,0x02,0x01,
1351 0x4,0x01,0x00,
1352 0x4,0x10,0x20,
1353 0x4,0x20,0x10,
1354 0x4,0x20,0x00,
1355 0x4,0x11,0x00,
1356 0x4,0x02,0x00,
1357 0x4,0x12,0x00,
1358 0x4,0x00,0x21,
1359 0x4,0x22,0x00,
1360 0x4,0x00,0x12,
1361 0x4,0x21,0x00,
1362 0x4,0x02,0x11,
1363 0x4,0x00,0x01,
1364 0x4,0x10,0x02,
1365 0x4,0x02,0x20,
1366 0x4,0x20,0x11,
1367 0x4,0x01,0x10,
1368 0x4,0x21,0x10,
1369 0x4,0x10,0x00,
1370 0x4,0x10,0x22,
1371 0x4,0x20,0x20,
1372 0x4,0x00,0x22,
1373 0x4,0x01,0x22,
1374 0x4,0x20,0x01,
1375 0x4,0x02,0x02,
1376 0x4,0x00,0x20,
1377 0x4,0x00,0x10,
1378 0x4,0x00,0x11,
1379 0x4,0x22,0x01,
1380 0x4,0x11,0x20,
1381 0x4,0x12,0x01,
1382 0x4,0x12,0x20,
1383 0x4,0x11,0x02,
1384 0x4,0x10,0x10,
1385 0x4,0x01,0x01,
1386 0x4,0x02,0x21,
1387 0x4,0x20,0x12,
1388 0x4,0x01,0x12,
1389 0x4,0x22,0x11,
1390 0x4,0x21,0x12,
1391 0x4,0x22,0x10,
1392 0x4,0x21,0x02,
1393 0x4,0x20,0x02,
1394 0x4,0x10,0x01,
1395 0x4,0x00,0x02,
1396 0x4,0x10,0x21,
1397 0x4,0x01,0x20,
1398 0x4,0x11,0x22,
1399 0x4,0x12,0x21,
1400 0x4,0x22,0x20,
1401 0x4,0x02,0x10,
1402 0x4,0x02,0x22,
1403 0x4,0x11,0x10,
1404 0x4,0x22,0x02,
1405 0x4,0x20,0x21,
1406 0x4,0x01,0x11,
1407 0x4,0x11,0x01,
1408 0x4,0x10,0x12,
1409 0x4,0x02,0x12,
1410 0x4,0x20,0x22,
1411 0x4,0x21,0x20,
1412 0x4,0x01,0x21,
1413 0x4,0x12,0x02,
1414 0x4,0x21,0x11,
1415 0x4,0x12,0x22,
1416 0x4,0x12,0x10,
1417 0x4,0x22,0x21,
1418 0x4,0x10,0x11,
1419 0x4,0x21,0x01,
1420 0x4,0x11,0x12,
1421 0x4,0x12,0x11,
1422 0x4,0x66,0x66,
1423 0x4,0x22,0x22,
1424 0x4,0x11,0x21,
1425 0x4,0x11,0x11,
1426 0x4,0x21,0x22,
1427 0x4,0x00,0x00,
1428 0x4,0x22,0x12,
1429 0x4,0x12,0x12,
1430 0x4,0x21,0x21,
1431 0x4,0x42,0x00,
1432 0x4,0x00,0x04,
1433 0x4,0x40,0x00,
1434 0x4,0x30,0x00,
1435 0x4,0x31,0x00,
1436 0x4,0x00,0x03,
1437 0x4,0x00,0x14,
1438 0x4,0x00,0x13,
1439 0x4,0x01,0x24,
1440 0x4,0x20,0x13,
1441 0x4,0x01,0x42,
1442 0x4,0x14,0x20,
1443 0x4,0x42,0x02,
1444 0x4,0x13,0x00,
1445 0x4,0x00,0x24,
1446 0x4,0x31,0x20,
1447 0x4,0x22,0x13,
1448 0x4,0x11,0x24,
1449 0x4,0x12,0x66,
1450 0x4,0x30,0x01,
1451 0x4,0x02,0x13,
1452 0x4,0x12,0x42,
1453 0x4,0x40,0x10,
1454 0x4,0x40,0x02,
1455 0x4,0x01,0x04,
1456 0x4,0x24,0x00,
1457 0x4,0x42,0x10,
1458 0x4,0x21,0x13,
1459 0x4,0x13,0x12,
1460 0x4,0x31,0x21,
1461 0x4,0x21,0x24,
1462 0x4,0x00,0x40,
1463 0x4,0x10,0x24,
1464 0x4,0x10,0x42,
1465 0x4,0x32,0x01,
1466 0x4,0x11,0x42,
1467 0x4,0x20,0x31,
1468 0x4,0x12,0x40,
1469 0x2,0x00,
1470 0x2,0x10,
1471 0x2,0x20,
1472 0x2,0x30,
1473 0x2,0x40,
1474 0x2,0x50,
1475 0x2,0x60,
1476 0x2,0x70,
1477 0x2,0x01,
1478 0x2,0x11,
1479 0x2,0x21,
1480 0x2,0x31,
1481 0x2,0x41,
1482 0x2,0x51,
1483 0x2,0x61,
1484 0x2,0x71,
1485 0x2,0x02,
1486 0x2,0x12,
1487 0x2,0x22,
1488 0x2,0x32,
1489 0x2,0x42,
1490 0x2,0x52,
1491 0x2,0x62,
1492 0x2,0x72,
1493 0x2,0x03,
1494 0x2,0x13,
1495 0x2,0x23,
1496 0x2,0x33,
1497 0x2,0x43,
1498 0x2,0x53,
1499 0x2,0x63,
1500 0x2,0x73,
1501 0x2,0x04,
1502 0x2,0x14,
1503 0x2,0x24,
1504 0x2,0x34,
1505 0x2,0x44,
1506 0x2,0x54,
1507 0x2,0x64,
1508 0x2,0x74,
1509 0x2,0x05,
1510 0x2,0x15,
1511 0x2,0x25,
1512 0x2,0x35,
1513 0x2,0x45,
1514 0x2,0x55,
1515 0x2,0x65,
1516 0x2,0x75,
1517 0x2,0x06,
1518 0x2,0x16,
1519 0x2,0x26,
1520 0x2,0x36,
1521 0x2,0x46,
1522 0x2,0x56,
1523 0x2,0x66,
1524 0x2,0x76,
1525 0x2,0x07,
1526 0x2,0x17,
1527 0x2,0x27,
1528 0x2,0x37,
1529 0x2,0x47,
1530 0x2,0x57,
1531 0x2,0x67,
1532 0x2,0x77
1533 ];
1534
1535 const DUCK_VECTABLES: [&[u8]; 3] = [ DUCK_VECTBL2, DUCK_VECTBL3, DUCK_VECTBL4 ];