add flush() to decoder interface
[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,
afe29743
KS
23 buf1: Vec<u8>,
24 buf2: Vec<u8>,
25 fbuf: bool,
26}
27
28const DEFAULT_PIXEL: u8 = 0x40;
29
30impl Buffers {
7a95487c 31 fn new() -> Self { Buffers { width: 0, height: 0, cw: 0, ch: 0, buf1: Vec::new(), buf2: Vec::new(), fbuf: true } }
afe29743
KS
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;
7a95487c
KS
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);
afe29743
KS
45 }
46 fn flip(&mut self) { self.fbuf = !self.fbuf; }
47 fn get_stride(&mut self, planeno: usize) -> usize {
7a95487c 48 if planeno == 0 { self.width } else { self.cw }
afe29743
KS
49 }
50 fn get_offset(&mut self, planeno: usize) -> usize {
51 match planeno {
52 1 => self.width * self.height,
7a95487c 53 2 => self.width * self.height + self.cw * self.ch,
afe29743
KS
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);
7a95487c 63 let width = if planeno == 0 { self.width } else { self.width >> 2 };
afe29743
KS
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..] };
1a967e6b 66 let dst = fbuf.get_data_mut().unwrap();
afe29743
KS
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)]
127fn apply_delta4x4(bufs: &mut Buffers, off: usize, stride: usize,
128 deltas: &[u8], topline: bool, first_line: bool) {
9037cf6b
KS
129 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4)] }
130 else { &mut bufs.buf2[off..(off + 4)] };
afe29743
KS
131 for i in 0..4 { dst[i] = dst[i].wrapping_add(deltas[i]) & 0x7F; }
132}
133
134#[allow(unused_variables)]
135fn apply_delta4x8(bufs: &mut Buffers, off: usize, stride: usize,
136 deltas: &[u8], topline: bool, first_line: bool) {
9037cf6b
KS
137 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4 + stride)] }
138 else { &mut bufs.buf2[off..(off + 4 + stride)] };
afe29743
KS
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)]
148fn apply_delta4x8m11(bufs: &mut Buffers, off: usize, stride: usize,
149 deltas: &[u8], topline: bool, first_line: bool) {
9037cf6b
KS
150 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 4 + stride)] }
151 else { &mut bufs.buf2[off..(off + 4 + stride)] };
afe29743
KS
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)]
157fn apply_delta8x8p(bufs: &mut Buffers, off: usize, stride: usize,
158 deltas: &[u8], topline: bool, first_line: bool) {
9037cf6b
KS
159 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8 + stride)] }
160 else { &mut bufs.buf2[off..(off + 8 + stride)] };
afe29743
KS
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
165fn apply_delta8x8i(bufs: &mut Buffers, off: usize, stride: usize,
166 deltas: &[u8], topline: bool, firstline: bool) {
9037cf6b
KS
167 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8 + stride)] }
168 else { &mut bufs.buf2[off..(off + 8 + stride)] };
afe29743
KS
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
181fn 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 }
9037cf6b
KS
190 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + bw)] }
191 else { &mut bufs.buf2[off..(off + bw)] };
afe29743
KS
192 for i in 0..bw { dst[i] = buf[i]; }
193}
194
195fn copy_line_top4x4(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
196 copy_line_top(bufs, off, stride, 4, topline);
197}
198
199fn 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
204fn 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 }
9037cf6b
KS
213 let dst = if bufs.fbuf { &mut bufs.buf1[off..(off + 8)] }
214 else { &mut bufs.buf2[off..(off + 8)] };
afe29743
KS
215 for i in 0..8 {dst[i] = buf[i]; }
216}
217
218fn 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 {
568cde81 226 for i in 0..8 { buf[i] = bufs.buf2[doff - stride + i]; }
afe29743
KS
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 };
8865cd08
KS
238 if topline {
239 didx += stride;
240 }
afe29743
KS
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
254struct Indeo3Decoder {
2422d969 255 info: NACodecInfoRef,
afe29743
KS
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)]
267struct 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
277impl IV3Cell {
278 fn new(w: u16, h: u16) -> Self {
f2af8eca 279 IV3Cell { x: 0, y: 0, w, h, d: 20, vqt: false, mv: None }
afe29743
KS
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 }
f2af8eca 309 fn no_mv(&self) -> bool { self.mv.is_none() }
afe29743
KS
310}
311
312struct 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
322const FRMH_TAG: u32 = ((b'F' as u32) << 24) | ((b'R' as u32) << 16)
323 | ((b'M' as u32) << 8) | (b'H' as u32);
324
325const H_SPLIT: u8 = 0;
326const V_SPLIT: u8 = 1;
327const SKIP_OR_TREE: u8 = 2;
328
329impl Indeo3Decoder {
330 fn new() -> Self {
2422d969 331 let dummy_info = NACodecInfo::new_dummy();
afe29743
KS
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();
f2af8eca
KS
368 let mx = i16::from(mv.x);
369 let my = i16::from(mv.y);
afe29743
KS
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,
8f4c4020 397 y == 0, (cell.y == 0) && (y == 0));
afe29743
KS
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 {
f2af8eca 476 let nl = 257 - i16::from(c) - (line as i16);
afe29743
KS
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();
f2af8eca
KS
516 let mx = i16::from(mv.x);
517 let my = i16::from(mv.y);
afe29743
KS
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;
f2af8eca 649 self.mvs.push(MV{ x, y });
afe29743
KS
650 }
651
652 let shift = if planeno == 0 { 2 } else { 4 };
7a95487c
KS
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);
afe29743
KS
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;
f2af8eca 674 self.mvs.push(MV{ x, y });
afe29743
KS
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
687const FLAG_KEYFRAME: u16 = 1 << 2;
688const FLAG_NONREF: u16 = 1 << 8;
689
690impl NADecoder for Indeo3Decoder {
01613464 691 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
afe29743
KS
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));
2422d969 697 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
afe29743
KS
698 self.bufs.reset();
699 Ok(())
700 } else {
701 Err(DecoderError::InvalidData)
702 }
703 }
01613464 704 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
afe29743
KS
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 }
f2af8eca 718 if i64::from(size) > br.left() { return Err(DecoderError::InvalidData); }
afe29743
KS
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
5658bdcc 758 let intraframe = (flags & FLAG_KEYFRAME) != 0;
afe29743 759 let vinfo = self.info.get_properties().get_video_info().unwrap();
7a95487c
KS
760 validate!((vinfo.get_width() & !3) == (self.width & !3).into());
761 validate!((vinfo.get_height() & !3) == (self.height & !3).into());
f2af8eca 762 let bufinfo = alloc_video_buffer(vinfo, 4)?;
afe29743 763 let mut buf = bufinfo.get_vbuf().unwrap();
f2af8eca
KS
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);
5658bdcc 770 if intraframe {
afe29743
KS
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);
5658bdcc
KS
782 frm.set_keyframe(intraframe);
783 frm.set_frame_type(if intraframe { FrameType::I } else { FrameType::P });
171860fc 784 Ok(frm.into_ref())
afe29743 785 }
f9be4e75
KS
786 fn flush(&mut self) {
787 self.bufs.reset();
788 }
afe29743
KS
789}
790
6011e201 791pub fn get_decoder() -> Box<dyn NADecoder> {
379fd781
KS
792 Box::new(Indeo3Decoder::new())
793}
794
afe29743
KS
795#[cfg(test)]
796mod test {
3167c45c
KS
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;
afe29743
KS
802 #[test]
803 fn test_indeo3() {
3167c45c
KS
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
1678d59a 809 test_file_decoding("avi", "assets/Indeo/iv32_example.avi", Some(10), true, false, None, &dmx_reg, &dec_reg);
afe29743
KS
810 }
811}
afe29743
KS
812
813const 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
865const 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
908const 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
945const 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
977const 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
1006const 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
1033const 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
1058const 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
1081const 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
1133const 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
1176const 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
1213const 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
1245const 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
1274const 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
1301const 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
1326const 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
1349const 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
1384const 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
1407const 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
1430const 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
1453const 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
1476const 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];