replace vec.truncate(0) with vec.clear()
[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
2890938d
KS
820 test_decoding("avi", "indeo3", "assets/Indeo/iv32_example.avi", Some(10),
821 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
822 [0x90be698e, 0x326db071, 0x08e8c6a5, 0x39349acc],
823 [0x25d677fc, 0x63f96aaa, 0xd412ca98, 0x61416313],
824 [0xc4368250, 0x63e7b6bc, 0xffcff950, 0x11f13239],
825 [0x7e869758, 0x027abc2e, 0x25204bca, 0x93fbaa03],
826 [0x5a1e822c, 0x2b1a4cd5, 0x72059843, 0xe5689ad1],
827 [0x3a971cce, 0x5ec22135, 0x1a45f802, 0x0f5f9264],
828 [0x0a65f782, 0xd8767cf3, 0x878b4b8d, 0xfc94c88b],
829 [0x4ac70139, 0x3300eac1, 0xba84b068, 0x47f5ff29],
830 [0x3e8c8ec4, 0x9421b38c, 0x580abbbd, 0x92792d19],
831 [0x9096ee9b, 0x8dd9fb14, 0x981e31e3, 0x3ffd7d29],
832 [0x22dc71ec, 0x3d8f6f7e, 0x1a198982, 0x41d17ecc]]));
afe29743
KS
833 }
834}
afe29743
KS
835
836const DT_1_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
837 0, 0, 2, 2, -2, -2, -1, 3,
838 1, -3, 3, -1, -3, 1, 4, 4,
839 -4, -4, 1, 5, -1, -5, 5, 1,
840 -5, -1, -4, 4, 4, -4, -2, 6,
841 2, -6, 6, -2, -6, 2, 4, 9,
842 -4, -9, 9, 4, -9, -4, 9, 9,
843 -9, -9, 1, 10, -1, -10, 10, 1,
844 -10, -1, -5, 8, 5, -8, 8, -5,
845 -8, 5, 9, 15, -9, -15, 15, 9,
846 -15, -9, -3, 12, 3, -12, 12, -3,
847 -12, 3, 4, 16, -4, -16, 16, 4,
848 -16, -4, 16, 16, -16, -16, 0, 18,
849 0, -18, 18, 0, -18, 0, -12, 12,
850 12, -12, -9, 16, 9, -16, 16, -9,
851 -16, 9, 11, 27, -11, -27, 27, 11,
852 -27, -11, 19, 28, -19, -28, 28, 19,
853 -28, -19, -6, 22, 6, -22, 22, -6,
854 -22, 6, 4, 29, -4, -29, 29, 4,
855 -29, -4, 30, 30, -30, -30, -2, 33,
856 2, -33, 33, -2, -33, 2, -18, 23,
857 18, -23, 23, -18, -23, 18, -15, 30,
858 15, -30, 30, -15, -30, 15, 22, 46,
859 -22, -46, 46, 22, -46, -22, 13, 47,
860 -13, -47, 47, 13, -47, -13, 35, 49,
861 -35, -49, 49, 35, -49, -35, -11, 41,
862 11, -41, 41, -11, -41, 11, 4, 51,
863 -4, -51, 51, 4, -51, -4, 54, 54,
864 -54, -54, -34, 34, 34, -34, -29, 42,
865 29, -42, 42, -29, -42, 29, -6, 60,
866 6, -60, 60, -6, -60, 6, 27, 76,
867 -27, -76, 76, 27, -76, -27, 43, 77,
868 -43, -77, 77, 43, -77, -43, -24, 55,
869 24, -55, 55, -24, -55, 24, 14, 79,
870 -14, -79, 79, 14, -79, -14, 63, 83,
871 -63, -83, 83, 63, -83, -63, -20, 74,
872 20, -74, 74, -20, -74, 20, 2, 88,
873 -2, -88, 88, 2, -88, -2, 93, 93,
874 -93, -93, -52, 61, 52, -61, 61, -52,
875 -61, 52, 52, 120, -52, -120, 120, 52,
876 -120, -52, -45, 75, 45, -75, 75, -45,
877 -75, 45, 75, 125, -75, -125, 125, 75,
878 -125, -75, 33, 122, -33, -122, 122, 33,
879 -122, -33, -13, 103, 13, -103, 103, -13,
880 -103, 13, -40, 96, 40, -96, 96, -40,
881 -96, 40, -34, 127, 34, -127, 127, -34,
882 -127, 34, -89, 89, 89, -89, -78, 105,
883 78, -105, 105, -78, -105, 78, 12, 12,
884 -12, -12, 23, 23, -23, -23, 42, 42,
885 -42, -42, 73, 73, -73, -73,
886]};
887
888const DT_1_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
889 0, 0, 3, 3, -3, -3, -1, 4,
890 1, -4, 4, -1, -4, 1, 7, 7,
891 -7, -7, 2, 8, -2, -8, 8, 2,
892 -8, -2, -2, 9, 2, -9, 9, -2,
893 -9, 2, -6, 6, 6, -6, 6, 13,
894 -6, -13, 13, 6, -13, -6, 13, 13,
895 -13, -13, 1, 14, -1, -14, 14, 1,
896 -14, -1, -8, 12, 8, -12, 12, -8,
897 -12, 8, 14, 23, -14, -23, 23, 14,
898 -23, -14, -5, 18, 5, -18, 18, -5,
899 -18, 5, 6, 24, -6, -24, 24, 6,
900 -24, -6, 24, 24, -24, -24, -1, 27,
901 1, -27, 27, -1, -27, 1, -17, 17,
902 17, -17, -13, 23, 13, -23, 23, -13,
903 -23, 13, 16, 40, -16, -40, 40, 16,
904 -40, -16, 28, 41, -28, -41, 41, 28,
905 -41, -28, -9, 33, 9, -33, 33, -9,
906 -33, 9, 6, 43, -6, -43, 43, 6,
907 -43, -6, 46, 46, -46, -46, -4, 50,
908 4, -50, 50, -4, -50, 4, -27, 34,
909 27, -34, 34, -27, -34, 27, -22, 45,
910 22, -45, 45, -22, -45, 22, 34, 69,
911 -34, -69, 69, 34, -69, -34, 19, 70,
912 -19, -70, 70, 19, -70, -19, 53, 73,
913 -53, -73, 73, 53, -73, -53, -17, 62,
914 17, -62, 62, -17, -62, 17, 5, 77,
915 -5, -77, 77, 5, -77, -5, 82, 82,
916 -82, -82, -51, 51, 51, -51, -43, 64,
917 43, -64, 64, -43, -64, 43, -10, 90,
918 10, -90, 90, -10, -90, 10, 41, 114,
919 -41, -114, 114, 41, -114, -41, 64, 116,
920 -64, -116, 116, 64, -116, -64, -37, 82,
921 37, -82, 82, -37, -82, 37, 22, 119,
922 -22, -119, 119, 22, -119, -22, 95, 124,
923 -95, -124, 124, 95, -124, -95, -30, 111,
924 30, -111, 111, -30, -111, 30, -78, 92,
925 78, -92, 92, -78, -92, 78, -68, 113,
926 68, -113, 113, -68, -113, 68, 18, 18,
927 -18, -18, 34, 34, -34, -34, 63, 63,
928 -63, -63, 109, 109, -109, -109,
929]};
930
931const DT_1_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
932 0, 0, 4, 4, -4, -4, -1, 5,
933 1, -5, 5, -1, -5, 1, 3, 10,
934 -3, -10, 10, 3, -10, -3, 9, 9,
935 -9, -9, -7, 7, 7, -7, -3, 12,
936 3, -12, 12, -3, -12, 3, 8, 17,
937 -8, -17, 17, 8, -17, -8, 17, 17,
938 -17, -17, 1, 19, -1, -19, 19, 1,
939 -19, -1, -11, 16, 11, -16, 16, -11,
940 -16, 11, -6, 23, 6, -23, 23, -6,
941 -23, 6, 18, 31, -18, -31, 31, 18,
942 -31, -18, 8, 32, -8, -32, 32, 8,
943 -32, -8, 33, 33, -33, -33, -1, 36,
944 1, -36, 36, -1, -36, 1, -23, 23,
945 23, -23, -17, 31, 17, -31, 31, -17,
946 -31, 17, 21, 54, -21, -54, 54, 21,
947 -54, -21, 37, 55, -37, -55, 55, 37,
948 -55, -37, -12, 44, 12, -44, 44, -12,
949 -44, 12, 8, 57, -8, -57, 57, 8,
950 -57, -8, 61, 61, -61, -61, -5, 66,
951 5, -66, 66, -5, -66, 5, -36, 45,
952 36, -45, 45, -36, -45, 36, -29, 60,
953 29, -60, 60, -29, -60, 29, 45, 92,
954 -45, -92, 92, 45, -92, -45, 25, 93,
955 -25, -93, 93, 25, -93, -25, 71, 97,
956 -71, -97, 97, 71, -97, -71, -22, 83,
957 22, -83, 83, -22, -83, 22, 7, 102,
958 -7, -102, 102, 7, -102, -7, 109, 109,
959 -109, -109, -68, 68, 68, -68, -57, 85,
960 57, -85, 85, -57, -85, 57, -13, 120,
961 13, -120, 120, -13, -120, 13, -49, 110,
962 49, -110, 110, -49, -110, 49, -104, 123,
963 104, -123, 123, -104, -123, 104, 24, 24,
964 -24, -24, 46, 46, -46, -46, 84, 84,
965 -84, -84,
966]};
967
968const DT_1_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
969 0, 0, 5, 5, -5, -5, -2, 7,
970 2, -7, 7, -2, -7, 2, 11, 11,
971 -11, -11, 3, 13, -3, -13, 13, 3,
972 -13, -3, -9, 9, 9, -9, -4, 15,
973 4, -15, 15, -4, -15, 4, 11, 22,
974 -11, -22, 22, 11, -22, -11, 21, 21,
975 -21, -21, 2, 24, -2, -24, 24, 2,
976 -24, -2, -14, 20, 14, -20, 20, -14,
977 -20, 14, 23, 38, -23, -38, 38, 23,
978 -38, -23, -8, 29, 8, -29, 29, -8,
979 -29, 8, 11, 39, -11, -39, 39, 11,
980 -39, -11, 41, 41, -41, -41, -1, 45,
981 1, -45, 45, -1, -45, 1, -29, 29,
982 29, -29, -22, 39, 22, -39, 39, -22,
983 -39, 22, 27, 67, -27, -67, 67, 27,
984 -67, -27, 47, 69, -47, -69, 69, 47,
985 -69, -47, -15, 56, 15, -56, 56, -15,
986 -56, 15, 11, 71, -11, -71, 71, 11,
987 -71, -11, 76, 76, -76, -76, -6, 83,
988 6, -83, 83, -6, -83, 6, -45, 57,
989 45, -57, 57, -45, -57, 45, -36, 75,
990 36, -75, 75, -36, -75, 36, 56, 115,
991 -56, -115, 115, 56, -115, -56, 31, 117,
992 -31, -117, 117, 31, -117, -31, 88, 122,
993 -88, -122, 122, 88, -122, -88, -28, 104,
994 28, -104, 104, -28, -104, 28, -85, 85,
995 85, -85, -72, 106, 72, -106, 106, -72,
996 -106, 72, 30, 30, -30, -30, 58, 58,
997 -58, -58, 105, 105, -105, -105,
998]};
999
1000const DT_1_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1001 0, 0, 6, 6, -6, -6, -2, 8,
1002 2, -8, 8, -2, -8, 2, 13, 13,
1003 -13, -13, 4, 15, -4, -15, 15, 4,
1004 -15, -4, -11, 11, 11, -11, -5, 18,
1005 5, -18, 18, -5, -18, 5, 13, 26,
1006 -13, -26, 26, 13, -26, -13, 26, 26,
1007 -26, -26, 2, 29, -2, -29, 29, 2,
1008 -29, -2, -16, 24, 16, -24, 24, -16,
1009 -24, 16, 28, 46, -28, -46, 46, 28,
1010 -46, -28, -9, 35, 9, -35, 35, -9,
1011 -35, 9, 13, 47, -13, -47, 47, 13,
1012 -47, -13, 49, 49, -49, -49, -1, 54,
1013 1, -54, 54, -1, -54, 1, -35, 35,
1014 35, -35, -26, 47, 26, -47, 47, -26,
1015 -47, 26, 32, 81, -32, -81, 81, 32,
1016 -81, -32, 56, 83, -56, -83, 83, 56,
1017 -83, -56, -18, 67, 18, -67, 67, -18,
1018 -67, 18, 13, 86, -13, -86, 86, 13,
1019 -86, -13, 91, 91, -91, -91, -7, 99,
1020 7, -99, 99, -7, -99, 7, -54, 68,
1021 54, -68, 68, -54, -68, 54, -44, 90,
1022 44, -90, 90, -44, -90, 44, -33, 124,
1023 33, -124, 124, -33, -124, 33, -103, 103,
1024 103, -103, -86, 127, 86, -127, 127, -86,
1025 -127, 86, 37, 37, -37, -37, 69, 69,
1026 -69, -69,
1027]};
1028
1029const DT_1_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1030 0, 0, 7, 7, -7, -7, -3, 10,
1031 3, -10, 10, -3, -10, 3, 16, 16,
1032 -16, -16, 5, 18, -5, -18, 18, 5,
1033 -18, -5, -13, 13, 13, -13, -6, 21,
1034 6, -21, 21, -6, -21, 6, 15, 30,
1035 -15, -30, 30, 15, -30, -15, 30, 30,
1036 -30, -30, 2, 34, -2, -34, 34, 2,
1037 -34, -2, -19, 28, 19, -28, 28, -19,
1038 -28, 19, 32, 54, -32, -54, 54, 32,
1039 -54, -32, -11, 41, 11, -41, 41, -11,
1040 -41, 11, 15, 55, -15, -55, 55, 15,
1041 -55, -15, 57, 57, -57, -57, -1, 63,
1042 1, -63, 63, -1, -63, 1, -40, 40,
1043 40, -40, -30, 55, 30, -55, 55, -30,
1044 -55, 30, 37, 94, -37, -94, 94, 37,
1045 -94, -37, 65, 96, -65, -96, 96, 65,
1046 -96, -65, -21, 78, 21, -78, 78, -21,
1047 -78, 21, 15, 100, -15, -100, 100, 15,
1048 -100, -15, 106, 106, -106, -106, -8, 116,
1049 8, -116, 116, -8, -116, 8, -63, 79,
1050 63, -79, 79, -63, -79, 63, -51, 105,
1051 51, -105, 105, -51, -105, 51, -120, 120,
1052 120, -120, 43, 43, -43, -43, 80, 80,
1053 -80, -80,
1054]};
1055
1056const DT_1_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1057 0, 0, 8, 8, -8, -8, -3, 11,
1058 3, -11, 11, -3, -11, 3, 18, 18,
1059 -18, -18, 5, 20, -5, -20, 20, 5,
1060 -20, -5, -15, 15, 15, -15, -7, 24,
1061 7, -24, 24, -7, -24, 7, 17, 35,
1062 -17, -35, 35, 17, -35, -17, 34, 34,
1063 -34, -34, 3, 38, -3, -38, 38, 3,
1064 -38, -3, -22, 32, 22, -32, 32, -22,
1065 -32, 22, 37, 61, -37, -61, 61, 37,
1066 -61, -37, -13, 47, 13, -47, 47, -13,
1067 -47, 13, 17, 63, -17, -63, 63, 17,
1068 -63, -17, 65, 65, -65, -65, -1, 72,
1069 1, -72, 72, -1, -72, 1, -46, 46,
1070 46, -46, -35, 63, 35, -63, 63, -35,
1071 -63, 35, 43, 107, -43, -107, 107, 43,
1072 -107, -43, 75, 110, -75, -110, 110, 75,
1073 -110, -75, -24, 89, 24, -89, 89, -24,
1074 -89, 24, 17, 114, -17, -114, 114, 17,
1075 -114, -17, 121, 121, -121, -121, -72, 91,
1076 72, -91, 91, -72, -91, 72, -58, 120,
1077 58, -120, 120, -58, -120, 58, 49, 49,
1078 -49, -49, 92, 92, -92, -92,
1079]};
1080
1081const DT_1_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1082 0, 0, 9, 9, -9, -9, -3, 12,
1083 3, -12, 12, -3, -12, 3, 20, 20,
1084 -20, -20, 6, 23, -6, -23, 23, 6,
1085 -23, -6, -17, 17, 17, -17, -7, 27,
1086 7, -27, 27, -7, -27, 7, 19, 39,
1087 -19, -39, 39, 19, -39, -19, 39, 39,
1088 -39, -39, 3, 43, -3, -43, 43, 3,
1089 -43, -3, -24, 36, 24, -36, 36, -24,
1090 -36, 24, 42, 69, -42, -69, 69, 42,
1091 -69, -42, -14, 53, 14, -53, 53, -14,
1092 -53, 14, 19, 71, -19, -71, 71, 19,
1093 -71, -19, 73, 73, -73, -73, -2, 80,
1094 2, -80, 80, -2, -80, 2, -52, 52,
1095 52, -52, -39, 70, 39, -70, 70, -39,
1096 -70, 39, 48, 121, -48, -121, 121, 48,
1097 -121, -48, 84, 124, -84, -124, 124, 84,
1098 -124, -84, -27, 100, 27, -100, 100, -27,
1099 -100, 27, -81, 102, 81, -102, 102, -81,
1100 -102, 81, 55, 55, -55, -55, 104, 104,
1101 -104, -104,
1102]};
1103
1104const DT_2_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
1105 0, 0, 2, 2, -2, -2, 0, 2,
1106 0, -2, 2, 0, -2, 0, 4, 4,
1107 -4, -4, 0, 4, 0, -4, 4, 0,
1108 -4, 0, -4, 4, 4, -4, -2, 6,
1109 2, -6, 6, -2, -6, 2, 4, 8,
1110 -4, -8, 8, 4, -8, -4, 8, 8,
1111 -8, -8, 0, 10, 0, -10, 10, 0,
1112 -10, 0, -4, 8, 4, -8, 8, -4,
1113 -8, 4, 8, 14, -8, -14, 14, 8,
1114 -14, -8, -2, 12, 2, -12, 12, -2,
1115 -12, 2, 4, 16, -4, -16, 16, 4,
1116 -16, -4, 16, 16, -16, -16, 0, 18,
1117 0, -18, 18, 0, -18, 0, -12, 12,
1118 12, -12, -8, 16, 8, -16, 16, -8,
1119 -16, 8, 10, 26, -10, -26, 26, 10,
1120 -26, -10, 18, 28, -18, -28, 28, 18,
1121 -28, -18, -6, 22, 6, -22, 22, -6,
1122 -22, 6, 4, 28, -4, -28, 28, 4,
1123 -28, -4, 30, 30, -30, -30, -2, 32,
1124 2, -32, 32, -2, -32, 2, -18, 22,
1125 18, -22, 22, -18, -22, 18, -14, 30,
1126 14, -30, 30, -14, -30, 14, 22, 46,
1127 -22, -46, 46, 22, -46, -22, 12, 46,
1128 -12, -46, 46, 12, -46, -12, 34, 48,
1129 -34, -48, 48, 34, -48, -34, -10, 40,
1130 10, -40, 40, -10, -40, 10, 4, 50,
1131 -4, -50, 50, 4, -50, -4, 54, 54,
1132 -54, -54, -34, 34, 34, -34, -28, 42,
1133 28, -42, 42, -28, -42, 28, -6, 60,
1134 6, -60, 60, -6, -60, 6, 26, 76,
1135 -26, -76, 76, 26, -76, -26, 42, 76,
1136 -42, -76, 76, 42, -76, -42, -24, 54,
1137 24, -54, 54, -24, -54, 24, 14, 78,
1138 -14, -78, 78, 14, -78, -14, 62, 82,
1139 -62, -82, 82, 62, -82, -62, -20, 74,
1140 20, -74, 74, -20, -74, 20, 2, 88,
1141 -2, -88, 88, 2, -88, -2, 92, 92,
1142 -92, -92, -52, 60, 52, -60, 60, -52,
1143 -60, 52, 52, 118, -52, -118, 118, 52,
1144 -118, -52, -44, 74, 44, -74, 74, -44,
1145 -74, 44, 74, 118, -74, -118, 118, 74,
1146 -118, -74, 32, 118, -32, -118, 118, 32,
1147 -118, -32, -12, 102, 12, -102, 102, -12,
1148 -102, 12, -40, 96, 40, -96, 96, -40,
1149 -96, 40, -34, 118, 34, -118, 118, -34,
1150 -118, 34, -88, 88, 88, -88, -78, 104,
1151 78, -104, 104, -78, -104, 78, 12, 12,
1152 -12, -12, 22, 22, -22, -22, 42, 42,
1153 -42, -42, 72, 72, -72, -72,
1154]};
1155
1156const DT_2_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
1157 0, 0, 3, 3, -3, -3, 0, 3,
1158 0, -3, 3, 0, -3, 0, 6, 6,
1159 -6, -6, 3, 9, -3, -9, 9, 3,
1160 -9, -3, -3, 9, 3, -9, 9, -3,
1161 -9, 3, -6, 6, 6, -6, 6, 12,
1162 -6, -12, 12, 6, -12, -6, 12, 12,
1163 -12, -12, 0, 15, 0, -15, 15, 0,
1164 -15, 0, -9, 12, 9, -12, 12, -9,
1165 -12, 9, 15, 24, -15, -24, 24, 15,
1166 -24, -15, -6, 18, 6, -18, 18, -6,
1167 -18, 6, 6, 24, -6, -24, 24, 6,
1168 -24, -6, 24, 24, -24, -24, 0, 27,
1169 0, -27, 27, 0, -27, 0, -18, 18,
1170 18, -18, -12, 24, 12, -24, 24, -12,
1171 -24, 12, 15, 39, -15, -39, 39, 15,
1172 -39, -15, 27, 42, -27, -42, 42, 27,
1173 -42, -27, -9, 33, 9, -33, 33, -9,
1174 -33, 9, 6, 42, -6, -42, 42, 6,
1175 -42, -6, 45, 45, -45, -45, -3, 51,
1176 3, -51, 51, -3, -51, 3, -27, 33,
1177 27, -33, 33, -27, -33, 27, -21, 45,
1178 21, -45, 45, -21, -45, 21, 33, 69,
1179 -33, -69, 69, 33, -69, -33, 18, 69,
1180 -18, -69, 69, 18, -69, -18, 54, 72,
1181 -54, -72, 72, 54, -72, -54, -18, 63,
1182 18, -63, 63, -18, -63, 18, 6, 78,
1183 -6, -78, 78, 6, -78, -6, 81, 81,
1184 -81, -81, -51, 51, 51, -51, -42, 63,
1185 42, -63, 63, -42, -63, 42, -9, 90,
1186 9, -90, 90, -9, -90, 9, 42, 114,
1187 -42, -114, 114, 42, -114, -42, 63, 117,
1188 -63, -117, 117, 63, -117, -63, -36, 81,
1189 36, -81, 81, -36, -81, 36, 21, 120,
1190 -21, -120, 120, 21, -120, -21, 96, 123,
1191 -96, -123, 123, 96, -123, -96, -30, 111,
1192 30, -111, 111, -30, -111, 30, -78, 93,
1193 78, -93, 93, -78, -93, 78, -69, 114,
1194 69, -114, 114, -69, -114, 69, 18, 18,
1195 -18, -18, 33, 33, -33, -33, 63, 63,
1196 -63, -63, 108, 108, -108, -108,
1197]};
1198
1199const DT_2_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
1200 0, 0, 4, 4, -4, -4, 0, 4,
1201 0, -4, 4, 0, -4, 0, 4, 8,
1202 -4, -8, 8, 4, -8, -4, 8, 8,
1203 -8, -8, -8, 8, 8, -8, -4, 12,
1204 4, -12, 12, -4, -12, 4, 8, 16,
1205 -8, -16, 16, 8, -16, -8, 16, 16,
1206 -16, -16, 0, 20, 0, -20, 20, 0,
1207 -20, 0, -12, 16, 12, -16, 16, -12,
1208 -16, 12, -4, 24, 4, -24, 24, -4,
1209 -24, 4, 16, 32, -16, -32, 32, 16,
1210 -32, -16, 8, 32, -8, -32, 32, 8,
1211 -32, -8, 32, 32, -32, -32, 0, 36,
1212 0, -36, 36, 0, -36, 0, -24, 24,
1213 24, -24, -16, 32, 16, -32, 32, -16,
1214 -32, 16, 20, 52, -20, -52, 52, 20,
1215 -52, -20, 36, 56, -36, -56, 56, 36,
1216 -56, -36, -12, 44, 12, -44, 44, -12,
1217 -44, 12, 8, 56, -8, -56, 56, 8,
1218 -56, -8, 60, 60, -60, -60, -4, 64,
1219 4, -64, 64, -4, -64, 4, -36, 44,
1220 36, -44, 44, -36, -44, 36, -28, 60,
1221 28, -60, 60, -28, -60, 28, 44, 92,
1222 -44, -92, 92, 44, -92, -44, 24, 92,
1223 -24, -92, 92, 24, -92, -24, 72, 96,
1224 -72, -96, 96, 72, -96, -72, -20, 84,
1225 20, -84, 84, -20, -84, 20, 8, 100,
1226 -8, -100, 100, 8, -100, -8, 108, 108,
1227 -108, -108, -68, 68, 68, -68, -56, 84,
1228 56, -84, 84, -56, -84, 56, -12, 120,
1229 12, -120, 120, -12, -120, 12, -48, 108,
1230 48, -108, 108, -48, -108, 48, -104, 124,
1231 104, -124, 124, -104, -124, 104, 24, 24,
1232 -24, -24, 44, 44, -44, -44, 84, 84,
1233 -84, -84,
1234]};
1235
1236const DT_2_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1237 0, 0, 5, 5, -5, -5, 0, 5,
1238 0, -5, 5, 0, -5, 0, 10, 10,
1239 -10, -10, 5, 15, -5, -15, 15, 5,
1240 -15, -5, -10, 10, 10, -10, -5, 15,
1241 5, -15, 15, -5, -15, 5, 10, 20,
1242 -10, -20, 20, 10, -20, -10, 20, 20,
1243 -20, -20, 0, 25, 0, -25, 25, 0,
1244 -25, 0, -15, 20, 15, -20, 20, -15,
1245 -20, 15, 25, 40, -25, -40, 40, 25,
1246 -40, -25, -10, 30, 10, -30, 30, -10,
1247 -30, 10, 10, 40, -10, -40, 40, 10,
1248 -40, -10, 40, 40, -40, -40, 0, 45,
1249 0, -45, 45, 0, -45, 0, -30, 30,
1250 30, -30, -20, 40, 20, -40, 40, -20,
1251 -40, 20, 25, 65, -25, -65, 65, 25,
1252 -65, -25, 45, 70, -45, -70, 70, 45,
1253 -70, -45, -15, 55, 15, -55, 55, -15,
1254 -55, 15, 10, 70, -10, -70, 70, 10,
1255 -70, -10, 75, 75, -75, -75, -5, 85,
1256 5, -85, 85, -5, -85, 5, -45, 55,
1257 45, -55, 55, -45, -55, 45, -35, 75,
1258 35, -75, 75, -35, -75, 35, 55, 115,
1259 -55, -115, 115, 55, -115, -55, 30, 115,
1260 -30, -115, 115, 30, -115, -30, 90, 120,
1261 -90, -120, 120, 90, -120, -90, -30, 105,
1262 30, -105, 105, -30, -105, 30, -85, 85,
1263 85, -85, -70, 105, 70, -105, 105, -70,
1264 -105, 70, 30, 30, -30, -30, 60, 60,
1265 -60, -60, 105, 105, -105, -105,
1266]};
1267
1268const DT_2_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1269 0, 0, 6, 6, -6, -6, 0, 6,
1270 0, -6, 6, 0, -6, 0, 12, 12,
1271 -12, -12, 6, 12, -6, -12, 12, 6,
1272 -12, -6, -12, 12, 12, -12, -6, 18,
1273 6, -18, 18, -6, -18, 6, 12, 24,
1274 -12, -24, 24, 12, -24, -12, 24, 24,
1275 -24, -24, 0, 30, 0, -30, 30, 0,
1276 -30, 0, -18, 24, 18, -24, 24, -18,
1277 -24, 18, 30, 48, -30, -48, 48, 30,
1278 -48, -30, -6, 36, 6, -36, 36, -6,
1279 -36, 6, 12, 48, -12, -48, 48, 12,
1280 -48, -12, 48, 48, -48, -48, 0, 54,
1281 0, -54, 54, 0, -54, 0, -36, 36,
1282 36, -36, -24, 48, 24, -48, 48, -24,
1283 -48, 24, 30, 78, -30, -78, 78, 30,
1284 -78, -30, 54, 84, -54, -84, 84, 54,
1285 -84, -54, -18, 66, 18, -66, 66, -18,
1286 -66, 18, 12, 84, -12, -84, 84, 12,
1287 -84, -12, 90, 90, -90, -90, -6, 96,
1288 6, -96, 96, -6, -96, 6, -54, 66,
1289 54, -66, 66, -54, -66, 54, -42, 90,
1290 42, -90, 90, -42, -90, 42, -30, 126,
1291 30, -126, 126, -30, -126, 30, -102, 102,
1292 102, -102, -84, 126, 84, -126, 126, -84,
1293 -126, 84, 36, 36, -36, -36, 66, 66,
1294 -66, -66,
1295]};
1296
1297const DT_2_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1298 0, 0, 7, 7, -7, -7, 0, 7,
1299 0, -7, 7, 0, -7, 0, 14, 14,
1300 -14, -14, 7, 21, -7, -21, 21, 7,
1301 -21, -7, -14, 14, 14, -14, -7, 21,
1302 7, -21, 21, -7, -21, 7, 14, 28,
1303 -14, -28, 28, 14, -28, -14, 28, 28,
1304 -28, -28, 0, 35, 0, -35, 35, 0,
1305 -35, 0, -21, 28, 21, -28, 28, -21,
1306 -28, 21, 35, 56, -35, -56, 56, 35,
1307 -56, -35, -14, 42, 14, -42, 42, -14,
1308 -42, 14, 14, 56, -14, -56, 56, 14,
1309 -56, -14, 56, 56, -56, -56, 0, 63,
1310 0, -63, 63, 0, -63, 0, -42, 42,
1311 42, -42, -28, 56, 28, -56, 56, -28,
1312 -56, 28, 35, 91, -35, -91, 91, 35,
1313 -91, -35, 63, 98, -63, -98, 98, 63,
1314 -98, -63, -21, 77, 21, -77, 77, -21,
1315 -77, 21, 14, 98, -14, -98, 98, 14,
1316 -98, -14, 105, 105, -105, -105, -7, 119,
1317 7, -119, 119, -7, -119, 7, -63, 77,
1318 63, -77, 77, -63, -77, 63, -49, 105,
1319 49, -105, 105, -49, -105, 49, -119, 119,
1320 119, -119, 42, 42, -42, -42, 77, 77,
1321 -77, -77,
1322]};
1323
1324const DT_2_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1325 0, 0, 8, 8, -8, -8, 0, 8,
1326 0, -8, 8, 0, -8, 0, 16, 16,
1327 -16, -16, 8, 16, -8, -16, 16, 8,
1328 -16, -8, -16, 16, 16, -16, -8, 24,
1329 8, -24, 24, -8, -24, 8, 16, 32,
1330 -16, -32, 32, 16, -32, -16, 32, 32,
1331 -32, -32, 0, 40, 0, -40, 40, 0,
1332 -40, 0, -24, 32, 24, -32, 32, -24,
1333 -32, 24, 40, 64, -40, -64, 64, 40,
1334 -64, -40, -16, 48, 16, -48, 48, -16,
1335 -48, 16, 16, 64, -16, -64, 64, 16,
1336 -64, -16, 64, 64, -64, -64, 0, 72,
1337 0, -72, 72, 0, -72, 0, -48, 48,
1338 48, -48, -32, 64, 32, -64, 64, -32,
1339 -64, 32, 40, 104, -40, -104, 104, 40,
1340 -104, -40, 72, 112, -72, -112, 112, 72,
1341 -112, -72, -24, 88, 24, -88, 88, -24,
1342 -88, 24, 16, 112, -16, -112, 112, 16,
1343 -112, -16, 120, 120, -120, -120, -72, 88,
1344 72, -88, 88, -72, -88, 72, -56, 120,
1345 56, -120, 120, -56, -120, 56, 48, 48,
1346 -48, -48, 88, 88, -88, -88,
1347]};
1348
1349const DT_2_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1350 0, 0, 9, 9, -9, -9, 0, 9,
1351 0, -9, 9, 0, -9, 0, 18, 18,
1352 -18, -18, 9, 27, -9, -27, 27, 9,
1353 -27, -9, -18, 18, 18, -18, -9, 27,
1354 9, -27, 27, -9, -27, 9, 18, 36,
1355 -18, -36, 36, 18, -36, -18, 36, 36,
1356 -36, -36, 0, 45, 0, -45, 45, 0,
1357 -45, 0, -27, 36, 27, -36, 36, -27,
1358 -36, 27, 45, 72, -45, -72, 72, 45,
1359 -72, -45, -18, 54, 18, -54, 54, -18,
1360 -54, 18, 18, 72, -18, -72, 72, 18,
1361 -72, -18, 72, 72, -72, -72, 0, 81,
1362 0, -81, 81, 0, -81, 0, -54, 54,
1363 54, -54, -36, 72, 36, -72, 72, -36,
1364 -72, 36, 45, 117, -45, -117, 117, 45,
1365 -117, -45, 81, 126, -81, -126, 126, 81,
1366 -126, -81, -27, 99, 27, -99, 99, -27,
1367 -99, 27, -81, 99, 81, -99, 99, -81,
1368 -99, 81, 54, 54, -54, -54, 108, 108,
1369 -108, -108,
1370]};
1371
1372const DT_3_1: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1373 0, 0, 2, 2, -2, -2, 0, 3,
1374 0, -3, 3, 0, -3, 0, 6, 6,
1375 -6, -6, 0, 7, 0, -7, 7, 0,
1376 -7, 0, -5, 5, 5, -5, 5, -5,
1377 -5, 5, 6, 11, -6, -11, 11, 6,
1378 -11, -6, 0, 8, 0, -8, 8, 0,
1379 -8, 0, 11, 11, -11, -11, 0, 12,
1380 0, -12, 12, 0, -12, 0, 12, 17,
1381 -12, -17, 17, 12, -17, -12, 17, 17,
1382 -17, -17, 6, 18, -6, -18, 18, 6,
1383 -18, -6, -8, 11, 8, -11, 11, -8,
1384 -11, 8, 0, 15, 0, -15, 15, 0,
1385 -15, 0, 0, 20, 0, -20, 20, 0,
1386 -20, 0, 18, 25, -18, -25, 25, 18,
1387 -25, -18, 11, 25, -11, -25, 25, 11,
1388 -25, -11, 25, 25, -25, -25, -14, 14,
1389 14, -14, 14, -14, -14, 14, 0, 26,
1390 0, -26, 26, 0, -26, 0, -11, 18,
1391 11, -18, 18, -11, -18, 11, -7, 22,
1392 7, -22, 22, -7, -22, 7, 26, 34,
1393 -26, -34, 34, 26, -34, -26, 18, 34,
1394 -18, -34, 34, 18, -34, -18, 34, 34,
1395 -34, -34, 11, 35, -11, -35, 35, 11,
1396 -35, -11, 0, 29, 0, -29, 29, 0,
1397 -29, 0, -19, 22, 19, -22, 22, -19,
1398 -22, 19, -15, 26, 15, -26, 26, -15,
1399 -26, 15, 0, 37, 0, -37, 37, 0,
1400 -37, 0, 27, 44, -27, -44, 44, 27,
1401 -44, -27, 36, 44, -36, -44, 44, 36,
1402 -44, -36, 18, 44, -18, -44, 44, 18,
1403 -44, -18, -10, 33, 10, -33, 33, -10,
1404 -33, 10, 45, 45, -45, -45, 0, 0,
1405]};
1406
1407const DT_3_2: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1408 0, 0, 0, 2, 0, -2, 2, 0,
1409 -2, 0, 2, 2, -2, -2, 6, 6,
1410 -6, -6, 0, 6, 0, -6, 6, 0,
1411 -6, 0, -4, 4, 4, -4, 10, -6,
1412 -10, 6, 0, -12, 0, 12, -6, -12,
1413 6, -12, -6, 12, 6, 12, -14, 0,
1414 14, 0, 12, 12, -12, -12, 0, -18,
1415 0, 18, 14, -12, -14, 12, -18, -6,
1416 18, -6, -18, 6, 18, 6, -10, -18,
1417 10, -18, -10, 18, 10, 18, -22, 0,
1418 22, 0, 0, -24, 0, 24, -22, -12,
1419 22, -12, -22, 12, 22, 12, -8, -24,
1420 8, -24, -8, 24, 8, 24, -26, -6,
1421 26, -6, -26, 6, 26, 6, -28, 0,
1422 28, 0, 20, 20, -20, -20, -14, -26,
1423 14, 26, -30, -12, 30, 12, -10, -32,
1424 10, 32, -18, -32, 18, 32, -26, -26,
1425 26, 26, -34, -20, 34, 20, -38, -12,
1426 38, 12, -32, -32, 32, 32, 32, 32,
1427 -22, -40, -34, -34, 34, 34,
1428]};
1429
1430const DT_3_3: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1431 0, 0, 0, 2, 0, -2, 2, 0,
1432 -2, 0, 4, 4, -4, -4, 10, 10,
1433 -10, -10, 0, 10, 0, -10, 10, 0,
1434 -10, 0, -6, 6, 6, -6, 14, -8,
1435 -14, 8, -18, 0, 18, 0, 10, -16,
1436 -10, 16, 0, -24, 0, 24, -24, -8,
1437 24, -8, -24, 8, 24, 8, 18, 18,
1438 -18, -18, 20, -16, -20, 16, -14, -26,
1439 14, -26, -14, 26, 14, 26, -30, 0,
1440 30, 0, 0, -34, 0, 34, -34, -8,
1441 34, -8, -34, 8, 34, 8, -30, -18,
1442 30, -18, -30, 18, 30, 18, -10, -34,
1443 10, -34, -10, 34, 10, 34, -20, -34,
1444 20, 34, -40, 0, 40, 0, 30, 30,
1445 -30, -30, -40, -18, 40, 18, 0, -44,
1446 0, 44, -16, -44, 16, 44, -36, -36,
1447 -36, -36, 36, 36, -26, -44, 26, 44,
1448 -46, -26, 46, 26, -52, -18, 52, 18,
1449 -20, -54, -44, -44, 44, 44, -32, -54,
1450 -46, -46, -46, -46, 46, 46,
1451]};
1452
1453const DT_3_4: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1454 0, 0, 0, 4, 0, -4, 4, 0,
1455 -4, 0, 4, 4, -4, -4, 12, 12,
1456 -12, -12, 0, 12, 0, -12, 12, 0,
1457 -12, 0, -8, 8, 8, -8, 8, -16,
1458 -8, 16, 0, -24, 0, 24, -24, -8,
1459 24, -8, -24, 8, 24, 8, 20, -16,
1460 -20, 16, -28, 0, 28, 0, -16, -24,
1461 16, -24, -16, 24, 16, 24, 0, -32,
1462 0, 32, -28, -16, 28, -16, -28, 16,
1463 28, 16, -8, -32, 8, -32, -32, -8,
1464 32, -8, -32, 8, 32, 8, -8, 32,
1465 8, 32, 24, 24, -24, -24, 24, -24,
1466 -24, 24, -20, -32, 20, 32, -40, 0,
1467 40, 0, -40, -16, 40, 16, 0, -44,
1468 0, -44, -44, 0, 44, 0, 0, 44,
1469 0, 44, -32, -32, 32, 32, -16, -44,
1470 16, 44, -24, -44, -44, -24, 44, 24,
1471 24, 44, -48, -16, 48, 16, -36, -36,
1472 -36, -36, 36, 36, 36, 36, -20, -52,
1473 40, 40, -40, -40, -32, -52,
1474]};
1475
1476const DT_3_5: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1477 0, 0, 2, 2, -2, -2, 6, 6,
1478 -6, -6, 12, 12, -12, -12, 20, 20,
1479 -20, -20, 32, 32, -32, -32, 46, 46,
1480 -46, -46, 0, 0, 0, 0, 0, 0,
1481 0, 0, 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,
1497]};
1498
1499const IVI3_DELTA_CBS: [&IviDeltaCB; 24] = [
1500 &DT_1_1, &DT_1_2, &DT_1_3, &DT_1_4, &DT_1_5, &DT_1_6, &DT_1_7, &DT_1_8,
1501 &DT_2_1, &DT_2_2, &DT_2_3, &DT_2_4, &DT_2_5, &DT_2_6, &DT_2_7, &DT_2_8,
1502 &DT_3_1, &DT_3_2, &DT_3_3, &DT_3_4, &DT_3_5, &DT_3_5, &DT_3_5, &DT_3_5
1503];