1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
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 }
17 fn get_next(&mut self) -> bool {
21 let res = (self.src[self.pos] & self.mask) == 0;
30 fn reset_row(&mut self) {
31 self.pos = self.row_pos;
34 fn next_row(&mut self) {
35 self.row_pos += self.row_size;
40 struct IndexState<'a> {
47 impl<'a> IndexState<'a> {
48 fn new(src: &'a [u8]) -> Self {
49 Self { src, pos: 0, vec_idx: 0, vec_subidx: 0 }
51 fn get_next(&mut self) -> DecoderResult<()> {
52 validate!(self.pos < self.src.len());
53 self.vec_idx = self.src[self.pos] as usize;
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;
64 if self.vec_idx == 0 {
66 let pred2 = self.get_pred(dtab);
67 pred = pred.wrapping_add((pred2 >> 1).wrapping_mul(5));
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;
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;
94 if self.vec_idx == 0 {
96 let pred2 = self.get_pred(esctab);
97 pred = pred.wrapping_add(pred2 >> 1);
101 self.vec_subidx += 1;
105 self.vec_subidx += 1;
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],
119 impl Default for DeltaTables {
120 fn default() -> Self {
124 fat_ydt: [[0; 4]; 256],
125 fat_cdt: [[0; 4]; 256],
132 last16: Option<NAVideoBufferRef<u16>>,
133 last24: Option<NAVideoBufferRef<u8>>,
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())
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())
157 fn reset(&mut self) {
163 impl Default for FrameBuf {
164 fn default() -> Self {
165 Self { last16: None, last24: None }
171 info: NACodecInfoRef,
172 last_delta_set: usize,
173 last_table_idx: usize,
174 delta_tables: DeltaTables,
181 const RGB555_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
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 }),
187 elem_size: 2, be: false, alpha: false, palette: false };
188 const BGR0_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
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 }),
194 elem_size: 4, be: false, alpha: false, palette: false };
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];
206 let mut vec_iter = vec.iter();
208 let len = (*vec_iter.next().unwrap() as usize) >> 1;
210 let pair = vec_iter.next().unwrap();
211 let lo = (pair >> 4) as usize;
212 let hi = (pair & 0xF) as usize;
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;
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;
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;
235 self.last_delta_set = delta_set;
236 self.last_table_idx = table_idx;
238 fn decode_16bit(&mut self, dst: &mut [u16], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
242 let mut hor_pred: u32 = 0;
243 for x in (0..width).step_by(4) {
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;
256 let dc1 = index.get_diff16(&self.delta_tables.cdt)?;
257 hor_pred = hor_pred.wrapping_add(dc1);
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;
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;
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;
291 let dc1 = index.get_diff16(&self.delta_tables.cdt)?;
292 hor_pred = hor_pred.wrapping_add(dc1);
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;
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;
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;
334 fn decode_sprite(&mut self, dst: &mut [u16], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
336 let _ = index.get_next();
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();
344 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
345 hor_pred = hor_pred.wrapping_add(dc0);
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 {
361 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
362 hor_pred = hor_pred.wrapping_add(dc0);
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;
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;
397 fn decode_24bit(&mut self, dst: &mut [u8], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
401 let mut hor_pred: u32 = 0;
402 for x in (0..width).step_by(2) {
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;
417 let dc1 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
418 hor_pred = hor_pred.wrapping_add(dc1);
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;
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;
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;
460 let dc1 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
461 hor_pred = hor_pred.wrapping_add(dc1);
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;
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;
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;
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();
524 Err(DecoderError::InvalidData)
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];
536 let mut mr = MemoryReader::new_read(&hdr[0..hdr_size-1]);
537 let mut br = ByteReader::new(&mut mr);
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);
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;
555 validate!(meta_type <= 3);
557 let frameinfo = br.read_byte()?;
558 let _control = br.read_byte()?;
560 is_intra = ((frameinfo & 0x10) != 0) || ((frameinfo & 0x08) == 0);
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;
574 validate!(tm1type < TM1_COMPR_TYPES.len());
575 let cinfo = TM1_COMPR_TYPES[tm1type];
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());
583 let compr_info = cinfo.unwrap();
584 let is_24bit = !is_sprite && compr_info.is_24bit;
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);
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
596 ((width >> 2) + 7) >> 3
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);
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();
611 self.lastframe.set16(bufinfo.get_vbuf16().unwrap());
613 self.lastframe.set24(bufinfo.get_vbuf().unwrap());
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);
623 if let Some(mut buf) = self.lastframe.get16() {
624 let stride = buf.get_stride(0);
626 let data = buf.get_data_mut().unwrap();
628 self.decode_16bit(data.as_mut_slice(), stride, out_width, height, &mut mask, &mut index)?;
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)?;
637 bufinfo = NABufferType::Video16(buf);
639 return Err(DecoderError::MissingReference);
641 } else if let Some(mut buf) = self.lastframe.get24() {
642 let stride = buf.get_stride(0);
644 let data = buf.get_data_mut().unwrap();
645 self.decode_24bit(data.as_mut_slice(), stride, out_width, height, &mut mask, &mut index)?;
647 bufinfo = NABufferType::VideoPacked(buf);
649 return Err(DecoderError::MissingReference);
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 });
657 fn flush(&mut self) {
658 self.lastframe.reset();
662 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
663 Box::new(TM1Decoder::new())
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;
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);
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);
708 #[derive(Clone,Copy)]
709 struct TM1ComprInfo {
715 const TM1_COMPR_TYPES: [Option<TM1ComprInfo>; 17] = [
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 }),
726 Some(TM1ComprInfo { is_24bit: true, block_w: 4, block_h: 4 }),
728 Some(TM1ComprInfo { is_24bit: true, block_w: 4, block_h: 2 }),
730 Some(TM1ComprInfo { is_24bit: true, block_w: 2, block_h: 4 }),
732 Some(TM1ComprInfo { is_24bit: true, block_w: 2, block_h: 2 }),
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 ]
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
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 ]
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
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,
1017 const DUCK_VECTBL3: &[u8] = &[
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,
1535 const DUCK_VECTABLES: [&[u8]; 3] = [ DUCK_VECTBL2, DUCK_VECTBL3, DUCK_VECTBL4 ];