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