fix some clippy warnings
[nihav.git] / nihav-duck / src / codecs / truemotion1.rs
CommitLineData
1b8522d6 1use nihav_core::codecs::*;
2d90e8b6
KS
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
6f263099 131#[derive(Default)]
2d90e8b6 132struct FrameBuf {
3fc28ece
KS
133 last16: Option<NAVideoBufferRef<u16>>,
134 last24: Option<NAVideoBufferRef<u8>>,
2d90e8b6
KS
135}
136
137impl FrameBuf {
3fc28ece
KS
138 fn set16(&mut self, buf: NAVideoBufferRef<u16>) { self.last16 = Some(buf); }
139 fn set24(&mut self, buf: NAVideoBufferRef<u8>) { self.last24 = Some(buf); }
140 fn get16(&mut self) -> Option<NAVideoBufferRef<u16>> {
2d90e8b6
KS
141 if let Some(ref mut frm) = self.last16 {
142 let newfrm = frm.copy_buffer();
3fc28ece
KS
143 *frm = newfrm.clone().into_ref();
144 Some(newfrm.into_ref())
2d90e8b6
KS
145 } else {
146 None
147 }
148 }
3fc28ece 149 fn get24(&mut self) -> Option<NAVideoBufferRef<u8>> {
2d90e8b6
KS
150 if let Some(ref mut frm) = self.last24 {
151 let newfrm = frm.copy_buffer();
3fc28ece
KS
152 *frm = newfrm.clone().into_ref();
153 Some(newfrm.into_ref())
2d90e8b6
KS
154 } else {
155 None
156 }
157 }
158 fn reset(&mut self) {
159 self.last16 = None;
160 self.last24 = None;
161 }
162}
163
2d90e8b6
KS
164#[derive(Default)]
165struct TM1Decoder {
2422d969 166 info: NACodecInfoRef,
2d90e8b6
KS
167 last_delta_set: usize,
168 last_table_idx: usize,
169 delta_tables: DeltaTables,
170 blk_w: usize,
171 blk_h: usize,
172 vert_pred: Vec<u32>,
173 lastframe: FrameBuf,
174}
175
176const RGB555_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
177 comp_info: [
178 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 10, comp_offs: 0, next_elem: 2 }),
179 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 5, comp_offs: 0, next_elem: 2 }),
180 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 0, comp_offs: 0, next_elem: 2 }),
181 None, None],
182 elem_size: 2, be: false, alpha: false, palette: false };
183const BGR0_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
184 comp_info: [
185 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 2, next_elem: 4 }),
186 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 1, next_elem: 4 }),
187 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 0, next_elem: 4 }),
188 None, None],
189 elem_size: 4, be: false, alpha: false, palette: false };
190
191impl TM1Decoder {
192 fn new() -> Self { Self::default() }
193 fn set_delta_tables(&mut self, delta_set: usize, table_idx: usize, is_24bit: bool) {
194 if (self.last_delta_set == delta_set) && (self.last_table_idx == table_idx) { return; }
195 let ydt = &DUCK_Y_DELTAS[delta_set];
196 let yfdt = DUCK_Y_FAT_DELTAS[delta_set];
197 let cdt = &DUCK_C_DELTAS[delta_set];
198 let cfdt = DUCK_C_FAT_DELTAS[delta_set];
199 let vec = DUCK_VECTABLES[table_idx - 1];
200
8a7352c0 201 let mut vec_iter = vec.iter();
2d90e8b6
KS
202 for i in 0..256 {
203 let len = (*vec_iter.next().unwrap() as usize) >> 1;
204 for j in 0..len {
205 let pair = vec_iter.next().unwrap();
206 let lo = (pair >> 4) as usize;
207 let hi = (pair & 0xF) as usize;
208 if !is_24bit {
209 let d_lo = ydt[lo] + (ydt[lo] << 5) + (ydt[lo] << 10);
210 let d_hi = ydt[hi] + (ydt[hi] << 5) + (ydt[hi] << 10);
211 self.delta_tables.ydt[i][j] = ((d_lo + (d_hi << 16)) << 1) as u32;
212 let d_c = cdt[hi] + (cdt[lo] << 10);
213 self.delta_tables.cdt[i][j] = ((d_c + (d_c << 16)) << 1) as u32;
214 let d_a = lo + hi * 5;
215 self.delta_tables.adt[i][j] = ((d_a << 16) << 1) as u32;
216 } else {
217 self.delta_tables.ydt[i][j] = ((ydt [lo] + (ydt [hi] << 8) + (ydt [hi] << 16)) << 1) as u32;
218 self.delta_tables.fat_ydt[i][j] = ((yfdt[lo] + (yfdt[hi] << 8) + (yfdt[hi] << 16)) << 1) as u32;
219 self.delta_tables.cdt[i][j] = ((cdt [hi] + (cdt [lo] << 16)) << 1) as u32;
220 self.delta_tables.fat_cdt[i][j] = ((cfdt[hi] + (cfdt[lo] << 16)) << 1) as u32;
221 }
222 }
223 self.delta_tables.ydt[i][len - 1] |= 1;
224 self.delta_tables.cdt[i][len - 1] |= 1;
225 self.delta_tables.adt[i][len - 1] |= 1;
226 self.delta_tables.fat_ydt[i][len - 1] |= 1;
227 self.delta_tables.fat_cdt[i][len - 1] |= 1;
228 }
229
230 self.last_delta_set = delta_set;
231 self.last_table_idx = table_idx;
232 }
233 fn decode_16bit(&mut self, dst: &mut [u16], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
234 let mut off = 0;
235 index.get_next()?;
236 for y in 0..height {
237 let mut hor_pred: u32 = 0;
238 for x in (0..width).step_by(4) {
239 if mask.get_next() {
240 match y & 3 {
241 0 => {
242 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
243 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
244 hor_pred = hor_pred.wrapping_add(dc0);
245 hor_pred = hor_pred.wrapping_add(dy0);
246 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
247 self.vert_pred[(x >> 1) + 0] = cur;
248 dst[off + x + 0] = cur as u16;
249 dst[off + x + 1] = (cur >> 16) as u16;
250 if self.blk_w == 2 {
251 let dc1 = index.get_diff16(&self.delta_tables.cdt)?;
252 hor_pred = hor_pred.wrapping_add(dc1);
253 }
254 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
255 hor_pred = hor_pred.wrapping_add(dy1);
256 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
257 self.vert_pred[(x >> 1) + 1] = cur;
258 dst[off + x + 2] = cur as u16;
259 dst[off + x + 3] = (cur >> 16) as u16;
260 },
261 1 | 3 => {
262 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
263 hor_pred = hor_pred.wrapping_add(dy0);
264 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
265 self.vert_pred[(x >> 1) + 0] = cur;
266 dst[off + x + 0] = cur as u16;
267 dst[off + x + 1] = (cur >> 16) as u16;
268 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
269 hor_pred = hor_pred.wrapping_add(dy1);
270 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
271 self.vert_pred[(x >> 1) + 1] = cur;
272 dst[off + x + 2] = cur as u16;
273 dst[off + x + 3] = (cur >> 16) as u16;
274 },
275 2 => {
276 if self.blk_h == 2 {
277 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
278 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
279 hor_pred = hor_pred.wrapping_add(dc0);
280 hor_pred = hor_pred.wrapping_add(dy0);
281 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
282 self.vert_pred[(x >> 1) + 0] = cur;
283 dst[off + x + 0] = cur as u16;
284 dst[off + x + 1] = (cur >> 16) as u16;
285 if self.blk_w == 2 {
286 let dc1 = index.get_diff16(&self.delta_tables.cdt)?;
287 hor_pred = hor_pred.wrapping_add(dc1);
288 }
289 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
290 hor_pred = hor_pred.wrapping_add(dy1);
291 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
292 self.vert_pred[(x >> 1) + 1] = cur;
293 dst[off + x + 2] = cur as u16;
294 dst[off + x + 3] = (cur >> 16) as u16;
295 } else {
296 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
297 hor_pred = hor_pred.wrapping_add(dy0);
298 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
299 self.vert_pred[(x >> 1) + 0] = cur;
300 dst[off + x + 0] = cur as u16;
301 dst[off + x + 1] = (cur >> 16) as u16;
302 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
303 hor_pred = hor_pred.wrapping_add(dy1);
304 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
305 self.vert_pred[(x >> 1) + 1] = cur;
306 dst[off + x + 2] = cur as u16;
307 dst[off + x + 3] = (cur >> 16) as u16;
308 }
309 },
310 _ => unreachable!(),
311 };
312 } else {
8a7352c0 313 let cur = u32::from(dst[off + x + 0]) | (u32::from(dst[off + x + 1]) << 16);
2d90e8b6 314 self.vert_pred[(x >> 1) + 0] = cur;
8a7352c0 315 let cur = u32::from(dst[off + x + 2]) | (u32::from(dst[off + x + 3]) << 16);
2d90e8b6
KS
316 hor_pred = cur.wrapping_sub(self.vert_pred[(x >> 1) + 1]);
317 self.vert_pred[(x >> 1) + 1] = cur;
318 }
319 }
320 if (y & 3) != 3 {
321 mask.reset_row();
322 } else {
323 mask.next_row();
324 }
325 off += stride;
326 }
327 Ok(())
328 }
329 fn decode_sprite(&mut self, dst: &mut [u16], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
330 let mut off = 0;
331 let _ = index.get_next();
332 for y in 0..height {
333 let mut hor_pred: u32 = 0;
334 for x in (0..width).step_by(4) {
335 let is_tm = !mask.get_next();
336 let is_sprite = !mask.get_next();
337 if is_tm {
338 if (y & 3) == 0 {
339 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
340 hor_pred = hor_pred.wrapping_add(dc0);
341 }
342 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
343 hor_pred = hor_pred.wrapping_add(dy0);
344 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
345 self.vert_pred[(x >> 1) + 0] = cur;
346 dst[off + x + 0] = cur as u16;
347 dst[off + x + 1] = (cur >> 16) as u16;
348 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
349 hor_pred = hor_pred.wrapping_add(dy1);
350 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
351 self.vert_pred[(x >> 1) + 1] = cur;
352 dst[off + x + 2] = cur as u16;
353 dst[off + x + 3] = (cur >> 16) as u16;
354 } else if is_sprite {
355 if (y & 3) == 0 {
356 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
357 hor_pred = hor_pred.wrapping_add(dc0);
358 }
359 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
360 hor_pred = hor_pred.wrapping_add(dy0);
361 let _da0 = index.get_diff16_noesc(&self.delta_tables.adt)?;
362 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
363 self.vert_pred[(x >> 1) + 0] = cur;
364 dst[off + x + 0] = cur as u16;
365 dst[off + x + 1] = (cur >> 16) as u16;
366 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
367 hor_pred = hor_pred.wrapping_add(dy1);
368 let _da1 = index.get_diff16_noesc(&self.delta_tables.adt)?;
369 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
370 self.vert_pred[(x >> 1) + 1] = cur;
371 dst[off + x + 2] = cur as u16;
372 dst[off + x + 3] = (cur >> 16) as u16;
373 } else {
374 hor_pred = 0;
375 dst[off + x + 0] = 0;
376 dst[off + x + 1] = 0;
377 dst[off + x + 2] = 0;
378 dst[off + x + 3] = 0;
379 self.vert_pred[(x >> 1) + 0] = 0;
380 self.vert_pred[(x >> 1) + 1] = 0;
381 }
382 }
383 if (y & 3) != 3 {
384 mask.reset_row();
385 } else {
386 mask.next_row();
387 }
388 off += stride;
389 }
390 Ok(())
391 }
392 fn decode_24bit(&mut self, dst: &mut [u8], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
393 let mut off = 0;
394 index.get_next()?;
395 for y in 0..height {
396 let mut hor_pred: u32 = 0;
397 for x in (0..width).step_by(2) {
398 if mask.get_next() {
399 match y & 3 {
400 0 => {
401 let dc0 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
402 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
403 hor_pred = hor_pred.wrapping_add(dc0);
404 hor_pred = hor_pred.wrapping_add(dy0);
405 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
406 self.vert_pred[x + 0] = cur;
407 dst[off + x*4 + 0] = cur as u8;
408 dst[off + x*4 + 1] = (cur >> 8) as u8;
409 dst[off + x*4 + 2] = (cur >> 16) as u8;
410 dst[off + x*4 + 3] = 0;
411 if self.blk_w == 2 {
412 let dc1 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
413 hor_pred = hor_pred.wrapping_add(dc1);
414 }
415 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
416 hor_pred = hor_pred.wrapping_add(dy1);
417 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
418 self.vert_pred[x + 1] = cur;
419 dst[off + x*4 + 4] = cur as u8;
420 dst[off + x*4 + 5] = (cur >> 8) as u8;
421 dst[off + x*4 + 6] = (cur >> 16) as u8;
422 dst[off + x*4 + 7] = 0;
423 },
424 1 | 3 => {
425 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
426 hor_pred = hor_pred.wrapping_add(dy0);
427 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
428 self.vert_pred[x + 0] = cur;
429 dst[off + x*4 + 0] = cur as u8;
430 dst[off + x*4 + 1] = (cur >> 8) as u8;
431 dst[off + x*4 + 2] = (cur >> 16) as u8;
432 dst[off + x*4 + 3] = 0;
433 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
434 hor_pred = hor_pred.wrapping_add(dy1);
435 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
436 self.vert_pred[x + 1] = cur;
437 dst[off + x*4 + 4] = cur as u8;
438 dst[off + x*4 + 5] = (cur >> 8) as u8;
439 dst[off + x*4 + 6] = (cur >> 16) as u8;
440 dst[off + x*4 + 7] = 0;
441 },
442 2 => {
443 if self.blk_h == 2 {
444 let dc0 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
445 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
446 hor_pred = hor_pred.wrapping_add(dc0);
447 hor_pred = hor_pred.wrapping_add(dy0);
448 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
449 self.vert_pred[x + 0] = cur;
450 dst[off + x*4 + 0] = cur as u8;
451 dst[off + x*4 + 1] = (cur >> 8) as u8;
452 dst[off + x*4 + 2] = (cur >> 16) as u8;
453 dst[off + x*4 + 3] = 0;
454 if self.blk_w == 2 {
455 let dc1 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
456 hor_pred = hor_pred.wrapping_add(dc1);
457 }
458 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
459 hor_pred = hor_pred.wrapping_add(dy1);
460 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
461 self.vert_pred[x + 1] = cur;
462 dst[off + x*4 + 4] = cur as u8;
463 dst[off + x*4 + 5] = (cur >> 8) as u8;
464 dst[off + x*4 + 6] = (cur >> 16) as u8;
465 dst[off + x*4 + 7] = 0;
466 } else {
467 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
468 hor_pred = hor_pred.wrapping_add(dy0);
469 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
470 self.vert_pred[x + 0] = cur;
471 dst[off + x*4 + 0] = cur as u8;
472 dst[off + x*4 + 1] = (cur >> 8) as u8;
473 dst[off + x*4 + 2] = (cur >> 16) as u8;
474 dst[off + x*4 + 3] = 0;
475 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
476 hor_pred = hor_pred.wrapping_add(dy1);
477 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
478 self.vert_pred[x + 1] = cur;
479 dst[off + x*4 + 4] = cur as u8;
480 dst[off + x*4 + 5] = (cur >> 8) as u8;
481 dst[off + x*4 + 6] = (cur >> 16) as u8;
482 dst[off + x*4 + 7] = 0;
483 }
484 },
485 _ => unreachable!(),
486 };
487 } else {
8a7352c0
KS
488 let cur = u32::from(dst[off + x*4 + 0])
489 | (u32::from(dst[off + x*4 + 1]) << 8)
490 | (u32::from(dst[off + x*4 + 2]) << 16)
491 | (u32::from(dst[off + x*4 + 3]) << 24);
2d90e8b6 492 self.vert_pred[x + 0] = cur;
8a7352c0
KS
493 let cur = u32::from(dst[off + x*4 + 4])
494 | (u32::from(dst[off + x*4 + 5]) << 8)
495 | (u32::from(dst[off + x*4 + 6]) << 16)
496 | (u32::from(dst[off + x*4 + 7]) << 24);
2d90e8b6
KS
497 hor_pred = cur.wrapping_sub(self.vert_pred[x + 1]);
498 self.vert_pred[x + 1] = cur;
499 }
500 }
501 if (y & 3) != 3 {
502 mask.reset_row();
503 } else {
504 mask.next_row();
505 }
506 off += stride;
507 }
508 Ok(())
509 }
510}
511
512impl NADecoder for TM1Decoder {
01613464 513 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
2d90e8b6
KS
514 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
515 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, YUV410_FORMAT));
2422d969 516 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
2d90e8b6
KS
517 Ok(())
518 } else {
519 Err(DecoderError::InvalidData)
520 }
521 }
01613464 522 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
2d90e8b6
KS
523 let src = pkt.get_buffer();
524 validate!(src.len() > 10);
525 let hdr_size = (src[0].rotate_left(3) & 0x7F) as usize;
526 validate!(hdr_size >= 12 && hdr_size < src.len());
527 let mut hdr: [u8; 127] = [0; 127];
528 for i in 1..hdr_size {
529 hdr[i - 1] = src[i] ^ src[i + 1];
530 }
531 let mut mr = MemoryReader::new_read(&hdr[0..hdr_size-1]);
532 let mut br = ByteReader::new(&mut mr);
533
534 let tm1type = br.read_byte()? as usize;
535 let delta_set = br.read_byte()? as usize;
536 let table_idx = br.read_byte()? as usize;
537 let height = br.read_u16le()? as usize;
538 let width = br.read_u16le()? as usize;
539 let _frameno = br.read_u16le()? as usize;
540 let version = br.read_byte()?;
541 let meta_type = br.read_byte()?;
542 validate!(width > 0 && height > 0);
543 let is_intra;
544 let mut is_sprite = false;
545 let mut spr_xoff = 0;
546 let mut spr_yoff = 0;
547 let mut spr_width = 0;
548 let mut spr_height = 0;
549 if version >= 2 {
550 validate!(meta_type <= 3);
551 if meta_type >= 2 {
552 let frameinfo = br.read_byte()?;
553 let _control = br.read_byte()?;
554
555 is_intra = ((frameinfo & 0x10) != 0) || ((frameinfo & 0x08) == 0);
556 } else {
557 is_intra = true;
558 }
559 if meta_type == 3 {
560 spr_xoff = br.read_u16le()? as usize;
561 spr_yoff = br.read_u16le()? as usize;
562 spr_width = br.read_u16le()? as usize;
563 spr_height = br.read_u16le()? as usize;
564 is_sprite = true;
565 }
566 } else {
567 is_intra = true;
568 }
569 validate!(tm1type < TM1_COMPR_TYPES.len());
570 let cinfo = TM1_COMPR_TYPES[tm1type];
571 if cinfo.is_none() {
572//check for missing ref
573 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
574 frm.set_keyframe(false);
575 frm.set_frame_type(FrameType::Skip);
171860fc 576 return Ok(frm.into_ref());
2d90e8b6
KS
577 }
578 let compr_info = cinfo.unwrap();
579 let is_24bit = !is_sprite && compr_info.is_24bit;
580
581 let vec_idx = if ((tm1type & 1) != 0) && (meta_type > 0) { 1 } else { table_idx };
582 validate!((delta_set < DUCK_Y_DELTAS.len()) && (vec_idx > 0) && (vec_idx <= DUCK_VECTABLES.len()));
583 self.set_delta_tables(delta_set, vec_idx, is_24bit);
584
585 let out_width = if is_24bit { width >> 1 } else { width };
586 let mask_row_size = if is_sprite {
587 ((spr_width >> 2) + 3) >> 2
588 } else if is_intra {
589 0
590 } else {
591 ((width >> 2) + 7) >> 3
592 };
593 let mask_size = mask_row_size * (if is_sprite { spr_height >> 2 } else { height >> 2 });
594 let mask_bits = &src[hdr_size..][..mask_size];
595 let index_bytes = &src[hdr_size+mask_size..];
596 validate!(src.len() >= hdr_size + mask_size);
37952415 597 self.vert_pred.clear();
2d90e8b6
KS
598 self.vert_pred.resize(out_width, 0);
599
600 if is_intra || is_sprite {
601 let fmt = if is_24bit { BGR0_FORMAT } else { RGB555_FORMAT };
602 let myinfo = NAVideoInfo::new(out_width, height, false, fmt);
8a7352c0 603 let bufinfo = alloc_video_buffer(myinfo, 2)?;
2d90e8b6
KS
604 self.lastframe.reset();
605 if !is_24bit {
606 self.lastframe.set16(bufinfo.get_vbuf16().unwrap());
607 } else {
608 self.lastframe.set24(bufinfo.get_vbuf().unwrap());
609 }
610 }
611
612 self.blk_w = compr_info.block_w;
613 self.blk_h = compr_info.block_h;
6f263099
KS
614 let mut mask = MaskState::new(is_intra && !is_sprite, mask_bits, mask_row_size);
615 let mut index = IndexState::new(index_bytes);
2d90e8b6
KS
616 let bufinfo;
617 if !is_24bit {
618 if let Some(mut buf) = self.lastframe.get16() {
619 let stride = buf.get_stride(0);
620 {
1a967e6b 621 let data = buf.get_data_mut().unwrap();
2d90e8b6
KS
622 if !is_sprite {
623 self.decode_16bit(data.as_mut_slice(), stride, out_width, height, &mut mask, &mut index)?;
624 } else {
625 validate!(spr_xoff + spr_width <= out_width);
626 validate!(spr_yoff + spr_height <= height);
627 for el in data.iter_mut() { *el = 0; }
628 let dst = &mut data[spr_xoff + spr_yoff * stride..];
629 self.decode_sprite(dst, stride, spr_width, spr_height, &mut mask, &mut index)?;
630 }
631 }
632 bufinfo = NABufferType::Video16(buf);
633 } else {
634 return Err(DecoderError::MissingReference);
635 }
8a7352c0
KS
636 } else if let Some(mut buf) = self.lastframe.get24() {
637 let stride = buf.get_stride(0);
638 {
639 let data = buf.get_data_mut().unwrap();
640 self.decode_24bit(data.as_mut_slice(), stride, out_width, height, &mut mask, &mut index)?;
2d90e8b6 641 }
8a7352c0
KS
642 bufinfo = NABufferType::VideoPacked(buf);
643 } else {
644 return Err(DecoderError::MissingReference);
2d90e8b6
KS
645 }
646
647 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
648 frm.set_keyframe(is_intra || is_sprite);
649 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
171860fc 650 Ok(frm.into_ref())
2d90e8b6 651 }
f9be4e75
KS
652 fn flush(&mut self) {
653 self.lastframe.reset();
654 }
2d90e8b6 655}
1b8522d6 656
7d57ae2f
KS
657impl NAOptionHandler for TM1Decoder {
658 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
659 fn set_options(&mut self, _options: &[NAOption]) { }
660 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
661}
662
08a1fab7 663pub fn get_decoder() -> Box<dyn NADecoder + Send> {
2d90e8b6 664 Box::new(TM1Decoder::new())
1b8522d6
KS
665}
666
2d90e8b6
KS
667#[cfg(test)]
668mod test {
669 use nihav_core::codecs::RegisteredDecoders;
670 use nihav_core::demuxers::RegisteredDemuxers;
ce742854 671 use nihav_codec_support::test::dec_video::*;
78fb6560 672 use crate::duck_register_all_decoders;
e64739f8 673 use nihav_commonfmt::generic_register_all_demuxers;
2d90e8b6
KS
674 #[test]
675 fn test_tm1() {
676 let mut dmx_reg = RegisteredDemuxers::new();
677 generic_register_all_demuxers(&mut dmx_reg);
678 let mut dec_reg = RegisteredDecoders::new();
78fb6560 679 duck_register_all_decoders(&mut dec_reg);
2d90e8b6 680
886cde48 681 // sample: https://samples.mplayerhq.hu/V-codecs/DUCK/phant2-940.duk
16b13997
KS
682 test_decoding("avi", "truemotion1", "assets/Duck/phant2-940.duk", Some(12), &dmx_reg, &dec_reg,
683 ExpectedTestResult::MD5Frames(vec![
684 [0x989e62b8, 0x5d85c23c, 0x1cffba6d, 0xe599f1c4],
685 [0xc4231321, 0x25561487, 0x9db11f57, 0x4faeb9a5],
686 [0x36e3a831, 0xdbd21f89, 0x0a446071, 0xf6d31ee7],
687 [0x0af640af, 0x64bc2bac, 0x0e95dd72, 0x9e55360b],
688 [0xbc9c5f8b, 0x6c06f2bc, 0x216f4129, 0x3a421337],
689 [0xd8ea7297, 0xce5f79fc, 0x46071f4c, 0xaed7fb7a],
690 [0x87617060, 0x72ce8df8, 0xde42eaa6, 0x804a6f45],
691 [0xfd8c45b3, 0xf424b683, 0xb4d6a9bd, 0xc622d0b9],
692 [0x6c233746, 0xba8ed68e, 0xc0ed0e85, 0xc99e1dc0],
693 [0x5842aac0, 0xd3d78242, 0x5da21218, 0xea1ed0ad],
694 [0xdea0db20, 0xe2ce3586, 0xf7386649, 0xecc374f9],
695 [0xb80ae9cb, 0x04eb938e, 0xd8a337ee, 0x0054b5ed],
696 [0xf8b80e1d, 0xd8eb3d6c, 0xa99b23ff, 0x562851a1]]));
697 test_decoding("avi", "truemotion1", "assets/Duck/SPRITES.AVI", Some(2), &dmx_reg, &dec_reg,
698 ExpectedTestResult::MD5([0xb89a4275, 0xf9797f5f, 0xe53c1ccd, 0xfa163e02]));
2d90e8b6 699 //let file = "assets/Duck/AVI-DUCK-dk3.duk";
16b13997 700 //let file = "assets/Duck/phant2-940.duk";
2d90e8b6
KS
701 //let file = "assets/Duck/bugsampler-m01-16bit.avi";
702 //let file = "assets/Duck/sonic3dblast_intro.avi";
703 //let file = "assets/Duck/BUTTONS.AVI";
704 //let file = "assets/Duck/SPRITES.AVI";
705 //let file = "assets/Duck/TRICORD.AVI";
16b13997 706 //test_file_decoding("avi", file, Some(42), true, false, None/*Some("tm1-")*/, &dmx_reg, &dec_reg);
2d90e8b6
KS
707 }
708}
709
710#[derive(Clone,Copy)]
711struct TM1ComprInfo {
712 is_24bit: bool,
713 block_w: usize,
714 block_h: usize,
715}
716
717const TM1_COMPR_TYPES: [Option<TM1ComprInfo>; 17] = [
718 None,
719 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 4 }),
720 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 4 }),
721 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 2 }),
722 Some(TM1ComprInfo { is_24bit: false, block_w: 4, block_h: 2 }),
723 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 4 }),
724 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 4 }),
725 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 2 }),
726 Some(TM1ComprInfo { is_24bit: false, block_w: 2, block_h: 2 }),
727 None,
728 Some(TM1ComprInfo { is_24bit: true, block_w: 4, block_h: 4 }),
729 None,
730 Some(TM1ComprInfo { is_24bit: true, block_w: 4, block_h: 2 }),
731 None,
732 Some(TM1ComprInfo { is_24bit: true, block_w: 2, block_h: 4 }),
733 None,
734 Some(TM1ComprInfo { is_24bit: true, block_w: 2, block_h: 2 }),
735];
736
737const DUCK_Y_DELTAS: [[i32; 8]; 4] = [
738 [ 0, -1, 1, -3, 3, -6, 6, -6 ],
739 [ 0, -1, 2, -3, 4, -6, 6, -6 ],
740 [ 2, -3, 10, -10, 23, -23, 47, -47 ],
741 [ 0, -2, 2, -8, 8, -18, 18, -40 ]
742];
743const DUCK_Y_FAT_DELTA3: [i32; 8] = [ 0, -15, 50, -50, 115, -115, 235, -235 ];
744const DUCK_Y_FAT_DELTA4: [i32; 8] = [ 0, 40, 80, -76, 160, -154, 236, -236 ];
745const DUCK_Y_FAT_DELTAS: [&[i32]; 4] = [
746 &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA3, &DUCK_Y_FAT_DELTA4
747];
748
749const DUCK_C_DELTAS: [[i32; 8]; 4] = [
750 [ 0, -1, 1, -2, 3, -4, 5, -4 ],
751 [ 0, -1, 1, -2, 3, -4, 5, -4 ],
752 [ 0, -4, 3, -16, 20, -32, 36, -32 ],
753 [ 0, -2, 2, -8, 8, -18, 18, -40 ]
754];
755const DUCK_C_FAT_DELTA3: [i32; 8] = [ 0, -20, 15, -80, 100, -160, 180, -160 ];
756const DUCK_C_FAT_DELTAS: [&[i32]; 4] = [
757 &DUCK_C_FAT_DELTA3, &DUCK_C_FAT_DELTA3, &DUCK_C_FAT_DELTA3, &DUCK_Y_FAT_DELTA4
758];
759
760const DUCK_VECTBL2: &[u8] = &[
7610x8,0x00,0x00,0x00,0x00,
7620x8,0x00,0x00,0x00,0x00,
7630x8,0x10,0x00,0x00,0x00,
7640x8,0x01,0x00,0x00,0x00,
7650x8,0x00,0x10,0x00,0x00,
7660x8,0x00,0x01,0x00,0x00,
7670x8,0x00,0x00,0x10,0x00,
7680x8,0x00,0x00,0x01,0x00,
7690x8,0x00,0x00,0x00,0x10,
7700x8,0x00,0x00,0x00,0x01,
7710x6,0x00,0x00,0x00,
7720x6,0x10,0x00,0x00,
7730x6,0x01,0x00,0x00,
7740x6,0x00,0x10,0x00,
7750x6,0x00,0x01,0x00,
7760x6,0x00,0x00,0x01,
7770x6,0x00,0x00,0x10,
7780x6,0x00,0x00,0x02,
7790x6,0x00,0x00,0x20,
7800x6,0x20,0x10,0x00,
7810x6,0x00,0x02,0x01,
7820x6,0x00,0x20,0x10,
7830x6,0x02,0x01,0x00,
7840x6,0x11,0x00,0x00,
7850x6,0x00,0x20,0x00,
7860x6,0x00,0x02,0x00,
7870x6,0x20,0x00,0x00,
7880x6,0x01,0x10,0x00,
7890x6,0x02,0x00,0x00,
7900x6,0x01,0x00,0x02,
7910x6,0x10,0x00,0x20,
7920x6,0x00,0x01,0x02,
7930x6,0x10,0x01,0x00,
7940x6,0x00,0x10,0x20,
7950x6,0x10,0x10,0x00,
7960x6,0x10,0x00,0x01,
7970x6,0x20,0x00,0x10,
7980x6,0x02,0x00,0x01,
7990x6,0x01,0x01,0x00,
8000x6,0x01,0x00,0x10,
8010x6,0x00,0x11,0x00,
8020x6,0x10,0x00,0x02,
8030x6,0x00,0x01,0x10,
8040x6,0x00,0x00,0x11,
8050x6,0x10,0x00,0x10,
8060x6,0x01,0x00,0x01,
8070x6,0x00,0x00,0x22,
8080x6,0x02,0x01,0x01,
8090x6,0x10,0x20,0x10,
8100x6,0x01,0x02,0x01,
8110x6,0x20,0x10,0x10,
8120x6,0x01,0x00,0x20,
8130x6,0x00,0x10,0x01,
8140x6,0x21,0x10,0x00,
8150x6,0x10,0x02,0x01,
8160x6,0x12,0x01,0x00,
8170x6,0x01,0x20,0x10,
8180x6,0x01,0x02,0x00,
8190x6,0x10,0x20,0x00,
8200x6,0x00,0x10,0x02,
8210x6,0x00,0x01,0x20,
8220x6,0x00,0x02,0x21,
8230x6,0x00,0x02,0x20,
8240x6,0x00,0x00,0x12,
8250x6,0x00,0x00,0x21,
8260x6,0x20,0x11,0x00,
8270x6,0x00,0x01,0x01,
8280x6,0x11,0x10,0x00,
8290x6,0x00,0x20,0x12,
8300x6,0x00,0x20,0x11,
8310x6,0x20,0x10,0x02,
8320x6,0x02,0x01,0x20,
8330x6,0x00,0x22,0x11,
8340x6,0x00,0x10,0x10,
8350x6,0x02,0x11,0x00,
8360x6,0x00,0x21,0x10,
8370x6,0x00,0x02,0x03,
8380x6,0x20,0x10,0x01,
8390x6,0x00,0x12,0x01,
8400x4,0x11,0x00,
8410x4,0x00,0x22,
8420x4,0x20,0x00,
8430x4,0x01,0x10,
8440x4,0x02,0x20,
8450x4,0x00,0x20,
8460x4,0x02,0x00,
8470x4,0x10,0x01,
8480x4,0x00,0x11,
8490x4,0x02,0x01,
8500x4,0x02,0x21,
8510x4,0x00,0x02,
8520x4,0x20,0x02,
8530x4,0x01,0x01,
8540x4,0x10,0x10,
8550x4,0x10,0x02,
8560x4,0x22,0x00,
8570x4,0x10,0x00,
8580x4,0x01,0x00,
8590x4,0x21,0x00,
8600x4,0x12,0x00,
8610x4,0x00,0x10,
8620x4,0x20,0x12,
8630x4,0x01,0x11,
8640x4,0x00,0x01,
8650x4,0x01,0x02,
8660x4,0x11,0x02,
8670x4,0x11,0x01,
8680x4,0x10,0x20,
8690x4,0x20,0x01,
8700x4,0x22,0x11,
8710x4,0x00,0x12,
8720x4,0x20,0x10,
8730x4,0x22,0x01,
8740x4,0x01,0x20,
8750x4,0x00,0x21,
8760x4,0x10,0x11,
8770x4,0x21,0x10,
8780x4,0x10,0x22,
8790x4,0x02,0x03,
8800x4,0x12,0x01,
8810x4,0x20,0x11,
8820x4,0x11,0x10,
8830x4,0x20,0x30,
8840x4,0x11,0x20,
8850x4,0x02,0x10,
8860x4,0x22,0x10,
8870x4,0x11,0x11,
8880x4,0x30,0x20,
8890x4,0x30,0x00,
8900x4,0x01,0x22,
8910x4,0x01,0x12,
8920x4,0x02,0x11,
8930x4,0x03,0x02,
8940x4,0x03,0x00,
8950x4,0x10,0x21,
8960x4,0x12,0x20,
8970x4,0x00,0x00,
8980x4,0x12,0x21,
8990x4,0x21,0x11,
9000x4,0x02,0x22,
9010x4,0x10,0x12,
9020x4,0x31,0x00,
9030x4,0x20,0x20,
9040x4,0x00,0x03,
9050x4,0x02,0x02,
9060x4,0x22,0x20,
9070x4,0x01,0x21,
9080x4,0x21,0x02,
9090x4,0x21,0x12,
9100x4,0x11,0x22,
9110x4,0x00,0x30,
9120x4,0x12,0x11,
9130x4,0x20,0x22,
9140x4,0x31,0x20,
9150x4,0x21,0x30,
9160x4,0x22,0x02,
9170x4,0x22,0x22,
9180x4,0x20,0x31,
9190x4,0x13,0x02,
9200x4,0x03,0x10,
9210x4,0x11,0x12,
9220x4,0x00,0x13,
9230x4,0x21,0x01,
9240x4,0x12,0x03,
9250x4,0x13,0x00,
9260x4,0x13,0x10,
9270x4,0x02,0x13,
9280x4,0x30,0x01,
9290x4,0x12,0x10,
9300x4,0x22,0x13,
9310x4,0x03,0x12,
9320x4,0x31,0x01,
9330x4,0x30,0x22,
9340x4,0x00,0x31,
9350x4,0x01,0x31,
9360x4,0x02,0x23,
9370x4,0x01,0x30,
9380x4,0x11,0x21,
9390x4,0x22,0x21,
9400x4,0x01,0x13,
9410x4,0x10,0x03,
9420x4,0x22,0x03,
9430x4,0x30,0x21,
9440x4,0x21,0x31,
9450x4,0x33,0x00,
9460x4,0x13,0x12,
9470x4,0x11,0x31,
9480x4,0x30,0x02,
9490x4,0x12,0x02,
9500x4,0x11,0x13,
9510x4,0x12,0x22,
9520x4,0x20,0x32,
9530x4,0x10,0x13,
9540x4,0x22,0x31,
9550x4,0x21,0x20,
9560x4,0x01,0x33,
9570x4,0x33,0x10,
9580x4,0x20,0x13,
9590x4,0x31,0x22,
9600x4,0x13,0x30,
9610x4,0x01,0x03,
9620x4,0x11,0x33,
9630x4,0x20,0x21,
9640x4,0x13,0x31,
9650x4,0x03,0x22,
9660x4,0x31,0x02,
9670x4,0x00,0x24,
9680x2,0x00,
9690x2,0x10,
9700x2,0x20,
9710x2,0x30,
9720x2,0x40,
9730x2,0x50,
9740x2,0x60,
9750x2,0x01,
9760x2,0x11,
9770x2,0x21,
9780x2,0x31,
9790x2,0x41,
9800x2,0x51,
9810x2,0x61,
9820x2,0x02,
9830x2,0x12,
9840x2,0x22,
9850x2,0x32,
9860x2,0x42,
9870x2,0x52,
9880x2,0x62,
9890x2,0x03,
9900x2,0x13,
9910x2,0x23,
9920x2,0x33,
9930x2,0x43,
9940x2,0x53,
9950x2,0x63,
9960x2,0x04,
9970x2,0x14,
9980x2,0x24,
9990x2,0x34,
10000x2,0x44,
10010x2,0x54,
10020x2,0x64,
10030x2,0x05,
10040x2,0x15,
10050x2,0x25,
10060x2,0x35,
10070x2,0x45,
10080x2,0x55,
10090x2,0x65,
10100x2,0x06,
10110x2,0x16,
10120x2,0x26,
10130x2,0x36,
10140x2,0x46,
10150x2,0x56,
10160x2,0x66
1017];
1018
1019const DUCK_VECTBL3: &[u8] = &[
10200x6,0x00,0x00,0x00,
10210x6,0x00,0x00,0x00,
10220x6,0x00,0x00,0x01,
10230x6,0x00,0x00,0x10,
10240x6,0x00,0x00,0x11,
10250x6,0x00,0x01,0x00,
10260x6,0x00,0x01,0x01,
10270x6,0x00,0x01,0x10,
10280x6,0x00,0x01,0x11,
10290x6,0x00,0x10,0x00,
10300x6,0x00,0x10,0x01,
10310x6,0x00,0x10,0x10,
10320x6,0x00,0x10,0x11,
10330x6,0x00,0x11,0x00,
10340x6,0x00,0x11,0x01,
10350x6,0x00,0x11,0x10,
10360x6,0x00,0x11,0x11,
10370x6,0x01,0x00,0x00,
10380x6,0x01,0x00,0x01,
10390x6,0x01,0x00,0x10,
10400x6,0x01,0x00,0x11,
10410x6,0x01,0x01,0x00,
10420x6,0x01,0x01,0x01,
10430x6,0x01,0x01,0x10,
10440x6,0x01,0x01,0x11,
10450x6,0x01,0x10,0x00,
10460x6,0x01,0x10,0x01,
10470x6,0x01,0x10,0x10,
10480x6,0x01,0x10,0x11,
10490x6,0x01,0x11,0x00,
10500x6,0x01,0x11,0x01,
10510x6,0x01,0x11,0x10,
10520x6,0x01,0x11,0x11,
10530x6,0x10,0x00,0x00,
10540x6,0x10,0x00,0x01,
10550x6,0x10,0x00,0x10,
10560x6,0x10,0x00,0x11,
10570x6,0x10,0x01,0x00,
10580x6,0x10,0x01,0x01,
10590x6,0x10,0x01,0x10,
10600x6,0x10,0x01,0x11,
10610x6,0x10,0x10,0x00,
10620x6,0x10,0x10,0x01,
10630x6,0x10,0x10,0x10,
10640x6,0x10,0x10,0x11,
10650x6,0x10,0x11,0x00,
10660x6,0x10,0x11,0x01,
10670x6,0x10,0x11,0x10,
10680x6,0x10,0x11,0x11,
10690x6,0x11,0x00,0x00,
10700x6,0x11,0x00,0x01,
10710x6,0x11,0x00,0x10,
10720x6,0x11,0x00,0x11,
10730x6,0x11,0x01,0x00,
10740x6,0x11,0x01,0x01,
10750x6,0x11,0x01,0x10,
10760x6,0x11,0x01,0x11,
10770x6,0x11,0x10,0x00,
10780x6,0x11,0x10,0x01,
10790x6,0x11,0x10,0x10,
10800x6,0x11,0x10,0x11,
10810x6,0x11,0x11,0x00,
10820x6,0x11,0x11,0x01,
10830x6,0x11,0x11,0x10,
10840x4,0x00,0x00,
10850x4,0x00,0x01,
10860x4,0x00,0x02,
10870x4,0x00,0x03,
10880x4,0x00,0x10,
10890x4,0x00,0x11,
10900x4,0x00,0x12,
10910x4,0x00,0x13,
10920x4,0x00,0x20,
10930x4,0x00,0x21,
10940x4,0x00,0x22,
10950x4,0x00,0x23,
10960x4,0x00,0x30,
10970x4,0x00,0x31,
10980x4,0x00,0x32,
10990x4,0x00,0x33,
11000x4,0x01,0x00,
11010x4,0x01,0x01,
11020x4,0x01,0x02,
11030x4,0x01,0x03,
11040x4,0x01,0x10,
11050x4,0x01,0x11,
11060x4,0x01,0x12,
11070x4,0x01,0x13,
11080x4,0x01,0x20,
11090x4,0x01,0x21,
11100x4,0x01,0x22,
11110x4,0x01,0x23,
11120x4,0x01,0x30,
11130x4,0x01,0x31,
11140x4,0x01,0x32,
11150x4,0x01,0x33,
11160x4,0x02,0x00,
11170x4,0x02,0x01,
11180x4,0x02,0x02,
11190x4,0x02,0x03,
11200x4,0x02,0x10,
11210x4,0x02,0x11,
11220x4,0x02,0x12,
11230x4,0x02,0x13,
11240x4,0x02,0x20,
11250x4,0x02,0x21,
11260x4,0x02,0x22,
11270x4,0x02,0x23,
11280x4,0x02,0x30,
11290x4,0x02,0x31,
11300x4,0x02,0x32,
11310x4,0x02,0x33,
11320x4,0x03,0x00,
11330x4,0x03,0x01,
11340x4,0x03,0x02,
11350x4,0x03,0x03,
11360x4,0x03,0x10,
11370x4,0x03,0x11,
11380x4,0x03,0x12,
11390x4,0x03,0x13,
11400x4,0x03,0x20,
11410x4,0x03,0x21,
11420x4,0x03,0x22,
11430x4,0x03,0x23,
11440x4,0x03,0x30,
11450x4,0x03,0x31,
11460x4,0x03,0x32,
11470x4,0x03,0x33,
11480x4,0x10,0x00,
11490x4,0x10,0x01,
11500x4,0x10,0x02,
11510x4,0x10,0x03,
11520x4,0x10,0x10,
11530x4,0x10,0x11,
11540x4,0x10,0x12,
11550x4,0x10,0x13,
11560x4,0x10,0x20,
11570x4,0x10,0x21,
11580x4,0x10,0x22,
11590x4,0x10,0x23,
11600x4,0x10,0x30,
11610x4,0x10,0x31,
11620x4,0x10,0x32,
11630x4,0x10,0x33,
11640x4,0x11,0x00,
11650x4,0x11,0x01,
11660x4,0x11,0x02,
11670x4,0x11,0x03,
11680x4,0x11,0x10,
11690x4,0x11,0x11,
11700x4,0x11,0x12,
11710x4,0x11,0x13,
11720x4,0x11,0x20,
11730x4,0x11,0x21,
11740x4,0x11,0x22,
11750x4,0x11,0x23,
11760x4,0x11,0x30,
11770x4,0x11,0x31,
11780x4,0x11,0x32,
11790x4,0x11,0x33,
11800x4,0x12,0x00,
11810x4,0x12,0x01,
11820x4,0x12,0x02,
11830x4,0x12,0x03,
11840x4,0x12,0x10,
11850x4,0x12,0x11,
11860x4,0x12,0x12,
11870x4,0x12,0x13,
11880x4,0x12,0x20,
11890x4,0x12,0x21,
11900x4,0x12,0x22,
11910x4,0x12,0x23,
11920x4,0x12,0x30,
11930x4,0x12,0x31,
11940x4,0x12,0x32,
11950x4,0x12,0x33,
11960x4,0x13,0x00,
11970x4,0x13,0x01,
11980x4,0x13,0x02,
11990x4,0x13,0x03,
12000x4,0x13,0x10,
12010x4,0x13,0x11,
12020x4,0x13,0x12,
12030x4,0x13,0x13,
12040x4,0x13,0x20,
12050x4,0x13,0x21,
12060x4,0x13,0x22,
12070x4,0x13,0x23,
12080x4,0x13,0x30,
12090x4,0x13,0x31,
12100x4,0x13,0x32,
12110x4,0x13,0x33,
12120x2,0x00,
12130x2,0x10,
12140x2,0x20,
12150x2,0x30,
12160x2,0x40,
12170x2,0x50,
12180x2,0x60,
12190x2,0x70,
12200x2,0x01,
12210x2,0x11,
12220x2,0x21,
12230x2,0x31,
12240x2,0x41,
12250x2,0x51,
12260x2,0x61,
12270x2,0x71,
12280x2,0x02,
12290x2,0x12,
12300x2,0x22,
12310x2,0x32,
12320x2,0x42,
12330x2,0x52,
12340x2,0x62,
12350x2,0x72,
12360x2,0x03,
12370x2,0x13,
12380x2,0x23,
12390x2,0x33,
12400x2,0x43,
12410x2,0x53,
12420x2,0x63,
12430x2,0x73,
12440x2,0x04,
12450x2,0x14,
12460x2,0x24,
12470x2,0x34,
12480x2,0x44,
12490x2,0x54,
12500x2,0x64,
12510x2,0x74,
12520x2,0x05,
12530x2,0x15,
12540x2,0x25,
12550x2,0x35,
12560x2,0x45,
12570x2,0x55,
12580x2,0x65,
12590x2,0x75,
12600x2,0x06,
12610x2,0x16,
12620x2,0x26,
12630x2,0x36,
12640x2,0x46,
12650x2,0x56,
12660x2,0x66,
12670x2,0x76,
12680x2,0x07,
12690x2,0x17,
12700x2,0x27,
12710x2,0x37,
12720x2,0x47,
12730x2,0x57,
12740x2,0x67,
12750x2,0x77
1276];
1277
1278const DUCK_VECTBL4: &[u8] = &[
12790x8,0x00,0x00,0x00,0x00,
12800x8,0x00,0x00,0x00,0x00,
12810x8,0x20,0x00,0x00,0x00,
12820x8,0x00,0x00,0x00,0x01,
12830x8,0x10,0x00,0x00,0x00,
12840x8,0x00,0x00,0x00,0x02,
12850x8,0x01,0x00,0x00,0x00,
12860x8,0x00,0x00,0x00,0x10,
12870x8,0x02,0x00,0x00,0x00,
12880x6,0x00,0x00,0x00,
12890x6,0x20,0x00,0x00,
12900x6,0x00,0x00,0x01,
12910x6,0x10,0x00,0x00,
12920x6,0x00,0x00,0x02,
12930x6,0x00,0x10,0x00,
12940x6,0x00,0x20,0x00,
12950x6,0x00,0x02,0x00,
12960x6,0x00,0x01,0x00,
12970x6,0x01,0x00,0x00,
12980x6,0x00,0x00,0x20,
12990x6,0x02,0x00,0x00,
13000x6,0x00,0x00,0x10,
13010x6,0x10,0x00,0x20,
13020x6,0x01,0x00,0x02,
13030x6,0x20,0x00,0x10,
13040x6,0x02,0x00,0x01,
13050x6,0x20,0x10,0x00,
13060x6,0x00,0x12,0x00,
13070x6,0x00,0x02,0x01,
13080x6,0x02,0x01,0x00,
13090x6,0x00,0x21,0x00,
13100x6,0x00,0x01,0x02,
13110x6,0x00,0x20,0x10,
13120x6,0x00,0x00,0x21,
13130x6,0x00,0x00,0x12,
13140x6,0x00,0x01,0x20,
13150x6,0x12,0x00,0x00,
13160x6,0x00,0x10,0x20,
13170x6,0x01,0x20,0x00,
13180x6,0x02,0x10,0x00,
13190x6,0x10,0x20,0x00,
13200x6,0x01,0x02,0x00,
13210x6,0x21,0x00,0x00,
13220x6,0x00,0x02,0x10,
13230x6,0x20,0x01,0x00,
13240x6,0x00,0x22,0x00,
13250x6,0x10,0x02,0x00,
13260x6,0x00,0x10,0x02,
13270x6,0x11,0x00,0x00,
13280x6,0x00,0x11,0x00,
13290x6,0x22,0x00,0x00,
13300x6,0x20,0x00,0x02,
13310x6,0x10,0x00,0x01,
13320x6,0x00,0x20,0x01,
13330x6,0x02,0x20,0x00,
13340x6,0x01,0x10,0x00,
13350x6,0x01,0x00,0x20,
13360x6,0x00,0x20,0x02,
13370x6,0x01,0x20,0x02,
13380x6,0x10,0x01,0x00,
13390x6,0x02,0x00,0x10,
13400x6,0x00,0x10,0x01,
13410x6,0x10,0x01,0x20,
13420x6,0x20,0x02,0x10,
13430x6,0x00,0x00,0x22,
13440x6,0x10,0x00,0x02,
13450x6,0x00,0x02,0x20,
13460x6,0x20,0x02,0x00,
13470x6,0x00,0x00,0x11,
13480x6,0x02,0x10,0x01,
13490x6,0x00,0x01,0x10,
13500x6,0x00,0x02,0x11,
13510x4,0x01,0x02,
13520x4,0x02,0x01,
13530x4,0x01,0x00,
13540x4,0x10,0x20,
13550x4,0x20,0x10,
13560x4,0x20,0x00,
13570x4,0x11,0x00,
13580x4,0x02,0x00,
13590x4,0x12,0x00,
13600x4,0x00,0x21,
13610x4,0x22,0x00,
13620x4,0x00,0x12,
13630x4,0x21,0x00,
13640x4,0x02,0x11,
13650x4,0x00,0x01,
13660x4,0x10,0x02,
13670x4,0x02,0x20,
13680x4,0x20,0x11,
13690x4,0x01,0x10,
13700x4,0x21,0x10,
13710x4,0x10,0x00,
13720x4,0x10,0x22,
13730x4,0x20,0x20,
13740x4,0x00,0x22,
13750x4,0x01,0x22,
13760x4,0x20,0x01,
13770x4,0x02,0x02,
13780x4,0x00,0x20,
13790x4,0x00,0x10,
13800x4,0x00,0x11,
13810x4,0x22,0x01,
13820x4,0x11,0x20,
13830x4,0x12,0x01,
13840x4,0x12,0x20,
13850x4,0x11,0x02,
13860x4,0x10,0x10,
13870x4,0x01,0x01,
13880x4,0x02,0x21,
13890x4,0x20,0x12,
13900x4,0x01,0x12,
13910x4,0x22,0x11,
13920x4,0x21,0x12,
13930x4,0x22,0x10,
13940x4,0x21,0x02,
13950x4,0x20,0x02,
13960x4,0x10,0x01,
13970x4,0x00,0x02,
13980x4,0x10,0x21,
13990x4,0x01,0x20,
14000x4,0x11,0x22,
14010x4,0x12,0x21,
14020x4,0x22,0x20,
14030x4,0x02,0x10,
14040x4,0x02,0x22,
14050x4,0x11,0x10,
14060x4,0x22,0x02,
14070x4,0x20,0x21,
14080x4,0x01,0x11,
14090x4,0x11,0x01,
14100x4,0x10,0x12,
14110x4,0x02,0x12,
14120x4,0x20,0x22,
14130x4,0x21,0x20,
14140x4,0x01,0x21,
14150x4,0x12,0x02,
14160x4,0x21,0x11,
14170x4,0x12,0x22,
14180x4,0x12,0x10,
14190x4,0x22,0x21,
14200x4,0x10,0x11,
14210x4,0x21,0x01,
14220x4,0x11,0x12,
14230x4,0x12,0x11,
14240x4,0x66,0x66,
14250x4,0x22,0x22,
14260x4,0x11,0x21,
14270x4,0x11,0x11,
14280x4,0x21,0x22,
14290x4,0x00,0x00,
14300x4,0x22,0x12,
14310x4,0x12,0x12,
14320x4,0x21,0x21,
14330x4,0x42,0x00,
14340x4,0x00,0x04,
14350x4,0x40,0x00,
14360x4,0x30,0x00,
14370x4,0x31,0x00,
14380x4,0x00,0x03,
14390x4,0x00,0x14,
14400x4,0x00,0x13,
14410x4,0x01,0x24,
14420x4,0x20,0x13,
14430x4,0x01,0x42,
14440x4,0x14,0x20,
14450x4,0x42,0x02,
14460x4,0x13,0x00,
14470x4,0x00,0x24,
14480x4,0x31,0x20,
14490x4,0x22,0x13,
14500x4,0x11,0x24,
14510x4,0x12,0x66,
14520x4,0x30,0x01,
14530x4,0x02,0x13,
14540x4,0x12,0x42,
14550x4,0x40,0x10,
14560x4,0x40,0x02,
14570x4,0x01,0x04,
14580x4,0x24,0x00,
14590x4,0x42,0x10,
14600x4,0x21,0x13,
14610x4,0x13,0x12,
14620x4,0x31,0x21,
14630x4,0x21,0x24,
14640x4,0x00,0x40,
14650x4,0x10,0x24,
14660x4,0x10,0x42,
14670x4,0x32,0x01,
14680x4,0x11,0x42,
14690x4,0x20,0x31,
14700x4,0x12,0x40,
14710x2,0x00,
14720x2,0x10,
14730x2,0x20,
14740x2,0x30,
14750x2,0x40,
14760x2,0x50,
14770x2,0x60,
14780x2,0x70,
14790x2,0x01,
14800x2,0x11,
14810x2,0x21,
14820x2,0x31,
14830x2,0x41,
14840x2,0x51,
14850x2,0x61,
14860x2,0x71,
14870x2,0x02,
14880x2,0x12,
14890x2,0x22,
14900x2,0x32,
14910x2,0x42,
14920x2,0x52,
14930x2,0x62,
14940x2,0x72,
14950x2,0x03,
14960x2,0x13,
14970x2,0x23,
14980x2,0x33,
14990x2,0x43,
15000x2,0x53,
15010x2,0x63,
15020x2,0x73,
15030x2,0x04,
15040x2,0x14,
15050x2,0x24,
15060x2,0x34,
15070x2,0x44,
15080x2,0x54,
15090x2,0x64,
15100x2,0x74,
15110x2,0x05,
15120x2,0x15,
15130x2,0x25,
15140x2,0x35,
15150x2,0x45,
15160x2,0x55,
15170x2,0x65,
15180x2,0x75,
15190x2,0x06,
15200x2,0x16,
15210x2,0x26,
15220x2,0x36,
15230x2,0x46,
15240x2,0x56,
15250x2,0x66,
15260x2,0x76,
15270x2,0x07,
15280x2,0x17,
15290x2,0x27,
15300x2,0x37,
15310x2,0x47,
15320x2,0x57,
15330x2,0x67,
15340x2,0x77
1535];
1536
1537const DUCK_VECTABLES: [&[u8]; 3] = [ DUCK_VECTBL2, DUCK_VECTBL3, DUCK_VECTBL4 ];