1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
10 fn decrypt(&mut self, buf: &mut [u8]) {
12 for el in buf.iter_mut() {
13 *el ^= self.key[(pos & 3) as usize];
14 pos = pos.wrapping_add(1);
17 fn set_state(&mut self, mut key: u32) {
19 let bit31 = (key >> 31) & 1;
20 let bit21 = (key >> 21) & 1;
21 let bit01 = (key >> 1) & 1;
23 key = (key << 1) | (bit31 ^ bit21 ^ bit01 ^ nbit0);
26 self.key[i] = (key >> (8 * (i ^ 3))) as u8;
32 tabs: [[i16; 256]; 2],
33 codebook: [[u8; 8]; 256],
34 num_elems: [usize; 256],
41 fn reset(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
42 let b = br.read_byte()? as usize;
47 fn get_val(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
48 if self.vq_idx > self.codebook.len() { return Err(DecoderError::ShortData); }
49 let ret = self.codebook[self.vq_idx][self.vq_pos];
51 if self.vq_pos == self.num_elems[self.vq_idx] {
55 self.vq_idx = self.codebook.len() + 1;
60 fn get_int(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
61 let b = self.get_val(br)?;
62 if b > 0 { unimplemented!(); }
65 fn get_dy(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
66 let b = self.get_val(br)?;
67 Ok(self.tabs[1][b as usize])
69 fn get_dc(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
70 let b = self.get_val(br)?;
71 Ok(self.tabs[0][b as usize])
75 impl Default for Deltas {
76 fn default() -> Self {
79 codebook: [[0; 8]; 256],
88 #[derive(Clone,Copy, Default)]
96 const NUM_CPARAMS: usize = 25;
97 const CPARAM_NONE: u8 = 42;
98 const CPARAM_MISSING: u8 = 42 * 2;
100 macro_rules! apply_delta {
101 ($buf:expr, $off:expr, $stride:expr, $hpred: expr, $delta:expr) => {
102 $hpred = $hpred.wrapping_add($delta);
103 $buf[$off] = $buf[$off - $stride].wrapping_add($hpred);
106 macro_rules! copy_line {
107 ($buf:expr, $off:expr, $stride:expr) => {
109 $buf[$off + i] = $buf[$off + i - $stride];
116 info: Rc<NACodecInfo>,
122 blk_info: Vec<BlkInfo>,
124 cparams: [[u8; 8]; NUM_CPARAMS],
133 fn new() -> Self { Self::default() }
134 fn output_frame(&mut self, buf: &mut NAVideoBuffer<u8>) {
135 let fmt = buf.get_info().get_format();
136 let offs = [fmt.get_chromaton(0).unwrap().get_offset() as usize,
137 fmt.get_chromaton(1).unwrap().get_offset() as usize,
138 fmt.get_chromaton(2).unwrap().get_offset() as usize];
139 let stride = buf.get_stride(0);
140 let mut data = buf.get_data_mut();
141 let dst = data.as_mut_slice();
144 let mut ysrc = self.ystride;
145 let mut csrc = self.cstride;
146 for _y in 0..self.height {
147 let out = &mut dst[off..];
148 for (x, pic) in out.chunks_exact_mut(3).take(self.width).enumerate() {
149 let y = self.ydata[ysrc + x];
150 let u = self.udata[csrc + x] - 128;
151 let v = self.vdata[csrc + x] - 128;
152 pic[offs[0]] = (y + v).max(0).min(255) as u8;
153 pic[offs[1]] = y.max(0).min(255) as u8;
154 pic[offs[2]] = (y + u).max(0).min(255) as u8;
157 ysrc += self.ystride;
158 csrc += self.cstride;
161 fn parse_init(&mut self, version: u8) -> DecoderResult<()> {
162 self.version = version;
164 let mut mr = MemoryReader::new_read(&self.dec_buf);
165 let mut br = ByteReader::new(&mut mr);
167 let _smth = br.read_u32be()?;
169 let height = br.read_u16be()? as usize;
170 let width = br.read_u16be()? as usize;
171 validate!(width == self.width && height == self.height);
173 let _smth = br.read_u32be()?;
175 let _smth = br.read_byte()?;
176 let _nfuncs = br.read_byte()? as usize;
177 let _smth = br.read_u16be()? as usize;
178 let has_mv = br.read_byte()?;
183 let _flags = br.read_u16be()?;
184 let id_len = br.read_byte()? as usize;
185 br.read_skip(id_len)?;
186 let _smth1 = br.read_byte()?;
187 let len = br.read_byte()? as usize;
189 let _smth = br.read_u32be()?;
194 fn parse_tabs(&mut self) -> DecoderResult<()> {
195 let mut mr = MemoryReader::new_read(&self.dec_buf);
196 let mut br = ByteReader::new(&mut mr);
198 let idx = br.read_byte()? as usize;
199 validate!(idx < self.deltas.tabs.len());
200 let len = br.read_byte()? as usize;
201 validate!(((len * 2) as i64) == br.left());
203 self.deltas.tabs[idx][i] = br.read_u16be()? as i16;
208 fn parse_cb_desc(&mut self, version: u8) -> DecoderResult<()> {
209 let mut mr = MemoryReader::new_read(&self.dec_buf);
210 let mut br = ByteReader::new(&mut mr);
213 let _esc_val = br.read_byte()?;
214 let _tag = br.read_u16be()?;
216 let len = br.read_u16be()? as usize;
217 validate!(len + 3 == (br.left() as usize));
218 let num_entries = br.read_u16be()?;
219 validate!(num_entries == 256);
220 let max_elems = br.read_byte()?;
221 validate!(max_elems > 0 && max_elems <= 8);
223 while br.left() > 0 {
224 validate!(idx < self.deltas.codebook.len());
225 let num_elems = br.read_byte()? as usize;
226 validate!(num_elems <= 8);
227 self.deltas.num_elems[idx] = num_elems;
228 for i in 0..num_elems {
229 self.deltas.codebook[idx][i] = br.read_byte()?;
233 validate!(idx == 256);
234 self.deltas.num_vq = idx;
238 fn decode_frame(&mut self, src: &[u8]) -> DecoderResult<()> {
239 let mut mr = MemoryReader::new_read(src);
240 let mut br = ByteReader::new(&mut mr);
242 self.deltas.reset(&mut br)?;
243 let bw = self.width / 8;
244 let bh = self.height / 8;
245 let ntiles = (bw + self.tile_size - 1) / self.tile_size;
246 let mut ypos = self.ystride;
247 let mut cpos = self.cstride;
249 for tile in 0..ntiles {
250 let xpos = tile * self.tile_size;
251 let len = self.tile_size.min(bw - xpos);
252 for el in self.blk_info.iter_mut().take(len) {
253 let t1 = self.deltas.get_val(&mut br)?;
254 let t2 = self.deltas.get_val(&mut br)?;
255 if t2 > 1 { unimplemented!(); }
256 validate!((t1 as usize) < NUM_CPARAMS);
257 validate!(self.cparams[t1 as usize][0] != CPARAM_MISSING);
261 el.mv_x = self.deltas.get_int(&mut br)?;
262 el.mv_y = self.deltas.get_int(&mut br)?;
269 let mut ypred = 0i16;
270 let mut upred = 0i16;
271 let mut vpred = 0i16;
274 let op = self.cparams[self.blk_info[x].btype as usize][line];
275 let cur_yoff = ypos + bx * 8 + line * self.ystride;
276 let cur_coff = cpos + bx * 8 + line * self.cstride;
280 let delta = self.deltas.get_dy(&mut br)?;
281 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
283 copy_line!(self.udata, cur_coff, self.cstride);
284 copy_line!(self.vdata, cur_coff, self.cstride);
291 let delta = self.deltas.get_dy(&mut br)?;
292 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
294 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
297 copy_line!(self.udata, cur_coff, self.cstride);
298 copy_line!(self.vdata, cur_coff, self.cstride);
305 let delta = self.deltas.get_dy(&mut br)?;
306 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
308 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
311 copy_line!(self.udata, cur_coff, self.cstride);
312 copy_line!(self.vdata, cur_coff, self.cstride);
317 let delta = self.deltas.get_dy(&mut br)?;
318 apply_delta!(self.ydata, cur_yoff, self.ystride, ypred, delta);
320 self.ydata[cur_yoff + i] = self.ydata[cur_yoff];
322 copy_line!(self.udata, cur_coff, self.cstride);
323 copy_line!(self.vdata, cur_coff, self.cstride);
327 4 => { // c2y2c2y2|c2y2c2y2
328 for i in (0..8).step_by(2) {
329 let delta = self.deltas.get_dc(&mut br)?;
330 apply_delta!(self.udata, cur_coff + i + 0, self.cstride, upred, delta);
331 self.udata[cur_coff + i + 1] = self.udata[cur_coff + i];
332 let delta = self.deltas.get_dc(&mut br)?;
333 apply_delta!(self.vdata, cur_coff + i + 0, self.cstride, vpred, delta);
334 self.vdata[cur_coff + i + 1] = self.vdata[cur_coff + i];
335 let delta = self.deltas.get_dy(&mut br)?;
336 apply_delta!(self.ydata, cur_yoff + i + 0, self.ystride, ypred, delta);
337 let delta = self.deltas.get_dy(&mut br)?;
338 apply_delta!(self.ydata, cur_yoff + i + 1, self.ystride, ypred, delta);
344 let delta = self.deltas.get_dc(&mut br)?;
345 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
346 let delta = self.deltas.get_dc(&mut br)?;
347 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
348 let delta = self.deltas.get_dy(&mut br)?;
349 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
351 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
352 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
353 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
357 6 | 7 => unreachable!(),
361 let delta = self.deltas.get_dc(&mut br)?;
362 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
363 let delta = self.deltas.get_dc(&mut br)?;
364 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
366 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
367 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
369 let delta = self.deltas.get_dy(&mut br)?;
370 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
376 let delta = self.deltas.get_dc(&mut br)?;
377 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
378 let delta = self.deltas.get_dc(&mut br)?;
379 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
381 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
382 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
385 let delta = self.deltas.get_dy(&mut br)?;
386 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
388 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
395 let delta = self.deltas.get_dc(&mut br)?;
396 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
397 let delta = self.deltas.get_dc(&mut br)?;
398 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
399 let delta = self.deltas.get_dy(&mut br)?;
400 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
402 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
403 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
404 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
408 11 => unreachable!(),
412 let delta = self.deltas.get_dc(&mut br)?;
413 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
414 let delta = self.deltas.get_dc(&mut br)?;
415 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
417 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
418 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
420 let delta = self.deltas.get_dy(&mut br)?;
421 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
427 let delta = self.deltas.get_dc(&mut br)?;
428 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
429 let delta = self.deltas.get_dc(&mut br)?;
430 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
432 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
433 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
436 let delta = self.deltas.get_dy(&mut br)?;
437 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
439 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
446 let delta = self.deltas.get_dc(&mut br)?;
447 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
448 let delta = self.deltas.get_dc(&mut br)?;
449 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
451 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
452 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
455 let delta = self.deltas.get_dy(&mut br)?;
456 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
458 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
465 let delta = self.deltas.get_dc(&mut br)?;
466 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
467 let delta = self.deltas.get_dc(&mut br)?;
468 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
469 let delta = self.deltas.get_dy(&mut br)?;
470 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
472 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
473 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
474 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
479 copy_line!(self.ydata, cur_yoff, self.ystride);
480 copy_line!(self.udata, cur_coff, self.cstride);
481 copy_line!(self.vdata, cur_coff, self.cstride);
491 ypos += 8 * self.ystride;
492 cpos += 8 * self.cstride;
499 impl NADecoder for TM2XDecoder {
500 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
501 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
502 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, RGB24_FORMAT));
503 self.width = vinfo.get_width();
504 self.height = vinfo.get_height();
505 self.ystride = self.width;
506 self.cstride = self.width;
507 self.ydata.resize(self.ystride * (self.height + 1), 0x80);
508 self.udata.resize(self.cstride * (self.height + 1), 0x80);
509 self.vdata.resize(self.cstride * (self.height + 1), 0x80);
510 self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
513 Err(DecoderError::InvalidData)
516 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
517 let src = pkt.get_buffer();
518 validate!(src.len() > 8);
519 let mut mr = MemoryReader::new_read(&src);
520 let mut br = ByteReader::new(&mut mr);
521 let mut dec = Decryptor::default();
523 let mut initialised = false;
524 let mut got_key = false;
525 let mut data_size = 0;
526 self.cparams = [[CPARAM_MISSING; 8]; NUM_CPARAMS];
527 while br.left() >= 8 {
528 let magic = br.read_u24be()?;
529 let ctype = br.read_byte()?;
530 let size = br.read_u32be()? as usize;
531 validate!(magic == 0xA00001 && br.left() >= (size as i64));
533 validate!(size >= 4);
534 let key = br.read_u32be()?;
535 validate!((key as usize) == size - 4);
537 data_size = size - 4;
538 br.read_skip(size - 4)?;
542 self.dec_buf.resize(size, 0);
543 br.read_buf(&mut self.dec_buf)?;
545 dec.decrypt(&mut self.dec_buf);
548 0x08 | 0x0C | 0x10 | 0x11 | 0x15 | 0x16 => {
549 if ctype < 0x15 { // old versions are not encrypted, roll back and zero key
550 dec.decrypt(&mut self.dec_buf);
554 validate!(got_key && !initialised);
556 0x08 => self.parse_init(0)?,
557 0x0C => self.parse_init(1)?,
558 0x10 => self.parse_init(2)?,
559 0x11 => self.parse_init(3)?,
560 0x15 => self.parse_init(4)?,
561 0x16 => self.parse_init(5)?,
567 validate!(initialised);
568 validate!(self.dec_buf.len() == 3);
569 validate!(self.dec_buf[0] == 8);
570 validate!(self.dec_buf[1] > 0);
571 validate!(self.dec_buf[2] == 1);
572 self.tile_size = self.dec_buf[1] as usize;
573 self.blk_info.resize(self.tile_size, BlkInfo::default());
576 validate!(initialised);
577 validate!(self.dec_buf.len() == 4);
578 let idx = self.dec_buf[3] as usize;
579 validate!(idx < NUM_CPARAMS);
580 validate!(self.dec_buf[0] != 0);
581 validate!((self.dec_buf[0] as usize) < TM2X_CODING_PARAMS.len());
582 let tab = &TM2X_CODING_PARAMS[self.dec_buf[0] as usize];
583 let m0 = tab[0] as usize;
584 let m1 = tab[1] as usize;
585 let m2 = tab[2] as usize;
586 let m3 = tab[3] as usize;
587 let full_mode = (m2 * 4 + m0) as u8;
588 let lores_mode = m0 as u8;
590 if (i % m1) == 0 && (i % m3) == 0 {
591 self.cparams[idx][i] = full_mode;
592 } else if (i % m1) == 0 {
593 self.cparams[idx][i] = lores_mode;
595 self.cparams[idx][i] = CPARAM_NONE;
600 validate!(initialised);
604 validate!(initialised);
605 self.parse_cb_desc(0xA)?;
607 _ => { unimplemented!(); },
610 self.decode_frame(&src[12..][..data_size])?;
612 let myinfo = NAVideoInfo::new(self.width, self.height, false, RGB24_FORMAT);
613 let bufret = alloc_video_buffer(myinfo, 2);
614 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
615 let bufinfo = bufret.unwrap();
616 let mut buf = bufinfo.get_vbuf().unwrap();
619 self.output_frame(&mut buf);
621 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
622 frm.set_keyframe(is_intra);
623 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
624 Ok(Rc::new(RefCell::new(frm)))
628 pub fn get_decoder() -> Box<NADecoder> {
629 Box::new(TM2XDecoder::new())
634 use nihav_core::codecs::RegisteredDecoders;
635 use nihav_core::demuxers::RegisteredDemuxers;
636 use nihav_core::test::dec_video::*;
637 use crate::codecs::duck_register_all_codecs;
638 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
641 let mut dmx_reg = RegisteredDemuxers::new();
642 generic_register_all_demuxers(&mut dmx_reg);
643 let mut dec_reg = RegisteredDecoders::new();
644 duck_register_all_codecs(&mut dec_reg);
646 test_file_decoding("avi", "assets/Duck/TM2x.avi", Some(16), true, false, None/*Some("tm2x")*/, &dmx_reg, &dec_reg);
650 const TM2X_CODING_PARAMS: [[u8; 4]; 25] = [
651 [ 0, 0, 0, 0 ], [ 0, 1, 1, 1 ], [ 0, 1, 1, 2 ], [ 0, 1, 2, 4 ], [ 1, 1, 2, 4 ],
652 [ 0, 2, 2, 4 ], [ 1, 2, 2, 4 ], [ 2, 2, 2, 4 ], [ 1, 4, 2, 4 ], [ 2, 4, 2, 4 ],
653 [ 2, 8, 3, 8 ], [ 3, 4, 3, 8 ], [ 3, 8, 3, 8 ], [ 0, 1, 1, 4 ], [ 0, 1, 2, 2 ],
654 [ 0, 2, 1, 4 ], [ 1, 1, 2, 2 ], [ 1, 4, 2, 8 ], [ 2, 2, 3, 4 ], [ 2, 4, 3, 8 ],
655 [ 0, 1, 3, 8 ], [ 1, 2, 3, 8 ], [ 2, 4, 2, 4 ], [ 2, 4, 3, 8 ], [ 3, 8, 3, 8 ]