]> git.nihav.org Git - nihav.git/blame_incremental - nihav-duck/src/codecs/truemotion1.rs
core: add UintCodeType::Limites{Zeroes,Ones} for clarity
[nihav.git] / nihav-duck / src / codecs / truemotion1.rs
... / ...
CommitLineData
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3
4struct 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
13impl<'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
40struct IndexState<'a> {
41 src: &'a [u8],
42 pos: usize,
43 vec_idx: usize,
44 vec_subidx: usize,
45}
46
47impl<'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
111struct 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
119impl 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
131struct FrameBuf {
132 last16: Option<NAVideoBufferRef<u16>>,
133 last24: Option<NAVideoBufferRef<u8>>,
134}
135
136impl 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
163impl Default for FrameBuf {
164 fn default() -> Self {
165 Self { last16: None, last24: None }
166 }
167}
168
169#[derive(Default)]
170struct 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
181const 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 };
188const 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
196impl 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
517impl 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}
658
659pub fn get_decoder() -> Box<dyn NADecoder> {
660 Box::new(TM1Decoder::new())
661}
662
663#[cfg(test)]
664mod test {
665 use nihav_core::codecs::RegisteredDecoders;
666 use nihav_core::demuxers::RegisteredDemuxers;
667 use nihav_core::test::dec_video::*;
668 use crate::codecs::duck_register_all_codecs;
669 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
670 #[test]
671 fn test_tm1() {
672 let mut dmx_reg = RegisteredDemuxers::new();
673 generic_register_all_demuxers(&mut dmx_reg);
674 let mut dec_reg = RegisteredDecoders::new();
675 duck_register_all_codecs(&mut dec_reg);
676
677 //let file = "assets/Duck/AVI-DUCK-dk3.duk";
678 let file = "assets/Duck/phant2-940.duk";
679 //let file = "assets/Duck/bugsampler-m01-16bit.avi";
680 //let file = "assets/Duck/sonic3dblast_intro.avi";
681 //let file = "assets/Duck/BUTTONS.AVI";
682 //let file = "assets/Duck/SPRITES.AVI";
683 //let file = "assets/Duck/TRICORD.AVI";
684 test_file_decoding("avi", file, Some(42), true, false, None/*Some("tm1-")*/, &dmx_reg, &dec_reg);
685 }
686}
687
688#[derive(Clone,Copy)]
689struct TM1ComprInfo {
690 is_24bit: bool,
691 block_w: usize,
692 block_h: usize,
693}
694
695const TM1_COMPR_TYPES: [Option<TM1ComprInfo>; 17] = [
696 None,
697 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 4 }),
698 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 4 }),
699 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 2 }),
700 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 2 }),
701 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 4 }),
702 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 4 }),
703 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 2 }),
704 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 2 }),
705 None,
706 Some(TM1ComprInfo { is_24bit: true, block_w: 4, block_h: 4 }),
707 None,
708 Some(TM1ComprInfo { is_24bit: true, block_w: 4, block_h: 2 }),
709 None,
710 Some(TM1ComprInfo { is_24bit: true, block_w: 2, block_h: 4 }),
711 None,
712 Some(TM1ComprInfo { is_24bit: true, block_w: 2, block_h: 2 }),
713];
714
715const DUCK_Y_DELTAS: [[i32; 8]; 4] = [
716 [ 0, -1, 1, -3, 3, -6, 6, -6 ],
717 [ 0, -1, 2, -3, 4, -6, 6, -6 ],
718 [ 2, -3, 10, -10, 23, -23, 47, -47 ],
719 [ 0, -2, 2, -8, 8, -18, 18, -40 ]
720];
721const DUCK_Y_FAT_DELTA3: [i32; 8] = [ 0, -15, 50, -50, 115, -115, 235, -235 ];
722const DUCK_Y_FAT_DELTA4: [i32; 8] = [ 0, 40, 80, -76, 160, -154, 236, -236 ];
723const DUCK_Y_FAT_DELTAS: [&[i32]; 4] = [
724 &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA4
725];
726
727const DUCK_C_DELTAS: [[i32; 8]; 4] = [
728 [ 0, -1, 1, -2, 3, -4, 5, -4 ],
729 [ 0, -1, 1, -2, 3, -4, 5, -4 ],
730 [ 0, -4, 3, -16, 20, -32, 36, -32 ],
731 [ 0, -2, 2, -8, 8, -18, 18, -40 ]
732];
733const DUCK_C_FAT_DELTA3: [i32; 8] = [ 0, -20, 15, -80, 100, -160, 180, -160 ];
734const DUCK_C_FAT_DELTAS: [&[i32]; 4] = [
735 &DUCK_C_FAT_DELTA3, &DUCK_C_FAT_DELTA3, &DUCK_C_FAT_DELTA3, &DUCK_Y_FAT_DELTA4
736];
737
738const DUCK_VECTBL2: &[u8] = &[
7390x8,0x00,0x00,0x00,0x00,
7400x8,0x00,0x00,0x00,0x00,
7410x8,0x10,0x00,0x00,0x00,
7420x8,0x01,0x00,0x00,0x00,
7430x8,0x00,0x10,0x00,0x00,
7440x8,0x00,0x01,0x00,0x00,
7450x8,0x00,0x00,0x10,0x00,
7460x8,0x00,0x00,0x01,0x00,
7470x8,0x00,0x00,0x00,0x10,
7480x8,0x00,0x00,0x00,0x01,
7490x6,0x00,0x00,0x00,
7500x6,0x10,0x00,0x00,
7510x6,0x01,0x00,0x00,
7520x6,0x00,0x10,0x00,
7530x6,0x00,0x01,0x00,
7540x6,0x00,0x00,0x01,
7550x6,0x00,0x00,0x10,
7560x6,0x00,0x00,0x02,
7570x6,0x00,0x00,0x20,
7580x6,0x20,0x10,0x00,
7590x6,0x00,0x02,0x01,
7600x6,0x00,0x20,0x10,
7610x6,0x02,0x01,0x00,
7620x6,0x11,0x00,0x00,
7630x6,0x00,0x20,0x00,
7640x6,0x00,0x02,0x00,
7650x6,0x20,0x00,0x00,
7660x6,0x01,0x10,0x00,
7670x6,0x02,0x00,0x00,
7680x6,0x01,0x00,0x02,
7690x6,0x10,0x00,0x20,
7700x6,0x00,0x01,0x02,
7710x6,0x10,0x01,0x00,
7720x6,0x00,0x10,0x20,
7730x6,0x10,0x10,0x00,
7740x6,0x10,0x00,0x01,
7750x6,0x20,0x00,0x10,
7760x6,0x02,0x00,0x01,
7770x6,0x01,0x01,0x00,
7780x6,0x01,0x00,0x10,
7790x6,0x00,0x11,0x00,
7800x6,0x10,0x00,0x02,
7810x6,0x00,0x01,0x10,
7820x6,0x00,0x00,0x11,
7830x6,0x10,0x00,0x10,
7840x6,0x01,0x00,0x01,
7850x6,0x00,0x00,0x22,
7860x6,0x02,0x01,0x01,
7870x6,0x10,0x20,0x10,
7880x6,0x01,0x02,0x01,
7890x6,0x20,0x10,0x10,
7900x6,0x01,0x00,0x20,
7910x6,0x00,0x10,0x01,
7920x6,0x21,0x10,0x00,
7930x6,0x10,0x02,0x01,
7940x6,0x12,0x01,0x00,
7950x6,0x01,0x20,0x10,
7960x6,0x01,0x02,0x00,
7970x6,0x10,0x20,0x00,
7980x6,0x00,0x10,0x02,
7990x6,0x00,0x01,0x20,
8000x6,0x00,0x02,0x21,
8010x6,0x00,0x02,0x20,
8020x6,0x00,0x00,0x12,
8030x6,0x00,0x00,0x21,
8040x6,0x20,0x11,0x00,
8050x6,0x00,0x01,0x01,
8060x6,0x11,0x10,0x00,
8070x6,0x00,0x20,0x12,
8080x6,0x00,0x20,0x11,
8090x6,0x20,0x10,0x02,
8100x6,0x02,0x01,0x20,
8110x6,0x00,0x22,0x11,
8120x6,0x00,0x10,0x10,
8130x6,0x02,0x11,0x00,
8140x6,0x00,0x21,0x10,
8150x6,0x00,0x02,0x03,
8160x6,0x20,0x10,0x01,
8170x6,0x00,0x12,0x01,
8180x4,0x11,0x00,
8190x4,0x00,0x22,
8200x4,0x20,0x00,
8210x4,0x01,0x10,
8220x4,0x02,0x20,
8230x4,0x00,0x20,
8240x4,0x02,0x00,
8250x4,0x10,0x01,
8260x4,0x00,0x11,
8270x4,0x02,0x01,
8280x4,0x02,0x21,
8290x4,0x00,0x02,
8300x4,0x20,0x02,
8310x4,0x01,0x01,
8320x4,0x10,0x10,
8330x4,0x10,0x02,
8340x4,0x22,0x00,
8350x4,0x10,0x00,
8360x4,0x01,0x00,
8370x4,0x21,0x00,
8380x4,0x12,0x00,
8390x4,0x00,0x10,
8400x4,0x20,0x12,
8410x4,0x01,0x11,
8420x4,0x00,0x01,
8430x4,0x01,0x02,
8440x4,0x11,0x02,
8450x4,0x11,0x01,
8460x4,0x10,0x20,
8470x4,0x20,0x01,
8480x4,0x22,0x11,
8490x4,0x00,0x12,
8500x4,0x20,0x10,
8510x4,0x22,0x01,
8520x4,0x01,0x20,
8530x4,0x00,0x21,
8540x4,0x10,0x11,
8550x4,0x21,0x10,
8560x4,0x10,0x22,
8570x4,0x02,0x03,
8580x4,0x12,0x01,
8590x4,0x20,0x11,
8600x4,0x11,0x10,
8610x4,0x20,0x30,
8620x4,0x11,0x20,
8630x4,0x02,0x10,
8640x4,0x22,0x10,
8650x4,0x11,0x11,
8660x4,0x30,0x20,
8670x4,0x30,0x00,
8680x4,0x01,0x22,
8690x4,0x01,0x12,
8700x4,0x02,0x11,
8710x4,0x03,0x02,
8720x4,0x03,0x00,
8730x4,0x10,0x21,
8740x4,0x12,0x20,
8750x4,0x00,0x00,
8760x4,0x12,0x21,
8770x4,0x21,0x11,
8780x4,0x02,0x22,
8790x4,0x10,0x12,
8800x4,0x31,0x00,
8810x4,0x20,0x20,
8820x4,0x00,0x03,
8830x4,0x02,0x02,
8840x4,0x22,0x20,
8850x4,0x01,0x21,
8860x4,0x21,0x02,
8870x4,0x21,0x12,
8880x4,0x11,0x22,
8890x4,0x00,0x30,
8900x4,0x12,0x11,
8910x4,0x20,0x22,
8920x4,0x31,0x20,
8930x4,0x21,0x30,
8940x4,0x22,0x02,
8950x4,0x22,0x22,
8960x4,0x20,0x31,
8970x4,0x13,0x02,
8980x4,0x03,0x10,
8990x4,0x11,0x12,
9000x4,0x00,0x13,
9010x4,0x21,0x01,
9020x4,0x12,0x03,
9030x4,0x13,0x00,
9040x4,0x13,0x10,
9050x4,0x02,0x13,
9060x4,0x30,0x01,
9070x4,0x12,0x10,
9080x4,0x22,0x13,
9090x4,0x03,0x12,
9100x4,0x31,0x01,
9110x4,0x30,0x22,
9120x4,0x00,0x31,
9130x4,0x01,0x31,
9140x4,0x02,0x23,
9150x4,0x01,0x30,
9160x4,0x11,0x21,
9170x4,0x22,0x21,
9180x4,0x01,0x13,
9190x4,0x10,0x03,
9200x4,0x22,0x03,
9210x4,0x30,0x21,
9220x4,0x21,0x31,
9230x4,0x33,0x00,
9240x4,0x13,0x12,
9250x4,0x11,0x31,
9260x4,0x30,0x02,
9270x4,0x12,0x02,
9280x4,0x11,0x13,
9290x4,0x12,0x22,
9300x4,0x20,0x32,
9310x4,0x10,0x13,
9320x4,0x22,0x31,
9330x4,0x21,0x20,
9340x4,0x01,0x33,
9350x4,0x33,0x10,
9360x4,0x20,0x13,
9370x4,0x31,0x22,
9380x4,0x13,0x30,
9390x4,0x01,0x03,
9400x4,0x11,0x33,
9410x4,0x20,0x21,
9420x4,0x13,0x31,
9430x4,0x03,0x22,
9440x4,0x31,0x02,
9450x4,0x00,0x24,
9460x2,0x00,
9470x2,0x10,
9480x2,0x20,
9490x2,0x30,
9500x2,0x40,
9510x2,0x50,
9520x2,0x60,
9530x2,0x01,
9540x2,0x11,
9550x2,0x21,
9560x2,0x31,
9570x2,0x41,
9580x2,0x51,
9590x2,0x61,
9600x2,0x02,
9610x2,0x12,
9620x2,0x22,
9630x2,0x32,
9640x2,0x42,
9650x2,0x52,
9660x2,0x62,
9670x2,0x03,
9680x2,0x13,
9690x2,0x23,
9700x2,0x33,
9710x2,0x43,
9720x2,0x53,
9730x2,0x63,
9740x2,0x04,
9750x2,0x14,
9760x2,0x24,
9770x2,0x34,
9780x2,0x44,
9790x2,0x54,
9800x2,0x64,
9810x2,0x05,
9820x2,0x15,
9830x2,0x25,
9840x2,0x35,
9850x2,0x45,
9860x2,0x55,
9870x2,0x65,
9880x2,0x06,
9890x2,0x16,
9900x2,0x26,
9910x2,0x36,
9920x2,0x46,
9930x2,0x56,
9940x2,0x66
995];
996
997const DUCK_VECTBL3: &[u8] = &[
9980x6,0x00,0x00,0x00,
9990x6,0x00,0x00,0x00,
10000x6,0x00,0x00,0x01,
10010x6,0x00,0x00,0x10,
10020x6,0x00,0x00,0x11,
10030x6,0x00,0x01,0x00,
10040x6,0x00,0x01,0x01,
10050x6,0x00,0x01,0x10,
10060x6,0x00,0x01,0x11,
10070x6,0x00,0x10,0x00,
10080x6,0x00,0x10,0x01,
10090x6,0x00,0x10,0x10,
10100x6,0x00,0x10,0x11,
10110x6,0x00,0x11,0x00,
10120x6,0x00,0x11,0x01,
10130x6,0x00,0x11,0x10,
10140x6,0x00,0x11,0x11,
10150x6,0x01,0x00,0x00,
10160x6,0x01,0x00,0x01,
10170x6,0x01,0x00,0x10,
10180x6,0x01,0x00,0x11,
10190x6,0x01,0x01,0x00,
10200x6,0x01,0x01,0x01,
10210x6,0x01,0x01,0x10,
10220x6,0x01,0x01,0x11,
10230x6,0x01,0x10,0x00,
10240x6,0x01,0x10,0x01,
10250x6,0x01,0x10,0x10,
10260x6,0x01,0x10,0x11,
10270x6,0x01,0x11,0x00,
10280x6,0x01,0x11,0x01,
10290x6,0x01,0x11,0x10,
10300x6,0x01,0x11,0x11,
10310x6,0x10,0x00,0x00,
10320x6,0x10,0x00,0x01,
10330x6,0x10,0x00,0x10,
10340x6,0x10,0x00,0x11,
10350x6,0x10,0x01,0x00,
10360x6,0x10,0x01,0x01,
10370x6,0x10,0x01,0x10,
10380x6,0x10,0x01,0x11,
10390x6,0x10,0x10,0x00,
10400x6,0x10,0x10,0x01,
10410x6,0x10,0x10,0x10,
10420x6,0x10,0x10,0x11,
10430x6,0x10,0x11,0x00,
10440x6,0x10,0x11,0x01,
10450x6,0x10,0x11,0x10,
10460x6,0x10,0x11,0x11,
10470x6,0x11,0x00,0x00,
10480x6,0x11,0x00,0x01,
10490x6,0x11,0x00,0x10,
10500x6,0x11,0x00,0x11,
10510x6,0x11,0x01,0x00,
10520x6,0x11,0x01,0x01,
10530x6,0x11,0x01,0x10,
10540x6,0x11,0x01,0x11,
10550x6,0x11,0x10,0x00,
10560x6,0x11,0x10,0x01,
10570x6,0x11,0x10,0x10,
10580x6,0x11,0x10,0x11,
10590x6,0x11,0x11,0x00,
10600x6,0x11,0x11,0x01,
10610x6,0x11,0x11,0x10,
10620x4,0x00,0x00,
10630x4,0x00,0x01,
10640x4,0x00,0x02,
10650x4,0x00,0x03,
10660x4,0x00,0x10,
10670x4,0x00,0x11,
10680x4,0x00,0x12,
10690x4,0x00,0x13,
10700x4,0x00,0x20,
10710x4,0x00,0x21,
10720x4,0x00,0x22,
10730x4,0x00,0x23,
10740x4,0x00,0x30,
10750x4,0x00,0x31,
10760x4,0x00,0x32,
10770x4,0x00,0x33,
10780x4,0x01,0x00,
10790x4,0x01,0x01,
10800x4,0x01,0x02,
10810x4,0x01,0x03,
10820x4,0x01,0x10,
10830x4,0x01,0x11,
10840x4,0x01,0x12,
10850x4,0x01,0x13,
10860x4,0x01,0x20,
10870x4,0x01,0x21,
10880x4,0x01,0x22,
10890x4,0x01,0x23,
10900x4,0x01,0x30,
10910x4,0x01,0x31,
10920x4,0x01,0x32,
10930x4,0x01,0x33,
10940x4,0x02,0x00,
10950x4,0x02,0x01,
10960x4,0x02,0x02,
10970x4,0x02,0x03,
10980x4,0x02,0x10,
10990x4,0x02,0x11,
11000x4,0x02,0x12,
11010x4,0x02,0x13,
11020x4,0x02,0x20,
11030x4,0x02,0x21,
11040x4,0x02,0x22,
11050x4,0x02,0x23,
11060x4,0x02,0x30,
11070x4,0x02,0x31,
11080x4,0x02,0x32,
11090x4,0x02,0x33,
11100x4,0x03,0x00,
11110x4,0x03,0x01,
11120x4,0x03,0x02,
11130x4,0x03,0x03,
11140x4,0x03,0x10,
11150x4,0x03,0x11,
11160x4,0x03,0x12,
11170x4,0x03,0x13,
11180x4,0x03,0x20,
11190x4,0x03,0x21,
11200x4,0x03,0x22,
11210x4,0x03,0x23,
11220x4,0x03,0x30,
11230x4,0x03,0x31,
11240x4,0x03,0x32,
11250x4,0x03,0x33,
11260x4,0x10,0x00,
11270x4,0x10,0x01,
11280x4,0x10,0x02,
11290x4,0x10,0x03,
11300x4,0x10,0x10,
11310x4,0x10,0x11,
11320x4,0x10,0x12,
11330x4,0x10,0x13,
11340x4,0x10,0x20,
11350x4,0x10,0x21,
11360x4,0x10,0x22,
11370x4,0x10,0x23,
11380x4,0x10,0x30,
11390x4,0x10,0x31,
11400x4,0x10,0x32,
11410x4,0x10,0x33,
11420x4,0x11,0x00,
11430x4,0x11,0x01,
11440x4,0x11,0x02,
11450x4,0x11,0x03,
11460x4,0x11,0x10,
11470x4,0x11,0x11,
11480x4,0x11,0x12,
11490x4,0x11,0x13,
11500x4,0x11,0x20,
11510x4,0x11,0x21,
11520x4,0x11,0x22,
11530x4,0x11,0x23,
11540x4,0x11,0x30,
11550x4,0x11,0x31,
11560x4,0x11,0x32,
11570x4,0x11,0x33,
11580x4,0x12,0x00,
11590x4,0x12,0x01,
11600x4,0x12,0x02,
11610x4,0x12,0x03,
11620x4,0x12,0x10,
11630x4,0x12,0x11,
11640x4,0x12,0x12,
11650x4,0x12,0x13,
11660x4,0x12,0x20,
11670x4,0x12,0x21,
11680x4,0x12,0x22,
11690x4,0x12,0x23,
11700x4,0x12,0x30,
11710x4,0x12,0x31,
11720x4,0x12,0x32,
11730x4,0x12,0x33,
11740x4,0x13,0x00,
11750x4,0x13,0x01,
11760x4,0x13,0x02,
11770x4,0x13,0x03,
11780x4,0x13,0x10,
11790x4,0x13,0x11,
11800x4,0x13,0x12,
11810x4,0x13,0x13,
11820x4,0x13,0x20,
11830x4,0x13,0x21,
11840x4,0x13,0x22,
11850x4,0x13,0x23,
11860x4,0x13,0x30,
11870x4,0x13,0x31,
11880x4,0x13,0x32,
11890x4,0x13,0x33,
11900x2,0x00,
11910x2,0x10,
11920x2,0x20,
11930x2,0x30,
11940x2,0x40,
11950x2,0x50,
11960x2,0x60,
11970x2,0x70,
11980x2,0x01,
11990x2,0x11,
12000x2,0x21,
12010x2,0x31,
12020x2,0x41,
12030x2,0x51,
12040x2,0x61,
12050x2,0x71,
12060x2,0x02,
12070x2,0x12,
12080x2,0x22,
12090x2,0x32,
12100x2,0x42,
12110x2,0x52,
12120x2,0x62,
12130x2,0x72,
12140x2,0x03,
12150x2,0x13,
12160x2,0x23,
12170x2,0x33,
12180x2,0x43,
12190x2,0x53,
12200x2,0x63,
12210x2,0x73,
12220x2,0x04,
12230x2,0x14,
12240x2,0x24,
12250x2,0x34,
12260x2,0x44,
12270x2,0x54,
12280x2,0x64,
12290x2,0x74,
12300x2,0x05,
12310x2,0x15,
12320x2,0x25,
12330x2,0x35,
12340x2,0x45,
12350x2,0x55,
12360x2,0x65,
12370x2,0x75,
12380x2,0x06,
12390x2,0x16,
12400x2,0x26,
12410x2,0x36,
12420x2,0x46,
12430x2,0x56,
12440x2,0x66,
12450x2,0x76,
12460x2,0x07,
12470x2,0x17,
12480x2,0x27,
12490x2,0x37,
12500x2,0x47,
12510x2,0x57,
12520x2,0x67,
12530x2,0x77
1254];
1255
1256const DUCK_VECTBL4: &[u8] = &[
12570x8,0x00,0x00,0x00,0x00,
12580x8,0x00,0x00,0x00,0x00,
12590x8,0x20,0x00,0x00,0x00,
12600x8,0x00,0x00,0x00,0x01,
12610x8,0x10,0x00,0x00,0x00,
12620x8,0x00,0x00,0x00,0x02,
12630x8,0x01,0x00,0x00,0x00,
12640x8,0x00,0x00,0x00,0x10,
12650x8,0x02,0x00,0x00,0x00,
12660x6,0x00,0x00,0x00,
12670x6,0x20,0x00,0x00,
12680x6,0x00,0x00,0x01,
12690x6,0x10,0x00,0x00,
12700x6,0x00,0x00,0x02,
12710x6,0x00,0x10,0x00,
12720x6,0x00,0x20,0x00,
12730x6,0x00,0x02,0x00,
12740x6,0x00,0x01,0x00,
12750x6,0x01,0x00,0x00,
12760x6,0x00,0x00,0x20,
12770x6,0x02,0x00,0x00,
12780x6,0x00,0x00,0x10,
12790x6,0x10,0x00,0x20,
12800x6,0x01,0x00,0x02,
12810x6,0x20,0x00,0x10,
12820x6,0x02,0x00,0x01,
12830x6,0x20,0x10,0x00,
12840x6,0x00,0x12,0x00,
12850x6,0x00,0x02,0x01,
12860x6,0x02,0x01,0x00,
12870x6,0x00,0x21,0x00,
12880x6,0x00,0x01,0x02,
12890x6,0x00,0x20,0x10,
12900x6,0x00,0x00,0x21,
12910x6,0x00,0x00,0x12,
12920x6,0x00,0x01,0x20,
12930x6,0x12,0x00,0x00,
12940x6,0x00,0x10,0x20,
12950x6,0x01,0x20,0x00,
12960x6,0x02,0x10,0x00,
12970x6,0x10,0x20,0x00,
12980x6,0x01,0x02,0x00,
12990x6,0x21,0x00,0x00,
13000x6,0x00,0x02,0x10,
13010x6,0x20,0x01,0x00,
13020x6,0x00,0x22,0x00,
13030x6,0x10,0x02,0x00,
13040x6,0x00,0x10,0x02,
13050x6,0x11,0x00,0x00,
13060x6,0x00,0x11,0x00,
13070x6,0x22,0x00,0x00,
13080x6,0x20,0x00,0x02,
13090x6,0x10,0x00,0x01,
13100x6,0x00,0x20,0x01,
13110x6,0x02,0x20,0x00,
13120x6,0x01,0x10,0x00,
13130x6,0x01,0x00,0x20,
13140x6,0x00,0x20,0x02,
13150x6,0x01,0x20,0x02,
13160x6,0x10,0x01,0x00,
13170x6,0x02,0x00,0x10,
13180x6,0x00,0x10,0x01,
13190x6,0x10,0x01,0x20,
13200x6,0x20,0x02,0x10,
13210x6,0x00,0x00,0x22,
13220x6,0x10,0x00,0x02,
13230x6,0x00,0x02,0x20,
13240x6,0x20,0x02,0x00,
13250x6,0x00,0x00,0x11,
13260x6,0x02,0x10,0x01,
13270x6,0x00,0x01,0x10,
13280x6,0x00,0x02,0x11,
13290x4,0x01,0x02,
13300x4,0x02,0x01,
13310x4,0x01,0x00,
13320x4,0x10,0x20,
13330x4,0x20,0x10,
13340x4,0x20,0x00,
13350x4,0x11,0x00,
13360x4,0x02,0x00,
13370x4,0x12,0x00,
13380x4,0x00,0x21,
13390x4,0x22,0x00,
13400x4,0x00,0x12,
13410x4,0x21,0x00,
13420x4,0x02,0x11,
13430x4,0x00,0x01,
13440x4,0x10,0x02,
13450x4,0x02,0x20,
13460x4,0x20,0x11,
13470x4,0x01,0x10,
13480x4,0x21,0x10,
13490x4,0x10,0x00,
13500x4,0x10,0x22,
13510x4,0x20,0x20,
13520x4,0x00,0x22,
13530x4,0x01,0x22,
13540x4,0x20,0x01,
13550x4,0x02,0x02,
13560x4,0x00,0x20,
13570x4,0x00,0x10,
13580x4,0x00,0x11,
13590x4,0x22,0x01,
13600x4,0x11,0x20,
13610x4,0x12,0x01,
13620x4,0x12,0x20,
13630x4,0x11,0x02,
13640x4,0x10,0x10,
13650x4,0x01,0x01,
13660x4,0x02,0x21,
13670x4,0x20,0x12,
13680x4,0x01,0x12,
13690x4,0x22,0x11,
13700x4,0x21,0x12,
13710x4,0x22,0x10,
13720x4,0x21,0x02,
13730x4,0x20,0x02,
13740x4,0x10,0x01,
13750x4,0x00,0x02,
13760x4,0x10,0x21,
13770x4,0x01,0x20,
13780x4,0x11,0x22,
13790x4,0x12,0x21,
13800x4,0x22,0x20,
13810x4,0x02,0x10,
13820x4,0x02,0x22,
13830x4,0x11,0x10,
13840x4,0x22,0x02,
13850x4,0x20,0x21,
13860x4,0x01,0x11,
13870x4,0x11,0x01,
13880x4,0x10,0x12,
13890x4,0x02,0x12,
13900x4,0x20,0x22,
13910x4,0x21,0x20,
13920x4,0x01,0x21,
13930x4,0x12,0x02,
13940x4,0x21,0x11,
13950x4,0x12,0x22,
13960x4,0x12,0x10,
13970x4,0x22,0x21,
13980x4,0x10,0x11,
13990x4,0x21,0x01,
14000x4,0x11,0x12,
14010x4,0x12,0x11,
14020x4,0x66,0x66,
14030x4,0x22,0x22,
14040x4,0x11,0x21,
14050x4,0x11,0x11,
14060x4,0x21,0x22,
14070x4,0x00,0x00,
14080x4,0x22,0x12,
14090x4,0x12,0x12,
14100x4,0x21,0x21,
14110x4,0x42,0x00,
14120x4,0x00,0x04,
14130x4,0x40,0x00,
14140x4,0x30,0x00,
14150x4,0x31,0x00,
14160x4,0x00,0x03,
14170x4,0x00,0x14,
14180x4,0x00,0x13,
14190x4,0x01,0x24,
14200x4,0x20,0x13,
14210x4,0x01,0x42,
14220x4,0x14,0x20,
14230x4,0x42,0x02,
14240x4,0x13,0x00,
14250x4,0x00,0x24,
14260x4,0x31,0x20,
14270x4,0x22,0x13,
14280x4,0x11,0x24,
14290x4,0x12,0x66,
14300x4,0x30,0x01,
14310x4,0x02,0x13,
14320x4,0x12,0x42,
14330x4,0x40,0x10,
14340x4,0x40,0x02,
14350x4,0x01,0x04,
14360x4,0x24,0x00,
14370x4,0x42,0x10,
14380x4,0x21,0x13,
14390x4,0x13,0x12,
14400x4,0x31,0x21,
14410x4,0x21,0x24,
14420x4,0x00,0x40,
14430x4,0x10,0x24,
14440x4,0x10,0x42,
14450x4,0x32,0x01,
14460x4,0x11,0x42,
14470x4,0x20,0x31,
14480x4,0x12,0x40,
14490x2,0x00,
14500x2,0x10,
14510x2,0x20,
14520x2,0x30,
14530x2,0x40,
14540x2,0x50,
14550x2,0x60,
14560x2,0x70,
14570x2,0x01,
14580x2,0x11,
14590x2,0x21,
14600x2,0x31,
14610x2,0x41,
14620x2,0x51,
14630x2,0x61,
14640x2,0x71,
14650x2,0x02,
14660x2,0x12,
14670x2,0x22,
14680x2,0x32,
14690x2,0x42,
14700x2,0x52,
14710x2,0x62,
14720x2,0x72,
14730x2,0x03,
14740x2,0x13,
14750x2,0x23,
14760x2,0x33,
14770x2,0x43,
14780x2,0x53,
14790x2,0x63,
14800x2,0x73,
14810x2,0x04,
14820x2,0x14,
14830x2,0x24,
14840x2,0x34,
14850x2,0x44,
14860x2,0x54,
14870x2,0x64,
14880x2,0x74,
14890x2,0x05,
14900x2,0x15,
14910x2,0x25,
14920x2,0x35,
14930x2,0x45,
14940x2,0x55,
14950x2,0x65,
14960x2,0x75,
14970x2,0x06,
14980x2,0x16,
14990x2,0x26,
15000x2,0x36,
15010x2,0x46,
15020x2,0x56,
15030x2,0x66,
15040x2,0x76,
15050x2,0x07,
15060x2,0x17,
15070x2,0x27,
15080x2,0x37,
15090x2,0x47,
15100x2,0x57,
15110x2,0x67,
15120x2,0x77
1513];
1514
1515const DUCK_VECTABLES: [&[u8]; 3] = [ DUCK_VECTBL2, DUCK_VECTBL3, DUCK_VECTBL4 ];