2 use std::cell::RefCell;
3 use nihav_core::formats;
4 use nihav_core::codecs::*;
5 use nihav_core::frame::*;
6 use nihav_core::io::byteio::*;
15 #[derive(Clone, Copy)]
29 const DEFAULT_PIXEL: u8 = 0x40;
32 fn new() -> Self { Buffers { width: 0, height: 0, buf1: Vec::new(), buf2: Vec::new(), fbuf: true } }
36 self.buf1.truncate(0);
37 self.buf2.truncate(0);
39 fn alloc(&mut self, w: usize, h: usize) {
42 self.buf1.resize(w * h + (w >> 2) * (h >> 2) * 2, DEFAULT_PIXEL);
43 self.buf2.resize(w * h + (w >> 2) * (h >> 2) * 2, DEFAULT_PIXEL);
45 fn flip(&mut self) { self.fbuf = !self.fbuf; }
46 fn get_stride(&mut self, planeno: usize) -> usize {
47 if planeno == 0 { self.width } else { self.width >> 2 }
49 fn get_offset(&mut self, planeno: usize) -> usize {
51 1 => self.width * self.height,
52 2 => self.width * self.height + (self.width >> 2) * (self.height >> 2),
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 = if self.fbuf { &self.buf1[0..] } else { &self.buf2[0..] };
65 let mut dst = fbuf.get_data_mut();
68 dst[doff + x] = src[soff + x] * 2;
75 fn copy_block(&mut self, doff: usize, soff: usize, stride: usize, w: usize, h: usize) {
80 for i in 0..w { self.buf1[didx + i] = self.buf2[sidx + i]; }
86 for i in 0..w { self.buf2[didx + i] = self.buf1[sidx + i]; }
92 fn fill_block(&mut self, doff: usize, stride: usize, w: usize, h: usize, topline: bool) {
94 let mut buf: [u8; 8] = [0; 8];
98 for i in 0..w { self.buf1[didx + i] = DEFAULT_PIXEL; }
103 for i in 0..w { self.buf2[didx + i] = DEFAULT_PIXEL; }
109 for i in 0..w { buf[i] = self.buf1[didx - stride + i]; }
111 for i in 0..w { self.buf1[didx + i] = buf[i]; }
115 for i in 0..w { buf[i] = self.buf2[didx - stride + i]; }
117 for i in 0..w { self.buf2[didx + i] = buf[i]; }
125 #[allow(unused_variables)]
126 fn apply_delta4x4(bufs: &mut Buffers, off: usize, stride: usize,
127 deltas: &[u8], topline: bool, first_line: bool) {
128 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4)] }
129 else { &mut bufs.buf2[off..(off + 4)] };
130 for i in 0..4 { dst[i] = dst[i].wrapping_add(deltas[i]) & 0x7F; }
133 #[allow(unused_variables)]
134 fn apply_delta4x8(bufs: &mut Buffers, off: usize, stride: usize,
135 deltas: &[u8], topline: bool, first_line: bool) {
136 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4 + stride)] }
137 else { &mut bufs.buf2[off..(off + 4 + stride)] };
138 for i in 0..4 { dst[i + stride] = dst[i].wrapping_add(deltas[i]) & 0x7F; }
140 for i in 0..4 { dst[i] = (dst[i + stride] + dst[i]) >> 1; }
142 for i in 0..4 { dst[i] = dst[i + stride]; }
146 #[allow(unused_variables)]
147 fn apply_delta4x8m11(bufs: &mut Buffers, off: usize, stride: usize,
148 deltas: &[u8], topline: bool, first_line: bool) {
149 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4 + stride)] }
150 else { &mut bufs.buf2[off..(off + 4 + stride)] };
151 for i in 0..4 { dst[i] = dst[i] .wrapping_add(deltas[i]) & 0x7F; }
152 for i in 0..4 { dst[i + stride] = dst[i + stride].wrapping_add(deltas[i]) & 0x7F; }
155 #[allow(unused_variables)]
156 fn apply_delta8x8p(bufs: &mut Buffers, off: usize, stride: usize,
157 deltas: &[u8], topline: bool, first_line: bool) {
158 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8 + stride)] }
159 else { &mut bufs.buf2[off..(off + 8 + stride)] };
160 for i in 0..8 { dst[i] = dst[i] .wrapping_add(deltas[i >> 1]) & 0x7F; }
161 for i in 0..8 { dst[i + stride] = dst[i + stride].wrapping_add(deltas[i >> 1]) & 0x7F; }
164 fn apply_delta8x8i(bufs: &mut Buffers, off: usize, stride: usize,
165 deltas: &[u8], topline: bool, firstline: bool) {
166 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8 + stride)] }
167 else { &mut bufs.buf2[off..(off + 8 + stride)] };
169 for i in 0..8 { dst[i + stride] = dst[i ].wrapping_add(deltas[i >> 1]) & 0x7F; }
171 for i in 0..8 { dst[i + stride] = dst[i & !1].wrapping_add(deltas[i >> 1]) & 0x7F; }
174 for i in 0..8 { dst[i] = (dst[i + stride] + dst[i]) >> 1; }
176 for i in 0..8 { dst[i] = dst[i + stride]; }
180 fn copy_line_top(bufs: &mut Buffers, off: usize, stride: usize, bw: usize, topline: bool) {
181 let mut buf: [u8; 8] = [0; 8];
183 let src = if bufs.fbuf { &bufs.buf1[(off - stride)..(off - stride + bw)] }
184 else { &bufs.buf2[(off - stride)..(off - stride + bw)] };
185 for i in 0..bw { buf[i] = src[i]; }
187 for i in 0..bw { buf[i] = DEFAULT_PIXEL; }
189 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + bw)] }
190 else { &mut bufs.buf2[off..(off + bw)] };
191 for i in 0..bw { dst[i] = buf[i]; }
194 fn copy_line_top4x4(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
195 copy_line_top(bufs, off, stride, 4, topline);
198 fn copy_line_top4x8(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
199 copy_line_top(bufs, off, stride, 4, topline);
200 copy_line_top(bufs, off + stride, stride, 4, false);
203 fn copy_line_top8x8(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
204 let mut buf: [u8; 8] = [0; 8];
206 let src = if bufs.fbuf { &bufs.buf1[(off - stride)..(off - stride + 8)] }
207 else { &bufs.buf2[(off - stride)..(off - stride + 8)] };
208 for i in 0..8 { buf[i] = src[i & !1]; }
210 for i in 0..8 { buf[i] = DEFAULT_PIXEL; }
212 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8)] }
213 else { &mut bufs.buf2[off..(off + 8)] };
214 for i in 0..8 {dst[i] = buf[i]; }
217 fn fill_block8x8(bufs: &mut Buffers, doff: usize, stride: usize, h: usize, topline: bool, firstline: bool) {
219 let mut buf: [u8; 8] = [0; 8];
221 for i in 0..8 { buf[i] = DEFAULT_PIXEL; }
222 } else if bufs.fbuf {
223 for i in 0..8 { buf[i] = bufs.buf1[doff - stride + i]; }
225 for i in 0..8 { buf[i] = bufs.buf1[doff - stride + i]; }
227 if topline && !firstline {
228 for i in 0..4 { buf[i * 2 + 1] = buf[i * 2]; }
230 for i in 0..8 { bufs.buf1[doff + i] = (bufs.buf1[doff - stride + i] + buf[i]) >> 1; }
232 for i in 0..8 { bufs.buf2[doff + i] = (bufs.buf2[doff - stride + i] + buf[i]) >> 1; }
236 let start = if !topline { 0 } else { 1 };
239 for i in 0..8 { bufs.buf1[didx + i] = buf[i]; }
244 for i in 0..8 { bufs.buf2[didx + i] = buf[i]; }
250 struct Indeo3Decoder {
251 info: Rc<NACodecInfo>,
262 #[derive(Clone,Copy)]
274 fn new(w: u16, h: u16) -> Self {
275 IV3Cell { x: 0, y: 0, w: w, h: h, d: 20, vqt: false, mv: None }
277 fn split_h(&self) -> (Self, Self) {
278 let h1 = if self.h > 2 { ((self.h + 2) >> 2) << 1 } else { 1 };
279 let h2 = self.h - h1;
280 let mut cell1 = *self;
283 let mut cell2 = *self;
289 fn split_w(&self, stripw: u16) -> (Self, Self) {
290 let w1 = if self.w > stripw {
291 if self.w > stripw * 2 { stripw * 2 } else { stripw }
293 if self.w > 2 { ((self.w + 2) >> 2) << 1 } else { 1 }
295 let w2 = self.w - w1;
296 let mut cell1 = *self;
299 let mut cell2 = *self;
305 fn no_mv(&self) -> bool { match self.mv { None => true, Some(_) => false } }
308 struct CellDecParams {
314 apply_delta: fn (&mut Buffers, usize, usize, &[u8], bool, bool),
315 copy_line_top: fn (&mut Buffers, usize, usize, bool),
318 const FRMH_TAG: u32 = ((b'F' as u32) << 24) | ((b'R' as u32) << 16)
319 | ((b'M' as u32) << 8) | (b'H' as u32);
321 const H_SPLIT: u8 = 0;
322 const V_SPLIT: u8 = 1;
323 const SKIP_OR_TREE: u8 = 2;
327 let dummy_info = Rc::new(DUMMY_CODEC_INFO);
328 Indeo3Decoder { info: dummy_info, bpos: 0, bbuf: 0, width: 0, height: 0,
329 mvs: Vec::new(), altquant: [0; 16],
330 vq_offset: 0, bufs: Buffers::new() }
333 fn br_reset(&mut self) {
338 fn get_2bits(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
340 self.bbuf = br.read_byte()?;
344 Ok((self.bbuf >> self.bpos) & 0x3)
347 fn decode_cell_data(&mut self, br: &mut ByteReader, cell: IV3Cell,
348 off: usize, stride: usize, params: CellDecParams) -> DecoderResult<()> {
349 let blk_w = cell.w * 4 / params.bw;
350 let blk_h = cell.h * 4 / params.bh;
351 let scale: usize = if params.bh == 4 { 1 } else { 2 };
353 validate!((((cell.w * 4) % params.bw) == 0) && (((cell.h * 4) % params.bh) == 0));
355 let mut run_blocks = 0;
356 let mut run_skip = false;
358 let mut didx: usize = ((cell.x*4) as usize) + ((cell.y * 4) as usize) * stride + off;
363 let mv = cell.mv.unwrap();
364 let mx = mv.x as i16;
365 let my = mv.y as i16;
366 let l = (cell.x as i16) * 4 + mx;
367 let t = (cell.y as i16) * 4 + my;
368 let r = ((cell.x + cell.w) as i16) * 4 + mx;
369 let b = ((cell.y + cell.h) as i16) * 4 + my;
372 validate!(r <= (self.width as i16));
373 validate!(b <= (self.height as i16));
374 sidx = (l as usize) + (t as usize) * stride + off;
377 let mut xoff: usize = 0;
380 if !run_skip || !cell.no_mv() {
381 if !(params.bw == 8 && cell.no_mv()) {
383 self.bufs.copy_block(didx + xoff, sidx + xoff, stride,
384 params.bw as usize, params.bh as usize);
386 self.bufs.fill_block(didx + xoff, stride,
387 params.bw as usize, params.bh as usize,
388 (cell.y == 0) && (y == 0));
391 fill_block8x8(&mut self.bufs,
392 didx + xoff, stride, 8,
393 y == 0, (cell.y == 0) && (y == 0));
398 let mut line: usize = 0;
400 let c = br.read_byte()?;
402 let delta_tab = if params.hq {
403 IVI3_DELTA_CBS[params.tab[line & 1]]
405 IVI3_DELTA_CBS[params.tab[1]]
409 if (c as usize) < delta_tab.data.len()/2 {
410 idx1 = br.read_byte()? as usize;
411 validate!(idx1 < delta_tab.data.len());
414 let tmp = (c as usize) - delta_tab.data.len()/2;
415 idx1 = tmp / (delta_tab.quad_radix as usize);
416 idx2 = tmp % (delta_tab.quad_radix as usize);
417 if params.swap_q[line & 1] {
418 mem::swap(&mut idx1, &mut idx2);
421 let deltas: [u8; 4] = [delta_tab.data[idx1 * 2] as u8,
422 delta_tab.data[idx1 * 2 + 1] as u8,
423 delta_tab.data[idx2 * 2 + 0] as u8,
424 delta_tab.data[idx2 * 2 + 1] as u8];
425 let topline = (cell.y == 0) && (y == 0) && (line == 0);
426 let first_line = (y == 0) && (line == 0);
428 (params.copy_line_top)(&mut self.bufs,
429 didx + xoff + line * scale * stride,
432 self.bufs.copy_block(didx + xoff + line * scale * stride,
433 sidx + xoff + line * scale * stride,
434 stride, params.bw as usize, scale);
436 (params.apply_delta)(&mut self.bufs,
437 didx + xoff + line * scale * stride,
438 stride, &deltas, topline, first_line);
441 let mut tocopy: usize = 0;
442 let mut do_copy = true;
443 if c == 0xF8 { return Err(DecoderError::InvalidData); }
447 validate!(line == 0);
449 do_copy = !cell.no_mv();
452 validate!(line == 0);
454 do_copy = !cell.no_mv();
457 let c = br.read_byte()?;
458 validate!((c < 64) && ((c & 0x1F) != 0));
459 run_blocks = (c & 0x1F) - 1;
460 run_skip = (c & 0x20) != 0;
462 if params.bw == 4 && cell.no_mv() && run_skip {
472 let nl = 257 - (c as i16) - (line as i16);
474 tocopy = nl as usize;
477 if !(params.bw == 8 && cell.no_mv()) {
479 self.bufs.copy_block(didx + xoff + line * scale * stride,
480 sidx + xoff + line * scale * stride,
481 stride, params.bw as usize,
484 self.bufs.fill_block(didx + xoff + line * scale * stride,
485 stride, params.bw as usize,
487 (cell.y == 0) && (y == 0) && (line == 0));
490 fill_block8x8(&mut self.bufs,
491 didx + xoff + line * 2 * stride,
493 (y == 0) && (line == 0),
494 (cell.y == 0) && (y == 0) && (line == 0));
501 xoff += params.bw as usize;
503 didx += stride * (params.bh as usize);
504 sidx += stride * (params.bh as usize);
509 fn copy_cell(&mut self, cell: IV3Cell, off: usize, stride: usize) -> DecoderResult<()> {
510 if cell.no_mv() { return Err(DecoderError::InvalidData); }
511 let mv = cell.mv.unwrap();
512 let mx = mv.x as i16;
513 let my = mv.y as i16;
514 let l = (cell.x as i16) * 4 + mx;
515 let t = (cell.y as i16) * 4 + my;
516 let r = ((cell.x + cell.w) as i16) * 4 + mx;
517 let b = ((cell.y + cell.h) as i16) * 4 + my;
520 validate!(r <= (self.width as i16));
521 validate!(b <= (self.height as i16));
522 let sidx: usize = off + (l as usize) + (t as usize) * stride;
523 let didx: usize = off + ((cell.x * 4) as usize) + ((cell.y * 4) as usize) * stride;
524 self.bufs.copy_block(didx, sidx, stride, (cell.w * 4) as usize, (cell.h * 4) as usize);
528 fn decode_cell(&mut self, br: &mut ByteReader, cell: IV3Cell, off: usize,
529 stride: usize, intra: bool) -> DecoderResult<()> {
530 let code = br.read_byte()?;
531 let mode = code >> 4;
532 let vq_idx = code & 0xF;
534 let mut idx1: usize = vq_idx as usize;
535 let mut idx2: usize = vq_idx as usize;
536 if (mode == 1) || (mode == 4) {
537 let c = self.altquant[vq_idx as usize];
538 idx1 = (c >> 4) as usize;
539 idx2 = (c & 0xF) as usize;
542 idx1 += self.vq_offset as usize;
543 idx2 += self.vq_offset as usize;
544 validate!((idx1 < 24) && (idx2 < 24));
546 let mut cp = CellDecParams {
549 swap_q: [idx2 >= 16, idx1 >= 16],
551 apply_delta: apply_delta4x4,
552 copy_line_top: copy_line_top4x4,
554 if (mode == 0) || (mode == 1) {
558 } else if (mode == 3) || (mode == 4) {
559 if !cell.no_mv() { return Err(DecoderError::InvalidData); }
563 cp.apply_delta = apply_delta4x8;
564 cp.copy_line_top = copy_line_top4x8;
565 } else if mode == 10 {
568 cp.apply_delta = apply_delta8x8p;
570 cp.apply_delta = apply_delta8x8i;
574 cp.copy_line_top = copy_line_top8x8;
575 } else if mode == 11 {
576 if cell.no_mv() { return Err(DecoderError::InvalidData); }
580 cp.apply_delta = apply_delta4x8m11;
581 cp.copy_line_top = copy_line_top4x8;
583 return Err(DecoderError::InvalidData);
585 self.decode_cell_data(br, cell, off, stride, cp)
588 fn parse_tree(&mut self, br: &mut ByteReader, cell: IV3Cell, off: usize,
589 stride: usize, stripw: u16, intra: bool) -> DecoderResult<()> {
590 let op = self.get_2bits(br)?;
592 validate!(cell.h > 1);
593 validate!(cell.d > 0);
594 let (cell1, cell2) = cell.split_h();
595 self.parse_tree(br, cell1, off, stride, stripw, intra)?;
596 self.parse_tree(br, cell2, off, stride, stripw, intra)?;
598 } else if op == V_SPLIT {
599 validate!(cell.w > 1);
600 validate!(cell.d > 0);
601 let (cell1, cell2) = cell.split_w(stripw);
602 self.parse_tree(br, cell1, off, stride, stripw, intra)?;
603 self.parse_tree(br, cell2, off, stride, stripw, intra)?;
605 } else if op == SKIP_OR_TREE {
607 let mut newcell = cell;
610 self.parse_tree(br, newcell, off, stride, stripw, intra)
613 let code = self.get_2bits(br)?;
615 if code == 1 { return Err(DecoderError::NotImplemented); }
616 self.copy_cell(cell, off, stride)
620 let mut newcell = cell;
623 let mv_idx = br.read_byte()? as usize;
624 validate!(mv_idx < self.mvs.len());
625 newcell.mv = Some(self.mvs[mv_idx]);
626 self.parse_tree(br, newcell, off, stride, stripw, intra)
628 self.decode_cell(br, cell, off, stride, intra)
633 fn decode_plane_intra(&mut self, br: &mut ByteReader, planeno: usize,
634 start: u64, end: u64) -> DecoderResult<()> {
635 let offs = self.bufs.get_offset(planeno);
636 let stride = self.bufs.get_stride(planeno);
637 br.seek(SeekFrom::Start(start))?;
639 let nvec = br.read_u32le()?;
640 validate!(nvec == 0); // for intra there should be no mc_vecs
641 self.mvs.truncate(0);
643 let x = br.read_byte()? as i8;
644 let y = br.read_byte()? as i8;
645 self.mvs.push(MV{ x: x, y: y });
648 let shift = if planeno == 0 { 2 } else { 4 };
649 let cell = IV3Cell::new((self.bufs.width >> shift) as u16,
650 (self.bufs.height >> shift) as u16);
652 self.parse_tree(br, cell, offs, stride, if planeno > 0 { 10 } else { 40 }, true)?;
653 validate!(br.tell() <= end);
657 fn decode_plane_inter(&mut self, br: &mut ByteReader, planeno: usize,
658 start: u64, end: u64) -> DecoderResult<()> {
659 let offs = self.bufs.get_offset(planeno);
660 let stride = self.bufs.get_stride(planeno);
661 br.seek(SeekFrom::Start(start))?;
663 let nvec = br.read_u32le()?;
664 validate!(nvec <= 256); // for intra there should be no mc_vecs
665 self.mvs.truncate(0);
667 let y = br.read_byte()? as i8;
668 let x = br.read_byte()? as i8;
669 self.mvs.push(MV{ x: x, y: y });
672 let shift = if planeno == 0 { 2 } else { 4 };
673 let cell = IV3Cell::new((self.bufs.width >> shift) as u16,
674 (self.bufs.height >> shift) as u16);
676 self.parse_tree(br, cell, offs, stride, if planeno > 0 { 10 } else { 40 }, false)?;
677 validate!(br.tell() <= end);
682 const FLAG_KEYFRAME: u16 = 1 << 2;
683 const FLAG_NONREF: u16 = 1 << 8;
685 impl NADecoder for Indeo3Decoder {
686 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
687 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
688 let w = vinfo.get_width();
689 let h = vinfo.get_height();
690 let fmt = formats::YUV410_FORMAT;
691 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, fmt));
692 self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
696 Err(DecoderError::InvalidData)
699 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
700 let src = pkt.get_buffer();
701 let mut mr = MemoryReader::new_read(&src);
702 let mut br = ByteReader::new(&mut mr);
703 let frameno = br.read_u32le()?;
704 let hdr_2 = br.read_u32le()?;
705 let check = br.read_u32le()?;
706 let size = br.read_u32le()?;
708 let data_start = br.tell();
710 if (frameno ^ hdr_2 ^ size ^ FRMH_TAG) != check {
711 return Err(DecoderError::InvalidData);
713 if (size as i64) > br.left() { return Err(DecoderError::InvalidData); }
714 let ver = br.read_u16le()?;
715 if ver != 32 { return Err(DecoderError::NotImplemented); }
716 let flags = br.read_u16le()?;
717 let size2 = br.read_u32le()?;
718 validate!(((size2 + 7) >> 3) <= size);
719 let cb = br.read_byte()?;
722 let height = br.read_u16le()?;
723 let width = br.read_u16le()?;
724 validate!((width >= 16) && (width <= 640));
725 validate!((height >= 16) && (height <= 640));
726 validate!(((width & 3) == 0) && ((height & 3) == 0));
727 if (self.bufs.width != (width as usize)) || (self.bufs.height != (height as usize)) {
728 self.bufs.alloc(width as usize, height as usize);
731 self.height = height;
733 let yoff = br.read_u32le()?;
734 let uoff = br.read_u32le()?;
735 let voff = br.read_u32le()?;
736 if yoff > size { return Err(DecoderError::InvalidData); }
737 if uoff > size { return Err(DecoderError::InvalidData); }
738 if voff > size { return Err(DecoderError::InvalidData); }
741 br.read_buf(&mut self.altquant)?;
743 let mut yend = src.len() as u32;//size;
744 if (uoff < yend) && (uoff > yoff) { yend = uoff; }
745 if (voff < yend) && (voff > yoff) { yend = voff; }
747 if (yoff < uend) && (yoff > uoff) { uend = yoff; }
748 if (voff < uend) && (voff > uoff) { uend = voff; }
750 if (yoff < vend) && (yoff > voff) { vend = yoff; }
751 if (uoff < vend) && (uoff > voff) { vend = uoff; }
753 let intraframe = (flags & FLAG_KEYFRAME) != 0;
754 let vinfo = self.info.get_properties().get_video_info().unwrap();
755 let bufret = alloc_video_buffer(vinfo, 2);
756 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
757 let mut bufinfo = bufret.unwrap();
758 let mut buf = bufinfo.get_vbuf().unwrap();
759 let ystart = data_start + (yoff as u64);
760 let ustart = data_start + (uoff as u64);
761 let vstart = data_start + (voff as u64);
762 let yendpos = data_start + (yend as u64);
763 let uendpos = data_start + (uend as u64);
764 let vendpos = data_start + (vend as u64);
766 self.decode_plane_intra(&mut br, 0, ystart, yendpos)?;
767 self.decode_plane_intra(&mut br, 1, ustart, uendpos)?;
768 self.decode_plane_intra(&mut br, 2, vstart, vendpos)?;
770 self.decode_plane_inter(&mut br, 0, ystart, yendpos)?;
771 self.decode_plane_inter(&mut br, 1, ustart, uendpos)?;
772 self.decode_plane_inter(&mut br, 2, vstart, vendpos)?;
774 self.bufs.fill_framebuf(&mut buf);
775 if (flags & FLAG_NONREF) == 0 { self.bufs.flip(); }
776 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
777 frm.set_keyframe(intraframe);
778 frm.set_frame_type(if intraframe { FrameType::I } else { FrameType::P });
779 Ok(Rc::new(RefCell::new(frm)))
783 pub fn get_decoder() -> Box<NADecoder> {
784 Box::new(Indeo3Decoder::new())
789 use nihav_core::codecs::RegisteredDecoders;
790 use nihav_core::demuxers::RegisteredDemuxers;
791 use nihav_core::test::dec_video::*;
792 use crate::codecs::indeo_register_all_codecs;
793 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
796 let mut dmx_reg = RegisteredDemuxers::new();
797 generic_register_all_demuxers(&mut dmx_reg);
798 let mut dec_reg = RegisteredDecoders::new();
799 indeo_register_all_codecs(&mut dec_reg);
801 test_file_decoding("avi", "assets/iv32_example.avi", Some(10), true, false, None, &dmx_reg, &dec_reg);
805 const DT_1_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
806 0, 0, 2, 2, -2, -2, -1, 3,
807 1, -3, 3, -1, -3, 1, 4, 4,
808 -4, -4, 1, 5, -1, -5, 5, 1,
809 -5, -1, -4, 4, 4, -4, -2, 6,
810 2, -6, 6, -2, -6, 2, 4, 9,
811 -4, -9, 9, 4, -9, -4, 9, 9,
812 -9, -9, 1, 10, -1, -10, 10, 1,
813 -10, -1, -5, 8, 5, -8, 8, -5,
814 -8, 5, 9, 15, -9, -15, 15, 9,
815 -15, -9, -3, 12, 3, -12, 12, -3,
816 -12, 3, 4, 16, -4, -16, 16, 4,
817 -16, -4, 16, 16, -16, -16, 0, 18,
818 0, -18, 18, 0, -18, 0, -12, 12,
819 12, -12, -9, 16, 9, -16, 16, -9,
820 -16, 9, 11, 27, -11, -27, 27, 11,
821 -27, -11, 19, 28, -19, -28, 28, 19,
822 -28, -19, -6, 22, 6, -22, 22, -6,
823 -22, 6, 4, 29, -4, -29, 29, 4,
824 -29, -4, 30, 30, -30, -30, -2, 33,
825 2, -33, 33, -2, -33, 2, -18, 23,
826 18, -23, 23, -18, -23, 18, -15, 30,
827 15, -30, 30, -15, -30, 15, 22, 46,
828 -22, -46, 46, 22, -46, -22, 13, 47,
829 -13, -47, 47, 13, -47, -13, 35, 49,
830 -35, -49, 49, 35, -49, -35, -11, 41,
831 11, -41, 41, -11, -41, 11, 4, 51,
832 -4, -51, 51, 4, -51, -4, 54, 54,
833 -54, -54, -34, 34, 34, -34, -29, 42,
834 29, -42, 42, -29, -42, 29, -6, 60,
835 6, -60, 60, -6, -60, 6, 27, 76,
836 -27, -76, 76, 27, -76, -27, 43, 77,
837 -43, -77, 77, 43, -77, -43, -24, 55,
838 24, -55, 55, -24, -55, 24, 14, 79,
839 -14, -79, 79, 14, -79, -14, 63, 83,
840 -63, -83, 83, 63, -83, -63, -20, 74,
841 20, -74, 74, -20, -74, 20, 2, 88,
842 -2, -88, 88, 2, -88, -2, 93, 93,
843 -93, -93, -52, 61, 52, -61, 61, -52,
844 -61, 52, 52, 120, -52, -120, 120, 52,
845 -120, -52, -45, 75, 45, -75, 75, -45,
846 -75, 45, 75, 125, -75, -125, 125, 75,
847 -125, -75, 33, 122, -33, -122, 122, 33,
848 -122, -33, -13, 103, 13, -103, 103, -13,
849 -103, 13, -40, 96, 40, -96, 96, -40,
850 -96, 40, -34, 127, 34, -127, 127, -34,
851 -127, 34, -89, 89, 89, -89, -78, 105,
852 78, -105, 105, -78, -105, 78, 12, 12,
853 -12, -12, 23, 23, -23, -23, 42, 42,
854 -42, -42, 73, 73, -73, -73,
857 const DT_1_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
858 0, 0, 3, 3, -3, -3, -1, 4,
859 1, -4, 4, -1, -4, 1, 7, 7,
860 -7, -7, 2, 8, -2, -8, 8, 2,
861 -8, -2, -2, 9, 2, -9, 9, -2,
862 -9, 2, -6, 6, 6, -6, 6, 13,
863 -6, -13, 13, 6, -13, -6, 13, 13,
864 -13, -13, 1, 14, -1, -14, 14, 1,
865 -14, -1, -8, 12, 8, -12, 12, -8,
866 -12, 8, 14, 23, -14, -23, 23, 14,
867 -23, -14, -5, 18, 5, -18, 18, -5,
868 -18, 5, 6, 24, -6, -24, 24, 6,
869 -24, -6, 24, 24, -24, -24, -1, 27,
870 1, -27, 27, -1, -27, 1, -17, 17,
871 17, -17, -13, 23, 13, -23, 23, -13,
872 -23, 13, 16, 40, -16, -40, 40, 16,
873 -40, -16, 28, 41, -28, -41, 41, 28,
874 -41, -28, -9, 33, 9, -33, 33, -9,
875 -33, 9, 6, 43, -6, -43, 43, 6,
876 -43, -6, 46, 46, -46, -46, -4, 50,
877 4, -50, 50, -4, -50, 4, -27, 34,
878 27, -34, 34, -27, -34, 27, -22, 45,
879 22, -45, 45, -22, -45, 22, 34, 69,
880 -34, -69, 69, 34, -69, -34, 19, 70,
881 -19, -70, 70, 19, -70, -19, 53, 73,
882 -53, -73, 73, 53, -73, -53, -17, 62,
883 17, -62, 62, -17, -62, 17, 5, 77,
884 -5, -77, 77, 5, -77, -5, 82, 82,
885 -82, -82, -51, 51, 51, -51, -43, 64,
886 43, -64, 64, -43, -64, 43, -10, 90,
887 10, -90, 90, -10, -90, 10, 41, 114,
888 -41, -114, 114, 41, -114, -41, 64, 116,
889 -64, -116, 116, 64, -116, -64, -37, 82,
890 37, -82, 82, -37, -82, 37, 22, 119,
891 -22, -119, 119, 22, -119, -22, 95, 124,
892 -95, -124, 124, 95, -124, -95, -30, 111,
893 30, -111, 111, -30, -111, 30, -78, 92,
894 78, -92, 92, -78, -92, 78, -68, 113,
895 68, -113, 113, -68, -113, 68, 18, 18,
896 -18, -18, 34, 34, -34, -34, 63, 63,
897 -63, -63, 109, 109, -109, -109,
900 const DT_1_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
901 0, 0, 4, 4, -4, -4, -1, 5,
902 1, -5, 5, -1, -5, 1, 3, 10,
903 -3, -10, 10, 3, -10, -3, 9, 9,
904 -9, -9, -7, 7, 7, -7, -3, 12,
905 3, -12, 12, -3, -12, 3, 8, 17,
906 -8, -17, 17, 8, -17, -8, 17, 17,
907 -17, -17, 1, 19, -1, -19, 19, 1,
908 -19, -1, -11, 16, 11, -16, 16, -11,
909 -16, 11, -6, 23, 6, -23, 23, -6,
910 -23, 6, 18, 31, -18, -31, 31, 18,
911 -31, -18, 8, 32, -8, -32, 32, 8,
912 -32, -8, 33, 33, -33, -33, -1, 36,
913 1, -36, 36, -1, -36, 1, -23, 23,
914 23, -23, -17, 31, 17, -31, 31, -17,
915 -31, 17, 21, 54, -21, -54, 54, 21,
916 -54, -21, 37, 55, -37, -55, 55, 37,
917 -55, -37, -12, 44, 12, -44, 44, -12,
918 -44, 12, 8, 57, -8, -57, 57, 8,
919 -57, -8, 61, 61, -61, -61, -5, 66,
920 5, -66, 66, -5, -66, 5, -36, 45,
921 36, -45, 45, -36, -45, 36, -29, 60,
922 29, -60, 60, -29, -60, 29, 45, 92,
923 -45, -92, 92, 45, -92, -45, 25, 93,
924 -25, -93, 93, 25, -93, -25, 71, 97,
925 -71, -97, 97, 71, -97, -71, -22, 83,
926 22, -83, 83, -22, -83, 22, 7, 102,
927 -7, -102, 102, 7, -102, -7, 109, 109,
928 -109, -109, -68, 68, 68, -68, -57, 85,
929 57, -85, 85, -57, -85, 57, -13, 120,
930 13, -120, 120, -13, -120, 13, -49, 110,
931 49, -110, 110, -49, -110, 49, -104, 123,
932 104, -123, 123, -104, -123, 104, 24, 24,
933 -24, -24, 46, 46, -46, -46, 84, 84,
937 const DT_1_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
938 0, 0, 5, 5, -5, -5, -2, 7,
939 2, -7, 7, -2, -7, 2, 11, 11,
940 -11, -11, 3, 13, -3, -13, 13, 3,
941 -13, -3, -9, 9, 9, -9, -4, 15,
942 4, -15, 15, -4, -15, 4, 11, 22,
943 -11, -22, 22, 11, -22, -11, 21, 21,
944 -21, -21, 2, 24, -2, -24, 24, 2,
945 -24, -2, -14, 20, 14, -20, 20, -14,
946 -20, 14, 23, 38, -23, -38, 38, 23,
947 -38, -23, -8, 29, 8, -29, 29, -8,
948 -29, 8, 11, 39, -11, -39, 39, 11,
949 -39, -11, 41, 41, -41, -41, -1, 45,
950 1, -45, 45, -1, -45, 1, -29, 29,
951 29, -29, -22, 39, 22, -39, 39, -22,
952 -39, 22, 27, 67, -27, -67, 67, 27,
953 -67, -27, 47, 69, -47, -69, 69, 47,
954 -69, -47, -15, 56, 15, -56, 56, -15,
955 -56, 15, 11, 71, -11, -71, 71, 11,
956 -71, -11, 76, 76, -76, -76, -6, 83,
957 6, -83, 83, -6, -83, 6, -45, 57,
958 45, -57, 57, -45, -57, 45, -36, 75,
959 36, -75, 75, -36, -75, 36, 56, 115,
960 -56, -115, 115, 56, -115, -56, 31, 117,
961 -31, -117, 117, 31, -117, -31, 88, 122,
962 -88, -122, 122, 88, -122, -88, -28, 104,
963 28, -104, 104, -28, -104, 28, -85, 85,
964 85, -85, -72, 106, 72, -106, 106, -72,
965 -106, 72, 30, 30, -30, -30, 58, 58,
966 -58, -58, 105, 105, -105, -105,
969 const DT_1_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
970 0, 0, 6, 6, -6, -6, -2, 8,
971 2, -8, 8, -2, -8, 2, 13, 13,
972 -13, -13, 4, 15, -4, -15, 15, 4,
973 -15, -4, -11, 11, 11, -11, -5, 18,
974 5, -18, 18, -5, -18, 5, 13, 26,
975 -13, -26, 26, 13, -26, -13, 26, 26,
976 -26, -26, 2, 29, -2, -29, 29, 2,
977 -29, -2, -16, 24, 16, -24, 24, -16,
978 -24, 16, 28, 46, -28, -46, 46, 28,
979 -46, -28, -9, 35, 9, -35, 35, -9,
980 -35, 9, 13, 47, -13, -47, 47, 13,
981 -47, -13, 49, 49, -49, -49, -1, 54,
982 1, -54, 54, -1, -54, 1, -35, 35,
983 35, -35, -26, 47, 26, -47, 47, -26,
984 -47, 26, 32, 81, -32, -81, 81, 32,
985 -81, -32, 56, 83, -56, -83, 83, 56,
986 -83, -56, -18, 67, 18, -67, 67, -18,
987 -67, 18, 13, 86, -13, -86, 86, 13,
988 -86, -13, 91, 91, -91, -91, -7, 99,
989 7, -99, 99, -7, -99, 7, -54, 68,
990 54, -68, 68, -54, -68, 54, -44, 90,
991 44, -90, 90, -44, -90, 44, -33, 124,
992 33, -124, 124, -33, -124, 33, -103, 103,
993 103, -103, -86, 127, 86, -127, 127, -86,
994 -127, 86, 37, 37, -37, -37, 69, 69,
998 const DT_1_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
999 0, 0, 7, 7, -7, -7, -3, 10,
1000 3, -10, 10, -3, -10, 3, 16, 16,
1001 -16, -16, 5, 18, -5, -18, 18, 5,
1002 -18, -5, -13, 13, 13, -13, -6, 21,
1003 6, -21, 21, -6, -21, 6, 15, 30,
1004 -15, -30, 30, 15, -30, -15, 30, 30,
1005 -30, -30, 2, 34, -2, -34, 34, 2,
1006 -34, -2, -19, 28, 19, -28, 28, -19,
1007 -28, 19, 32, 54, -32, -54, 54, 32,
1008 -54, -32, -11, 41, 11, -41, 41, -11,
1009 -41, 11, 15, 55, -15, -55, 55, 15,
1010 -55, -15, 57, 57, -57, -57, -1, 63,
1011 1, -63, 63, -1, -63, 1, -40, 40,
1012 40, -40, -30, 55, 30, -55, 55, -30,
1013 -55, 30, 37, 94, -37, -94, 94, 37,
1014 -94, -37, 65, 96, -65, -96, 96, 65,
1015 -96, -65, -21, 78, 21, -78, 78, -21,
1016 -78, 21, 15, 100, -15, -100, 100, 15,
1017 -100, -15, 106, 106, -106, -106, -8, 116,
1018 8, -116, 116, -8, -116, 8, -63, 79,
1019 63, -79, 79, -63, -79, 63, -51, 105,
1020 51, -105, 105, -51, -105, 51, -120, 120,
1021 120, -120, 43, 43, -43, -43, 80, 80,
1025 const DT_1_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1026 0, 0, 8, 8, -8, -8, -3, 11,
1027 3, -11, 11, -3, -11, 3, 18, 18,
1028 -18, -18, 5, 20, -5, -20, 20, 5,
1029 -20, -5, -15, 15, 15, -15, -7, 24,
1030 7, -24, 24, -7, -24, 7, 17, 35,
1031 -17, -35, 35, 17, -35, -17, 34, 34,
1032 -34, -34, 3, 38, -3, -38, 38, 3,
1033 -38, -3, -22, 32, 22, -32, 32, -22,
1034 -32, 22, 37, 61, -37, -61, 61, 37,
1035 -61, -37, -13, 47, 13, -47, 47, -13,
1036 -47, 13, 17, 63, -17, -63, 63, 17,
1037 -63, -17, 65, 65, -65, -65, -1, 72,
1038 1, -72, 72, -1, -72, 1, -46, 46,
1039 46, -46, -35, 63, 35, -63, 63, -35,
1040 -63, 35, 43, 107, -43, -107, 107, 43,
1041 -107, -43, 75, 110, -75, -110, 110, 75,
1042 -110, -75, -24, 89, 24, -89, 89, -24,
1043 -89, 24, 17, 114, -17, -114, 114, 17,
1044 -114, -17, 121, 121, -121, -121, -72, 91,
1045 72, -91, 91, -72, -91, 72, -58, 120,
1046 58, -120, 120, -58, -120, 58, 49, 49,
1047 -49, -49, 92, 92, -92, -92,
1050 const DT_1_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1051 0, 0, 9, 9, -9, -9, -3, 12,
1052 3, -12, 12, -3, -12, 3, 20, 20,
1053 -20, -20, 6, 23, -6, -23, 23, 6,
1054 -23, -6, -17, 17, 17, -17, -7, 27,
1055 7, -27, 27, -7, -27, 7, 19, 39,
1056 -19, -39, 39, 19, -39, -19, 39, 39,
1057 -39, -39, 3, 43, -3, -43, 43, 3,
1058 -43, -3, -24, 36, 24, -36, 36, -24,
1059 -36, 24, 42, 69, -42, -69, 69, 42,
1060 -69, -42, -14, 53, 14, -53, 53, -14,
1061 -53, 14, 19, 71, -19, -71, 71, 19,
1062 -71, -19, 73, 73, -73, -73, -2, 80,
1063 2, -80, 80, -2, -80, 2, -52, 52,
1064 52, -52, -39, 70, 39, -70, 70, -39,
1065 -70, 39, 48, 121, -48, -121, 121, 48,
1066 -121, -48, 84, 124, -84, -124, 124, 84,
1067 -124, -84, -27, 100, 27, -100, 100, -27,
1068 -100, 27, -81, 102, 81, -102, 102, -81,
1069 -102, 81, 55, 55, -55, -55, 104, 104,
1073 const DT_2_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
1074 0, 0, 2, 2, -2, -2, 0, 2,
1075 0, -2, 2, 0, -2, 0, 4, 4,
1076 -4, -4, 0, 4, 0, -4, 4, 0,
1077 -4, 0, -4, 4, 4, -4, -2, 6,
1078 2, -6, 6, -2, -6, 2, 4, 8,
1079 -4, -8, 8, 4, -8, -4, 8, 8,
1080 -8, -8, 0, 10, 0, -10, 10, 0,
1081 -10, 0, -4, 8, 4, -8, 8, -4,
1082 -8, 4, 8, 14, -8, -14, 14, 8,
1083 -14, -8, -2, 12, 2, -12, 12, -2,
1084 -12, 2, 4, 16, -4, -16, 16, 4,
1085 -16, -4, 16, 16, -16, -16, 0, 18,
1086 0, -18, 18, 0, -18, 0, -12, 12,
1087 12, -12, -8, 16, 8, -16, 16, -8,
1088 -16, 8, 10, 26, -10, -26, 26, 10,
1089 -26, -10, 18, 28, -18, -28, 28, 18,
1090 -28, -18, -6, 22, 6, -22, 22, -6,
1091 -22, 6, 4, 28, -4, -28, 28, 4,
1092 -28, -4, 30, 30, -30, -30, -2, 32,
1093 2, -32, 32, -2, -32, 2, -18, 22,
1094 18, -22, 22, -18, -22, 18, -14, 30,
1095 14, -30, 30, -14, -30, 14, 22, 46,
1096 -22, -46, 46, 22, -46, -22, 12, 46,
1097 -12, -46, 46, 12, -46, -12, 34, 48,
1098 -34, -48, 48, 34, -48, -34, -10, 40,
1099 10, -40, 40, -10, -40, 10, 4, 50,
1100 -4, -50, 50, 4, -50, -4, 54, 54,
1101 -54, -54, -34, 34, 34, -34, -28, 42,
1102 28, -42, 42, -28, -42, 28, -6, 60,
1103 6, -60, 60, -6, -60, 6, 26, 76,
1104 -26, -76, 76, 26, -76, -26, 42, 76,
1105 -42, -76, 76, 42, -76, -42, -24, 54,
1106 24, -54, 54, -24, -54, 24, 14, 78,
1107 -14, -78, 78, 14, -78, -14, 62, 82,
1108 -62, -82, 82, 62, -82, -62, -20, 74,
1109 20, -74, 74, -20, -74, 20, 2, 88,
1110 -2, -88, 88, 2, -88, -2, 92, 92,
1111 -92, -92, -52, 60, 52, -60, 60, -52,
1112 -60, 52, 52, 118, -52, -118, 118, 52,
1113 -118, -52, -44, 74, 44, -74, 74, -44,
1114 -74, 44, 74, 118, -74, -118, 118, 74,
1115 -118, -74, 32, 118, -32, -118, 118, 32,
1116 -118, -32, -12, 102, 12, -102, 102, -12,
1117 -102, 12, -40, 96, 40, -96, 96, -40,
1118 -96, 40, -34, 118, 34, -118, 118, -34,
1119 -118, 34, -88, 88, 88, -88, -78, 104,
1120 78, -104, 104, -78, -104, 78, 12, 12,
1121 -12, -12, 22, 22, -22, -22, 42, 42,
1122 -42, -42, 72, 72, -72, -72,
1125 const DT_2_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
1126 0, 0, 3, 3, -3, -3, 0, 3,
1127 0, -3, 3, 0, -3, 0, 6, 6,
1128 -6, -6, 3, 9, -3, -9, 9, 3,
1129 -9, -3, -3, 9, 3, -9, 9, -3,
1130 -9, 3, -6, 6, 6, -6, 6, 12,
1131 -6, -12, 12, 6, -12, -6, 12, 12,
1132 -12, -12, 0, 15, 0, -15, 15, 0,
1133 -15, 0, -9, 12, 9, -12, 12, -9,
1134 -12, 9, 15, 24, -15, -24, 24, 15,
1135 -24, -15, -6, 18, 6, -18, 18, -6,
1136 -18, 6, 6, 24, -6, -24, 24, 6,
1137 -24, -6, 24, 24, -24, -24, 0, 27,
1138 0, -27, 27, 0, -27, 0, -18, 18,
1139 18, -18, -12, 24, 12, -24, 24, -12,
1140 -24, 12, 15, 39, -15, -39, 39, 15,
1141 -39, -15, 27, 42, -27, -42, 42, 27,
1142 -42, -27, -9, 33, 9, -33, 33, -9,
1143 -33, 9, 6, 42, -6, -42, 42, 6,
1144 -42, -6, 45, 45, -45, -45, -3, 51,
1145 3, -51, 51, -3, -51, 3, -27, 33,
1146 27, -33, 33, -27, -33, 27, -21, 45,
1147 21, -45, 45, -21, -45, 21, 33, 69,
1148 -33, -69, 69, 33, -69, -33, 18, 69,
1149 -18, -69, 69, 18, -69, -18, 54, 72,
1150 -54, -72, 72, 54, -72, -54, -18, 63,
1151 18, -63, 63, -18, -63, 18, 6, 78,
1152 -6, -78, 78, 6, -78, -6, 81, 81,
1153 -81, -81, -51, 51, 51, -51, -42, 63,
1154 42, -63, 63, -42, -63, 42, -9, 90,
1155 9, -90, 90, -9, -90, 9, 42, 114,
1156 -42, -114, 114, 42, -114, -42, 63, 117,
1157 -63, -117, 117, 63, -117, -63, -36, 81,
1158 36, -81, 81, -36, -81, 36, 21, 120,
1159 -21, -120, 120, 21, -120, -21, 96, 123,
1160 -96, -123, 123, 96, -123, -96, -30, 111,
1161 30, -111, 111, -30, -111, 30, -78, 93,
1162 78, -93, 93, -78, -93, 78, -69, 114,
1163 69, -114, 114, -69, -114, 69, 18, 18,
1164 -18, -18, 33, 33, -33, -33, 63, 63,
1165 -63, -63, 108, 108, -108, -108,
1168 const DT_2_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
1169 0, 0, 4, 4, -4, -4, 0, 4,
1170 0, -4, 4, 0, -4, 0, 4, 8,
1171 -4, -8, 8, 4, -8, -4, 8, 8,
1172 -8, -8, -8, 8, 8, -8, -4, 12,
1173 4, -12, 12, -4, -12, 4, 8, 16,
1174 -8, -16, 16, 8, -16, -8, 16, 16,
1175 -16, -16, 0, 20, 0, -20, 20, 0,
1176 -20, 0, -12, 16, 12, -16, 16, -12,
1177 -16, 12, -4, 24, 4, -24, 24, -4,
1178 -24, 4, 16, 32, -16, -32, 32, 16,
1179 -32, -16, 8, 32, -8, -32, 32, 8,
1180 -32, -8, 32, 32, -32, -32, 0, 36,
1181 0, -36, 36, 0, -36, 0, -24, 24,
1182 24, -24, -16, 32, 16, -32, 32, -16,
1183 -32, 16, 20, 52, -20, -52, 52, 20,
1184 -52, -20, 36, 56, -36, -56, 56, 36,
1185 -56, -36, -12, 44, 12, -44, 44, -12,
1186 -44, 12, 8, 56, -8, -56, 56, 8,
1187 -56, -8, 60, 60, -60, -60, -4, 64,
1188 4, -64, 64, -4, -64, 4, -36, 44,
1189 36, -44, 44, -36, -44, 36, -28, 60,
1190 28, -60, 60, -28, -60, 28, 44, 92,
1191 -44, -92, 92, 44, -92, -44, 24, 92,
1192 -24, -92, 92, 24, -92, -24, 72, 96,
1193 -72, -96, 96, 72, -96, -72, -20, 84,
1194 20, -84, 84, -20, -84, 20, 8, 100,
1195 -8, -100, 100, 8, -100, -8, 108, 108,
1196 -108, -108, -68, 68, 68, -68, -56, 84,
1197 56, -84, 84, -56, -84, 56, -12, 120,
1198 12, -120, 120, -12, -120, 12, -48, 108,
1199 48, -108, 108, -48, -108, 48, -104, 124,
1200 104, -124, 124, -104, -124, 104, 24, 24,
1201 -24, -24, 44, 44, -44, -44, 84, 84,
1205 const DT_2_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1206 0, 0, 5, 5, -5, -5, 0, 5,
1207 0, -5, 5, 0, -5, 0, 10, 10,
1208 -10, -10, 5, 15, -5, -15, 15, 5,
1209 -15, -5, -10, 10, 10, -10, -5, 15,
1210 5, -15, 15, -5, -15, 5, 10, 20,
1211 -10, -20, 20, 10, -20, -10, 20, 20,
1212 -20, -20, 0, 25, 0, -25, 25, 0,
1213 -25, 0, -15, 20, 15, -20, 20, -15,
1214 -20, 15, 25, 40, -25, -40, 40, 25,
1215 -40, -25, -10, 30, 10, -30, 30, -10,
1216 -30, 10, 10, 40, -10, -40, 40, 10,
1217 -40, -10, 40, 40, -40, -40, 0, 45,
1218 0, -45, 45, 0, -45, 0, -30, 30,
1219 30, -30, -20, 40, 20, -40, 40, -20,
1220 -40, 20, 25, 65, -25, -65, 65, 25,
1221 -65, -25, 45, 70, -45, -70, 70, 45,
1222 -70, -45, -15, 55, 15, -55, 55, -15,
1223 -55, 15, 10, 70, -10, -70, 70, 10,
1224 -70, -10, 75, 75, -75, -75, -5, 85,
1225 5, -85, 85, -5, -85, 5, -45, 55,
1226 45, -55, 55, -45, -55, 45, -35, 75,
1227 35, -75, 75, -35, -75, 35, 55, 115,
1228 -55, -115, 115, 55, -115, -55, 30, 115,
1229 -30, -115, 115, 30, -115, -30, 90, 120,
1230 -90, -120, 120, 90, -120, -90, -30, 105,
1231 30, -105, 105, -30, -105, 30, -85, 85,
1232 85, -85, -70, 105, 70, -105, 105, -70,
1233 -105, 70, 30, 30, -30, -30, 60, 60,
1234 -60, -60, 105, 105, -105, -105,
1237 const DT_2_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1238 0, 0, 6, 6, -6, -6, 0, 6,
1239 0, -6, 6, 0, -6, 0, 12, 12,
1240 -12, -12, 6, 12, -6, -12, 12, 6,
1241 -12, -6, -12, 12, 12, -12, -6, 18,
1242 6, -18, 18, -6, -18, 6, 12, 24,
1243 -12, -24, 24, 12, -24, -12, 24, 24,
1244 -24, -24, 0, 30, 0, -30, 30, 0,
1245 -30, 0, -18, 24, 18, -24, 24, -18,
1246 -24, 18, 30, 48, -30, -48, 48, 30,
1247 -48, -30, -6, 36, 6, -36, 36, -6,
1248 -36, 6, 12, 48, -12, -48, 48, 12,
1249 -48, -12, 48, 48, -48, -48, 0, 54,
1250 0, -54, 54, 0, -54, 0, -36, 36,
1251 36, -36, -24, 48, 24, -48, 48, -24,
1252 -48, 24, 30, 78, -30, -78, 78, 30,
1253 -78, -30, 54, 84, -54, -84, 84, 54,
1254 -84, -54, -18, 66, 18, -66, 66, -18,
1255 -66, 18, 12, 84, -12, -84, 84, 12,
1256 -84, -12, 90, 90, -90, -90, -6, 96,
1257 6, -96, 96, -6, -96, 6, -54, 66,
1258 54, -66, 66, -54, -66, 54, -42, 90,
1259 42, -90, 90, -42, -90, 42, -30, 126,
1260 30, -126, 126, -30, -126, 30, -102, 102,
1261 102, -102, -84, 126, 84, -126, 126, -84,
1262 -126, 84, 36, 36, -36, -36, 66, 66,
1266 const DT_2_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1267 0, 0, 7, 7, -7, -7, 0, 7,
1268 0, -7, 7, 0, -7, 0, 14, 14,
1269 -14, -14, 7, 21, -7, -21, 21, 7,
1270 -21, -7, -14, 14, 14, -14, -7, 21,
1271 7, -21, 21, -7, -21, 7, 14, 28,
1272 -14, -28, 28, 14, -28, -14, 28, 28,
1273 -28, -28, 0, 35, 0, -35, 35, 0,
1274 -35, 0, -21, 28, 21, -28, 28, -21,
1275 -28, 21, 35, 56, -35, -56, 56, 35,
1276 -56, -35, -14, 42, 14, -42, 42, -14,
1277 -42, 14, 14, 56, -14, -56, 56, 14,
1278 -56, -14, 56, 56, -56, -56, 0, 63,
1279 0, -63, 63, 0, -63, 0, -42, 42,
1280 42, -42, -28, 56, 28, -56, 56, -28,
1281 -56, 28, 35, 91, -35, -91, 91, 35,
1282 -91, -35, 63, 98, -63, -98, 98, 63,
1283 -98, -63, -21, 77, 21, -77, 77, -21,
1284 -77, 21, 14, 98, -14, -98, 98, 14,
1285 -98, -14, 105, 105, -105, -105, -7, 119,
1286 7, -119, 119, -7, -119, 7, -63, 77,
1287 63, -77, 77, -63, -77, 63, -49, 105,
1288 49, -105, 105, -49, -105, 49, -119, 119,
1289 119, -119, 42, 42, -42, -42, 77, 77,
1293 const DT_2_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1294 0, 0, 8, 8, -8, -8, 0, 8,
1295 0, -8, 8, 0, -8, 0, 16, 16,
1296 -16, -16, 8, 16, -8, -16, 16, 8,
1297 -16, -8, -16, 16, 16, -16, -8, 24,
1298 8, -24, 24, -8, -24, 8, 16, 32,
1299 -16, -32, 32, 16, -32, -16, 32, 32,
1300 -32, -32, 0, 40, 0, -40, 40, 0,
1301 -40, 0, -24, 32, 24, -32, 32, -24,
1302 -32, 24, 40, 64, -40, -64, 64, 40,
1303 -64, -40, -16, 48, 16, -48, 48, -16,
1304 -48, 16, 16, 64, -16, -64, 64, 16,
1305 -64, -16, 64, 64, -64, -64, 0, 72,
1306 0, -72, 72, 0, -72, 0, -48, 48,
1307 48, -48, -32, 64, 32, -64, 64, -32,
1308 -64, 32, 40, 104, -40, -104, 104, 40,
1309 -104, -40, 72, 112, -72, -112, 112, 72,
1310 -112, -72, -24, 88, 24, -88, 88, -24,
1311 -88, 24, 16, 112, -16, -112, 112, 16,
1312 -112, -16, 120, 120, -120, -120, -72, 88,
1313 72, -88, 88, -72, -88, 72, -56, 120,
1314 56, -120, 120, -56, -120, 56, 48, 48,
1315 -48, -48, 88, 88, -88, -88,
1318 const DT_2_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1319 0, 0, 9, 9, -9, -9, 0, 9,
1320 0, -9, 9, 0, -9, 0, 18, 18,
1321 -18, -18, 9, 27, -9, -27, 27, 9,
1322 -27, -9, -18, 18, 18, -18, -9, 27,
1323 9, -27, 27, -9, -27, 9, 18, 36,
1324 -18, -36, 36, 18, -36, -18, 36, 36,
1325 -36, -36, 0, 45, 0, -45, 45, 0,
1326 -45, 0, -27, 36, 27, -36, 36, -27,
1327 -36, 27, 45, 72, -45, -72, 72, 45,
1328 -72, -45, -18, 54, 18, -54, 54, -18,
1329 -54, 18, 18, 72, -18, -72, 72, 18,
1330 -72, -18, 72, 72, -72, -72, 0, 81,
1331 0, -81, 81, 0, -81, 0, -54, 54,
1332 54, -54, -36, 72, 36, -72, 72, -36,
1333 -72, 36, 45, 117, -45, -117, 117, 45,
1334 -117, -45, 81, 126, -81, -126, 126, 81,
1335 -126, -81, -27, 99, 27, -99, 99, -27,
1336 -99, 27, -81, 99, 81, -99, 99, -81,
1337 -99, 81, 54, 54, -54, -54, 108, 108,
1341 const DT_3_1: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1342 0, 0, 2, 2, -2, -2, 0, 3,
1343 0, -3, 3, 0, -3, 0, 6, 6,
1344 -6, -6, 0, 7, 0, -7, 7, 0,
1345 -7, 0, -5, 5, 5, -5, 5, -5,
1346 -5, 5, 6, 11, -6, -11, 11, 6,
1347 -11, -6, 0, 8, 0, -8, 8, 0,
1348 -8, 0, 11, 11, -11, -11, 0, 12,
1349 0, -12, 12, 0, -12, 0, 12, 17,
1350 -12, -17, 17, 12, -17, -12, 17, 17,
1351 -17, -17, 6, 18, -6, -18, 18, 6,
1352 -18, -6, -8, 11, 8, -11, 11, -8,
1353 -11, 8, 0, 15, 0, -15, 15, 0,
1354 -15, 0, 0, 20, 0, -20, 20, 0,
1355 -20, 0, 18, 25, -18, -25, 25, 18,
1356 -25, -18, 11, 25, -11, -25, 25, 11,
1357 -25, -11, 25, 25, -25, -25, -14, 14,
1358 14, -14, 14, -14, -14, 14, 0, 26,
1359 0, -26, 26, 0, -26, 0, -11, 18,
1360 11, -18, 18, -11, -18, 11, -7, 22,
1361 7, -22, 22, -7, -22, 7, 26, 34,
1362 -26, -34, 34, 26, -34, -26, 18, 34,
1363 -18, -34, 34, 18, -34, -18, 34, 34,
1364 -34, -34, 11, 35, -11, -35, 35, 11,
1365 -35, -11, 0, 29, 0, -29, 29, 0,
1366 -29, 0, -19, 22, 19, -22, 22, -19,
1367 -22, 19, -15, 26, 15, -26, 26, -15,
1368 -26, 15, 0, 37, 0, -37, 37, 0,
1369 -37, 0, 27, 44, -27, -44, 44, 27,
1370 -44, -27, 36, 44, -36, -44, 44, 36,
1371 -44, -36, 18, 44, -18, -44, 44, 18,
1372 -44, -18, -10, 33, 10, -33, 33, -10,
1373 -33, 10, 45, 45, -45, -45, 0, 0,
1376 const DT_3_2: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1377 0, 0, 0, 2, 0, -2, 2, 0,
1378 -2, 0, 2, 2, -2, -2, 6, 6,
1379 -6, -6, 0, 6, 0, -6, 6, 0,
1380 -6, 0, -4, 4, 4, -4, 10, -6,
1381 -10, 6, 0, -12, 0, 12, -6, -12,
1382 6, -12, -6, 12, 6, 12, -14, 0,
1383 14, 0, 12, 12, -12, -12, 0, -18,
1384 0, 18, 14, -12, -14, 12, -18, -6,
1385 18, -6, -18, 6, 18, 6, -10, -18,
1386 10, -18, -10, 18, 10, 18, -22, 0,
1387 22, 0, 0, -24, 0, 24, -22, -12,
1388 22, -12, -22, 12, 22, 12, -8, -24,
1389 8, -24, -8, 24, 8, 24, -26, -6,
1390 26, -6, -26, 6, 26, 6, -28, 0,
1391 28, 0, 20, 20, -20, -20, -14, -26,
1392 14, 26, -30, -12, 30, 12, -10, -32,
1393 10, 32, -18, -32, 18, 32, -26, -26,
1394 26, 26, -34, -20, 34, 20, -38, -12,
1395 38, 12, -32, -32, 32, 32, 32, 32,
1396 -22, -40, -34, -34, 34, 34,
1399 const DT_3_3: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1400 0, 0, 0, 2, 0, -2, 2, 0,
1401 -2, 0, 4, 4, -4, -4, 10, 10,
1402 -10, -10, 0, 10, 0, -10, 10, 0,
1403 -10, 0, -6, 6, 6, -6, 14, -8,
1404 -14, 8, -18, 0, 18, 0, 10, -16,
1405 -10, 16, 0, -24, 0, 24, -24, -8,
1406 24, -8, -24, 8, 24, 8, 18, 18,
1407 -18, -18, 20, -16, -20, 16, -14, -26,
1408 14, -26, -14, 26, 14, 26, -30, 0,
1409 30, 0, 0, -34, 0, 34, -34, -8,
1410 34, -8, -34, 8, 34, 8, -30, -18,
1411 30, -18, -30, 18, 30, 18, -10, -34,
1412 10, -34, -10, 34, 10, 34, -20, -34,
1413 20, 34, -40, 0, 40, 0, 30, 30,
1414 -30, -30, -40, -18, 40, 18, 0, -44,
1415 0, 44, -16, -44, 16, 44, -36, -36,
1416 -36, -36, 36, 36, -26, -44, 26, 44,
1417 -46, -26, 46, 26, -52, -18, 52, 18,
1418 -20, -54, -44, -44, 44, 44, -32, -54,
1419 -46, -46, -46, -46, 46, 46,
1422 const DT_3_4: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1423 0, 0, 0, 4, 0, -4, 4, 0,
1424 -4, 0, 4, 4, -4, -4, 12, 12,
1425 -12, -12, 0, 12, 0, -12, 12, 0,
1426 -12, 0, -8, 8, 8, -8, 8, -16,
1427 -8, 16, 0, -24, 0, 24, -24, -8,
1428 24, -8, -24, 8, 24, 8, 20, -16,
1429 -20, 16, -28, 0, 28, 0, -16, -24,
1430 16, -24, -16, 24, 16, 24, 0, -32,
1431 0, 32, -28, -16, 28, -16, -28, 16,
1432 28, 16, -8, -32, 8, -32, -32, -8,
1433 32, -8, -32, 8, 32, 8, -8, 32,
1434 8, 32, 24, 24, -24, -24, 24, -24,
1435 -24, 24, -20, -32, 20, 32, -40, 0,
1436 40, 0, -40, -16, 40, 16, 0, -44,
1437 0, -44, -44, 0, 44, 0, 0, 44,
1438 0, 44, -32, -32, 32, 32, -16, -44,
1439 16, 44, -24, -44, -44, -24, 44, 24,
1440 24, 44, -48, -16, 48, 16, -36, -36,
1441 -36, -36, 36, 36, 36, 36, -20, -52,
1442 40, 40, -40, -40, -32, -52,
1445 const DT_3_5: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1446 0, 0, 2, 2, -2, -2, 6, 6,
1447 -6, -6, 12, 12, -12, -12, 20, 20,
1448 -20, -20, 32, 32, -32, -32, 46, 46,
1449 -46, -46, 0, 0, 0, 0, 0, 0,
1450 0, 0, 0, 0, 0, 0, 0, 0,
1451 0, 0, 0, 0, 0, 0, 0, 0,
1452 0, 0, 0, 0, 0, 0, 0, 0,
1453 0, 0, 0, 0, 0, 0, 0, 0,
1454 0, 0, 0, 0, 0, 0, 0, 0,
1455 0, 0, 0, 0, 0, 0, 0, 0,
1456 0, 0, 0, 0, 0, 0, 0, 0,
1457 0, 0, 0, 0, 0, 0, 0, 0,
1458 0, 0, 0, 0, 0, 0, 0, 0,
1459 0, 0, 0, 0, 0, 0, 0, 0,
1460 0, 0, 0, 0, 0, 0, 0, 0,
1461 0, 0, 0, 0, 0, 0, 0, 0,
1462 0, 0, 0, 0, 0, 0, 0, 0,
1463 0, 0, 0, 0, 0, 0, 0, 0,
1464 0, 0, 0, 0, 0, 0, 0, 0,
1468 const IVI3_DELTA_CBS: [&IviDeltaCB; 24] = [
1469 &DT_1_1, &DT_1_2, &DT_1_3, &DT_1_4, &DT_1_5, &DT_1_6, &DT_1_7, &DT_1_8,
1470 &DT_2_1, &DT_2_2, &DT_2_3, &DT_2_4, &DT_2_5, &DT_2_6, &DT_2_7, &DT_2_8,
1471 &DT_3_1, &DT_3_2, &DT_3_3, &DT_3_4, &DT_3_5, &DT_3_5, &DT_3_5, &DT_3_5