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