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