add flush() to decoder interface
[nihav.git] / nihav-indeo / src / codecs / indeo3.rs
1 use nihav_core::formats;
2 use nihav_core::codecs::*;
3 use nihav_core::io::byteio::*;
4 use std::io::SeekFrom;
5 use std::mem;
6
7 struct IviDeltaCB {
8 quad_radix: u8,
9 data: &'static [i8],
10 }
11
12 #[derive(Clone, Copy)]
13 struct MV {
14 x: i8,
15 y: i8
16 }
17
18 struct Buffers {
19 width: usize,
20 height: usize,
21 cw: usize,
22 ch: usize,
23 buf1: Vec<u8>,
24 buf2: Vec<u8>,
25 fbuf: bool,
26 }
27
28 const DEFAULT_PIXEL: u8 = 0x40;
29
30 impl Buffers {
31 fn new() -> Self { Buffers { width: 0, height: 0, cw: 0, ch: 0, buf1: Vec::new(), buf2: Vec::new(), fbuf: true } }
32 fn reset(&mut self) {
33 self.width = 0;
34 self.height = 0;
35 self.buf1.truncate(0);
36 self.buf2.truncate(0);
37 }
38 fn alloc(&mut self, w: usize, h: usize) {
39 self.width = w;
40 self.height = h;
41 self.cw = ((w >> 2) + 3) & !3;
42 self.ch = ((h >> 2) + 3) & !3;
43 self.buf1.resize(w * h + self.cw * self.ch * 2, DEFAULT_PIXEL);
44 self.buf2.resize(w * h + self.cw * self.ch * 2, DEFAULT_PIXEL);
45 }
46 fn flip(&mut self) { self.fbuf = !self.fbuf; }
47 fn get_stride(&mut self, planeno: usize) -> usize {
48 if planeno == 0 { self.width } else { self.cw }
49 }
50 fn get_offset(&mut self, planeno: usize) -> usize {
51 match planeno {
52 1 => self.width * self.height,
53 2 => self.width * self.height + self.cw * self.ch,
54 _ => 0,
55 }
56 }
57 fn fill_framebuf(&mut self, fbuf: &mut NAVideoBuffer<u8>) {
58 for planeno in 0..3 {
59 let mut soff = self.get_offset(planeno);
60 let mut doff = fbuf.get_offset(planeno);
61 let sstride = self.get_stride(planeno);
62 let dstride = fbuf.get_stride(planeno);
63 let width = if planeno == 0 { self.width } else { self.width >> 2 };
64 let height = if planeno == 0 { self.height } else { self.height >> 2 };
65 let src = if self.fbuf { &self.buf1[0..] } else { &self.buf2[0..] };
66 let dst = fbuf.get_data_mut().unwrap();
67 for _ in 0..height {
68 for x in 0..width {
69 dst[doff + x] = src[soff + x] * 2;
70 }
71 soff += sstride;
72 doff += dstride;
73 }
74 }
75 }
76 fn copy_block(&mut self, doff: usize, soff: usize, stride: usize, w: usize, h: usize) {
77 let mut sidx = soff;
78 let mut didx = doff;
79 if self.fbuf {
80 for _ in 0..h {
81 for i in 0..w { self.buf1[didx + i] = self.buf2[sidx + i]; }
82 sidx += stride;
83 didx += stride;
84 }
85 } else {
86 for _ in 0..h {
87 for i in 0..w { self.buf2[didx + i] = self.buf1[sidx + i]; }
88 sidx += stride;
89 didx += stride;
90 }
91 }
92 }
93 fn fill_block(&mut self, doff: usize, stride: usize, w: usize, h: usize, topline: bool) {
94 let mut didx = doff;
95 let mut buf: [u8; 8] = [0; 8];
96 if topline {
97 if self.fbuf {
98 for _ in 0..h {
99 for i in 0..w { self.buf1[didx + i] = DEFAULT_PIXEL; }
100 didx += stride;
101 }
102 } else {
103 for _ in 0..h {
104 for i in 0..w { self.buf2[didx + i] = DEFAULT_PIXEL; }
105 didx += stride;
106 }
107 }
108 } else {
109 if self.fbuf {
110 for i in 0..w { buf[i] = self.buf1[didx - stride + i]; }
111 for _ in 0..h {
112 for i in 0..w { self.buf1[didx + i] = buf[i]; }
113 didx += stride;
114 }
115 } else {
116 for i in 0..w { buf[i] = self.buf2[didx - stride + i]; }
117 for _ in 0..h {
118 for i in 0..w { self.buf2[didx + i] = buf[i]; }
119 didx += stride;
120 }
121 }
122 }
123 }
124 }
125
126 #[allow(unused_variables)]
127 fn apply_delta4x4(bufs: &mut Buffers, off: usize, stride: usize,
128 deltas: &[u8], topline: bool, first_line: bool) {
129 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4)] }
130 else { &mut bufs.buf2[off..(off + 4)] };
131 for i in 0..4 { dst[i] = dst[i].wrapping_add(deltas[i]) & 0x7F; }
132 }
133
134 #[allow(unused_variables)]
135 fn apply_delta4x8(bufs: &mut Buffers, off: usize, stride: usize,
136 deltas: &[u8], topline: bool, first_line: bool) {
137 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4 + stride)] }
138 else { &mut bufs.buf2[off..(off + 4 + stride)] };
139 for i in 0..4 { dst[i + stride] = dst[i].wrapping_add(deltas[i]) & 0x7F; }
140 if !topline {
141 for i in 0..4 { dst[i] = (dst[i + stride] + dst[i]) >> 1; }
142 } else {
143 for i in 0..4 { dst[i] = dst[i + stride]; }
144 }
145 }
146
147 #[allow(unused_variables)]
148 fn apply_delta4x8m11(bufs: &mut Buffers, off: usize, stride: usize,
149 deltas: &[u8], topline: bool, first_line: bool) {
150 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4 + stride)] }
151 else { &mut bufs.buf2[off..(off + 4 + stride)] };
152 for i in 0..4 { dst[i] = dst[i] .wrapping_add(deltas[i]) & 0x7F; }
153 for i in 0..4 { dst[i + stride] = dst[i + stride].wrapping_add(deltas[i]) & 0x7F; }
154 }
155
156 #[allow(unused_variables)]
157 fn apply_delta8x8p(bufs: &mut Buffers, off: usize, stride: usize,
158 deltas: &[u8], topline: bool, first_line: bool) {
159 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8 + stride)] }
160 else { &mut bufs.buf2[off..(off + 8 + stride)] };
161 for i in 0..8 { dst[i] = dst[i] .wrapping_add(deltas[i >> 1]) & 0x7F; }
162 for i in 0..8 { dst[i + stride] = dst[i + stride].wrapping_add(deltas[i >> 1]) & 0x7F; }
163 }
164
165 fn apply_delta8x8i(bufs: &mut Buffers, off: usize, stride: usize,
166 deltas: &[u8], topline: bool, firstline: bool) {
167 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8 + stride)] }
168 else { &mut bufs.buf2[off..(off + 8 + stride)] };
169 if !firstline {
170 for i in 0..8 { dst[i + stride] = dst[i ].wrapping_add(deltas[i >> 1]) & 0x7F; }
171 } else {
172 for i in 0..8 { dst[i + stride] = dst[i & !1].wrapping_add(deltas[i >> 1]) & 0x7F; }
173 }
174 if !topline {
175 for i in 0..8 { dst[i] = (dst[i + stride] + dst[i]) >> 1; }
176 } else {
177 for i in 0..8 { dst[i] = dst[i + stride]; }
178 }
179 }
180
181 fn copy_line_top(bufs: &mut Buffers, off: usize, stride: usize, bw: usize, topline: bool) {
182 let mut buf: [u8; 8] = [0; 8];
183 if !topline {
184 let src = if bufs.fbuf { &bufs.buf1[(off - stride)..(off - stride + bw)] }
185 else { &bufs.buf2[(off - stride)..(off - stride + bw)] };
186 for i in 0..bw { buf[i] = src[i]; }
187 } else {
188 for i in 0..bw { buf[i] = DEFAULT_PIXEL; }
189 }
190 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + bw)] }
191 else { &mut bufs.buf2[off..(off + bw)] };
192 for i in 0..bw { dst[i] = buf[i]; }
193 }
194
195 fn copy_line_top4x4(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
196 copy_line_top(bufs, off, stride, 4, topline);
197 }
198
199 fn copy_line_top4x8(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
200 copy_line_top(bufs, off, stride, 4, topline);
201 copy_line_top(bufs, off + stride, stride, 4, false);
202 }
203
204 fn copy_line_top8x8(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
205 let mut buf: [u8; 8] = [0; 8];
206 if !topline {
207 let src = if bufs.fbuf { &bufs.buf1[(off - stride)..(off - stride + 8)] }
208 else { &bufs.buf2[(off - stride)..(off - stride + 8)] };
209 for i in 0..8 { buf[i] = src[i & !1]; }
210 } else {
211 for i in 0..8 { buf[i] = DEFAULT_PIXEL; }
212 }
213 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8)] }
214 else { &mut bufs.buf2[off..(off + 8)] };
215 for i in 0..8 {dst[i] = buf[i]; }
216 }
217
218 fn fill_block8x8(bufs: &mut Buffers, doff: usize, stride: usize, h: usize, topline: bool, firstline: bool) {
219 let mut didx = doff;
220 let mut buf: [u8; 8] = [0; 8];
221 if firstline {
222 for i in 0..8 { buf[i] = DEFAULT_PIXEL; }
223 } else if bufs.fbuf {
224 for i in 0..8 { buf[i] = bufs.buf1[doff - stride + i]; }
225 } else {
226 for i in 0..8 { buf[i] = bufs.buf2[doff - stride + i]; }
227 }
228 if topline && !firstline {
229 for i in 0..4 { buf[i * 2 + 1] = buf[i * 2]; }
230 if bufs.fbuf {
231 for i in 0..8 { bufs.buf1[doff + i] = (bufs.buf1[doff - stride + i] + buf[i]) >> 1; }
232 } else {
233 for i in 0..8 { bufs.buf2[doff + i] = (bufs.buf2[doff - stride + i] + buf[i]) >> 1; }
234 }
235 }
236
237 let start = if !topline { 0 } else { 1 };
238 if topline {
239 didx += stride;
240 }
241 if bufs.fbuf {
242 for _ in start..h {
243 for i in 0..8 { bufs.buf1[didx + i] = buf[i]; }
244 didx += stride;
245 }
246 } else {
247 for _ in start..h {
248 for i in 0..8 { bufs.buf2[didx + i] = buf[i]; }
249 didx += stride;
250 }
251 }
252 }
253
254 struct Indeo3Decoder {
255 info: NACodecInfoRef,
256 bpos: u8,
257 bbuf: u8,
258 width: u16,
259 height: u16,
260 mvs: Vec<MV>,
261 altquant: [u8; 16],
262 vq_offset: u8,
263 bufs: Buffers,
264 }
265
266 #[derive(Clone,Copy)]
267 struct IV3Cell {
268 x: u16,
269 y: u16,
270 w: u16,
271 h: u16,
272 d: u8,
273 vqt: bool,
274 mv: Option<MV>,
275 }
276
277 impl IV3Cell {
278 fn new(w: u16, h: u16) -> Self {
279 IV3Cell { x: 0, y: 0, w, h, d: 20, vqt: false, mv: None }
280 }
281 fn split_h(&self) -> (Self, Self) {
282 let h1 = if self.h > 2 { ((self.h + 2) >> 2) << 1 } else { 1 };
283 let h2 = self.h - h1;
284 let mut cell1 = *self;
285 cell1.h = h1;
286 cell1.d -= 1;
287 let mut cell2 = *self;
288 cell2.y += h1;
289 cell2.h = h2;
290 cell2.d -= 1;
291 (cell1, cell2)
292 }
293 fn split_w(&self, stripw: u16) -> (Self, Self) {
294 let w1 = if self.w > stripw {
295 if self.w > stripw * 2 { stripw * 2 } else { stripw }
296 } else {
297 if self.w > 2 { ((self.w + 2) >> 2) << 1 } else { 1 }
298 };
299 let w2 = self.w - w1;
300 let mut cell1 = *self;
301 cell1.w = w1;
302 cell1.d -= 1;
303 let mut cell2 = *self;
304 cell2.x += w1;
305 cell2.w = w2;
306 cell2.d -= 1;
307 (cell1, cell2)
308 }
309 fn no_mv(&self) -> bool { self.mv.is_none() }
310 }
311
312 struct CellDecParams {
313 tab: [usize; 2],
314 bw: u16,
315 bh: u16,
316 swap_q: [bool; 2],
317 hq: bool,
318 apply_delta: fn (&mut Buffers, usize, usize, &[u8], bool, bool),
319 copy_line_top: fn (&mut Buffers, usize, usize, bool),
320 }
321
322 const FRMH_TAG: u32 = ((b'F' as u32) << 24) | ((b'R' as u32) << 16)
323 | ((b'M' as u32) << 8) | (b'H' as u32);
324
325 const H_SPLIT: u8 = 0;
326 const V_SPLIT: u8 = 1;
327 const SKIP_OR_TREE: u8 = 2;
328
329 impl Indeo3Decoder {
330 fn new() -> Self {
331 let dummy_info = NACodecInfo::new_dummy();
332 Indeo3Decoder { info: dummy_info, bpos: 0, bbuf: 0, width: 0, height: 0,
333 mvs: Vec::new(), altquant: [0; 16],
334 vq_offset: 0, bufs: Buffers::new() }
335 }
336
337 fn br_reset(&mut self) {
338 self.bpos = 0;
339 self.bbuf = 0;
340 }
341
342 fn get_2bits(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
343 if self.bpos == 0 {
344 self.bbuf = br.read_byte()?;
345 self.bpos = 8;
346 }
347 self.bpos -= 2;
348 Ok((self.bbuf >> self.bpos) & 0x3)
349 }
350
351 fn decode_cell_data(&mut self, br: &mut ByteReader, cell: IV3Cell,
352 off: usize, stride: usize, params: CellDecParams) -> DecoderResult<()> {
353 let blk_w = cell.w * 4 / params.bw;
354 let blk_h = cell.h * 4 / params.bh;
355 let scale: usize = if params.bh == 4 { 1 } else { 2 };
356
357 validate!((((cell.w * 4) % params.bw) == 0) && (((cell.h * 4) % params.bh) == 0));
358
359 let mut run_blocks = 0;
360 let mut run_skip = false;
361
362 let mut didx: usize = ((cell.x*4) as usize) + ((cell.y * 4) as usize) * stride + off;
363 let mut sidx: usize;
364 if cell.no_mv() {
365 sidx = 0;
366 } else {
367 let mv = cell.mv.unwrap();
368 let mx = i16::from(mv.x);
369 let my = i16::from(mv.y);
370 let l = (cell.x as i16) * 4 + mx;
371 let t = (cell.y as i16) * 4 + my;
372 let r = ((cell.x + cell.w) as i16) * 4 + mx;
373 let b = ((cell.y + cell.h) as i16) * 4 + my;
374 validate!(l >= 0);
375 validate!(t >= 0);
376 validate!(r <= (self.width as i16));
377 validate!(b <= (self.height as i16));
378 sidx = (l as usize) + (t as usize) * stride + off;
379 }
380 for y in 0..blk_h {
381 let mut xoff: usize = 0;
382 for _ in 0..blk_w {
383 if run_blocks > 0 {
384 if !run_skip || !cell.no_mv() {
385 if !(params.bw == 8 && cell.no_mv()) {
386 if !cell.no_mv() {
387 self.bufs.copy_block(didx + xoff, sidx + xoff, stride,
388 params.bw as usize, params.bh as usize);
389 } else {
390 self.bufs.fill_block(didx + xoff, stride,
391 params.bw as usize, params.bh as usize,
392 (cell.y == 0) && (y == 0));
393 }
394 } else {
395 fill_block8x8(&mut self.bufs,
396 didx + xoff, stride, 8,
397 y == 0, (cell.y == 0) && (y == 0));
398 }
399 }
400 run_blocks -= 1;
401 } else {
402 let mut line: usize = 0;
403 while line < 4 {
404 let c = br.read_byte()?;
405 if c < 0xF8 {
406 let delta_tab = if params.hq {
407 IVI3_DELTA_CBS[params.tab[line & 1]]
408 } else {
409 IVI3_DELTA_CBS[params.tab[1]]
410 };
411 let mut idx1;
412 let mut idx2;
413 if (c as usize) < delta_tab.data.len()/2 {
414 idx1 = br.read_byte()? as usize;
415 validate!(idx1 < delta_tab.data.len());
416 idx2 = c as usize;
417 } else {
418 let tmp = (c as usize) - delta_tab.data.len()/2;
419 idx1 = tmp / (delta_tab.quad_radix as usize);
420 idx2 = tmp % (delta_tab.quad_radix as usize);
421 if params.swap_q[line & 1] {
422 mem::swap(&mut idx1, &mut idx2);
423 }
424 }
425 let deltas: [u8; 4] = [delta_tab.data[idx1 * 2] as u8,
426 delta_tab.data[idx1 * 2 + 1] as u8,
427 delta_tab.data[idx2 * 2 + 0] as u8,
428 delta_tab.data[idx2 * 2 + 1] as u8];
429 let topline = (cell.y == 0) && (y == 0) && (line == 0);
430 let first_line = (y == 0) && (line == 0);
431 if cell.no_mv() {
432 (params.copy_line_top)(&mut self.bufs,
433 didx + xoff + line * scale * stride,
434 stride, topline);
435 } else {
436 self.bufs.copy_block(didx + xoff + line * scale * stride,
437 sidx + xoff + line * scale * stride,
438 stride, params.bw as usize, scale);
439 }
440 (params.apply_delta)(&mut self.bufs,
441 didx + xoff + line * scale * stride,
442 stride, &deltas, topline, first_line);
443 line += 1;
444 } else {
445 let mut tocopy: usize = 0;
446 let mut do_copy = true;
447 if c == 0xF8 { return Err(DecoderError::InvalidData); }
448 if c == 0xF9 {
449 run_blocks = 1;
450 run_skip = true;
451 validate!(line == 0);
452 tocopy = 4;
453 do_copy = !cell.no_mv();
454 }
455 if c == 0xFA {
456 validate!(line == 0);
457 tocopy = 4;
458 do_copy = !cell.no_mv();
459 }
460 if c == 0xFB {
461 let c = br.read_byte()?;
462 validate!((c < 64) && ((c & 0x1F) != 0));
463 run_blocks = (c & 0x1F) - 1;
464 run_skip = (c & 0x20) != 0;
465 tocopy = 4 - line;
466 if params.bw == 4 && cell.no_mv() && run_skip {
467 do_copy = false;
468 }
469 }
470 if c == 0xFC {
471 run_skip = false;
472 run_blocks = 1;
473 tocopy = 4 - line;
474 }
475 if c >= 0xFD {
476 let nl = 257 - i16::from(c) - (line as i16);
477 validate!(nl > 0);
478 tocopy = nl as usize;
479 }
480 if do_copy {
481 if !(params.bw == 8 && cell.no_mv()) {
482 if !cell.no_mv() {
483 self.bufs.copy_block(didx + xoff + line * scale * stride,
484 sidx + xoff + line * scale * stride,
485 stride, params.bw as usize,
486 tocopy * scale);
487 } else {
488 self.bufs.fill_block(didx + xoff + line * scale * stride,
489 stride, params.bw as usize,
490 tocopy * scale,
491 (cell.y == 0) && (y == 0) && (line == 0));
492 }
493 } else {
494 fill_block8x8(&mut self.bufs,
495 didx + xoff + line * 2 * stride,
496 stride, tocopy * 2,
497 (y == 0) && (line == 0),
498 (cell.y == 0) && (y == 0) && (line == 0));
499 }
500 }
501 line += tocopy;
502 }
503 }
504 }
505 xoff += params.bw as usize;
506 }
507 didx += stride * (params.bh as usize);
508 sidx += stride * (params.bh as usize);
509 }
510 Ok(())
511 }
512
513 fn copy_cell(&mut self, cell: IV3Cell, off: usize, stride: usize) -> DecoderResult<()> {
514 if cell.no_mv() { return Err(DecoderError::InvalidData); }
515 let mv = cell.mv.unwrap();
516 let mx = i16::from(mv.x);
517 let my = i16::from(mv.y);
518 let l = (cell.x as i16) * 4 + mx;
519 let t = (cell.y as i16) * 4 + my;
520 let r = ((cell.x + cell.w) as i16) * 4 + mx;
521 let b = ((cell.y + cell.h) as i16) * 4 + my;
522 validate!(l >= 0);
523 validate!(t >= 0);
524 validate!(r <= (self.width as i16));
525 validate!(b <= (self.height as i16));
526 let sidx: usize = off + (l as usize) + (t as usize) * stride;
527 let didx: usize = off + ((cell.x * 4) as usize) + ((cell.y * 4) as usize) * stride;
528 self.bufs.copy_block(didx, sidx, stride, (cell.w * 4) as usize, (cell.h * 4) as usize);
529 Ok(())
530 }
531
532 fn decode_cell(&mut self, br: &mut ByteReader, cell: IV3Cell, off: usize,
533 stride: usize, intra: bool) -> DecoderResult<()> {
534 let code = br.read_byte()?;
535 let mode = code >> 4;
536 let vq_idx = code & 0xF;
537
538 let mut idx1: usize = vq_idx as usize;
539 let mut idx2: usize = vq_idx as usize;
540 if (mode == 1) || (mode == 4) {
541 let c = self.altquant[vq_idx as usize];
542 idx1 = (c >> 4) as usize;
543 idx2 = (c & 0xF) as usize;
544 }
545
546 idx1 += self.vq_offset as usize;
547 idx2 += self.vq_offset as usize;
548 validate!((idx1 < 24) && (idx2 < 24));
549
550 let mut cp = CellDecParams {
551 tab: [idx2, idx1],
552 bw: 0, bh: 0,
553 swap_q: [idx2 >= 16, idx1 >= 16],
554 hq: false,
555 apply_delta: apply_delta4x4,
556 copy_line_top: copy_line_top4x4,
557 };
558 if (mode == 0) || (mode == 1) {
559 cp.bw = 4;
560 cp.bh = 4;
561 cp.hq = true;
562 } else if (mode == 3) || (mode == 4) {
563 if !cell.no_mv() { return Err(DecoderError::InvalidData); }
564 cp.bw = 4;
565 cp.bh = 8;
566 cp.hq = true;
567 cp.apply_delta = apply_delta4x8;
568 cp.copy_line_top = copy_line_top4x8;
569 } else if mode == 10 {
570 if !cell.no_mv() {
571 validate!(!intra);
572 cp.apply_delta = apply_delta8x8p;
573 } else {
574 cp.apply_delta = apply_delta8x8i;
575 }
576 cp.bw = 8;
577 cp.bh = 8;
578 cp.copy_line_top = copy_line_top8x8;
579 } else if mode == 11 {
580 if cell.no_mv() { return Err(DecoderError::InvalidData); }
581 validate!(!intra);
582 cp.bw = 4;
583 cp.bh = 8;
584 cp.apply_delta = apply_delta4x8m11;
585 cp.copy_line_top = copy_line_top4x8;
586 } else {
587 return Err(DecoderError::InvalidData);
588 }
589 self.decode_cell_data(br, cell, off, stride, cp)
590 }
591
592 fn parse_tree(&mut self, br: &mut ByteReader, cell: IV3Cell, off: usize,
593 stride: usize, stripw: u16, intra: bool) -> DecoderResult<()> {
594 let op = self.get_2bits(br)?;
595 if op == H_SPLIT {
596 validate!(cell.h > 1);
597 validate!(cell.d > 0);
598 let (cell1, cell2) = cell.split_h();
599 self.parse_tree(br, cell1, off, stride, stripw, intra)?;
600 self.parse_tree(br, cell2, off, stride, stripw, intra)?;
601 Ok(())
602 } else if op == V_SPLIT {
603 validate!(cell.w > 1);
604 validate!(cell.d > 0);
605 let (cell1, cell2) = cell.split_w(stripw);
606 self.parse_tree(br, cell1, off, stride, stripw, intra)?;
607 self.parse_tree(br, cell2, off, stride, stripw, intra)?;
608 Ok(())
609 } else if op == SKIP_OR_TREE {
610 if !cell.vqt {
611 let mut newcell = cell;
612 newcell.vqt = true;
613 newcell.d -= 1;
614 self.parse_tree(br, newcell, off, stride, stripw, intra)
615 } else {
616 validate!(!intra);
617 let code = self.get_2bits(br)?;
618 validate!(code < 2);
619 if code == 1 { return Err(DecoderError::NotImplemented); }
620 self.copy_cell(cell, off, stride)
621 }
622 } else {
623 if !cell.vqt {
624 let mut newcell = cell;
625 newcell.vqt = true;
626 newcell.d -= 1;
627 let mv_idx = br.read_byte()? as usize;
628 validate!(mv_idx < self.mvs.len());
629 newcell.mv = Some(self.mvs[mv_idx]);
630 self.parse_tree(br, newcell, off, stride, stripw, intra)
631 } else {
632 self.decode_cell(br, cell, off, stride, intra)
633 }
634 }
635 }
636
637 fn decode_plane_intra(&mut self, br: &mut ByteReader, planeno: usize,
638 start: u64, end: u64) -> DecoderResult<()> {
639 let offs = self.bufs.get_offset(planeno);
640 let stride = self.bufs.get_stride(planeno);
641 br.seek(SeekFrom::Start(start))?;
642
643 let nvec = br.read_u32le()?;
644 validate!(nvec == 0); // for intra there should be no mc_vecs
645 self.mvs.truncate(0);
646 for _ in 0..nvec {
647 let x = br.read_byte()? as i8;
648 let y = br.read_byte()? as i8;
649 self.mvs.push(MV{ x, y });
650 }
651
652 let shift = if planeno == 0 { 2 } else { 4 };
653 let round = (1 << shift) - 1;
654 let cell = IV3Cell::new(((self.bufs.width + round) >> shift) as u16,
655 ((self.bufs.height + round) >> shift) as u16);
656 self.br_reset();
657 self.parse_tree(br, cell, offs, stride, if planeno > 0 { 10 } else { 40 }, true)?;
658 validate!(br.tell() <= end);
659 Ok(())
660 }
661
662 fn decode_plane_inter(&mut self, br: &mut ByteReader, planeno: usize,
663 start: u64, end: u64) -> DecoderResult<()> {
664 let offs = self.bufs.get_offset(planeno);
665 let stride = self.bufs.get_stride(planeno);
666 br.seek(SeekFrom::Start(start))?;
667
668 let nvec = br.read_u32le()?;
669 validate!(nvec <= 256); // for intra there should be no mc_vecs
670 self.mvs.truncate(0);
671 for _ in 0..nvec {
672 let y = br.read_byte()? as i8;
673 let x = br.read_byte()? as i8;
674 self.mvs.push(MV{ x, y });
675 }
676
677 let shift = if planeno == 0 { 2 } else { 4 };
678 let cell = IV3Cell::new((self.bufs.width >> shift) as u16,
679 (self.bufs.height >> shift) as u16);
680 self.br_reset();
681 self.parse_tree(br, cell, offs, stride, if planeno > 0 { 10 } else { 40 }, false)?;
682 validate!(br.tell() <= end);
683 Ok(())
684 }
685 }
686
687 const FLAG_KEYFRAME: u16 = 1 << 2;
688 const FLAG_NONREF: u16 = 1 << 8;
689
690 impl NADecoder for Indeo3Decoder {
691 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
692 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
693 let w = vinfo.get_width();
694 let h = vinfo.get_height();
695 let fmt = formats::YUV410_FORMAT;
696 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, fmt));
697 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
698 self.bufs.reset();
699 Ok(())
700 } else {
701 Err(DecoderError::InvalidData)
702 }
703 }
704 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
705 let src = pkt.get_buffer();
706 let mut mr = MemoryReader::new_read(&src);
707 let mut br = ByteReader::new(&mut mr);
708 let frameno = br.read_u32le()?;
709 let hdr_2 = br.read_u32le()?;
710 let check = br.read_u32le()?;
711 let size = br.read_u32le()?;
712
713 let data_start = br.tell();
714
715 if (frameno ^ hdr_2 ^ size ^ FRMH_TAG) != check {
716 return Err(DecoderError::InvalidData);
717 }
718 if i64::from(size) > br.left() { return Err(DecoderError::InvalidData); }
719 let ver = br.read_u16le()?;
720 if ver != 32 { return Err(DecoderError::NotImplemented); }
721 let flags = br.read_u16le()?;
722 let size2 = br.read_u32le()?;
723 validate!(((size2 + 7) >> 3) <= size);
724 let cb = br.read_byte()?;
725 self.vq_offset = cb;
726 br.read_skip(3)?;
727 let height = br.read_u16le()?;
728 let width = br.read_u16le()?;
729 validate!((width >= 16) && (width <= 640));
730 validate!((height >= 16) && (height <= 640));
731 validate!(((width & 3) == 0) && ((height & 3) == 0));
732 if (self.bufs.width != (width as usize)) || (self.bufs.height != (height as usize)) {
733 self.bufs.alloc(width as usize, height as usize);
734 }
735 self.width = width;
736 self.height = height;
737
738 let yoff = br.read_u32le()?;
739 let uoff = br.read_u32le()?;
740 let voff = br.read_u32le()?;
741 if yoff > size { return Err(DecoderError::InvalidData); }
742 if uoff > size { return Err(DecoderError::InvalidData); }
743 if voff > size { return Err(DecoderError::InvalidData); }
744
745 br.read_skip(4)?;
746 br.read_buf(&mut self.altquant)?;
747
748 let mut yend = src.len() as u32;//size;
749 if (uoff < yend) && (uoff > yoff) { yend = uoff; }
750 if (voff < yend) && (voff > yoff) { yend = voff; }
751 let mut uend = size;
752 if (yoff < uend) && (yoff > uoff) { uend = yoff; }
753 if (voff < uend) && (voff > uoff) { uend = voff; }
754 let mut vend = size;
755 if (yoff < vend) && (yoff > voff) { vend = yoff; }
756 if (uoff < vend) && (uoff > voff) { vend = uoff; }
757
758 let intraframe = (flags & FLAG_KEYFRAME) != 0;
759 let vinfo = self.info.get_properties().get_video_info().unwrap();
760 validate!((vinfo.get_width() & !3) == (self.width & !3).into());
761 validate!((vinfo.get_height() & !3) == (self.height & !3).into());
762 let bufinfo = alloc_video_buffer(vinfo, 4)?;
763 let mut buf = bufinfo.get_vbuf().unwrap();
764 let ystart = data_start + u64::from(yoff);
765 let ustart = data_start + u64::from(uoff);
766 let vstart = data_start + u64::from(voff);
767 let yendpos = data_start + u64::from(yend);
768 let uendpos = data_start + u64::from(uend);
769 let vendpos = data_start + u64::from(vend);
770 if intraframe {
771 self.decode_plane_intra(&mut br, 0, ystart, yendpos)?;
772 self.decode_plane_intra(&mut br, 1, ustart, uendpos)?;
773 self.decode_plane_intra(&mut br, 2, vstart, vendpos)?;
774 } else {
775 self.decode_plane_inter(&mut br, 0, ystart, yendpos)?;
776 self.decode_plane_inter(&mut br, 1, ustart, uendpos)?;
777 self.decode_plane_inter(&mut br, 2, vstart, vendpos)?;
778 }
779 self.bufs.fill_framebuf(&mut buf);
780 if (flags & FLAG_NONREF) == 0 { self.bufs.flip(); }
781 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
782 frm.set_keyframe(intraframe);
783 frm.set_frame_type(if intraframe { FrameType::I } else { FrameType::P });
784 Ok(frm.into_ref())
785 }
786 fn flush(&mut self) {
787 self.bufs.reset();
788 }
789 }
790
791 pub fn get_decoder() -> Box<dyn NADecoder> {
792 Box::new(Indeo3Decoder::new())
793 }
794
795 #[cfg(test)]
796 mod test {
797 use nihav_core::codecs::RegisteredDecoders;
798 use nihav_core::demuxers::RegisteredDemuxers;
799 use nihav_core::test::dec_video::*;
800 use crate::codecs::indeo_register_all_codecs;
801 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
802 #[test]
803 fn test_indeo3() {
804 let mut dmx_reg = RegisteredDemuxers::new();
805 generic_register_all_demuxers(&mut dmx_reg);
806 let mut dec_reg = RegisteredDecoders::new();
807 indeo_register_all_codecs(&mut dec_reg);
808
809 test_file_decoding("avi", "assets/Indeo/iv32_example.avi", Some(10), true, false, None, &dmx_reg, &dec_reg);
810 }
811 }
812
813 const DT_1_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
814 0, 0, 2, 2, -2, -2, -1, 3,
815 1, -3, 3, -1, -3, 1, 4, 4,
816 -4, -4, 1, 5, -1, -5, 5, 1,
817 -5, -1, -4, 4, 4, -4, -2, 6,
818 2, -6, 6, -2, -6, 2, 4, 9,
819 -4, -9, 9, 4, -9, -4, 9, 9,
820 -9, -9, 1, 10, -1, -10, 10, 1,
821 -10, -1, -5, 8, 5, -8, 8, -5,
822 -8, 5, 9, 15, -9, -15, 15, 9,
823 -15, -9, -3, 12, 3, -12, 12, -3,
824 -12, 3, 4, 16, -4, -16, 16, 4,
825 -16, -4, 16, 16, -16, -16, 0, 18,
826 0, -18, 18, 0, -18, 0, -12, 12,
827 12, -12, -9, 16, 9, -16, 16, -9,
828 -16, 9, 11, 27, -11, -27, 27, 11,
829 -27, -11, 19, 28, -19, -28, 28, 19,
830 -28, -19, -6, 22, 6, -22, 22, -6,
831 -22, 6, 4, 29, -4, -29, 29, 4,
832 -29, -4, 30, 30, -30, -30, -2, 33,
833 2, -33, 33, -2, -33, 2, -18, 23,
834 18, -23, 23, -18, -23, 18, -15, 30,
835 15, -30, 30, -15, -30, 15, 22, 46,
836 -22, -46, 46, 22, -46, -22, 13, 47,
837 -13, -47, 47, 13, -47, -13, 35, 49,
838 -35, -49, 49, 35, -49, -35, -11, 41,
839 11, -41, 41, -11, -41, 11, 4, 51,
840 -4, -51, 51, 4, -51, -4, 54, 54,
841 -54, -54, -34, 34, 34, -34, -29, 42,
842 29, -42, 42, -29, -42, 29, -6, 60,
843 6, -60, 60, -6, -60, 6, 27, 76,
844 -27, -76, 76, 27, -76, -27, 43, 77,
845 -43, -77, 77, 43, -77, -43, -24, 55,
846 24, -55, 55, -24, -55, 24, 14, 79,
847 -14, -79, 79, 14, -79, -14, 63, 83,
848 -63, -83, 83, 63, -83, -63, -20, 74,
849 20, -74, 74, -20, -74, 20, 2, 88,
850 -2, -88, 88, 2, -88, -2, 93, 93,
851 -93, -93, -52, 61, 52, -61, 61, -52,
852 -61, 52, 52, 120, -52, -120, 120, 52,
853 -120, -52, -45, 75, 45, -75, 75, -45,
854 -75, 45, 75, 125, -75, -125, 125, 75,
855 -125, -75, 33, 122, -33, -122, 122, 33,
856 -122, -33, -13, 103, 13, -103, 103, -13,
857 -103, 13, -40, 96, 40, -96, 96, -40,
858 -96, 40, -34, 127, 34, -127, 127, -34,
859 -127, 34, -89, 89, 89, -89, -78, 105,
860 78, -105, 105, -78, -105, 78, 12, 12,
861 -12, -12, 23, 23, -23, -23, 42, 42,
862 -42, -42, 73, 73, -73, -73,
863 ]};
864
865 const DT_1_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
866 0, 0, 3, 3, -3, -3, -1, 4,
867 1, -4, 4, -1, -4, 1, 7, 7,
868 -7, -7, 2, 8, -2, -8, 8, 2,
869 -8, -2, -2, 9, 2, -9, 9, -2,
870 -9, 2, -6, 6, 6, -6, 6, 13,
871 -6, -13, 13, 6, -13, -6, 13, 13,
872 -13, -13, 1, 14, -1, -14, 14, 1,
873 -14, -1, -8, 12, 8, -12, 12, -8,
874 -12, 8, 14, 23, -14, -23, 23, 14,
875 -23, -14, -5, 18, 5, -18, 18, -5,
876 -18, 5, 6, 24, -6, -24, 24, 6,
877 -24, -6, 24, 24, -24, -24, -1, 27,
878 1, -27, 27, -1, -27, 1, -17, 17,
879 17, -17, -13, 23, 13, -23, 23, -13,
880 -23, 13, 16, 40, -16, -40, 40, 16,
881 -40, -16, 28, 41, -28, -41, 41, 28,
882 -41, -28, -9, 33, 9, -33, 33, -9,
883 -33, 9, 6, 43, -6, -43, 43, 6,
884 -43, -6, 46, 46, -46, -46, -4, 50,
885 4, -50, 50, -4, -50, 4, -27, 34,
886 27, -34, 34, -27, -34, 27, -22, 45,
887 22, -45, 45, -22, -45, 22, 34, 69,
888 -34, -69, 69, 34, -69, -34, 19, 70,
889 -19, -70, 70, 19, -70, -19, 53, 73,
890 -53, -73, 73, 53, -73, -53, -17, 62,
891 17, -62, 62, -17, -62, 17, 5, 77,
892 -5, -77, 77, 5, -77, -5, 82, 82,
893 -82, -82, -51, 51, 51, -51, -43, 64,
894 43, -64, 64, -43, -64, 43, -10, 90,
895 10, -90, 90, -10, -90, 10, 41, 114,
896 -41, -114, 114, 41, -114, -41, 64, 116,
897 -64, -116, 116, 64, -116, -64, -37, 82,
898 37, -82, 82, -37, -82, 37, 22, 119,
899 -22, -119, 119, 22, -119, -22, 95, 124,
900 -95, -124, 124, 95, -124, -95, -30, 111,
901 30, -111, 111, -30, -111, 30, -78, 92,
902 78, -92, 92, -78, -92, 78, -68, 113,
903 68, -113, 113, -68, -113, 68, 18, 18,
904 -18, -18, 34, 34, -34, -34, 63, 63,
905 -63, -63, 109, 109, -109, -109,
906 ]};
907
908 const DT_1_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
909 0, 0, 4, 4, -4, -4, -1, 5,
910 1, -5, 5, -1, -5, 1, 3, 10,
911 -3, -10, 10, 3, -10, -3, 9, 9,
912 -9, -9, -7, 7, 7, -7, -3, 12,
913 3, -12, 12, -3, -12, 3, 8, 17,
914 -8, -17, 17, 8, -17, -8, 17, 17,
915 -17, -17, 1, 19, -1, -19, 19, 1,
916 -19, -1, -11, 16, 11, -16, 16, -11,
917 -16, 11, -6, 23, 6, -23, 23, -6,
918 -23, 6, 18, 31, -18, -31, 31, 18,
919 -31, -18, 8, 32, -8, -32, 32, 8,
920 -32, -8, 33, 33, -33, -33, -1, 36,
921 1, -36, 36, -1, -36, 1, -23, 23,
922 23, -23, -17, 31, 17, -31, 31, -17,
923 -31, 17, 21, 54, -21, -54, 54, 21,
924 -54, -21, 37, 55, -37, -55, 55, 37,
925 -55, -37, -12, 44, 12, -44, 44, -12,
926 -44, 12, 8, 57, -8, -57, 57, 8,
927 -57, -8, 61, 61, -61, -61, -5, 66,
928 5, -66, 66, -5, -66, 5, -36, 45,
929 36, -45, 45, -36, -45, 36, -29, 60,
930 29, -60, 60, -29, -60, 29, 45, 92,
931 -45, -92, 92, 45, -92, -45, 25, 93,
932 -25, -93, 93, 25, -93, -25, 71, 97,
933 -71, -97, 97, 71, -97, -71, -22, 83,
934 22, -83, 83, -22, -83, 22, 7, 102,
935 -7, -102, 102, 7, -102, -7, 109, 109,
936 -109, -109, -68, 68, 68, -68, -57, 85,
937 57, -85, 85, -57, -85, 57, -13, 120,
938 13, -120, 120, -13, -120, 13, -49, 110,
939 49, -110, 110, -49, -110, 49, -104, 123,
940 104, -123, 123, -104, -123, 104, 24, 24,
941 -24, -24, 46, 46, -46, -46, 84, 84,
942 -84, -84,
943 ]};
944
945 const DT_1_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
946 0, 0, 5, 5, -5, -5, -2, 7,
947 2, -7, 7, -2, -7, 2, 11, 11,
948 -11, -11, 3, 13, -3, -13, 13, 3,
949 -13, -3, -9, 9, 9, -9, -4, 15,
950 4, -15, 15, -4, -15, 4, 11, 22,
951 -11, -22, 22, 11, -22, -11, 21, 21,
952 -21, -21, 2, 24, -2, -24, 24, 2,
953 -24, -2, -14, 20, 14, -20, 20, -14,
954 -20, 14, 23, 38, -23, -38, 38, 23,
955 -38, -23, -8, 29, 8, -29, 29, -8,
956 -29, 8, 11, 39, -11, -39, 39, 11,
957 -39, -11, 41, 41, -41, -41, -1, 45,
958 1, -45, 45, -1, -45, 1, -29, 29,
959 29, -29, -22, 39, 22, -39, 39, -22,
960 -39, 22, 27, 67, -27, -67, 67, 27,
961 -67, -27, 47, 69, -47, -69, 69, 47,
962 -69, -47, -15, 56, 15, -56, 56, -15,
963 -56, 15, 11, 71, -11, -71, 71, 11,
964 -71, -11, 76, 76, -76, -76, -6, 83,
965 6, -83, 83, -6, -83, 6, -45, 57,
966 45, -57, 57, -45, -57, 45, -36, 75,
967 36, -75, 75, -36, -75, 36, 56, 115,
968 -56, -115, 115, 56, -115, -56, 31, 117,
969 -31, -117, 117, 31, -117, -31, 88, 122,
970 -88, -122, 122, 88, -122, -88, -28, 104,
971 28, -104, 104, -28, -104, 28, -85, 85,
972 85, -85, -72, 106, 72, -106, 106, -72,
973 -106, 72, 30, 30, -30, -30, 58, 58,
974 -58, -58, 105, 105, -105, -105,
975 ]};
976
977 const DT_1_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
978 0, 0, 6, 6, -6, -6, -2, 8,
979 2, -8, 8, -2, -8, 2, 13, 13,
980 -13, -13, 4, 15, -4, -15, 15, 4,
981 -15, -4, -11, 11, 11, -11, -5, 18,
982 5, -18, 18, -5, -18, 5, 13, 26,
983 -13, -26, 26, 13, -26, -13, 26, 26,
984 -26, -26, 2, 29, -2, -29, 29, 2,
985 -29, -2, -16, 24, 16, -24, 24, -16,
986 -24, 16, 28, 46, -28, -46, 46, 28,
987 -46, -28, -9, 35, 9, -35, 35, -9,
988 -35, 9, 13, 47, -13, -47, 47, 13,
989 -47, -13, 49, 49, -49, -49, -1, 54,
990 1, -54, 54, -1, -54, 1, -35, 35,
991 35, -35, -26, 47, 26, -47, 47, -26,
992 -47, 26, 32, 81, -32, -81, 81, 32,
993 -81, -32, 56, 83, -56, -83, 83, 56,
994 -83, -56, -18, 67, 18, -67, 67, -18,
995 -67, 18, 13, 86, -13, -86, 86, 13,
996 -86, -13, 91, 91, -91, -91, -7, 99,
997 7, -99, 99, -7, -99, 7, -54, 68,
998 54, -68, 68, -54, -68, 54, -44, 90,
999 44, -90, 90, -44, -90, 44, -33, 124,
1000 33, -124, 124, -33, -124, 33, -103, 103,
1001 103, -103, -86, 127, 86, -127, 127, -86,
1002 -127, 86, 37, 37, -37, -37, 69, 69,
1003 -69, -69,
1004 ]};
1005
1006 const DT_1_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1007 0, 0, 7, 7, -7, -7, -3, 10,
1008 3, -10, 10, -3, -10, 3, 16, 16,
1009 -16, -16, 5, 18, -5, -18, 18, 5,
1010 -18, -5, -13, 13, 13, -13, -6, 21,
1011 6, -21, 21, -6, -21, 6, 15, 30,
1012 -15, -30, 30, 15, -30, -15, 30, 30,
1013 -30, -30, 2, 34, -2, -34, 34, 2,
1014 -34, -2, -19, 28, 19, -28, 28, -19,
1015 -28, 19, 32, 54, -32, -54, 54, 32,
1016 -54, -32, -11, 41, 11, -41, 41, -11,
1017 -41, 11, 15, 55, -15, -55, 55, 15,
1018 -55, -15, 57, 57, -57, -57, -1, 63,
1019 1, -63, 63, -1, -63, 1, -40, 40,
1020 40, -40, -30, 55, 30, -55, 55, -30,
1021 -55, 30, 37, 94, -37, -94, 94, 37,
1022 -94, -37, 65, 96, -65, -96, 96, 65,
1023 -96, -65, -21, 78, 21, -78, 78, -21,
1024 -78, 21, 15, 100, -15, -100, 100, 15,
1025 -100, -15, 106, 106, -106, -106, -8, 116,
1026 8, -116, 116, -8, -116, 8, -63, 79,
1027 63, -79, 79, -63, -79, 63, -51, 105,
1028 51, -105, 105, -51, -105, 51, -120, 120,
1029 120, -120, 43, 43, -43, -43, 80, 80,
1030 -80, -80,
1031 ]};
1032
1033 const DT_1_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1034 0, 0, 8, 8, -8, -8, -3, 11,
1035 3, -11, 11, -3, -11, 3, 18, 18,
1036 -18, -18, 5, 20, -5, -20, 20, 5,
1037 -20, -5, -15, 15, 15, -15, -7, 24,
1038 7, -24, 24, -7, -24, 7, 17, 35,
1039 -17, -35, 35, 17, -35, -17, 34, 34,
1040 -34, -34, 3, 38, -3, -38, 38, 3,
1041 -38, -3, -22, 32, 22, -32, 32, -22,
1042 -32, 22, 37, 61, -37, -61, 61, 37,
1043 -61, -37, -13, 47, 13, -47, 47, -13,
1044 -47, 13, 17, 63, -17, -63, 63, 17,
1045 -63, -17, 65, 65, -65, -65, -1, 72,
1046 1, -72, 72, -1, -72, 1, -46, 46,
1047 46, -46, -35, 63, 35, -63, 63, -35,
1048 -63, 35, 43, 107, -43, -107, 107, 43,
1049 -107, -43, 75, 110, -75, -110, 110, 75,
1050 -110, -75, -24, 89, 24, -89, 89, -24,
1051 -89, 24, 17, 114, -17, -114, 114, 17,
1052 -114, -17, 121, 121, -121, -121, -72, 91,
1053 72, -91, 91, -72, -91, 72, -58, 120,
1054 58, -120, 120, -58, -120, 58, 49, 49,
1055 -49, -49, 92, 92, -92, -92,
1056 ]};
1057
1058 const DT_1_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1059 0, 0, 9, 9, -9, -9, -3, 12,
1060 3, -12, 12, -3, -12, 3, 20, 20,
1061 -20, -20, 6, 23, -6, -23, 23, 6,
1062 -23, -6, -17, 17, 17, -17, -7, 27,
1063 7, -27, 27, -7, -27, 7, 19, 39,
1064 -19, -39, 39, 19, -39, -19, 39, 39,
1065 -39, -39, 3, 43, -3, -43, 43, 3,
1066 -43, -3, -24, 36, 24, -36, 36, -24,
1067 -36, 24, 42, 69, -42, -69, 69, 42,
1068 -69, -42, -14, 53, 14, -53, 53, -14,
1069 -53, 14, 19, 71, -19, -71, 71, 19,
1070 -71, -19, 73, 73, -73, -73, -2, 80,
1071 2, -80, 80, -2, -80, 2, -52, 52,
1072 52, -52, -39, 70, 39, -70, 70, -39,
1073 -70, 39, 48, 121, -48, -121, 121, 48,
1074 -121, -48, 84, 124, -84, -124, 124, 84,
1075 -124, -84, -27, 100, 27, -100, 100, -27,
1076 -100, 27, -81, 102, 81, -102, 102, -81,
1077 -102, 81, 55, 55, -55, -55, 104, 104,
1078 -104, -104,
1079 ]};
1080
1081 const DT_2_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
1082 0, 0, 2, 2, -2, -2, 0, 2,
1083 0, -2, 2, 0, -2, 0, 4, 4,
1084 -4, -4, 0, 4, 0, -4, 4, 0,
1085 -4, 0, -4, 4, 4, -4, -2, 6,
1086 2, -6, 6, -2, -6, 2, 4, 8,
1087 -4, -8, 8, 4, -8, -4, 8, 8,
1088 -8, -8, 0, 10, 0, -10, 10, 0,
1089 -10, 0, -4, 8, 4, -8, 8, -4,
1090 -8, 4, 8, 14, -8, -14, 14, 8,
1091 -14, -8, -2, 12, 2, -12, 12, -2,
1092 -12, 2, 4, 16, -4, -16, 16, 4,
1093 -16, -4, 16, 16, -16, -16, 0, 18,
1094 0, -18, 18, 0, -18, 0, -12, 12,
1095 12, -12, -8, 16, 8, -16, 16, -8,
1096 -16, 8, 10, 26, -10, -26, 26, 10,
1097 -26, -10, 18, 28, -18, -28, 28, 18,
1098 -28, -18, -6, 22, 6, -22, 22, -6,
1099 -22, 6, 4, 28, -4, -28, 28, 4,
1100 -28, -4, 30, 30, -30, -30, -2, 32,
1101 2, -32, 32, -2, -32, 2, -18, 22,
1102 18, -22, 22, -18, -22, 18, -14, 30,
1103 14, -30, 30, -14, -30, 14, 22, 46,
1104 -22, -46, 46, 22, -46, -22, 12, 46,
1105 -12, -46, 46, 12, -46, -12, 34, 48,
1106 -34, -48, 48, 34, -48, -34, -10, 40,
1107 10, -40, 40, -10, -40, 10, 4, 50,
1108 -4, -50, 50, 4, -50, -4, 54, 54,
1109 -54, -54, -34, 34, 34, -34, -28, 42,
1110 28, -42, 42, -28, -42, 28, -6, 60,
1111 6, -60, 60, -6, -60, 6, 26, 76,
1112 -26, -76, 76, 26, -76, -26, 42, 76,
1113 -42, -76, 76, 42, -76, -42, -24, 54,
1114 24, -54, 54, -24, -54, 24, 14, 78,
1115 -14, -78, 78, 14, -78, -14, 62, 82,
1116 -62, -82, 82, 62, -82, -62, -20, 74,
1117 20, -74, 74, -20, -74, 20, 2, 88,
1118 -2, -88, 88, 2, -88, -2, 92, 92,
1119 -92, -92, -52, 60, 52, -60, 60, -52,
1120 -60, 52, 52, 118, -52, -118, 118, 52,
1121 -118, -52, -44, 74, 44, -74, 74, -44,
1122 -74, 44, 74, 118, -74, -118, 118, 74,
1123 -118, -74, 32, 118, -32, -118, 118, 32,
1124 -118, -32, -12, 102, 12, -102, 102, -12,
1125 -102, 12, -40, 96, 40, -96, 96, -40,
1126 -96, 40, -34, 118, 34, -118, 118, -34,
1127 -118, 34, -88, 88, 88, -88, -78, 104,
1128 78, -104, 104, -78, -104, 78, 12, 12,
1129 -12, -12, 22, 22, -22, -22, 42, 42,
1130 -42, -42, 72, 72, -72, -72,
1131 ]};
1132
1133 const DT_2_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
1134 0, 0, 3, 3, -3, -3, 0, 3,
1135 0, -3, 3, 0, -3, 0, 6, 6,
1136 -6, -6, 3, 9, -3, -9, 9, 3,
1137 -9, -3, -3, 9, 3, -9, 9, -3,
1138 -9, 3, -6, 6, 6, -6, 6, 12,
1139 -6, -12, 12, 6, -12, -6, 12, 12,
1140 -12, -12, 0, 15, 0, -15, 15, 0,
1141 -15, 0, -9, 12, 9, -12, 12, -9,
1142 -12, 9, 15, 24, -15, -24, 24, 15,
1143 -24, -15, -6, 18, 6, -18, 18, -6,
1144 -18, 6, 6, 24, -6, -24, 24, 6,
1145 -24, -6, 24, 24, -24, -24, 0, 27,
1146 0, -27, 27, 0, -27, 0, -18, 18,
1147 18, -18, -12, 24, 12, -24, 24, -12,
1148 -24, 12, 15, 39, -15, -39, 39, 15,
1149 -39, -15, 27, 42, -27, -42, 42, 27,
1150 -42, -27, -9, 33, 9, -33, 33, -9,
1151 -33, 9, 6, 42, -6, -42, 42, 6,
1152 -42, -6, 45, 45, -45, -45, -3, 51,
1153 3, -51, 51, -3, -51, 3, -27, 33,
1154 27, -33, 33, -27, -33, 27, -21, 45,
1155 21, -45, 45, -21, -45, 21, 33, 69,
1156 -33, -69, 69, 33, -69, -33, 18, 69,
1157 -18, -69, 69, 18, -69, -18, 54, 72,
1158 -54, -72, 72, 54, -72, -54, -18, 63,
1159 18, -63, 63, -18, -63, 18, 6, 78,
1160 -6, -78, 78, 6, -78, -6, 81, 81,
1161 -81, -81, -51, 51, 51, -51, -42, 63,
1162 42, -63, 63, -42, -63, 42, -9, 90,
1163 9, -90, 90, -9, -90, 9, 42, 114,
1164 -42, -114, 114, 42, -114, -42, 63, 117,
1165 -63, -117, 117, 63, -117, -63, -36, 81,
1166 36, -81, 81, -36, -81, 36, 21, 120,
1167 -21, -120, 120, 21, -120, -21, 96, 123,
1168 -96, -123, 123, 96, -123, -96, -30, 111,
1169 30, -111, 111, -30, -111, 30, -78, 93,
1170 78, -93, 93, -78, -93, 78, -69, 114,
1171 69, -114, 114, -69, -114, 69, 18, 18,
1172 -18, -18, 33, 33, -33, -33, 63, 63,
1173 -63, -63, 108, 108, -108, -108,
1174 ]};
1175
1176 const DT_2_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
1177 0, 0, 4, 4, -4, -4, 0, 4,
1178 0, -4, 4, 0, -4, 0, 4, 8,
1179 -4, -8, 8, 4, -8, -4, 8, 8,
1180 -8, -8, -8, 8, 8, -8, -4, 12,
1181 4, -12, 12, -4, -12, 4, 8, 16,
1182 -8, -16, 16, 8, -16, -8, 16, 16,
1183 -16, -16, 0, 20, 0, -20, 20, 0,
1184 -20, 0, -12, 16, 12, -16, 16, -12,
1185 -16, 12, -4, 24, 4, -24, 24, -4,
1186 -24, 4, 16, 32, -16, -32, 32, 16,
1187 -32, -16, 8, 32, -8, -32, 32, 8,
1188 -32, -8, 32, 32, -32, -32, 0, 36,
1189 0, -36, 36, 0, -36, 0, -24, 24,
1190 24, -24, -16, 32, 16, -32, 32, -16,
1191 -32, 16, 20, 52, -20, -52, 52, 20,
1192 -52, -20, 36, 56, -36, -56, 56, 36,
1193 -56, -36, -12, 44, 12, -44, 44, -12,
1194 -44, 12, 8, 56, -8, -56, 56, 8,
1195 -56, -8, 60, 60, -60, -60, -4, 64,
1196 4, -64, 64, -4, -64, 4, -36, 44,
1197 36, -44, 44, -36, -44, 36, -28, 60,
1198 28, -60, 60, -28, -60, 28, 44, 92,
1199 -44, -92, 92, 44, -92, -44, 24, 92,
1200 -24, -92, 92, 24, -92, -24, 72, 96,
1201 -72, -96, 96, 72, -96, -72, -20, 84,
1202 20, -84, 84, -20, -84, 20, 8, 100,
1203 -8, -100, 100, 8, -100, -8, 108, 108,
1204 -108, -108, -68, 68, 68, -68, -56, 84,
1205 56, -84, 84, -56, -84, 56, -12, 120,
1206 12, -120, 120, -12, -120, 12, -48, 108,
1207 48, -108, 108, -48, -108, 48, -104, 124,
1208 104, -124, 124, -104, -124, 104, 24, 24,
1209 -24, -24, 44, 44, -44, -44, 84, 84,
1210 -84, -84,
1211 ]};
1212
1213 const DT_2_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1214 0, 0, 5, 5, -5, -5, 0, 5,
1215 0, -5, 5, 0, -5, 0, 10, 10,
1216 -10, -10, 5, 15, -5, -15, 15, 5,
1217 -15, -5, -10, 10, 10, -10, -5, 15,
1218 5, -15, 15, -5, -15, 5, 10, 20,
1219 -10, -20, 20, 10, -20, -10, 20, 20,
1220 -20, -20, 0, 25, 0, -25, 25, 0,
1221 -25, 0, -15, 20, 15, -20, 20, -15,
1222 -20, 15, 25, 40, -25, -40, 40, 25,
1223 -40, -25, -10, 30, 10, -30, 30, -10,
1224 -30, 10, 10, 40, -10, -40, 40, 10,
1225 -40, -10, 40, 40, -40, -40, 0, 45,
1226 0, -45, 45, 0, -45, 0, -30, 30,
1227 30, -30, -20, 40, 20, -40, 40, -20,
1228 -40, 20, 25, 65, -25, -65, 65, 25,
1229 -65, -25, 45, 70, -45, -70, 70, 45,
1230 -70, -45, -15, 55, 15, -55, 55, -15,
1231 -55, 15, 10, 70, -10, -70, 70, 10,
1232 -70, -10, 75, 75, -75, -75, -5, 85,
1233 5, -85, 85, -5, -85, 5, -45, 55,
1234 45, -55, 55, -45, -55, 45, -35, 75,
1235 35, -75, 75, -35, -75, 35, 55, 115,
1236 -55, -115, 115, 55, -115, -55, 30, 115,
1237 -30, -115, 115, 30, -115, -30, 90, 120,
1238 -90, -120, 120, 90, -120, -90, -30, 105,
1239 30, -105, 105, -30, -105, 30, -85, 85,
1240 85, -85, -70, 105, 70, -105, 105, -70,
1241 -105, 70, 30, 30, -30, -30, 60, 60,
1242 -60, -60, 105, 105, -105, -105,
1243 ]};
1244
1245 const DT_2_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1246 0, 0, 6, 6, -6, -6, 0, 6,
1247 0, -6, 6, 0, -6, 0, 12, 12,
1248 -12, -12, 6, 12, -6, -12, 12, 6,
1249 -12, -6, -12, 12, 12, -12, -6, 18,
1250 6, -18, 18, -6, -18, 6, 12, 24,
1251 -12, -24, 24, 12, -24, -12, 24, 24,
1252 -24, -24, 0, 30, 0, -30, 30, 0,
1253 -30, 0, -18, 24, 18, -24, 24, -18,
1254 -24, 18, 30, 48, -30, -48, 48, 30,
1255 -48, -30, -6, 36, 6, -36, 36, -6,
1256 -36, 6, 12, 48, -12, -48, 48, 12,
1257 -48, -12, 48, 48, -48, -48, 0, 54,
1258 0, -54, 54, 0, -54, 0, -36, 36,
1259 36, -36, -24, 48, 24, -48, 48, -24,
1260 -48, 24, 30, 78, -30, -78, 78, 30,
1261 -78, -30, 54, 84, -54, -84, 84, 54,
1262 -84, -54, -18, 66, 18, -66, 66, -18,
1263 -66, 18, 12, 84, -12, -84, 84, 12,
1264 -84, -12, 90, 90, -90, -90, -6, 96,
1265 6, -96, 96, -6, -96, 6, -54, 66,
1266 54, -66, 66, -54, -66, 54, -42, 90,
1267 42, -90, 90, -42, -90, 42, -30, 126,
1268 30, -126, 126, -30, -126, 30, -102, 102,
1269 102, -102, -84, 126, 84, -126, 126, -84,
1270 -126, 84, 36, 36, -36, -36, 66, 66,
1271 -66, -66,
1272 ]};
1273
1274 const DT_2_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1275 0, 0, 7, 7, -7, -7, 0, 7,
1276 0, -7, 7, 0, -7, 0, 14, 14,
1277 -14, -14, 7, 21, -7, -21, 21, 7,
1278 -21, -7, -14, 14, 14, -14, -7, 21,
1279 7, -21, 21, -7, -21, 7, 14, 28,
1280 -14, -28, 28, 14, -28, -14, 28, 28,
1281 -28, -28, 0, 35, 0, -35, 35, 0,
1282 -35, 0, -21, 28, 21, -28, 28, -21,
1283 -28, 21, 35, 56, -35, -56, 56, 35,
1284 -56, -35, -14, 42, 14, -42, 42, -14,
1285 -42, 14, 14, 56, -14, -56, 56, 14,
1286 -56, -14, 56, 56, -56, -56, 0, 63,
1287 0, -63, 63, 0, -63, 0, -42, 42,
1288 42, -42, -28, 56, 28, -56, 56, -28,
1289 -56, 28, 35, 91, -35, -91, 91, 35,
1290 -91, -35, 63, 98, -63, -98, 98, 63,
1291 -98, -63, -21, 77, 21, -77, 77, -21,
1292 -77, 21, 14, 98, -14, -98, 98, 14,
1293 -98, -14, 105, 105, -105, -105, -7, 119,
1294 7, -119, 119, -7, -119, 7, -63, 77,
1295 63, -77, 77, -63, -77, 63, -49, 105,
1296 49, -105, 105, -49, -105, 49, -119, 119,
1297 119, -119, 42, 42, -42, -42, 77, 77,
1298 -77, -77,
1299 ]};
1300
1301 const DT_2_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1302 0, 0, 8, 8, -8, -8, 0, 8,
1303 0, -8, 8, 0, -8, 0, 16, 16,
1304 -16, -16, 8, 16, -8, -16, 16, 8,
1305 -16, -8, -16, 16, 16, -16, -8, 24,
1306 8, -24, 24, -8, -24, 8, 16, 32,
1307 -16, -32, 32, 16, -32, -16, 32, 32,
1308 -32, -32, 0, 40, 0, -40, 40, 0,
1309 -40, 0, -24, 32, 24, -32, 32, -24,
1310 -32, 24, 40, 64, -40, -64, 64, 40,
1311 -64, -40, -16, 48, 16, -48, 48, -16,
1312 -48, 16, 16, 64, -16, -64, 64, 16,
1313 -64, -16, 64, 64, -64, -64, 0, 72,
1314 0, -72, 72, 0, -72, 0, -48, 48,
1315 48, -48, -32, 64, 32, -64, 64, -32,
1316 -64, 32, 40, 104, -40, -104, 104, 40,
1317 -104, -40, 72, 112, -72, -112, 112, 72,
1318 -112, -72, -24, 88, 24, -88, 88, -24,
1319 -88, 24, 16, 112, -16, -112, 112, 16,
1320 -112, -16, 120, 120, -120, -120, -72, 88,
1321 72, -88, 88, -72, -88, 72, -56, 120,
1322 56, -120, 120, -56, -120, 56, 48, 48,
1323 -48, -48, 88, 88, -88, -88,
1324 ]};
1325
1326 const DT_2_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1327 0, 0, 9, 9, -9, -9, 0, 9,
1328 0, -9, 9, 0, -9, 0, 18, 18,
1329 -18, -18, 9, 27, -9, -27, 27, 9,
1330 -27, -9, -18, 18, 18, -18, -9, 27,
1331 9, -27, 27, -9, -27, 9, 18, 36,
1332 -18, -36, 36, 18, -36, -18, 36, 36,
1333 -36, -36, 0, 45, 0, -45, 45, 0,
1334 -45, 0, -27, 36, 27, -36, 36, -27,
1335 -36, 27, 45, 72, -45, -72, 72, 45,
1336 -72, -45, -18, 54, 18, -54, 54, -18,
1337 -54, 18, 18, 72, -18, -72, 72, 18,
1338 -72, -18, 72, 72, -72, -72, 0, 81,
1339 0, -81, 81, 0, -81, 0, -54, 54,
1340 54, -54, -36, 72, 36, -72, 72, -36,
1341 -72, 36, 45, 117, -45, -117, 117, 45,
1342 -117, -45, 81, 126, -81, -126, 126, 81,
1343 -126, -81, -27, 99, 27, -99, 99, -27,
1344 -99, 27, -81, 99, 81, -99, 99, -81,
1345 -99, 81, 54, 54, -54, -54, 108, 108,
1346 -108, -108,
1347 ]};
1348
1349 const DT_3_1: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1350 0, 0, 2, 2, -2, -2, 0, 3,
1351 0, -3, 3, 0, -3, 0, 6, 6,
1352 -6, -6, 0, 7, 0, -7, 7, 0,
1353 -7, 0, -5, 5, 5, -5, 5, -5,
1354 -5, 5, 6, 11, -6, -11, 11, 6,
1355 -11, -6, 0, 8, 0, -8, 8, 0,
1356 -8, 0, 11, 11, -11, -11, 0, 12,
1357 0, -12, 12, 0, -12, 0, 12, 17,
1358 -12, -17, 17, 12, -17, -12, 17, 17,
1359 -17, -17, 6, 18, -6, -18, 18, 6,
1360 -18, -6, -8, 11, 8, -11, 11, -8,
1361 -11, 8, 0, 15, 0, -15, 15, 0,
1362 -15, 0, 0, 20, 0, -20, 20, 0,
1363 -20, 0, 18, 25, -18, -25, 25, 18,
1364 -25, -18, 11, 25, -11, -25, 25, 11,
1365 -25, -11, 25, 25, -25, -25, -14, 14,
1366 14, -14, 14, -14, -14, 14, 0, 26,
1367 0, -26, 26, 0, -26, 0, -11, 18,
1368 11, -18, 18, -11, -18, 11, -7, 22,
1369 7, -22, 22, -7, -22, 7, 26, 34,
1370 -26, -34, 34, 26, -34, -26, 18, 34,
1371 -18, -34, 34, 18, -34, -18, 34, 34,
1372 -34, -34, 11, 35, -11, -35, 35, 11,
1373 -35, -11, 0, 29, 0, -29, 29, 0,
1374 -29, 0, -19, 22, 19, -22, 22, -19,
1375 -22, 19, -15, 26, 15, -26, 26, -15,
1376 -26, 15, 0, 37, 0, -37, 37, 0,
1377 -37, 0, 27, 44, -27, -44, 44, 27,
1378 -44, -27, 36, 44, -36, -44, 44, 36,
1379 -44, -36, 18, 44, -18, -44, 44, 18,
1380 -44, -18, -10, 33, 10, -33, 33, -10,
1381 -33, 10, 45, 45, -45, -45, 0, 0,
1382 ]};
1383
1384 const DT_3_2: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1385 0, 0, 0, 2, 0, -2, 2, 0,
1386 -2, 0, 2, 2, -2, -2, 6, 6,
1387 -6, -6, 0, 6, 0, -6, 6, 0,
1388 -6, 0, -4, 4, 4, -4, 10, -6,
1389 -10, 6, 0, -12, 0, 12, -6, -12,
1390 6, -12, -6, 12, 6, 12, -14, 0,
1391 14, 0, 12, 12, -12, -12, 0, -18,
1392 0, 18, 14, -12, -14, 12, -18, -6,
1393 18, -6, -18, 6, 18, 6, -10, -18,
1394 10, -18, -10, 18, 10, 18, -22, 0,
1395 22, 0, 0, -24, 0, 24, -22, -12,
1396 22, -12, -22, 12, 22, 12, -8, -24,
1397 8, -24, -8, 24, 8, 24, -26, -6,
1398 26, -6, -26, 6, 26, 6, -28, 0,
1399 28, 0, 20, 20, -20, -20, -14, -26,
1400 14, 26, -30, -12, 30, 12, -10, -32,
1401 10, 32, -18, -32, 18, 32, -26, -26,
1402 26, 26, -34, -20, 34, 20, -38, -12,
1403 38, 12, -32, -32, 32, 32, 32, 32,
1404 -22, -40, -34, -34, 34, 34,
1405 ]};
1406
1407 const DT_3_3: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1408 0, 0, 0, 2, 0, -2, 2, 0,
1409 -2, 0, 4, 4, -4, -4, 10, 10,
1410 -10, -10, 0, 10, 0, -10, 10, 0,
1411 -10, 0, -6, 6, 6, -6, 14, -8,
1412 -14, 8, -18, 0, 18, 0, 10, -16,
1413 -10, 16, 0, -24, 0, 24, -24, -8,
1414 24, -8, -24, 8, 24, 8, 18, 18,
1415 -18, -18, 20, -16, -20, 16, -14, -26,
1416 14, -26, -14, 26, 14, 26, -30, 0,
1417 30, 0, 0, -34, 0, 34, -34, -8,
1418 34, -8, -34, 8, 34, 8, -30, -18,
1419 30, -18, -30, 18, 30, 18, -10, -34,
1420 10, -34, -10, 34, 10, 34, -20, -34,
1421 20, 34, -40, 0, 40, 0, 30, 30,
1422 -30, -30, -40, -18, 40, 18, 0, -44,
1423 0, 44, -16, -44, 16, 44, -36, -36,
1424 -36, -36, 36, 36, -26, -44, 26, 44,
1425 -46, -26, 46, 26, -52, -18, 52, 18,
1426 -20, -54, -44, -44, 44, 44, -32, -54,
1427 -46, -46, -46, -46, 46, 46,
1428 ]};
1429
1430 const DT_3_4: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1431 0, 0, 0, 4, 0, -4, 4, 0,
1432 -4, 0, 4, 4, -4, -4, 12, 12,
1433 -12, -12, 0, 12, 0, -12, 12, 0,
1434 -12, 0, -8, 8, 8, -8, 8, -16,
1435 -8, 16, 0, -24, 0, 24, -24, -8,
1436 24, -8, -24, 8, 24, 8, 20, -16,
1437 -20, 16, -28, 0, 28, 0, -16, -24,
1438 16, -24, -16, 24, 16, 24, 0, -32,
1439 0, 32, -28, -16, 28, -16, -28, 16,
1440 28, 16, -8, -32, 8, -32, -32, -8,
1441 32, -8, -32, 8, 32, 8, -8, 32,
1442 8, 32, 24, 24, -24, -24, 24, -24,
1443 -24, 24, -20, -32, 20, 32, -40, 0,
1444 40, 0, -40, -16, 40, 16, 0, -44,
1445 0, -44, -44, 0, 44, 0, 0, 44,
1446 0, 44, -32, -32, 32, 32, -16, -44,
1447 16, 44, -24, -44, -44, -24, 44, 24,
1448 24, 44, -48, -16, 48, 16, -36, -36,
1449 -36, -36, 36, 36, 36, 36, -20, -52,
1450 40, 40, -40, -40, -32, -52,
1451 ]};
1452
1453 const DT_3_5: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1454 0, 0, 2, 2, -2, -2, 6, 6,
1455 -6, -6, 12, 12, -12, -12, 20, 20,
1456 -20, -20, 32, 32, -32, -32, 46, 46,
1457 -46, -46, 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,
1465 0, 0, 0, 0, 0, 0, 0, 0,
1466 0, 0, 0, 0, 0, 0, 0, 0,
1467 0, 0, 0, 0, 0, 0, 0, 0,
1468 0, 0, 0, 0, 0, 0, 0, 0,
1469 0, 0, 0, 0, 0, 0, 0, 0,
1470 0, 0, 0, 0, 0, 0, 0, 0,
1471 0, 0, 0, 0, 0, 0, 0, 0,
1472 0, 0, 0, 0, 0, 0, 0, 0,
1473 0, 0, 0, 0, 0, 0,
1474 ]};
1475
1476 const IVI3_DELTA_CBS: [&IviDeltaCB; 24] = [
1477 &DT_1_1, &DT_1_2, &DT_1_3, &DT_1_4, &DT_1_5, &DT_1_6, &DT_1_7, &DT_1_8,
1478 &DT_2_1, &DT_2_2, &DT_2_3, &DT_2_4, &DT_2_5, &DT_2_6, &DT_2_7, &DT_2_8,
1479 &DT_3_1, &DT_3_2, &DT_3_3, &DT_3_4, &DT_3_5, &DT_3_5, &DT_3_5, &DT_3_5
1480 ];