1 use nihav_core::formats;
2 use nihav_core::codecs::*;
3 use nihav_core::io::byteio::*;
12 #[derive(Clone, Copy)]
27 const DEFAULT_PIXEL: u8 = 0x40;
30 fn new() -> Self { Buffers { width: 0, height: 0, cw: 0, ch: 0, sbuf: Vec::new(), dbuf: Vec::new() } }
34 self.sbuf.truncate(0);
35 self.dbuf.truncate(0);
37 fn alloc(&mut self, w: usize, h: usize) {
40 self.cw = ((w >> 2) + 3) & !3;
41 self.ch = ((h >> 2) + 3) & !3;
42 self.sbuf.resize(w * h + self.cw * self.ch * 2, DEFAULT_PIXEL);
43 self.dbuf.resize(w * h + self.cw * self.ch * 2, DEFAULT_PIXEL);
45 fn flip(&mut self) { std::mem::swap(&mut self.sbuf, &mut self.dbuf); }
46 fn get_stride(&mut self, planeno: usize) -> usize {
47 if planeno == 0 { self.width } else { self.cw }
49 fn get_offset(&mut self, planeno: usize) -> usize {
51 1 => self.width * self.height,
52 2 => self.width * self.height + self.cw * self.ch,
56 fn fill_framebuf(&mut self, fbuf: &mut NAVideoBuffer<u8>) {
58 let mut soff = self.get_offset(planeno);
59 let mut doff = fbuf.get_offset(planeno);
60 let sstride = self.get_stride(planeno);
61 let dstride = fbuf.get_stride(planeno);
62 let width = if planeno == 0 { self.width } else { self.width >> 2 };
63 let height = if planeno == 0 { self.height } else { self.height >> 2 };
64 let src = self.dbuf.as_slice();
65 let dst = fbuf.get_data_mut().unwrap();
68 dst[doff + x] = src[soff + x] * 2;
75 fn copy_block(&mut self, doff: usize, soff: usize, stride: usize, w: usize, h: usize) {
79 for i in 0..w { self.dbuf[didx + i] = self.sbuf[sidx + i]; }
84 fn fill_block(&mut self, doff: usize, stride: usize, w: usize, h: usize, topline: bool) {
86 let mut buf: [u8; 8] = [0; 8];
89 for i in 0..w { self.dbuf[didx + i] = DEFAULT_PIXEL; }
93 for i in 0..w { buf[i] = self.dbuf[didx - stride + i]; }
95 for i in 0..w { self.dbuf[didx + i] = buf[i]; }
102 #[allow(unused_variables)]
103 fn apply_delta4x4(bufs: &mut Buffers, off: usize, stride: usize,
104 deltas: &[u8], topline: bool, first_line: bool) {
105 let dst = &mut bufs.dbuf[off..][..4];
106 for i in 0..4 { dst[i] = dst[i].wrapping_add(deltas[i]) & 0x7F; }
109 #[allow(unused_variables)]
110 fn apply_delta4x8(bufs: &mut Buffers, off: usize, stride: usize,
111 deltas: &[u8], topline: bool, first_line: bool) {
112 let dst = &mut bufs.dbuf[off..][..stride + 4];
113 for i in 0..4 { dst[i + stride] = dst[i].wrapping_add(deltas[i]) & 0x7F; }
115 for i in 0..4 { dst[i] = (dst[i + stride] + dst[i]) >> 1; }
117 for i in 0..4 { dst[i] = dst[i + stride]; }
121 #[allow(unused_variables)]
122 fn apply_delta4x8m11(bufs: &mut Buffers, off: usize, stride: usize,
123 deltas: &[u8], topline: bool, first_line: bool) {
124 let dst = &mut bufs.dbuf[off..][..stride + 4];
125 for i in 0..4 { dst[i] = dst[i] .wrapping_add(deltas[i]) & 0x7F; }
126 for i in 0..4 { dst[i + stride] = dst[i + stride].wrapping_add(deltas[i]) & 0x7F; }
129 #[allow(unused_variables)]
130 fn apply_delta8x8p(bufs: &mut Buffers, off: usize, stride: usize,
131 deltas: &[u8], topline: bool, first_line: bool) {
132 let dst = &mut bufs.dbuf[off..][..stride + 8];
133 for i in 0..8 { dst[i] = dst[i] .wrapping_add(deltas[i >> 1]) & 0x7F; }
134 for i in 0..8 { dst[i + stride] = dst[i + stride].wrapping_add(deltas[i >> 1]) & 0x7F; }
137 fn apply_delta8x8i(bufs: &mut Buffers, off: usize, stride: usize,
138 deltas: &[u8], topline: bool, firstline: bool) {
139 let dst = &mut bufs.dbuf[off..][..stride + 8];
141 for i in 0..8 { dst[i + stride] = dst[i ].wrapping_add(deltas[i >> 1]) & 0x7F; }
143 for i in 0..8 { dst[i + stride] = dst[i & !1].wrapping_add(deltas[i >> 1]) & 0x7F; }
146 for i in 0..8 { dst[i] = (dst[i + stride] + dst[i]) >> 1; }
148 for i in 0..8 { dst[i] = dst[i + stride]; }
152 fn copy_line_top(bufs: &mut Buffers, off: usize, stride: usize, bw: usize, topline: bool) {
153 let mut buf: [u8; 8] = [0; 8];
155 let src = &bufs.dbuf[(off - stride)..(off - stride + bw)];
156 for i in 0..bw { buf[i] = src[i]; }
158 for i in 0..bw { buf[i] = DEFAULT_PIXEL; }
160 let dst = &mut bufs.dbuf[off..][..bw];
161 for i in 0..bw { dst[i] = buf[i]; }
164 fn copy_line_top4x4(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
165 copy_line_top(bufs, off, stride, 4, topline);
168 fn copy_line_top4x8(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
169 copy_line_top(bufs, off, stride, 4, topline);
170 copy_line_top(bufs, off + stride, stride, 4, false);
173 fn copy_line_top8x8(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
174 let mut buf: [u8; 8] = [0; 8];
176 let src = &bufs.dbuf[(off - stride)..(off - stride + 8)];
177 for i in 0..8 { buf[i] = src[i & !1]; }
179 for i in 0..8 { buf[i] = DEFAULT_PIXEL; }
181 let dst = &mut bufs.dbuf[off..][..8];
182 for i in 0..8 {dst[i] = buf[i]; }
185 fn fill_block8x8(bufs: &mut Buffers, doff: usize, stride: usize, h: usize, topline: bool, firstline: bool) {
187 let mut buf: [u8; 8] = [0; 8];
189 for i in 0..8 { buf[i] = DEFAULT_PIXEL; }
191 for i in 0..8 { buf[i] = bufs.dbuf[doff - stride + i]; }
193 if topline && !firstline {
194 for i in 0..4 { buf[i * 2 + 1] = buf[i * 2]; }
195 for i in 0..8 { bufs.dbuf[doff + i] = (bufs.dbuf[doff - stride + i] + buf[i]) >> 1; }
198 let start = if !topline { 0 } else { 1 };
203 for i in 0..8 { bufs.dbuf[didx + i] = buf[i]; }
208 struct Indeo3Decoder {
209 info: NACodecInfoRef,
218 requant_tab: [[u8; 128]; 8],
221 #[derive(Clone,Copy)]
233 fn new(w: u16, h: u16) -> Self {
234 IV3Cell { x: 0, y: 0, w, h, d: 20, vqt: false, mv: None }
236 fn split_h(&self) -> (Self, Self) {
237 let h1 = if self.h > 2 { ((self.h + 2) >> 2) << 1 } else { 1 };
238 let h2 = self.h - h1;
239 let mut cell1 = *self;
242 let mut cell2 = *self;
248 fn split_w(&self, stripw: u16) -> (Self, Self) {
249 let w1 = if self.w > stripw {
250 if self.w > stripw * 2 { stripw * 2 } else { stripw }
252 if self.w > 2 { ((self.w + 2) >> 2) << 1 } else { 1 }
254 let w2 = self.w - w1;
255 let mut cell1 = *self;
258 let mut cell2 = *self;
264 fn no_mv(&self) -> bool { self.mv.is_none() }
267 struct CellDecParams {
273 apply_delta: fn (&mut Buffers, usize, usize, &[u8], bool, bool),
274 copy_line_top: fn (&mut Buffers, usize, usize, bool),
277 const FRMH_TAG: u32 = ((b'F' as u32) << 24) | ((b'R' as u32) << 16)
278 | ((b'M' as u32) << 8) | (b'H' as u32);
280 const H_SPLIT: u8 = 0;
281 const V_SPLIT: u8 = 1;
282 const SKIP_OR_TREE: u8 = 2;
286 const REQUANT_OFF: [i32; 8] = [ 0, 1, 0, 4, 4, 1, 0, 1 ];
288 let dummy_info = NACodecInfo::new_dummy();
290 let mut requant_tab = [[0u8; 128]; 8];
292 let step = (i as i32) + 2;
293 let start = if (i == 3) || (i == 4) { -3 } else { step / 2 };
296 requant_tab[i][j] = (((j as i32) + start) / step * step + REQUANT_OFF[i]) as u8;
297 if requant_tab[i][j] < 128 {
298 last = requant_tab[i][j];
300 requant_tab[i][j] = last;
304 requant_tab[1][7] = 10;
305 requant_tab[1][119] = 118;
306 requant_tab[1][120] = 118;
307 requant_tab[4][8] = 10;
309 Indeo3Decoder { info: dummy_info, bpos: 0, bbuf: 0, width: 0, height: 0,
310 mvs: Vec::new(), altquant: [0; 16],
311 vq_offset: 0, bufs: Buffers::new(), requant_tab }
314 fn br_reset(&mut self) {
319 fn get_2bits(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
321 self.bbuf = br.read_byte()?;
325 Ok((self.bbuf >> self.bpos) & 0x3)
328 fn decode_cell_data(&mut self, br: &mut ByteReader, cell: IV3Cell,
329 off: usize, stride: usize, params: CellDecParams, vq_idx: u8) -> DecoderResult<()> {
330 let blk_w = cell.w * 4 / params.bw;
331 let blk_h = cell.h * 4 / params.bh;
332 let scale: usize = if params.bh == 4 { 1 } else { 2 };
334 validate!((((cell.w * 4) % params.bw) == 0) && (((cell.h * 4) % params.bh) == 0));
336 let mut run_blocks = 0;
337 let mut run_skip = false;
339 let mut didx: usize = ((cell.x*4) as usize) + ((cell.y * 4) as usize) * stride + off;
345 let mv = cell.mv.unwrap();
346 let mx = i16::from(mv.x);
347 let my = i16::from(mv.y);
348 let l = (cell.x as i16) * 4 + mx;
349 let t = (cell.y as i16) * 4 + my;
350 let r = ((cell.x + cell.w) as i16) * 4 + mx;
351 let b = ((cell.y + cell.h) as i16) * 4 + my;
354 validate!(r <= (self.width as i16));
355 validate!(b <= (self.height as i16));
356 sidx = (l as usize) + (t as usize) * stride + off;
359 let requant_tab = &self.requant_tab[(vq_idx & 7) as usize];
362 for x in 0..(cell.w as usize) * 4 {
363 self.bufs.dbuf[didx + x - stride] = requant_tab[self.bufs.dbuf[didx + x - stride] as usize];
367 for x in 0..(cell.w as usize) * 4 {
368 self.bufs.sbuf[sidx + x] = requant_tab[self.bufs.sbuf[sidx + x] as usize];
373 let mut xoff: usize = 0;
376 if !run_skip || !cell.no_mv() {
377 if !(params.bw == 8 && cell.no_mv()) {
379 self.bufs.copy_block(didx + xoff, sidx + xoff, stride,
380 params.bw as usize, params.bh as usize);
382 self.bufs.fill_block(didx + xoff, stride,
383 params.bw as usize, params.bh as usize,
384 (cell.y == 0) && (y == 0));
387 fill_block8x8(&mut self.bufs,
388 didx + xoff, stride, 8,
389 y == 0, (cell.y == 0) && (y == 0));
394 let mut line: usize = 0;
396 let c = br.read_byte()?;
398 let delta_tab = if params.hq {
399 IVI3_DELTA_CBS[params.tab[line & 1]]
401 IVI3_DELTA_CBS[params.tab[1]]
405 if (c as usize) < delta_tab.data.len()/2 {
406 idx1 = br.read_byte()? as usize;
407 validate!(idx1 < delta_tab.data.len() / 2);
410 let tmp = (c as usize) - delta_tab.data.len()/2;
411 idx1 = tmp / (delta_tab.quad_radix as usize);
412 idx2 = tmp % (delta_tab.quad_radix as usize);
413 if params.swap_q[line & 1] {
414 mem::swap(&mut idx1, &mut idx2);
417 let deltas: [u8; 4] = [delta_tab.data[idx1 * 2] as u8,
418 delta_tab.data[idx1 * 2 + 1] as u8,
419 delta_tab.data[idx2 * 2 + 0] as u8,
420 delta_tab.data[idx2 * 2 + 1] as u8];
421 let topline = (cell.y == 0) && (y == 0) && (line == 0);
422 let first_line = (y == 0) && (line == 0);
424 (params.copy_line_top)(&mut self.bufs,
425 didx + xoff + line * scale * stride,
428 self.bufs.copy_block(didx + xoff + line * scale * stride,
429 sidx + xoff + line * scale * stride,
430 stride, params.bw as usize, scale);
432 (params.apply_delta)(&mut self.bufs,
433 didx + xoff + line * scale * stride,
434 stride, &deltas, topline, first_line);
437 let mut tocopy: usize = 0;
438 let mut do_copy = true;
439 if c == 0xF8 { return Err(DecoderError::InvalidData); }
443 validate!(line == 0);
445 do_copy = !cell.no_mv();
448 validate!(line == 0);
450 do_copy = !cell.no_mv();
453 let c = br.read_byte()?;
454 validate!((c < 64) && ((c & 0x1F) != 0));
455 run_blocks = (c & 0x1F) - 1;
456 run_skip = (c & 0x20) != 0;
458 if params.bw == 4 && cell.no_mv() && run_skip {
468 let nl = 257 - i16::from(c) - (line as i16);
470 tocopy = nl as usize;
473 if !(params.bh == 8 && cell.no_mv()) {
475 self.bufs.copy_block(didx + xoff + line * scale * stride,
476 sidx + xoff + line * scale * stride,
477 stride, params.bw as usize,
480 self.bufs.fill_block(didx + xoff + line * scale * stride,
481 stride, params.bw as usize,
483 (cell.y == 0) && (y == 0) && (line == 0));
486 fill_block8x8(&mut self.bufs,
487 didx + xoff + line * 2 * stride,
489 (y == 0) && (line == 0),
490 (cell.y == 0) && (y == 0) && (line == 0));
497 xoff += params.bw as usize;
499 didx += stride * (params.bh as usize);
500 sidx += stride * (params.bh as usize);
505 fn copy_cell(&mut self, cell: IV3Cell, off: usize, stride: usize) -> DecoderResult<()> {
506 if cell.no_mv() { return Err(DecoderError::InvalidData); }
507 let mv = cell.mv.unwrap();
508 let mx = i16::from(mv.x);
509 let my = i16::from(mv.y);
510 let l = (cell.x as i16) * 4 + mx;
511 let t = (cell.y as i16) * 4 + my;
512 let r = ((cell.x + cell.w) as i16) * 4 + mx;
513 let b = ((cell.y + cell.h) as i16) * 4 + my;
516 validate!(r <= (self.width as i16));
517 validate!(b <= (self.height as i16));
518 let sidx: usize = off + (l as usize) + (t as usize) * stride;
519 let didx: usize = off + ((cell.x * 4) as usize) + ((cell.y * 4) as usize) * stride;
520 self.bufs.copy_block(didx, sidx, stride, (cell.w * 4) as usize, (cell.h * 4) as usize);
524 fn decode_cell(&mut self, br: &mut ByteReader, cell: IV3Cell, off: usize,
525 stride: usize, intra: bool) -> DecoderResult<()> {
526 let code = br.read_byte()?;
527 let mode = code >> 4;
528 let vq_idx = code & 0xF;
530 let mut idx1: usize = vq_idx as usize;
531 let mut idx2: usize = vq_idx as usize;
532 if (mode == 1) || (mode == 4) {
533 let c = self.altquant[vq_idx as usize];
534 idx1 = (c >> 4) as usize;
535 idx2 = (c & 0xF) as usize;
537 idx1 += self.vq_offset as usize;
538 idx2 += self.vq_offset as usize;
540 validate!((idx1 < 24) && (idx2 < 24));
542 let mut cp = CellDecParams {
545 swap_q: [idx2 >= 16, idx1 >= 16],
547 apply_delta: apply_delta4x4,
548 copy_line_top: copy_line_top4x4,
550 if (mode == 0) || (mode == 1) {
554 } else if (mode == 3) || (mode == 4) {
555 if !cell.no_mv() { return Err(DecoderError::InvalidData); }
559 cp.apply_delta = apply_delta4x8;
560 cp.copy_line_top = copy_line_top4x8;
561 } else if mode == 10 {
564 cp.apply_delta = apply_delta8x8p;
566 cp.apply_delta = apply_delta8x8i;
570 cp.copy_line_top = copy_line_top8x8;
571 } else if mode == 11 {
572 if cell.no_mv() { return Err(DecoderError::InvalidData); }
576 cp.apply_delta = apply_delta4x8m11;
577 cp.copy_line_top = copy_line_top4x8;
579 return Err(DecoderError::InvalidData);
581 self.decode_cell_data(br, cell, off, stride, cp, vq_idx)
584 fn parse_tree(&mut self, br: &mut ByteReader, cell: IV3Cell, off: usize,
585 stride: usize, stripw: u16, intra: bool) -> DecoderResult<()> {
586 let op = self.get_2bits(br)?;
588 validate!(cell.h > 1);
589 validate!(cell.d > 0);
590 let (cell1, cell2) = cell.split_h();
591 self.parse_tree(br, cell1, off, stride, stripw, intra)?;
592 self.parse_tree(br, cell2, off, stride, stripw, intra)?;
594 } else if op == V_SPLIT {
595 validate!(cell.w > 1);
596 validate!(cell.d > 0);
597 let (cell1, cell2) = cell.split_w(stripw);
598 self.parse_tree(br, cell1, off, stride, stripw, intra)?;
599 self.parse_tree(br, cell2, off, stride, stripw, intra)?;
601 } else if op == SKIP_OR_TREE {
603 let mut newcell = cell;
606 self.parse_tree(br, newcell, off, stride, stripw, intra)
609 let code = self.get_2bits(br)?;
611 if code == 1 { return Err(DecoderError::NotImplemented); }
612 self.copy_cell(cell, off, stride)
616 let mut newcell = cell;
619 let mv_idx = br.read_byte()? as usize;
620 validate!(mv_idx < self.mvs.len());
621 newcell.mv = Some(self.mvs[mv_idx]);
622 self.parse_tree(br, newcell, off, stride, stripw, intra)
624 self.decode_cell(br, cell, off, stride, intra)
629 fn decode_plane_intra(&mut self, br: &mut ByteReader, planeno: usize,
630 start: u64, end: u64) -> DecoderResult<()> {
631 let offs = self.bufs.get_offset(planeno);
632 let stride = self.bufs.get_stride(planeno);
633 br.seek(SeekFrom::Start(start))?;
635 let nvec = br.read_u32le()?;
636 validate!(nvec == 0); // for intra there should be no mc_vecs
637 self.mvs.truncate(0);
639 let x = br.read_byte()? as i8;
640 let y = br.read_byte()? as i8;
641 self.mvs.push(MV{ x, y });
644 let (cellwidth, cellheight) = if planeno == 0 {
645 (self.bufs.width >> 2, self.bufs.height >> 2)
647 (((self.bufs.width >> 2) + 3) >> 2, ((self.bufs.height >> 2) + 3) >> 2)
649 let cell = IV3Cell::new(cellwidth as u16, cellheight as u16);
651 self.parse_tree(br, cell, offs, stride, if planeno > 0 { 10 } else { 40 }, true)?;
652 validate!(br.tell() <= end);
656 fn decode_plane_inter(&mut self, br: &mut ByteReader, planeno: usize,
657 start: u64, end: u64) -> DecoderResult<()> {
658 let offs = self.bufs.get_offset(planeno);
659 let stride = self.bufs.get_stride(planeno);
660 br.seek(SeekFrom::Start(start))?;
662 let nvec = br.read_u32le()?;
663 validate!(nvec <= 256); // for intra there should be no mc_vecs
664 self.mvs.truncate(0);
666 let y = br.read_byte()? as i8;
667 let x = br.read_byte()? as i8;
668 self.mvs.push(MV{ x, y });
671 let (cellwidth, cellheight) = if planeno == 0 {
672 (self.bufs.width >> 2, self.bufs.height >> 2)
674 (((self.bufs.width >> 2) + 3) >> 2, ((self.bufs.height >> 2) + 3) >> 2)
676 let cell = IV3Cell::new(cellwidth as u16, cellheight as u16);
678 self.parse_tree(br, cell, offs, stride, if planeno > 0 { 10 } else { 40 }, false)?;
679 validate!(br.tell() <= end);
684 const FLAG_KEYFRAME: u16 = 1 << 2;
685 const FLAG_NONREF: u16 = 1 << 8;
687 impl NADecoder for Indeo3Decoder {
688 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
689 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
690 let w = vinfo.get_width();
691 let h = vinfo.get_height();
692 let fmt = formats::YUV410_FORMAT;
693 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, fmt));
694 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
698 Err(DecoderError::InvalidData)
701 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
702 let src = pkt.get_buffer();
703 let mut mr = MemoryReader::new_read(&src);
704 let mut br = ByteReader::new(&mut mr);
705 let frameno = br.read_u32le()?;
706 let hdr_2 = br.read_u32le()?;
707 let check = br.read_u32le()?;
708 let size = br.read_u32le()?;
710 let data_start = br.tell();
712 if (frameno ^ hdr_2 ^ size ^ FRMH_TAG) != check {
713 return Err(DecoderError::InvalidData);
715 if i64::from(size) > br.left() { return Err(DecoderError::InvalidData); }
716 let ver = br.read_u16le()?;
717 if ver != 32 { return Err(DecoderError::NotImplemented); }
718 let flags = br.read_u16le()?;
719 let size2 = br.read_u32le()?;
721 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
722 frm.set_keyframe(false);
723 frm.set_frame_type(FrameType::Skip);
724 return Ok(frm.into_ref());
726 validate!(((size2 + 7) >> 3) <= size);
727 let cb = br.read_byte()?;
730 let height = br.read_u16le()?;
731 let width = br.read_u16le()?;
732 validate!((width >= 16) && (width <= 640));
733 validate!((height >= 16) && (height <= 640));
734 validate!(((width & 3) == 0) && ((height & 3) == 0));
736 if (self.bufs.width != (width as usize)) || (self.bufs.height != (height as usize)) {
737 self.bufs.alloc(width as usize, height as usize);
738 vinfo = NAVideoInfo::new(width as usize, height as usize, false, formats::YUV410_FORMAT);
740 vinfo = self.info.get_properties().get_video_info().unwrap();
743 self.height = height;
745 let yoff = br.read_u32le()?;
746 let uoff = br.read_u32le()?;
747 let voff = br.read_u32le()?;
748 if yoff > size { return Err(DecoderError::InvalidData); }
749 if uoff > size { return Err(DecoderError::InvalidData); }
750 if voff > size { return Err(DecoderError::InvalidData); }
753 br.read_buf(&mut self.altquant)?;
755 let mut yend = src.len() as u32;//size;
756 if (uoff < yend) && (uoff > yoff) { yend = uoff; }
757 if (voff < yend) && (voff > yoff) { yend = voff; }
759 if (yoff < uend) && (yoff > uoff) { uend = yoff; }
760 if (voff < uend) && (voff > uoff) { uend = voff; }
762 if (yoff < vend) && (yoff > voff) { vend = yoff; }
763 if (uoff < vend) && (uoff > voff) { vend = uoff; }
765 let intraframe = (flags & FLAG_KEYFRAME) != 0;
766 let bufinfo = alloc_video_buffer(vinfo, 4)?;
767 let mut buf = bufinfo.get_vbuf().unwrap();
768 let ystart = data_start + u64::from(yoff);
769 let ustart = data_start + u64::from(uoff);
770 let vstart = data_start + u64::from(voff);
771 let yendpos = data_start + u64::from(yend);
772 let uendpos = data_start + u64::from(uend);
773 let vendpos = data_start + u64::from(vend);
775 self.decode_plane_intra(&mut br, 0, ystart, yendpos)?;
776 self.decode_plane_intra(&mut br, 1, vstart, vendpos)?;
777 self.decode_plane_intra(&mut br, 2, ustart, uendpos)?;
779 self.decode_plane_inter(&mut br, 0, ystart, yendpos)?;
780 self.decode_plane_inter(&mut br, 1, vstart, vendpos)?;
781 self.decode_plane_inter(&mut br, 2, ustart, uendpos)?;
783 self.bufs.fill_framebuf(&mut buf);
784 if (flags & FLAG_NONREF) == 0 { self.bufs.flip(); }
785 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
786 frm.set_keyframe(intraframe);
787 frm.set_frame_type(if intraframe { FrameType::I } else { FrameType::P });
790 fn flush(&mut self) {
795 impl NAOptionHandler for Indeo3Decoder {
796 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
797 fn set_options(&mut self, _options: &[NAOption]) { }
798 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
801 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
802 Box::new(Indeo3Decoder::new())
807 use nihav_core::codecs::RegisteredDecoders;
808 use nihav_core::demuxers::RegisteredDemuxers;
809 use nihav_codec_support::test::dec_video::*;
810 use crate::indeo_register_all_codecs;
811 use nihav_commonfmt::generic_register_all_demuxers;
814 let mut dmx_reg = RegisteredDemuxers::new();
815 generic_register_all_demuxers(&mut dmx_reg);
816 let mut dec_reg = RegisteredDecoders::new();
817 indeo_register_all_codecs(&mut dec_reg);
819 test_decoding("avi", "indeo3", "assets/Indeo/iv32_example.avi", Some(10),
820 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
821 [0x90be698e, 0x326db071, 0x08e8c6a5, 0x39349acc],
822 [0x25d677fc, 0x63f96aaa, 0xd412ca98, 0x61416313],
823 [0xc4368250, 0x63e7b6bc, 0xffcff950, 0x11f13239],
824 [0x7e869758, 0x027abc2e, 0x25204bca, 0x93fbaa03],
825 [0x5a1e822c, 0x2b1a4cd5, 0x72059843, 0xe5689ad1],
826 [0x3a971cce, 0x5ec22135, 0x1a45f802, 0x0f5f9264],
827 [0x0a65f782, 0xd8767cf3, 0x878b4b8d, 0xfc94c88b],
828 [0x4ac70139, 0x3300eac1, 0xba84b068, 0x47f5ff29],
829 [0x3e8c8ec4, 0x9421b38c, 0x580abbbd, 0x92792d19],
830 [0x9096ee9b, 0x8dd9fb14, 0x981e31e3, 0x3ffd7d29],
831 [0x22dc71ec, 0x3d8f6f7e, 0x1a198982, 0x41d17ecc]]));
835 const DT_1_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
836 0, 0, 2, 2, -2, -2, -1, 3,
837 1, -3, 3, -1, -3, 1, 4, 4,
838 -4, -4, 1, 5, -1, -5, 5, 1,
839 -5, -1, -4, 4, 4, -4, -2, 6,
840 2, -6, 6, -2, -6, 2, 4, 9,
841 -4, -9, 9, 4, -9, -4, 9, 9,
842 -9, -9, 1, 10, -1, -10, 10, 1,
843 -10, -1, -5, 8, 5, -8, 8, -5,
844 -8, 5, 9, 15, -9, -15, 15, 9,
845 -15, -9, -3, 12, 3, -12, 12, -3,
846 -12, 3, 4, 16, -4, -16, 16, 4,
847 -16, -4, 16, 16, -16, -16, 0, 18,
848 0, -18, 18, 0, -18, 0, -12, 12,
849 12, -12, -9, 16, 9, -16, 16, -9,
850 -16, 9, 11, 27, -11, -27, 27, 11,
851 -27, -11, 19, 28, -19, -28, 28, 19,
852 -28, -19, -6, 22, 6, -22, 22, -6,
853 -22, 6, 4, 29, -4, -29, 29, 4,
854 -29, -4, 30, 30, -30, -30, -2, 33,
855 2, -33, 33, -2, -33, 2, -18, 23,
856 18, -23, 23, -18, -23, 18, -15, 30,
857 15, -30, 30, -15, -30, 15, 22, 46,
858 -22, -46, 46, 22, -46, -22, 13, 47,
859 -13, -47, 47, 13, -47, -13, 35, 49,
860 -35, -49, 49, 35, -49, -35, -11, 41,
861 11, -41, 41, -11, -41, 11, 4, 51,
862 -4, -51, 51, 4, -51, -4, 54, 54,
863 -54, -54, -34, 34, 34, -34, -29, 42,
864 29, -42, 42, -29, -42, 29, -6, 60,
865 6, -60, 60, -6, -60, 6, 27, 76,
866 -27, -76, 76, 27, -76, -27, 43, 77,
867 -43, -77, 77, 43, -77, -43, -24, 55,
868 24, -55, 55, -24, -55, 24, 14, 79,
869 -14, -79, 79, 14, -79, -14, 63, 83,
870 -63, -83, 83, 63, -83, -63, -20, 74,
871 20, -74, 74, -20, -74, 20, 2, 88,
872 -2, -88, 88, 2, -88, -2, 93, 93,
873 -93, -93, -52, 61, 52, -61, 61, -52,
874 -61, 52, 52, 120, -52, -120, 120, 52,
875 -120, -52, -45, 75, 45, -75, 75, -45,
876 -75, 45, 75, 125, -75, -125, 125, 75,
877 -125, -75, 33, 122, -33, -122, 122, 33,
878 -122, -33, -13, 103, 13, -103, 103, -13,
879 -103, 13, -40, 96, 40, -96, 96, -40,
880 -96, 40, -34, 127, 34, -127, 127, -34,
881 -127, 34, -89, 89, 89, -89, -78, 105,
882 78, -105, 105, -78, -105, 78, 12, 12,
883 -12, -12, 23, 23, -23, -23, 42, 42,
884 -42, -42, 73, 73, -73, -73,
887 const DT_1_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
888 0, 0, 3, 3, -3, -3, -1, 4,
889 1, -4, 4, -1, -4, 1, 7, 7,
890 -7, -7, 2, 8, -2, -8, 8, 2,
891 -8, -2, -2, 9, 2, -9, 9, -2,
892 -9, 2, -6, 6, 6, -6, 6, 13,
893 -6, -13, 13, 6, -13, -6, 13, 13,
894 -13, -13, 1, 14, -1, -14, 14, 1,
895 -14, -1, -8, 12, 8, -12, 12, -8,
896 -12, 8, 14, 23, -14, -23, 23, 14,
897 -23, -14, -5, 18, 5, -18, 18, -5,
898 -18, 5, 6, 24, -6, -24, 24, 6,
899 -24, -6, 24, 24, -24, -24, -1, 27,
900 1, -27, 27, -1, -27, 1, -17, 17,
901 17, -17, -13, 23, 13, -23, 23, -13,
902 -23, 13, 16, 40, -16, -40, 40, 16,
903 -40, -16, 28, 41, -28, -41, 41, 28,
904 -41, -28, -9, 33, 9, -33, 33, -9,
905 -33, 9, 6, 43, -6, -43, 43, 6,
906 -43, -6, 46, 46, -46, -46, -4, 50,
907 4, -50, 50, -4, -50, 4, -27, 34,
908 27, -34, 34, -27, -34, 27, -22, 45,
909 22, -45, 45, -22, -45, 22, 34, 69,
910 -34, -69, 69, 34, -69, -34, 19, 70,
911 -19, -70, 70, 19, -70, -19, 53, 73,
912 -53, -73, 73, 53, -73, -53, -17, 62,
913 17, -62, 62, -17, -62, 17, 5, 77,
914 -5, -77, 77, 5, -77, -5, 82, 82,
915 -82, -82, -51, 51, 51, -51, -43, 64,
916 43, -64, 64, -43, -64, 43, -10, 90,
917 10, -90, 90, -10, -90, 10, 41, 114,
918 -41, -114, 114, 41, -114, -41, 64, 116,
919 -64, -116, 116, 64, -116, -64, -37, 82,
920 37, -82, 82, -37, -82, 37, 22, 119,
921 -22, -119, 119, 22, -119, -22, 95, 124,
922 -95, -124, 124, 95, -124, -95, -30, 111,
923 30, -111, 111, -30, -111, 30, -78, 92,
924 78, -92, 92, -78, -92, 78, -68, 113,
925 68, -113, 113, -68, -113, 68, 18, 18,
926 -18, -18, 34, 34, -34, -34, 63, 63,
927 -63, -63, 109, 109, -109, -109,
930 const DT_1_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
931 0, 0, 4, 4, -4, -4, -1, 5,
932 1, -5, 5, -1, -5, 1, 3, 10,
933 -3, -10, 10, 3, -10, -3, 9, 9,
934 -9, -9, -7, 7, 7, -7, -3, 12,
935 3, -12, 12, -3, -12, 3, 8, 17,
936 -8, -17, 17, 8, -17, -8, 17, 17,
937 -17, -17, 1, 19, -1, -19, 19, 1,
938 -19, -1, -11, 16, 11, -16, 16, -11,
939 -16, 11, -6, 23, 6, -23, 23, -6,
940 -23, 6, 18, 31, -18, -31, 31, 18,
941 -31, -18, 8, 32, -8, -32, 32, 8,
942 -32, -8, 33, 33, -33, -33, -1, 36,
943 1, -36, 36, -1, -36, 1, -23, 23,
944 23, -23, -17, 31, 17, -31, 31, -17,
945 -31, 17, 21, 54, -21, -54, 54, 21,
946 -54, -21, 37, 55, -37, -55, 55, 37,
947 -55, -37, -12, 44, 12, -44, 44, -12,
948 -44, 12, 8, 57, -8, -57, 57, 8,
949 -57, -8, 61, 61, -61, -61, -5, 66,
950 5, -66, 66, -5, -66, 5, -36, 45,
951 36, -45, 45, -36, -45, 36, -29, 60,
952 29, -60, 60, -29, -60, 29, 45, 92,
953 -45, -92, 92, 45, -92, -45, 25, 93,
954 -25, -93, 93, 25, -93, -25, 71, 97,
955 -71, -97, 97, 71, -97, -71, -22, 83,
956 22, -83, 83, -22, -83, 22, 7, 102,
957 -7, -102, 102, 7, -102, -7, 109, 109,
958 -109, -109, -68, 68, 68, -68, -57, 85,
959 57, -85, 85, -57, -85, 57, -13, 120,
960 13, -120, 120, -13, -120, 13, -49, 110,
961 49, -110, 110, -49, -110, 49, -104, 123,
962 104, -123, 123, -104, -123, 104, 24, 24,
963 -24, -24, 46, 46, -46, -46, 84, 84,
967 const DT_1_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
968 0, 0, 5, 5, -5, -5, -2, 7,
969 2, -7, 7, -2, -7, 2, 11, 11,
970 -11, -11, 3, 13, -3, -13, 13, 3,
971 -13, -3, -9, 9, 9, -9, -4, 15,
972 4, -15, 15, -4, -15, 4, 11, 22,
973 -11, -22, 22, 11, -22, -11, 21, 21,
974 -21, -21, 2, 24, -2, -24, 24, 2,
975 -24, -2, -14, 20, 14, -20, 20, -14,
976 -20, 14, 23, 38, -23, -38, 38, 23,
977 -38, -23, -8, 29, 8, -29, 29, -8,
978 -29, 8, 11, 39, -11, -39, 39, 11,
979 -39, -11, 41, 41, -41, -41, -1, 45,
980 1, -45, 45, -1, -45, 1, -29, 29,
981 29, -29, -22, 39, 22, -39, 39, -22,
982 -39, 22, 27, 67, -27, -67, 67, 27,
983 -67, -27, 47, 69, -47, -69, 69, 47,
984 -69, -47, -15, 56, 15, -56, 56, -15,
985 -56, 15, 11, 71, -11, -71, 71, 11,
986 -71, -11, 76, 76, -76, -76, -6, 83,
987 6, -83, 83, -6, -83, 6, -45, 57,
988 45, -57, 57, -45, -57, 45, -36, 75,
989 36, -75, 75, -36, -75, 36, 56, 115,
990 -56, -115, 115, 56, -115, -56, 31, 117,
991 -31, -117, 117, 31, -117, -31, 88, 122,
992 -88, -122, 122, 88, -122, -88, -28, 104,
993 28, -104, 104, -28, -104, 28, -85, 85,
994 85, -85, -72, 106, 72, -106, 106, -72,
995 -106, 72, 30, 30, -30, -30, 58, 58,
996 -58, -58, 105, 105, -105, -105,
999 const DT_1_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1000 0, 0, 6, 6, -6, -6, -2, 8,
1001 2, -8, 8, -2, -8, 2, 13, 13,
1002 -13, -13, 4, 15, -4, -15, 15, 4,
1003 -15, -4, -11, 11, 11, -11, -5, 18,
1004 5, -18, 18, -5, -18, 5, 13, 26,
1005 -13, -26, 26, 13, -26, -13, 26, 26,
1006 -26, -26, 2, 29, -2, -29, 29, 2,
1007 -29, -2, -16, 24, 16, -24, 24, -16,
1008 -24, 16, 28, 46, -28, -46, 46, 28,
1009 -46, -28, -9, 35, 9, -35, 35, -9,
1010 -35, 9, 13, 47, -13, -47, 47, 13,
1011 -47, -13, 49, 49, -49, -49, -1, 54,
1012 1, -54, 54, -1, -54, 1, -35, 35,
1013 35, -35, -26, 47, 26, -47, 47, -26,
1014 -47, 26, 32, 81, -32, -81, 81, 32,
1015 -81, -32, 56, 83, -56, -83, 83, 56,
1016 -83, -56, -18, 67, 18, -67, 67, -18,
1017 -67, 18, 13, 86, -13, -86, 86, 13,
1018 -86, -13, 91, 91, -91, -91, -7, 99,
1019 7, -99, 99, -7, -99, 7, -54, 68,
1020 54, -68, 68, -54, -68, 54, -44, 90,
1021 44, -90, 90, -44, -90, 44, -33, 124,
1022 33, -124, 124, -33, -124, 33, -103, 103,
1023 103, -103, -86, 127, 86, -127, 127, -86,
1024 -127, 86, 37, 37, -37, -37, 69, 69,
1028 const DT_1_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1029 0, 0, 7, 7, -7, -7, -3, 10,
1030 3, -10, 10, -3, -10, 3, 16, 16,
1031 -16, -16, 5, 18, -5, -18, 18, 5,
1032 -18, -5, -13, 13, 13, -13, -6, 21,
1033 6, -21, 21, -6, -21, 6, 15, 30,
1034 -15, -30, 30, 15, -30, -15, 30, 30,
1035 -30, -30, 2, 34, -2, -34, 34, 2,
1036 -34, -2, -19, 28, 19, -28, 28, -19,
1037 -28, 19, 32, 54, -32, -54, 54, 32,
1038 -54, -32, -11, 41, 11, -41, 41, -11,
1039 -41, 11, 15, 55, -15, -55, 55, 15,
1040 -55, -15, 57, 57, -57, -57, -1, 63,
1041 1, -63, 63, -1, -63, 1, -40, 40,
1042 40, -40, -30, 55, 30, -55, 55, -30,
1043 -55, 30, 37, 94, -37, -94, 94, 37,
1044 -94, -37, 65, 96, -65, -96, 96, 65,
1045 -96, -65, -21, 78, 21, -78, 78, -21,
1046 -78, 21, 15, 100, -15, -100, 100, 15,
1047 -100, -15, 106, 106, -106, -106, -8, 116,
1048 8, -116, 116, -8, -116, 8, -63, 79,
1049 63, -79, 79, -63, -79, 63, -51, 105,
1050 51, -105, 105, -51, -105, 51, -120, 120,
1051 120, -120, 43, 43, -43, -43, 80, 80,
1055 const DT_1_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1056 0, 0, 8, 8, -8, -8, -3, 11,
1057 3, -11, 11, -3, -11, 3, 18, 18,
1058 -18, -18, 5, 20, -5, -20, 20, 5,
1059 -20, -5, -15, 15, 15, -15, -7, 24,
1060 7, -24, 24, -7, -24, 7, 17, 35,
1061 -17, -35, 35, 17, -35, -17, 34, 34,
1062 -34, -34, 3, 38, -3, -38, 38, 3,
1063 -38, -3, -22, 32, 22, -32, 32, -22,
1064 -32, 22, 37, 61, -37, -61, 61, 37,
1065 -61, -37, -13, 47, 13, -47, 47, -13,
1066 -47, 13, 17, 63, -17, -63, 63, 17,
1067 -63, -17, 65, 65, -65, -65, -1, 72,
1068 1, -72, 72, -1, -72, 1, -46, 46,
1069 46, -46, -35, 63, 35, -63, 63, -35,
1070 -63, 35, 43, 107, -43, -107, 107, 43,
1071 -107, -43, 75, 110, -75, -110, 110, 75,
1072 -110, -75, -24, 89, 24, -89, 89, -24,
1073 -89, 24, 17, 114, -17, -114, 114, 17,
1074 -114, -17, 121, 121, -121, -121, -72, 91,
1075 72, -91, 91, -72, -91, 72, -58, 120,
1076 58, -120, 120, -58, -120, 58, 49, 49,
1077 -49, -49, 92, 92, -92, -92,
1080 const DT_1_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1081 0, 0, 9, 9, -9, -9, -3, 12,
1082 3, -12, 12, -3, -12, 3, 20, 20,
1083 -20, -20, 6, 23, -6, -23, 23, 6,
1084 -23, -6, -17, 17, 17, -17, -7, 27,
1085 7, -27, 27, -7, -27, 7, 19, 39,
1086 -19, -39, 39, 19, -39, -19, 39, 39,
1087 -39, -39, 3, 43, -3, -43, 43, 3,
1088 -43, -3, -24, 36, 24, -36, 36, -24,
1089 -36, 24, 42, 69, -42, -69, 69, 42,
1090 -69, -42, -14, 53, 14, -53, 53, -14,
1091 -53, 14, 19, 71, -19, -71, 71, 19,
1092 -71, -19, 73, 73, -73, -73, -2, 80,
1093 2, -80, 80, -2, -80, 2, -52, 52,
1094 52, -52, -39, 70, 39, -70, 70, -39,
1095 -70, 39, 48, 121, -48, -121, 121, 48,
1096 -121, -48, 84, 124, -84, -124, 124, 84,
1097 -124, -84, -27, 100, 27, -100, 100, -27,
1098 -100, 27, -81, 102, 81, -102, 102, -81,
1099 -102, 81, 55, 55, -55, -55, 104, 104,
1103 const DT_2_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
1104 0, 0, 2, 2, -2, -2, 0, 2,
1105 0, -2, 2, 0, -2, 0, 4, 4,
1106 -4, -4, 0, 4, 0, -4, 4, 0,
1107 -4, 0, -4, 4, 4, -4, -2, 6,
1108 2, -6, 6, -2, -6, 2, 4, 8,
1109 -4, -8, 8, 4, -8, -4, 8, 8,
1110 -8, -8, 0, 10, 0, -10, 10, 0,
1111 -10, 0, -4, 8, 4, -8, 8, -4,
1112 -8, 4, 8, 14, -8, -14, 14, 8,
1113 -14, -8, -2, 12, 2, -12, 12, -2,
1114 -12, 2, 4, 16, -4, -16, 16, 4,
1115 -16, -4, 16, 16, -16, -16, 0, 18,
1116 0, -18, 18, 0, -18, 0, -12, 12,
1117 12, -12, -8, 16, 8, -16, 16, -8,
1118 -16, 8, 10, 26, -10, -26, 26, 10,
1119 -26, -10, 18, 28, -18, -28, 28, 18,
1120 -28, -18, -6, 22, 6, -22, 22, -6,
1121 -22, 6, 4, 28, -4, -28, 28, 4,
1122 -28, -4, 30, 30, -30, -30, -2, 32,
1123 2, -32, 32, -2, -32, 2, -18, 22,
1124 18, -22, 22, -18, -22, 18, -14, 30,
1125 14, -30, 30, -14, -30, 14, 22, 46,
1126 -22, -46, 46, 22, -46, -22, 12, 46,
1127 -12, -46, 46, 12, -46, -12, 34, 48,
1128 -34, -48, 48, 34, -48, -34, -10, 40,
1129 10, -40, 40, -10, -40, 10, 4, 50,
1130 -4, -50, 50, 4, -50, -4, 54, 54,
1131 -54, -54, -34, 34, 34, -34, -28, 42,
1132 28, -42, 42, -28, -42, 28, -6, 60,
1133 6, -60, 60, -6, -60, 6, 26, 76,
1134 -26, -76, 76, 26, -76, -26, 42, 76,
1135 -42, -76, 76, 42, -76, -42, -24, 54,
1136 24, -54, 54, -24, -54, 24, 14, 78,
1137 -14, -78, 78, 14, -78, -14, 62, 82,
1138 -62, -82, 82, 62, -82, -62, -20, 74,
1139 20, -74, 74, -20, -74, 20, 2, 88,
1140 -2, -88, 88, 2, -88, -2, 92, 92,
1141 -92, -92, -52, 60, 52, -60, 60, -52,
1142 -60, 52, 52, 118, -52, -118, 118, 52,
1143 -118, -52, -44, 74, 44, -74, 74, -44,
1144 -74, 44, 74, 118, -74, -118, 118, 74,
1145 -118, -74, 32, 118, -32, -118, 118, 32,
1146 -118, -32, -12, 102, 12, -102, 102, -12,
1147 -102, 12, -40, 96, 40, -96, 96, -40,
1148 -96, 40, -34, 118, 34, -118, 118, -34,
1149 -118, 34, -88, 88, 88, -88, -78, 104,
1150 78, -104, 104, -78, -104, 78, 12, 12,
1151 -12, -12, 22, 22, -22, -22, 42, 42,
1152 -42, -42, 72, 72, -72, -72,
1155 const DT_2_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
1156 0, 0, 3, 3, -3, -3, 0, 3,
1157 0, -3, 3, 0, -3, 0, 6, 6,
1158 -6, -6, 3, 9, -3, -9, 9, 3,
1159 -9, -3, -3, 9, 3, -9, 9, -3,
1160 -9, 3, -6, 6, 6, -6, 6, 12,
1161 -6, -12, 12, 6, -12, -6, 12, 12,
1162 -12, -12, 0, 15, 0, -15, 15, 0,
1163 -15, 0, -9, 12, 9, -12, 12, -9,
1164 -12, 9, 15, 24, -15, -24, 24, 15,
1165 -24, -15, -6, 18, 6, -18, 18, -6,
1166 -18, 6, 6, 24, -6, -24, 24, 6,
1167 -24, -6, 24, 24, -24, -24, 0, 27,
1168 0, -27, 27, 0, -27, 0, -18, 18,
1169 18, -18, -12, 24, 12, -24, 24, -12,
1170 -24, 12, 15, 39, -15, -39, 39, 15,
1171 -39, -15, 27, 42, -27, -42, 42, 27,
1172 -42, -27, -9, 33, 9, -33, 33, -9,
1173 -33, 9, 6, 42, -6, -42, 42, 6,
1174 -42, -6, 45, 45, -45, -45, -3, 51,
1175 3, -51, 51, -3, -51, 3, -27, 33,
1176 27, -33, 33, -27, -33, 27, -21, 45,
1177 21, -45, 45, -21, -45, 21, 33, 69,
1178 -33, -69, 69, 33, -69, -33, 18, 69,
1179 -18, -69, 69, 18, -69, -18, 54, 72,
1180 -54, -72, 72, 54, -72, -54, -18, 63,
1181 18, -63, 63, -18, -63, 18, 6, 78,
1182 -6, -78, 78, 6, -78, -6, 81, 81,
1183 -81, -81, -51, 51, 51, -51, -42, 63,
1184 42, -63, 63, -42, -63, 42, -9, 90,
1185 9, -90, 90, -9, -90, 9, 42, 114,
1186 -42, -114, 114, 42, -114, -42, 63, 117,
1187 -63, -117, 117, 63, -117, -63, -36, 81,
1188 36, -81, 81, -36, -81, 36, 21, 120,
1189 -21, -120, 120, 21, -120, -21, 96, 123,
1190 -96, -123, 123, 96, -123, -96, -30, 111,
1191 30, -111, 111, -30, -111, 30, -78, 93,
1192 78, -93, 93, -78, -93, 78, -69, 114,
1193 69, -114, 114, -69, -114, 69, 18, 18,
1194 -18, -18, 33, 33, -33, -33, 63, 63,
1195 -63, -63, 108, 108, -108, -108,
1198 const DT_2_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
1199 0, 0, 4, 4, -4, -4, 0, 4,
1200 0, -4, 4, 0, -4, 0, 4, 8,
1201 -4, -8, 8, 4, -8, -4, 8, 8,
1202 -8, -8, -8, 8, 8, -8, -4, 12,
1203 4, -12, 12, -4, -12, 4, 8, 16,
1204 -8, -16, 16, 8, -16, -8, 16, 16,
1205 -16, -16, 0, 20, 0, -20, 20, 0,
1206 -20, 0, -12, 16, 12, -16, 16, -12,
1207 -16, 12, -4, 24, 4, -24, 24, -4,
1208 -24, 4, 16, 32, -16, -32, 32, 16,
1209 -32, -16, 8, 32, -8, -32, 32, 8,
1210 -32, -8, 32, 32, -32, -32, 0, 36,
1211 0, -36, 36, 0, -36, 0, -24, 24,
1212 24, -24, -16, 32, 16, -32, 32, -16,
1213 -32, 16, 20, 52, -20, -52, 52, 20,
1214 -52, -20, 36, 56, -36, -56, 56, 36,
1215 -56, -36, -12, 44, 12, -44, 44, -12,
1216 -44, 12, 8, 56, -8, -56, 56, 8,
1217 -56, -8, 60, 60, -60, -60, -4, 64,
1218 4, -64, 64, -4, -64, 4, -36, 44,
1219 36, -44, 44, -36, -44, 36, -28, 60,
1220 28, -60, 60, -28, -60, 28, 44, 92,
1221 -44, -92, 92, 44, -92, -44, 24, 92,
1222 -24, -92, 92, 24, -92, -24, 72, 96,
1223 -72, -96, 96, 72, -96, -72, -20, 84,
1224 20, -84, 84, -20, -84, 20, 8, 100,
1225 -8, -100, 100, 8, -100, -8, 108, 108,
1226 -108, -108, -68, 68, 68, -68, -56, 84,
1227 56, -84, 84, -56, -84, 56, -12, 120,
1228 12, -120, 120, -12, -120, 12, -48, 108,
1229 48, -108, 108, -48, -108, 48, -104, 124,
1230 104, -124, 124, -104, -124, 104, 24, 24,
1231 -24, -24, 44, 44, -44, -44, 84, 84,
1235 const DT_2_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1236 0, 0, 5, 5, -5, -5, 0, 5,
1237 0, -5, 5, 0, -5, 0, 10, 10,
1238 -10, -10, 5, 15, -5, -15, 15, 5,
1239 -15, -5, -10, 10, 10, -10, -5, 15,
1240 5, -15, 15, -5, -15, 5, 10, 20,
1241 -10, -20, 20, 10, -20, -10, 20, 20,
1242 -20, -20, 0, 25, 0, -25, 25, 0,
1243 -25, 0, -15, 20, 15, -20, 20, -15,
1244 -20, 15, 25, 40, -25, -40, 40, 25,
1245 -40, -25, -10, 30, 10, -30, 30, -10,
1246 -30, 10, 10, 40, -10, -40, 40, 10,
1247 -40, -10, 40, 40, -40, -40, 0, 45,
1248 0, -45, 45, 0, -45, 0, -30, 30,
1249 30, -30, -20, 40, 20, -40, 40, -20,
1250 -40, 20, 25, 65, -25, -65, 65, 25,
1251 -65, -25, 45, 70, -45, -70, 70, 45,
1252 -70, -45, -15, 55, 15, -55, 55, -15,
1253 -55, 15, 10, 70, -10, -70, 70, 10,
1254 -70, -10, 75, 75, -75, -75, -5, 85,
1255 5, -85, 85, -5, -85, 5, -45, 55,
1256 45, -55, 55, -45, -55, 45, -35, 75,
1257 35, -75, 75, -35, -75, 35, 55, 115,
1258 -55, -115, 115, 55, -115, -55, 30, 115,
1259 -30, -115, 115, 30, -115, -30, 90, 120,
1260 -90, -120, 120, 90, -120, -90, -30, 105,
1261 30, -105, 105, -30, -105, 30, -85, 85,
1262 85, -85, -70, 105, 70, -105, 105, -70,
1263 -105, 70, 30, 30, -30, -30, 60, 60,
1264 -60, -60, 105, 105, -105, -105,
1267 const DT_2_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1268 0, 0, 6, 6, -6, -6, 0, 6,
1269 0, -6, 6, 0, -6, 0, 12, 12,
1270 -12, -12, 6, 12, -6, -12, 12, 6,
1271 -12, -6, -12, 12, 12, -12, -6, 18,
1272 6, -18, 18, -6, -18, 6, 12, 24,
1273 -12, -24, 24, 12, -24, -12, 24, 24,
1274 -24, -24, 0, 30, 0, -30, 30, 0,
1275 -30, 0, -18, 24, 18, -24, 24, -18,
1276 -24, 18, 30, 48, -30, -48, 48, 30,
1277 -48, -30, -6, 36, 6, -36, 36, -6,
1278 -36, 6, 12, 48, -12, -48, 48, 12,
1279 -48, -12, 48, 48, -48, -48, 0, 54,
1280 0, -54, 54, 0, -54, 0, -36, 36,
1281 36, -36, -24, 48, 24, -48, 48, -24,
1282 -48, 24, 30, 78, -30, -78, 78, 30,
1283 -78, -30, 54, 84, -54, -84, 84, 54,
1284 -84, -54, -18, 66, 18, -66, 66, -18,
1285 -66, 18, 12, 84, -12, -84, 84, 12,
1286 -84, -12, 90, 90, -90, -90, -6, 96,
1287 6, -96, 96, -6, -96, 6, -54, 66,
1288 54, -66, 66, -54, -66, 54, -42, 90,
1289 42, -90, 90, -42, -90, 42, -30, 126,
1290 30, -126, 126, -30, -126, 30, -102, 102,
1291 102, -102, -84, 126, 84, -126, 126, -84,
1292 -126, 84, 36, 36, -36, -36, 66, 66,
1296 const DT_2_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1297 0, 0, 7, 7, -7, -7, 0, 7,
1298 0, -7, 7, 0, -7, 0, 14, 14,
1299 -14, -14, 7, 21, -7, -21, 21, 7,
1300 -21, -7, -14, 14, 14, -14, -7, 21,
1301 7, -21, 21, -7, -21, 7, 14, 28,
1302 -14, -28, 28, 14, -28, -14, 28, 28,
1303 -28, -28, 0, 35, 0, -35, 35, 0,
1304 -35, 0, -21, 28, 21, -28, 28, -21,
1305 -28, 21, 35, 56, -35, -56, 56, 35,
1306 -56, -35, -14, 42, 14, -42, 42, -14,
1307 -42, 14, 14, 56, -14, -56, 56, 14,
1308 -56, -14, 56, 56, -56, -56, 0, 63,
1309 0, -63, 63, 0, -63, 0, -42, 42,
1310 42, -42, -28, 56, 28, -56, 56, -28,
1311 -56, 28, 35, 91, -35, -91, 91, 35,
1312 -91, -35, 63, 98, -63, -98, 98, 63,
1313 -98, -63, -21, 77, 21, -77, 77, -21,
1314 -77, 21, 14, 98, -14, -98, 98, 14,
1315 -98, -14, 105, 105, -105, -105, -7, 119,
1316 7, -119, 119, -7, -119, 7, -63, 77,
1317 63, -77, 77, -63, -77, 63, -49, 105,
1318 49, -105, 105, -49, -105, 49, -119, 119,
1319 119, -119, 42, 42, -42, -42, 77, 77,
1323 const DT_2_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1324 0, 0, 8, 8, -8, -8, 0, 8,
1325 0, -8, 8, 0, -8, 0, 16, 16,
1326 -16, -16, 8, 16, -8, -16, 16, 8,
1327 -16, -8, -16, 16, 16, -16, -8, 24,
1328 8, -24, 24, -8, -24, 8, 16, 32,
1329 -16, -32, 32, 16, -32, -16, 32, 32,
1330 -32, -32, 0, 40, 0, -40, 40, 0,
1331 -40, 0, -24, 32, 24, -32, 32, -24,
1332 -32, 24, 40, 64, -40, -64, 64, 40,
1333 -64, -40, -16, 48, 16, -48, 48, -16,
1334 -48, 16, 16, 64, -16, -64, 64, 16,
1335 -64, -16, 64, 64, -64, -64, 0, 72,
1336 0, -72, 72, 0, -72, 0, -48, 48,
1337 48, -48, -32, 64, 32, -64, 64, -32,
1338 -64, 32, 40, 104, -40, -104, 104, 40,
1339 -104, -40, 72, 112, -72, -112, 112, 72,
1340 -112, -72, -24, 88, 24, -88, 88, -24,
1341 -88, 24, 16, 112, -16, -112, 112, 16,
1342 -112, -16, 120, 120, -120, -120, -72, 88,
1343 72, -88, 88, -72, -88, 72, -56, 120,
1344 56, -120, 120, -56, -120, 56, 48, 48,
1345 -48, -48, 88, 88, -88, -88,
1348 const DT_2_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1349 0, 0, 9, 9, -9, -9, 0, 9,
1350 0, -9, 9, 0, -9, 0, 18, 18,
1351 -18, -18, 9, 27, -9, -27, 27, 9,
1352 -27, -9, -18, 18, 18, -18, -9, 27,
1353 9, -27, 27, -9, -27, 9, 18, 36,
1354 -18, -36, 36, 18, -36, -18, 36, 36,
1355 -36, -36, 0, 45, 0, -45, 45, 0,
1356 -45, 0, -27, 36, 27, -36, 36, -27,
1357 -36, 27, 45, 72, -45, -72, 72, 45,
1358 -72, -45, -18, 54, 18, -54, 54, -18,
1359 -54, 18, 18, 72, -18, -72, 72, 18,
1360 -72, -18, 72, 72, -72, -72, 0, 81,
1361 0, -81, 81, 0, -81, 0, -54, 54,
1362 54, -54, -36, 72, 36, -72, 72, -36,
1363 -72, 36, 45, 117, -45, -117, 117, 45,
1364 -117, -45, 81, 126, -81, -126, 126, 81,
1365 -126, -81, -27, 99, 27, -99, 99, -27,
1366 -99, 27, -81, 99, 81, -99, 99, -81,
1367 -99, 81, 54, 54, -54, -54, 108, 108,
1371 const DT_3_1: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1372 0, 0, 2, 2, -2, -2, 0, 3,
1373 0, -3, 3, 0, -3, 0, 6, 6,
1374 -6, -6, 0, 7, 0, -7, 7, 0,
1375 -7, 0, -5, 5, 5, -5, 5, -5,
1376 -5, 5, 6, 11, -6, -11, 11, 6,
1377 -11, -6, 0, 8, 0, -8, 8, 0,
1378 -8, 0, 11, 11, -11, -11, 0, 12,
1379 0, -12, 12, 0, -12, 0, 12, 17,
1380 -12, -17, 17, 12, -17, -12, 17, 17,
1381 -17, -17, 6, 18, -6, -18, 18, 6,
1382 -18, -6, -8, 11, 8, -11, 11, -8,
1383 -11, 8, 0, 15, 0, -15, 15, 0,
1384 -15, 0, 0, 20, 0, -20, 20, 0,
1385 -20, 0, 18, 25, -18, -25, 25, 18,
1386 -25, -18, 11, 25, -11, -25, 25, 11,
1387 -25, -11, 25, 25, -25, -25, -14, 14,
1388 14, -14, 14, -14, -14, 14, 0, 26,
1389 0, -26, 26, 0, -26, 0, -11, 18,
1390 11, -18, 18, -11, -18, 11, -7, 22,
1391 7, -22, 22, -7, -22, 7, 26, 34,
1392 -26, -34, 34, 26, -34, -26, 18, 34,
1393 -18, -34, 34, 18, -34, -18, 34, 34,
1394 -34, -34, 11, 35, -11, -35, 35, 11,
1395 -35, -11, 0, 29, 0, -29, 29, 0,
1396 -29, 0, -19, 22, 19, -22, 22, -19,
1397 -22, 19, -15, 26, 15, -26, 26, -15,
1398 -26, 15, 0, 37, 0, -37, 37, 0,
1399 -37, 0, 27, 44, -27, -44, 44, 27,
1400 -44, -27, 36, 44, -36, -44, 44, 36,
1401 -44, -36, 18, 44, -18, -44, 44, 18,
1402 -44, -18, -10, 33, 10, -33, 33, -10,
1403 -33, 10, 45, 45, -45, -45, 0, 0,
1406 const DT_3_2: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1407 0, 0, 0, 2, 0, -2, 2, 0,
1408 -2, 0, 2, 2, -2, -2, 6, 6,
1409 -6, -6, 0, 6, 0, -6, 6, 0,
1410 -6, 0, -4, 4, 4, -4, 10, -6,
1411 -10, 6, 0, -12, 0, 12, -6, -12,
1412 6, -12, -6, 12, 6, 12, -14, 0,
1413 14, 0, 12, 12, -12, -12, 0, -18,
1414 0, 18, 14, -12, -14, 12, -18, -6,
1415 18, -6, -18, 6, 18, 6, -10, -18,
1416 10, -18, -10, 18, 10, 18, -22, 0,
1417 22, 0, 0, -24, 0, 24, -22, -12,
1418 22, -12, -22, 12, 22, 12, -8, -24,
1419 8, -24, -8, 24, 8, 24, -26, -6,
1420 26, -6, -26, 6, 26, 6, -28, 0,
1421 28, 0, 20, 20, -20, -20, -14, -26,
1422 14, 26, -30, -12, 30, 12, -10, -32,
1423 10, 32, -18, -32, 18, 32, -26, -26,
1424 26, 26, -34, -20, 34, 20, -38, -12,
1425 38, 12, -32, -32, 32, 32, 32, 32,
1426 -22, -40, -34, -34, 34, 34,
1429 const DT_3_3: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1430 0, 0, 0, 2, 0, -2, 2, 0,
1431 -2, 0, 4, 4, -4, -4, 10, 10,
1432 -10, -10, 0, 10, 0, -10, 10, 0,
1433 -10, 0, -6, 6, 6, -6, 14, -8,
1434 -14, 8, -18, 0, 18, 0, 10, -16,
1435 -10, 16, 0, -24, 0, 24, -24, -8,
1436 24, -8, -24, 8, 24, 8, 18, 18,
1437 -18, -18, 20, -16, -20, 16, -14, -26,
1438 14, -26, -14, 26, 14, 26, -30, 0,
1439 30, 0, 0, -34, 0, 34, -34, -8,
1440 34, -8, -34, 8, 34, 8, -30, -18,
1441 30, -18, -30, 18, 30, 18, -10, -34,
1442 10, -34, -10, 34, 10, 34, -20, -34,
1443 20, 34, -40, 0, 40, 0, 30, 30,
1444 -30, -30, -40, -18, 40, 18, 0, -44,
1445 0, 44, -16, -44, 16, 44, -36, -36,
1446 -36, -36, 36, 36, -26, -44, 26, 44,
1447 -46, -26, 46, 26, -52, -18, 52, 18,
1448 -20, -54, -44, -44, 44, 44, -32, -54,
1449 -46, -46, -46, -46, 46, 46,
1452 const DT_3_4: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1453 0, 0, 0, 4, 0, -4, 4, 0,
1454 -4, 0, 4, 4, -4, -4, 12, 12,
1455 -12, -12, 0, 12, 0, -12, 12, 0,
1456 -12, 0, -8, 8, 8, -8, 8, -16,
1457 -8, 16, 0, -24, 0, 24, -24, -8,
1458 24, -8, -24, 8, 24, 8, 20, -16,
1459 -20, 16, -28, 0, 28, 0, -16, -24,
1460 16, -24, -16, 24, 16, 24, 0, -32,
1461 0, 32, -28, -16, 28, -16, -28, 16,
1462 28, 16, -8, -32, 8, -32, -32, -8,
1463 32, -8, -32, 8, 32, 8, -8, 32,
1464 8, 32, 24, 24, -24, -24, 24, -24,
1465 -24, 24, -20, -32, 20, 32, -40, 0,
1466 40, 0, -40, -16, 40, 16, 0, -44,
1467 0, -44, -44, 0, 44, 0, 0, 44,
1468 0, 44, -32, -32, 32, 32, -16, -44,
1469 16, 44, -24, -44, -44, -24, 44, 24,
1470 24, 44, -48, -16, 48, 16, -36, -36,
1471 -36, -36, 36, 36, 36, 36, -20, -52,
1472 40, 40, -40, -40, -32, -52,
1475 const DT_3_5: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1476 0, 0, 2, 2, -2, -2, 6, 6,
1477 -6, -6, 12, 12, -12, -12, 20, 20,
1478 -20, -20, 32, 32, -32, -32, 46, 46,
1479 -46, -46, 0, 0, 0, 0, 0, 0,
1480 0, 0, 0, 0, 0, 0, 0, 0,
1481 0, 0, 0, 0, 0, 0, 0, 0,
1482 0, 0, 0, 0, 0, 0, 0, 0,
1483 0, 0, 0, 0, 0, 0, 0, 0,
1484 0, 0, 0, 0, 0, 0, 0, 0,
1485 0, 0, 0, 0, 0, 0, 0, 0,
1486 0, 0, 0, 0, 0, 0, 0, 0,
1487 0, 0, 0, 0, 0, 0, 0, 0,
1488 0, 0, 0, 0, 0, 0, 0, 0,
1489 0, 0, 0, 0, 0, 0, 0, 0,
1490 0, 0, 0, 0, 0, 0, 0, 0,
1491 0, 0, 0, 0, 0, 0, 0, 0,
1492 0, 0, 0, 0, 0, 0, 0, 0,
1493 0, 0, 0, 0, 0, 0, 0, 0,
1494 0, 0, 0, 0, 0, 0, 0, 0,
1498 const IVI3_DELTA_CBS: [&IviDeltaCB; 24] = [
1499 &DT_1_1, &DT_1_2, &DT_1_3, &DT_1_4, &DT_1_5, &DT_1_6, &DT_1_7, &DT_1_8,
1500 &DT_2_1, &DT_2_2, &DT_2_3, &DT_2_4, &DT_2_5, &DT_2_6, &DT_2_7, &DT_2_8,
1501 &DT_3_1, &DT_3_2, &DT_3_3, &DT_3_4, &DT_3_5, &DT_3_5, &DT_3_5, &DT_3_5