make all codec crates export just register_all functions and document them
[nihav.git] / nihav-indeo / src / codecs / indeo3.rs
1 use nihav_core::formats;
2 use nihav_core::codecs::*;
3 use nihav_core::io::byteio::*;
4 use std::io::SeekFrom;
5 use std::mem;
6
7 struct IviDeltaCB {
8 quad_radix: u8,
9 data: &'static [i8],
10 }
11
12 #[derive(Clone, Copy)]
13 struct MV {
14 x: i8,
15 y: i8
16 }
17
18 struct Buffers {
19 width: usize,
20 height: usize,
21 cw: usize,
22 ch: usize,
23 sbuf: Vec<u8>,
24 dbuf: Vec<u8>,
25 }
26
27 const DEFAULT_PIXEL: u8 = 0x40;
28
29 impl Buffers {
30 fn new() -> Self { Buffers { width: 0, height: 0, cw: 0, ch: 0, sbuf: Vec::new(), dbuf: Vec::new() } }
31 fn reset(&mut self) {
32 self.width = 0;
33 self.height = 0;
34 self.sbuf.truncate(0);
35 self.dbuf.truncate(0);
36 }
37 fn alloc(&mut self, w: usize, h: usize) {
38 self.width = w;
39 self.height = h;
40 self.cw = ((w >> 2) + 3) & !3;
41 self.ch = ((h >> 2) + 3) & !3;
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);
44 }
45 fn flip(&mut self) { std::mem::swap(&mut self.sbuf, &mut self.dbuf); }
46 fn get_stride(&mut self, planeno: usize) -> usize {
47 if planeno == 0 { self.width } else { self.cw }
48 }
49 fn get_offset(&mut self, planeno: usize) -> usize {
50 match planeno {
51 1 => self.width * self.height,
52 2 => self.width * self.height + self.cw * self.ch,
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);
62 let width = if planeno == 0 { self.width } else { self.width >> 2 };
63 let height = if planeno == 0 { self.height } else { self.height >> 2 };
64 let src = self.dbuf.as_slice();
65 let dst = fbuf.get_data_mut().unwrap();
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;
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;
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 {
88 for _ in 0..h {
89 for i in 0..w { self.dbuf[didx + i] = DEFAULT_PIXEL; }
90 didx += stride;
91 }
92 } else {
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;
97 }
98 }
99 }
100 }
101
102 #[allow(unused_variables)]
103 fn apply_delta4x4(bufs: &mut Buffers, off: usize, stride: usize,
104 deltas: &[u8], topline: bool, first_line: bool) {
105 let dst = &mut bufs.dbuf[off..][..4];
106 for i in 0..4 { dst[i] = dst[i].wrapping_add(deltas[i]) & 0x7F; }
107 }
108
109 #[allow(unused_variables)]
110 fn apply_delta4x8(bufs: &mut Buffers, off: usize, stride: usize,
111 deltas: &[u8], topline: bool, first_line: bool) {
112 let dst = &mut bufs.dbuf[off..][..stride + 4];
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)]
122 fn apply_delta4x8m11(bufs: &mut Buffers, off: usize, stride: usize,
123 deltas: &[u8], topline: bool, first_line: bool) {
124 let dst = &mut bufs.dbuf[off..][..stride + 4];
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)]
130 fn apply_delta8x8p(bufs: &mut Buffers, off: usize, stride: usize,
131 deltas: &[u8], topline: bool, first_line: bool) {
132 let dst = &mut bufs.dbuf[off..][..stride + 8];
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
137 fn apply_delta8x8i(bufs: &mut Buffers, off: usize, stride: usize,
138 deltas: &[u8], topline: bool, firstline: bool) {
139 let dst = &mut bufs.dbuf[off..][..stride + 8];
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
152 fn 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 {
155 let src = &bufs.dbuf[(off - stride)..(off - stride + bw)];
156 for i in 0..bw { buf[i] = src[i]; }
157 } else {
158 for i in 0..bw { buf[i] = DEFAULT_PIXEL; }
159 }
160 let dst = &mut bufs.dbuf[off..][..bw];
161 for i in 0..bw { dst[i] = buf[i]; }
162 }
163
164 fn copy_line_top4x4(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
165 copy_line_top(bufs, off, stride, 4, topline);
166 }
167
168 fn 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
173 fn copy_line_top8x8(bufs: &mut Buffers, off: usize, stride: usize, topline: bool) {
174 let mut buf: [u8; 8] = [0; 8];
175 if !topline {
176 let src = &bufs.dbuf[(off - stride)..(off - stride + 8)];
177 for i in 0..8 { buf[i] = src[i & !1]; }
178 } else {
179 for i in 0..8 { buf[i] = DEFAULT_PIXEL; }
180 }
181 let dst = &mut bufs.dbuf[off..][..8];
182 for i in 0..8 {dst[i] = buf[i]; }
183 }
184
185 fn 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; }
190 } else {
191 for i in 0..8 { buf[i] = bufs.dbuf[doff - stride + i]; }
192 }
193 if topline && !firstline {
194 for i in 0..4 { buf[i * 2 + 1] = buf[i * 2]; }
195 for i in 0..8 { bufs.dbuf[doff + i] = (bufs.dbuf[doff - stride + i] + buf[i]) >> 1; }
196 }
197
198 let start = if !topline { 0 } else { 1 };
199 if topline {
200 didx += stride;
201 }
202 for _ in start..h {
203 for i in 0..8 { bufs.dbuf[didx + i] = buf[i]; }
204 didx += stride;
205 }
206 }
207
208 struct Indeo3Decoder {
209 info: NACodecInfoRef,
210 bpos: u8,
211 bbuf: u8,
212 width: u16,
213 height: u16,
214 mvs: Vec<MV>,
215 altquant: [u8; 16],
216 vq_offset: u8,
217 bufs: Buffers,
218 requant_tab: [[u8; 128]; 8],
219 }
220
221 #[derive(Clone,Copy)]
222 struct 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
232 impl IV3Cell {
233 fn new(w: u16, h: u16) -> Self {
234 IV3Cell { x: 0, y: 0, w, h, d: 20, vqt: false, mv: None }
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 }
264 fn no_mv(&self) -> bool { self.mv.is_none() }
265 }
266
267 struct 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
277 const FRMH_TAG: u32 = ((b'F' as u32) << 24) | ((b'R' as u32) << 16)
278 | ((b'M' as u32) << 8) | (b'H' as u32);
279
280 const H_SPLIT: u8 = 0;
281 const V_SPLIT: u8 = 1;
282 const SKIP_OR_TREE: u8 = 2;
283
284 impl Indeo3Decoder {
285 fn new() -> Self {
286 const REQUANT_OFF: [i32; 8] = [ 0, 1, 0, 4, 4, 1, 0, 1 ];
287
288 let dummy_info = NACodecInfo::new_dummy();
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
309 Indeo3Decoder { info: dummy_info, bpos: 0, bbuf: 0, width: 0, height: 0,
310 mvs: Vec::new(), altquant: [0; 16],
311 vq_offset: 0, bufs: Buffers::new(), requant_tab }
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,
329 off: usize, stride: usize, params: CellDecParams, vq_idx: u8) -> DecoderResult<()> {
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;
341
342 if cell.no_mv() {
343 sidx = 0;
344 } else {
345 let mv = cell.mv.unwrap();
346 let mx = i16::from(mv.x);
347 let my = i16::from(mv.y);
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 }
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 }
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,
389 y == 0, (cell.y == 0) && (y == 0));
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;
407 validate!(idx1 < delta_tab.data.len() / 2);
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 {
468 let nl = 257 - i16::from(c) - (line as i16);
469 validate!(nl > 0);
470 tocopy = nl as usize;
471 }
472 if do_copy {
473 if !(params.bh == 8 && cell.no_mv()) {
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();
508 let mx = i16::from(mv.x);
509 let my = i16::from(mv.y);
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;
536 } else {
537 idx1 += self.vq_offset as usize;
538 idx2 += self.vq_offset as usize;
539 }
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 }
581 self.decode_cell_data(br, cell, off, stride, cp, vq_idx)
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;
641 self.mvs.push(MV{ x, y });
642 }
643
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);
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;
668 self.mvs.push(MV{ x, y });
669 }
670
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);
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
684 const FLAG_KEYFRAME: u16 = 1 << 2;
685 const FLAG_NONREF: u16 = 1 << 8;
686
687 impl NADecoder for Indeo3Decoder {
688 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
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));
694 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
695 self.bufs.reset();
696 Ok(())
697 } else {
698 Err(DecoderError::InvalidData)
699 }
700 }
701 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
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 }
715 if i64::from(size) > br.left() { return Err(DecoderError::InvalidData); }
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()?;
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 }
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 let vinfo;
736 if (self.bufs.width != (width as usize)) || (self.bufs.height != (height as usize)) {
737 self.bufs.alloc(width as usize, height as usize);
738 vinfo = NAVideoInfo::new(width as usize, height as usize, false, formats::YUV410_FORMAT);
739 } else {
740 vinfo = self.info.get_properties().get_video_info().unwrap();
741 }
742 self.width = width;
743 self.height = height;
744
745 let yoff = br.read_u32le()?;
746 let uoff = br.read_u32le()?;
747 let voff = br.read_u32le()?;
748 if yoff > size { return Err(DecoderError::InvalidData); }
749 if uoff > size { return Err(DecoderError::InvalidData); }
750 if voff > size { return Err(DecoderError::InvalidData); }
751
752 br.read_skip(4)?;
753 br.read_buf(&mut self.altquant)?;
754
755 let mut yend = src.len() as u32;//size;
756 if (uoff < yend) && (uoff > yoff) { yend = uoff; }
757 if (voff < yend) && (voff > yoff) { yend = voff; }
758 let mut uend = size;
759 if (yoff < uend) && (yoff > uoff) { uend = yoff; }
760 if (voff < uend) && (voff > uoff) { uend = voff; }
761 let mut vend = size;
762 if (yoff < vend) && (yoff > voff) { vend = yoff; }
763 if (uoff < vend) && (uoff > voff) { vend = uoff; }
764
765 let intraframe = (flags & FLAG_KEYFRAME) != 0;
766 let bufinfo = alloc_video_buffer(vinfo, 4)?;
767 let mut buf = bufinfo.get_vbuf().unwrap();
768 let ystart = data_start + u64::from(yoff);
769 let ustart = data_start + u64::from(uoff);
770 let vstart = data_start + u64::from(voff);
771 let yendpos = data_start + u64::from(yend);
772 let uendpos = data_start + u64::from(uend);
773 let vendpos = data_start + u64::from(vend);
774 if intraframe {
775 self.decode_plane_intra(&mut br, 0, ystart, yendpos)?;
776 self.decode_plane_intra(&mut br, 1, vstart, vendpos)?;
777 self.decode_plane_intra(&mut br, 2, ustart, uendpos)?;
778 } else {
779 self.decode_plane_inter(&mut br, 0, ystart, yendpos)?;
780 self.decode_plane_inter(&mut br, 1, vstart, vendpos)?;
781 self.decode_plane_inter(&mut br, 2, ustart, uendpos)?;
782 }
783 self.bufs.fill_framebuf(&mut buf);
784 if (flags & FLAG_NONREF) == 0 { self.bufs.flip(); }
785 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
786 frm.set_keyframe(intraframe);
787 frm.set_frame_type(if intraframe { FrameType::I } else { FrameType::P });
788 Ok(frm.into_ref())
789 }
790 fn flush(&mut self) {
791 self.bufs.reset();
792 }
793 }
794
795 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
796 Box::new(Indeo3Decoder::new())
797 }
798
799 #[cfg(test)]
800 mod test {
801 use nihav_core::codecs::RegisteredDecoders;
802 use nihav_core::demuxers::RegisteredDemuxers;
803 use nihav_core::test::dec_video::*;
804 use crate::indeo_register_all_codecs;
805 use nihav_commonfmt::generic_register_all_demuxers;
806 #[test]
807 fn test_indeo3() {
808 let mut dmx_reg = RegisteredDemuxers::new();
809 generic_register_all_demuxers(&mut dmx_reg);
810 let mut dec_reg = RegisteredDecoders::new();
811 indeo_register_all_codecs(&mut dec_reg);
812
813 test_decoding("avi", "indeo3", "assets/Indeo/iv32_example.avi", Some(10),
814 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
815 [0x90be698e, 0x326db071, 0x08e8c6a5, 0x39349acc],
816 [0x25d677fc, 0x63f96aaa, 0xd412ca98, 0x61416313],
817 [0xc4368250, 0x63e7b6bc, 0xffcff950, 0x11f13239],
818 [0x7e869758, 0x027abc2e, 0x25204bca, 0x93fbaa03],
819 [0x5a1e822c, 0x2b1a4cd5, 0x72059843, 0xe5689ad1],
820 [0x3a971cce, 0x5ec22135, 0x1a45f802, 0x0f5f9264],
821 [0x0a65f782, 0xd8767cf3, 0x878b4b8d, 0xfc94c88b],
822 [0x4ac70139, 0x3300eac1, 0xba84b068, 0x47f5ff29],
823 [0x3e8c8ec4, 0x9421b38c, 0x580abbbd, 0x92792d19],
824 [0x9096ee9b, 0x8dd9fb14, 0x981e31e3, 0x3ffd7d29],
825 [0x22dc71ec, 0x3d8f6f7e, 0x1a198982, 0x41d17ecc]]));
826 }
827 }
828
829 const DT_1_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
830 0, 0, 2, 2, -2, -2, -1, 3,
831 1, -3, 3, -1, -3, 1, 4, 4,
832 -4, -4, 1, 5, -1, -5, 5, 1,
833 -5, -1, -4, 4, 4, -4, -2, 6,
834 2, -6, 6, -2, -6, 2, 4, 9,
835 -4, -9, 9, 4, -9, -4, 9, 9,
836 -9, -9, 1, 10, -1, -10, 10, 1,
837 -10, -1, -5, 8, 5, -8, 8, -5,
838 -8, 5, 9, 15, -9, -15, 15, 9,
839 -15, -9, -3, 12, 3, -12, 12, -3,
840 -12, 3, 4, 16, -4, -16, 16, 4,
841 -16, -4, 16, 16, -16, -16, 0, 18,
842 0, -18, 18, 0, -18, 0, -12, 12,
843 12, -12, -9, 16, 9, -16, 16, -9,
844 -16, 9, 11, 27, -11, -27, 27, 11,
845 -27, -11, 19, 28, -19, -28, 28, 19,
846 -28, -19, -6, 22, 6, -22, 22, -6,
847 -22, 6, 4, 29, -4, -29, 29, 4,
848 -29, -4, 30, 30, -30, -30, -2, 33,
849 2, -33, 33, -2, -33, 2, -18, 23,
850 18, -23, 23, -18, -23, 18, -15, 30,
851 15, -30, 30, -15, -30, 15, 22, 46,
852 -22, -46, 46, 22, -46, -22, 13, 47,
853 -13, -47, 47, 13, -47, -13, 35, 49,
854 -35, -49, 49, 35, -49, -35, -11, 41,
855 11, -41, 41, -11, -41, 11, 4, 51,
856 -4, -51, 51, 4, -51, -4, 54, 54,
857 -54, -54, -34, 34, 34, -34, -29, 42,
858 29, -42, 42, -29, -42, 29, -6, 60,
859 6, -60, 60, -6, -60, 6, 27, 76,
860 -27, -76, 76, 27, -76, -27, 43, 77,
861 -43, -77, 77, 43, -77, -43, -24, 55,
862 24, -55, 55, -24, -55, 24, 14, 79,
863 -14, -79, 79, 14, -79, -14, 63, 83,
864 -63, -83, 83, 63, -83, -63, -20, 74,
865 20, -74, 74, -20, -74, 20, 2, 88,
866 -2, -88, 88, 2, -88, -2, 93, 93,
867 -93, -93, -52, 61, 52, -61, 61, -52,
868 -61, 52, 52, 120, -52, -120, 120, 52,
869 -120, -52, -45, 75, 45, -75, 75, -45,
870 -75, 45, 75, 125, -75, -125, 125, 75,
871 -125, -75, 33, 122, -33, -122, 122, 33,
872 -122, -33, -13, 103, 13, -103, 103, -13,
873 -103, 13, -40, 96, 40, -96, 96, -40,
874 -96, 40, -34, 127, 34, -127, 127, -34,
875 -127, 34, -89, 89, 89, -89, -78, 105,
876 78, -105, 105, -78, -105, 78, 12, 12,
877 -12, -12, 23, 23, -23, -23, 42, 42,
878 -42, -42, 73, 73, -73, -73,
879 ]};
880
881 const DT_1_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
882 0, 0, 3, 3, -3, -3, -1, 4,
883 1, -4, 4, -1, -4, 1, 7, 7,
884 -7, -7, 2, 8, -2, -8, 8, 2,
885 -8, -2, -2, 9, 2, -9, 9, -2,
886 -9, 2, -6, 6, 6, -6, 6, 13,
887 -6, -13, 13, 6, -13, -6, 13, 13,
888 -13, -13, 1, 14, -1, -14, 14, 1,
889 -14, -1, -8, 12, 8, -12, 12, -8,
890 -12, 8, 14, 23, -14, -23, 23, 14,
891 -23, -14, -5, 18, 5, -18, 18, -5,
892 -18, 5, 6, 24, -6, -24, 24, 6,
893 -24, -6, 24, 24, -24, -24, -1, 27,
894 1, -27, 27, -1, -27, 1, -17, 17,
895 17, -17, -13, 23, 13, -23, 23, -13,
896 -23, 13, 16, 40, -16, -40, 40, 16,
897 -40, -16, 28, 41, -28, -41, 41, 28,
898 -41, -28, -9, 33, 9, -33, 33, -9,
899 -33, 9, 6, 43, -6, -43, 43, 6,
900 -43, -6, 46, 46, -46, -46, -4, 50,
901 4, -50, 50, -4, -50, 4, -27, 34,
902 27, -34, 34, -27, -34, 27, -22, 45,
903 22, -45, 45, -22, -45, 22, 34, 69,
904 -34, -69, 69, 34, -69, -34, 19, 70,
905 -19, -70, 70, 19, -70, -19, 53, 73,
906 -53, -73, 73, 53, -73, -53, -17, 62,
907 17, -62, 62, -17, -62, 17, 5, 77,
908 -5, -77, 77, 5, -77, -5, 82, 82,
909 -82, -82, -51, 51, 51, -51, -43, 64,
910 43, -64, 64, -43, -64, 43, -10, 90,
911 10, -90, 90, -10, -90, 10, 41, 114,
912 -41, -114, 114, 41, -114, -41, 64, 116,
913 -64, -116, 116, 64, -116, -64, -37, 82,
914 37, -82, 82, -37, -82, 37, 22, 119,
915 -22, -119, 119, 22, -119, -22, 95, 124,
916 -95, -124, 124, 95, -124, -95, -30, 111,
917 30, -111, 111, -30, -111, 30, -78, 92,
918 78, -92, 92, -78, -92, 78, -68, 113,
919 68, -113, 113, -68, -113, 68, 18, 18,
920 -18, -18, 34, 34, -34, -34, 63, 63,
921 -63, -63, 109, 109, -109, -109,
922 ]};
923
924 const DT_1_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
925 0, 0, 4, 4, -4, -4, -1, 5,
926 1, -5, 5, -1, -5, 1, 3, 10,
927 -3, -10, 10, 3, -10, -3, 9, 9,
928 -9, -9, -7, 7, 7, -7, -3, 12,
929 3, -12, 12, -3, -12, 3, 8, 17,
930 -8, -17, 17, 8, -17, -8, 17, 17,
931 -17, -17, 1, 19, -1, -19, 19, 1,
932 -19, -1, -11, 16, 11, -16, 16, -11,
933 -16, 11, -6, 23, 6, -23, 23, -6,
934 -23, 6, 18, 31, -18, -31, 31, 18,
935 -31, -18, 8, 32, -8, -32, 32, 8,
936 -32, -8, 33, 33, -33, -33, -1, 36,
937 1, -36, 36, -1, -36, 1, -23, 23,
938 23, -23, -17, 31, 17, -31, 31, -17,
939 -31, 17, 21, 54, -21, -54, 54, 21,
940 -54, -21, 37, 55, -37, -55, 55, 37,
941 -55, -37, -12, 44, 12, -44, 44, -12,
942 -44, 12, 8, 57, -8, -57, 57, 8,
943 -57, -8, 61, 61, -61, -61, -5, 66,
944 5, -66, 66, -5, -66, 5, -36, 45,
945 36, -45, 45, -36, -45, 36, -29, 60,
946 29, -60, 60, -29, -60, 29, 45, 92,
947 -45, -92, 92, 45, -92, -45, 25, 93,
948 -25, -93, 93, 25, -93, -25, 71, 97,
949 -71, -97, 97, 71, -97, -71, -22, 83,
950 22, -83, 83, -22, -83, 22, 7, 102,
951 -7, -102, 102, 7, -102, -7, 109, 109,
952 -109, -109, -68, 68, 68, -68, -57, 85,
953 57, -85, 85, -57, -85, 57, -13, 120,
954 13, -120, 120, -13, -120, 13, -49, 110,
955 49, -110, 110, -49, -110, 49, -104, 123,
956 104, -123, 123, -104, -123, 104, 24, 24,
957 -24, -24, 46, 46, -46, -46, 84, 84,
958 -84, -84,
959 ]};
960
961 const DT_1_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
962 0, 0, 5, 5, -5, -5, -2, 7,
963 2, -7, 7, -2, -7, 2, 11, 11,
964 -11, -11, 3, 13, -3, -13, 13, 3,
965 -13, -3, -9, 9, 9, -9, -4, 15,
966 4, -15, 15, -4, -15, 4, 11, 22,
967 -11, -22, 22, 11, -22, -11, 21, 21,
968 -21, -21, 2, 24, -2, -24, 24, 2,
969 -24, -2, -14, 20, 14, -20, 20, -14,
970 -20, 14, 23, 38, -23, -38, 38, 23,
971 -38, -23, -8, 29, 8, -29, 29, -8,
972 -29, 8, 11, 39, -11, -39, 39, 11,
973 -39, -11, 41, 41, -41, -41, -1, 45,
974 1, -45, 45, -1, -45, 1, -29, 29,
975 29, -29, -22, 39, 22, -39, 39, -22,
976 -39, 22, 27, 67, -27, -67, 67, 27,
977 -67, -27, 47, 69, -47, -69, 69, 47,
978 -69, -47, -15, 56, 15, -56, 56, -15,
979 -56, 15, 11, 71, -11, -71, 71, 11,
980 -71, -11, 76, 76, -76, -76, -6, 83,
981 6, -83, 83, -6, -83, 6, -45, 57,
982 45, -57, 57, -45, -57, 45, -36, 75,
983 36, -75, 75, -36, -75, 36, 56, 115,
984 -56, -115, 115, 56, -115, -56, 31, 117,
985 -31, -117, 117, 31, -117, -31, 88, 122,
986 -88, -122, 122, 88, -122, -88, -28, 104,
987 28, -104, 104, -28, -104, 28, -85, 85,
988 85, -85, -72, 106, 72, -106, 106, -72,
989 -106, 72, 30, 30, -30, -30, 58, 58,
990 -58, -58, 105, 105, -105, -105,
991 ]};
992
993 const DT_1_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
994 0, 0, 6, 6, -6, -6, -2, 8,
995 2, -8, 8, -2, -8, 2, 13, 13,
996 -13, -13, 4, 15, -4, -15, 15, 4,
997 -15, -4, -11, 11, 11, -11, -5, 18,
998 5, -18, 18, -5, -18, 5, 13, 26,
999 -13, -26, 26, 13, -26, -13, 26, 26,
1000 -26, -26, 2, 29, -2, -29, 29, 2,
1001 -29, -2, -16, 24, 16, -24, 24, -16,
1002 -24, 16, 28, 46, -28, -46, 46, 28,
1003 -46, -28, -9, 35, 9, -35, 35, -9,
1004 -35, 9, 13, 47, -13, -47, 47, 13,
1005 -47, -13, 49, 49, -49, -49, -1, 54,
1006 1, -54, 54, -1, -54, 1, -35, 35,
1007 35, -35, -26, 47, 26, -47, 47, -26,
1008 -47, 26, 32, 81, -32, -81, 81, 32,
1009 -81, -32, 56, 83, -56, -83, 83, 56,
1010 -83, -56, -18, 67, 18, -67, 67, -18,
1011 -67, 18, 13, 86, -13, -86, 86, 13,
1012 -86, -13, 91, 91, -91, -91, -7, 99,
1013 7, -99, 99, -7, -99, 7, -54, 68,
1014 54, -68, 68, -54, -68, 54, -44, 90,
1015 44, -90, 90, -44, -90, 44, -33, 124,
1016 33, -124, 124, -33, -124, 33, -103, 103,
1017 103, -103, -86, 127, 86, -127, 127, -86,
1018 -127, 86, 37, 37, -37, -37, 69, 69,
1019 -69, -69,
1020 ]};
1021
1022 const DT_1_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1023 0, 0, 7, 7, -7, -7, -3, 10,
1024 3, -10, 10, -3, -10, 3, 16, 16,
1025 -16, -16, 5, 18, -5, -18, 18, 5,
1026 -18, -5, -13, 13, 13, -13, -6, 21,
1027 6, -21, 21, -6, -21, 6, 15, 30,
1028 -15, -30, 30, 15, -30, -15, 30, 30,
1029 -30, -30, 2, 34, -2, -34, 34, 2,
1030 -34, -2, -19, 28, 19, -28, 28, -19,
1031 -28, 19, 32, 54, -32, -54, 54, 32,
1032 -54, -32, -11, 41, 11, -41, 41, -11,
1033 -41, 11, 15, 55, -15, -55, 55, 15,
1034 -55, -15, 57, 57, -57, -57, -1, 63,
1035 1, -63, 63, -1, -63, 1, -40, 40,
1036 40, -40, -30, 55, 30, -55, 55, -30,
1037 -55, 30, 37, 94, -37, -94, 94, 37,
1038 -94, -37, 65, 96, -65, -96, 96, 65,
1039 -96, -65, -21, 78, 21, -78, 78, -21,
1040 -78, 21, 15, 100, -15, -100, 100, 15,
1041 -100, -15, 106, 106, -106, -106, -8, 116,
1042 8, -116, 116, -8, -116, 8, -63, 79,
1043 63, -79, 79, -63, -79, 63, -51, 105,
1044 51, -105, 105, -51, -105, 51, -120, 120,
1045 120, -120, 43, 43, -43, -43, 80, 80,
1046 -80, -80,
1047 ]};
1048
1049 const DT_1_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1050 0, 0, 8, 8, -8, -8, -3, 11,
1051 3, -11, 11, -3, -11, 3, 18, 18,
1052 -18, -18, 5, 20, -5, -20, 20, 5,
1053 -20, -5, -15, 15, 15, -15, -7, 24,
1054 7, -24, 24, -7, -24, 7, 17, 35,
1055 -17, -35, 35, 17, -35, -17, 34, 34,
1056 -34, -34, 3, 38, -3, -38, 38, 3,
1057 -38, -3, -22, 32, 22, -32, 32, -22,
1058 -32, 22, 37, 61, -37, -61, 61, 37,
1059 -61, -37, -13, 47, 13, -47, 47, -13,
1060 -47, 13, 17, 63, -17, -63, 63, 17,
1061 -63, -17, 65, 65, -65, -65, -1, 72,
1062 1, -72, 72, -1, -72, 1, -46, 46,
1063 46, -46, -35, 63, 35, -63, 63, -35,
1064 -63, 35, 43, 107, -43, -107, 107, 43,
1065 -107, -43, 75, 110, -75, -110, 110, 75,
1066 -110, -75, -24, 89, 24, -89, 89, -24,
1067 -89, 24, 17, 114, -17, -114, 114, 17,
1068 -114, -17, 121, 121, -121, -121, -72, 91,
1069 72, -91, 91, -72, -91, 72, -58, 120,
1070 58, -120, 120, -58, -120, 58, 49, 49,
1071 -49, -49, 92, 92, -92, -92,
1072 ]};
1073
1074 const DT_1_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1075 0, 0, 9, 9, -9, -9, -3, 12,
1076 3, -12, 12, -3, -12, 3, 20, 20,
1077 -20, -20, 6, 23, -6, -23, 23, 6,
1078 -23, -6, -17, 17, 17, -17, -7, 27,
1079 7, -27, 27, -7, -27, 7, 19, 39,
1080 -19, -39, 39, 19, -39, -19, 39, 39,
1081 -39, -39, 3, 43, -3, -43, 43, 3,
1082 -43, -3, -24, 36, 24, -36, 36, -24,
1083 -36, 24, 42, 69, -42, -69, 69, 42,
1084 -69, -42, -14, 53, 14, -53, 53, -14,
1085 -53, 14, 19, 71, -19, -71, 71, 19,
1086 -71, -19, 73, 73, -73, -73, -2, 80,
1087 2, -80, 80, -2, -80, 2, -52, 52,
1088 52, -52, -39, 70, 39, -70, 70, -39,
1089 -70, 39, 48, 121, -48, -121, 121, 48,
1090 -121, -48, 84, 124, -84, -124, 124, 84,
1091 -124, -84, -27, 100, 27, -100, 100, -27,
1092 -100, 27, -81, 102, 81, -102, 102, -81,
1093 -102, 81, 55, 55, -55, -55, 104, 104,
1094 -104, -104,
1095 ]};
1096
1097 const DT_2_1: IviDeltaCB = IviDeltaCB{ quad_radix: 7, data: &[
1098 0, 0, 2, 2, -2, -2, 0, 2,
1099 0, -2, 2, 0, -2, 0, 4, 4,
1100 -4, -4, 0, 4, 0, -4, 4, 0,
1101 -4, 0, -4, 4, 4, -4, -2, 6,
1102 2, -6, 6, -2, -6, 2, 4, 8,
1103 -4, -8, 8, 4, -8, -4, 8, 8,
1104 -8, -8, 0, 10, 0, -10, 10, 0,
1105 -10, 0, -4, 8, 4, -8, 8, -4,
1106 -8, 4, 8, 14, -8, -14, 14, 8,
1107 -14, -8, -2, 12, 2, -12, 12, -2,
1108 -12, 2, 4, 16, -4, -16, 16, 4,
1109 -16, -4, 16, 16, -16, -16, 0, 18,
1110 0, -18, 18, 0, -18, 0, -12, 12,
1111 12, -12, -8, 16, 8, -16, 16, -8,
1112 -16, 8, 10, 26, -10, -26, 26, 10,
1113 -26, -10, 18, 28, -18, -28, 28, 18,
1114 -28, -18, -6, 22, 6, -22, 22, -6,
1115 -22, 6, 4, 28, -4, -28, 28, 4,
1116 -28, -4, 30, 30, -30, -30, -2, 32,
1117 2, -32, 32, -2, -32, 2, -18, 22,
1118 18, -22, 22, -18, -22, 18, -14, 30,
1119 14, -30, 30, -14, -30, 14, 22, 46,
1120 -22, -46, 46, 22, -46, -22, 12, 46,
1121 -12, -46, 46, 12, -46, -12, 34, 48,
1122 -34, -48, 48, 34, -48, -34, -10, 40,
1123 10, -40, 40, -10, -40, 10, 4, 50,
1124 -4, -50, 50, 4, -50, -4, 54, 54,
1125 -54, -54, -34, 34, 34, -34, -28, 42,
1126 28, -42, 42, -28, -42, 28, -6, 60,
1127 6, -60, 60, -6, -60, 6, 26, 76,
1128 -26, -76, 76, 26, -76, -26, 42, 76,
1129 -42, -76, 76, 42, -76, -42, -24, 54,
1130 24, -54, 54, -24, -54, 24, 14, 78,
1131 -14, -78, 78, 14, -78, -14, 62, 82,
1132 -62, -82, 82, 62, -82, -62, -20, 74,
1133 20, -74, 74, -20, -74, 20, 2, 88,
1134 -2, -88, 88, 2, -88, -2, 92, 92,
1135 -92, -92, -52, 60, 52, -60, 60, -52,
1136 -60, 52, 52, 118, -52, -118, 118, 52,
1137 -118, -52, -44, 74, 44, -74, 74, -44,
1138 -74, 44, 74, 118, -74, -118, 118, 74,
1139 -118, -74, 32, 118, -32, -118, 118, 32,
1140 -118, -32, -12, 102, 12, -102, 102, -12,
1141 -102, 12, -40, 96, 40, -96, 96, -40,
1142 -96, 40, -34, 118, 34, -118, 118, -34,
1143 -118, 34, -88, 88, 88, -88, -78, 104,
1144 78, -104, 104, -78, -104, 78, 12, 12,
1145 -12, -12, 22, 22, -22, -22, 42, 42,
1146 -42, -42, 72, 72, -72, -72,
1147 ]};
1148
1149 const DT_2_2: IviDeltaCB = IviDeltaCB{ quad_radix: 9, data: &[
1150 0, 0, 3, 3, -3, -3, 0, 3,
1151 0, -3, 3, 0, -3, 0, 6, 6,
1152 -6, -6, 3, 9, -3, -9, 9, 3,
1153 -9, -3, -3, 9, 3, -9, 9, -3,
1154 -9, 3, -6, 6, 6, -6, 6, 12,
1155 -6, -12, 12, 6, -12, -6, 12, 12,
1156 -12, -12, 0, 15, 0, -15, 15, 0,
1157 -15, 0, -9, 12, 9, -12, 12, -9,
1158 -12, 9, 15, 24, -15, -24, 24, 15,
1159 -24, -15, -6, 18, 6, -18, 18, -6,
1160 -18, 6, 6, 24, -6, -24, 24, 6,
1161 -24, -6, 24, 24, -24, -24, 0, 27,
1162 0, -27, 27, 0, -27, 0, -18, 18,
1163 18, -18, -12, 24, 12, -24, 24, -12,
1164 -24, 12, 15, 39, -15, -39, 39, 15,
1165 -39, -15, 27, 42, -27, -42, 42, 27,
1166 -42, -27, -9, 33, 9, -33, 33, -9,
1167 -33, 9, 6, 42, -6, -42, 42, 6,
1168 -42, -6, 45, 45, -45, -45, -3, 51,
1169 3, -51, 51, -3, -51, 3, -27, 33,
1170 27, -33, 33, -27, -33, 27, -21, 45,
1171 21, -45, 45, -21, -45, 21, 33, 69,
1172 -33, -69, 69, 33, -69, -33, 18, 69,
1173 -18, -69, 69, 18, -69, -18, 54, 72,
1174 -54, -72, 72, 54, -72, -54, -18, 63,
1175 18, -63, 63, -18, -63, 18, 6, 78,
1176 -6, -78, 78, 6, -78, -6, 81, 81,
1177 -81, -81, -51, 51, 51, -51, -42, 63,
1178 42, -63, 63, -42, -63, 42, -9, 90,
1179 9, -90, 90, -9, -90, 9, 42, 114,
1180 -42, -114, 114, 42, -114, -42, 63, 117,
1181 -63, -117, 117, 63, -117, -63, -36, 81,
1182 36, -81, 81, -36, -81, 36, 21, 120,
1183 -21, -120, 120, 21, -120, -21, 96, 123,
1184 -96, -123, 123, 96, -123, -96, -30, 111,
1185 30, -111, 111, -30, -111, 30, -78, 93,
1186 78, -93, 93, -78, -93, 78, -69, 114,
1187 69, -114, 114, -69, -114, 69, 18, 18,
1188 -18, -18, 33, 33, -33, -33, 63, 63,
1189 -63, -63, 108, 108, -108, -108,
1190 ]};
1191
1192 const DT_2_3: IviDeltaCB = IviDeltaCB{ quad_radix: 10, data: &[
1193 0, 0, 4, 4, -4, -4, 0, 4,
1194 0, -4, 4, 0, -4, 0, 4, 8,
1195 -4, -8, 8, 4, -8, -4, 8, 8,
1196 -8, -8, -8, 8, 8, -8, -4, 12,
1197 4, -12, 12, -4, -12, 4, 8, 16,
1198 -8, -16, 16, 8, -16, -8, 16, 16,
1199 -16, -16, 0, 20, 0, -20, 20, 0,
1200 -20, 0, -12, 16, 12, -16, 16, -12,
1201 -16, 12, -4, 24, 4, -24, 24, -4,
1202 -24, 4, 16, 32, -16, -32, 32, 16,
1203 -32, -16, 8, 32, -8, -32, 32, 8,
1204 -32, -8, 32, 32, -32, -32, 0, 36,
1205 0, -36, 36, 0, -36, 0, -24, 24,
1206 24, -24, -16, 32, 16, -32, 32, -16,
1207 -32, 16, 20, 52, -20, -52, 52, 20,
1208 -52, -20, 36, 56, -36, -56, 56, 36,
1209 -56, -36, -12, 44, 12, -44, 44, -12,
1210 -44, 12, 8, 56, -8, -56, 56, 8,
1211 -56, -8, 60, 60, -60, -60, -4, 64,
1212 4, -64, 64, -4, -64, 4, -36, 44,
1213 36, -44, 44, -36, -44, 36, -28, 60,
1214 28, -60, 60, -28, -60, 28, 44, 92,
1215 -44, -92, 92, 44, -92, -44, 24, 92,
1216 -24, -92, 92, 24, -92, -24, 72, 96,
1217 -72, -96, 96, 72, -96, -72, -20, 84,
1218 20, -84, 84, -20, -84, 20, 8, 100,
1219 -8, -100, 100, 8, -100, -8, 108, 108,
1220 -108, -108, -68, 68, 68, -68, -56, 84,
1221 56, -84, 84, -56, -84, 56, -12, 120,
1222 12, -120, 120, -12, -120, 12, -48, 108,
1223 48, -108, 108, -48, -108, 48, -104, 124,
1224 104, -124, 124, -104, -124, 104, 24, 24,
1225 -24, -24, 44, 44, -44, -44, 84, 84,
1226 -84, -84,
1227 ]};
1228
1229 const DT_2_4: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1230 0, 0, 5, 5, -5, -5, 0, 5,
1231 0, -5, 5, 0, -5, 0, 10, 10,
1232 -10, -10, 5, 15, -5, -15, 15, 5,
1233 -15, -5, -10, 10, 10, -10, -5, 15,
1234 5, -15, 15, -5, -15, 5, 10, 20,
1235 -10, -20, 20, 10, -20, -10, 20, 20,
1236 -20, -20, 0, 25, 0, -25, 25, 0,
1237 -25, 0, -15, 20, 15, -20, 20, -15,
1238 -20, 15, 25, 40, -25, -40, 40, 25,
1239 -40, -25, -10, 30, 10, -30, 30, -10,
1240 -30, 10, 10, 40, -10, -40, 40, 10,
1241 -40, -10, 40, 40, -40, -40, 0, 45,
1242 0, -45, 45, 0, -45, 0, -30, 30,
1243 30, -30, -20, 40, 20, -40, 40, -20,
1244 -40, 20, 25, 65, -25, -65, 65, 25,
1245 -65, -25, 45, 70, -45, -70, 70, 45,
1246 -70, -45, -15, 55, 15, -55, 55, -15,
1247 -55, 15, 10, 70, -10, -70, 70, 10,
1248 -70, -10, 75, 75, -75, -75, -5, 85,
1249 5, -85, 85, -5, -85, 5, -45, 55,
1250 45, -55, 55, -45, -55, 45, -35, 75,
1251 35, -75, 75, -35, -75, 35, 55, 115,
1252 -55, -115, 115, 55, -115, -55, 30, 115,
1253 -30, -115, 115, 30, -115, -30, 90, 120,
1254 -90, -120, 120, 90, -120, -90, -30, 105,
1255 30, -105, 105, -30, -105, 30, -85, 85,
1256 85, -85, -70, 105, 70, -105, 105, -70,
1257 -105, 70, 30, 30, -30, -30, 60, 60,
1258 -60, -60, 105, 105, -105, -105,
1259 ]};
1260
1261 const DT_2_5: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1262 0, 0, 6, 6, -6, -6, 0, 6,
1263 0, -6, 6, 0, -6, 0, 12, 12,
1264 -12, -12, 6, 12, -6, -12, 12, 6,
1265 -12, -6, -12, 12, 12, -12, -6, 18,
1266 6, -18, 18, -6, -18, 6, 12, 24,
1267 -12, -24, 24, 12, -24, -12, 24, 24,
1268 -24, -24, 0, 30, 0, -30, 30, 0,
1269 -30, 0, -18, 24, 18, -24, 24, -18,
1270 -24, 18, 30, 48, -30, -48, 48, 30,
1271 -48, -30, -6, 36, 6, -36, 36, -6,
1272 -36, 6, 12, 48, -12, -48, 48, 12,
1273 -48, -12, 48, 48, -48, -48, 0, 54,
1274 0, -54, 54, 0, -54, 0, -36, 36,
1275 36, -36, -24, 48, 24, -48, 48, -24,
1276 -48, 24, 30, 78, -30, -78, 78, 30,
1277 -78, -30, 54, 84, -54, -84, 84, 54,
1278 -84, -54, -18, 66, 18, -66, 66, -18,
1279 -66, 18, 12, 84, -12, -84, 84, 12,
1280 -84, -12, 90, 90, -90, -90, -6, 96,
1281 6, -96, 96, -6, -96, 6, -54, 66,
1282 54, -66, 66, -54, -66, 54, -42, 90,
1283 42, -90, 90, -42, -90, 42, -30, 126,
1284 30, -126, 126, -30, -126, 30, -102, 102,
1285 102, -102, -84, 126, 84, -126, 126, -84,
1286 -126, 84, 36, 36, -36, -36, 66, 66,
1287 -66, -66,
1288 ]};
1289
1290 const DT_2_6: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1291 0, 0, 7, 7, -7, -7, 0, 7,
1292 0, -7, 7, 0, -7, 0, 14, 14,
1293 -14, -14, 7, 21, -7, -21, 21, 7,
1294 -21, -7, -14, 14, 14, -14, -7, 21,
1295 7, -21, 21, -7, -21, 7, 14, 28,
1296 -14, -28, 28, 14, -28, -14, 28, 28,
1297 -28, -28, 0, 35, 0, -35, 35, 0,
1298 -35, 0, -21, 28, 21, -28, 28, -21,
1299 -28, 21, 35, 56, -35, -56, 56, 35,
1300 -56, -35, -14, 42, 14, -42, 42, -14,
1301 -42, 14, 14, 56, -14, -56, 56, 14,
1302 -56, -14, 56, 56, -56, -56, 0, 63,
1303 0, -63, 63, 0, -63, 0, -42, 42,
1304 42, -42, -28, 56, 28, -56, 56, -28,
1305 -56, 28, 35, 91, -35, -91, 91, 35,
1306 -91, -35, 63, 98, -63, -98, 98, 63,
1307 -98, -63, -21, 77, 21, -77, 77, -21,
1308 -77, 21, 14, 98, -14, -98, 98, 14,
1309 -98, -14, 105, 105, -105, -105, -7, 119,
1310 7, -119, 119, -7, -119, 7, -63, 77,
1311 63, -77, 77, -63, -77, 63, -49, 105,
1312 49, -105, 105, -49, -105, 49, -119, 119,
1313 119, -119, 42, 42, -42, -42, 77, 77,
1314 -77, -77,
1315 ]};
1316
1317 const DT_2_7: IviDeltaCB = IviDeltaCB{ quad_radix: 12, data: &[
1318 0, 0, 8, 8, -8, -8, 0, 8,
1319 0, -8, 8, 0, -8, 0, 16, 16,
1320 -16, -16, 8, 16, -8, -16, 16, 8,
1321 -16, -8, -16, 16, 16, -16, -8, 24,
1322 8, -24, 24, -8, -24, 8, 16, 32,
1323 -16, -32, 32, 16, -32, -16, 32, 32,
1324 -32, -32, 0, 40, 0, -40, 40, 0,
1325 -40, 0, -24, 32, 24, -32, 32, -24,
1326 -32, 24, 40, 64, -40, -64, 64, 40,
1327 -64, -40, -16, 48, 16, -48, 48, -16,
1328 -48, 16, 16, 64, -16, -64, 64, 16,
1329 -64, -16, 64, 64, -64, -64, 0, 72,
1330 0, -72, 72, 0, -72, 0, -48, 48,
1331 48, -48, -32, 64, 32, -64, 64, -32,
1332 -64, 32, 40, 104, -40, -104, 104, 40,
1333 -104, -40, 72, 112, -72, -112, 112, 72,
1334 -112, -72, -24, 88, 24, -88, 88, -24,
1335 -88, 24, 16, 112, -16, -112, 112, 16,
1336 -112, -16, 120, 120, -120, -120, -72, 88,
1337 72, -88, 88, -72, -88, 72, -56, 120,
1338 56, -120, 120, -56, -120, 56, 48, 48,
1339 -48, -48, 88, 88, -88, -88,
1340 ]};
1341
1342 const DT_2_8: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1343 0, 0, 9, 9, -9, -9, 0, 9,
1344 0, -9, 9, 0, -9, 0, 18, 18,
1345 -18, -18, 9, 27, -9, -27, 27, 9,
1346 -27, -9, -18, 18, 18, -18, -9, 27,
1347 9, -27, 27, -9, -27, 9, 18, 36,
1348 -18, -36, 36, 18, -36, -18, 36, 36,
1349 -36, -36, 0, 45, 0, -45, 45, 0,
1350 -45, 0, -27, 36, 27, -36, 36, -27,
1351 -36, 27, 45, 72, -45, -72, 72, 45,
1352 -72, -45, -18, 54, 18, -54, 54, -18,
1353 -54, 18, 18, 72, -18, -72, 72, 18,
1354 -72, -18, 72, 72, -72, -72, 0, 81,
1355 0, -81, 81, 0, -81, 0, -54, 54,
1356 54, -54, -36, 72, 36, -72, 72, -36,
1357 -72, 36, 45, 117, -45, -117, 117, 45,
1358 -117, -45, 81, 126, -81, -126, 126, 81,
1359 -126, -81, -27, 99, 27, -99, 99, -27,
1360 -99, 27, -81, 99, 81, -99, 99, -81,
1361 -99, 81, 54, 54, -54, -54, 108, 108,
1362 -108, -108,
1363 ]};
1364
1365 const DT_3_1: IviDeltaCB = IviDeltaCB{ quad_radix: 11, data: &[
1366 0, 0, 2, 2, -2, -2, 0, 3,
1367 0, -3, 3, 0, -3, 0, 6, 6,
1368 -6, -6, 0, 7, 0, -7, 7, 0,
1369 -7, 0, -5, 5, 5, -5, 5, -5,
1370 -5, 5, 6, 11, -6, -11, 11, 6,
1371 -11, -6, 0, 8, 0, -8, 8, 0,
1372 -8, 0, 11, 11, -11, -11, 0, 12,
1373 0, -12, 12, 0, -12, 0, 12, 17,
1374 -12, -17, 17, 12, -17, -12, 17, 17,
1375 -17, -17, 6, 18, -6, -18, 18, 6,
1376 -18, -6, -8, 11, 8, -11, 11, -8,
1377 -11, 8, 0, 15, 0, -15, 15, 0,
1378 -15, 0, 0, 20, 0, -20, 20, 0,
1379 -20, 0, 18, 25, -18, -25, 25, 18,
1380 -25, -18, 11, 25, -11, -25, 25, 11,
1381 -25, -11, 25, 25, -25, -25, -14, 14,
1382 14, -14, 14, -14, -14, 14, 0, 26,
1383 0, -26, 26, 0, -26, 0, -11, 18,
1384 11, -18, 18, -11, -18, 11, -7, 22,
1385 7, -22, 22, -7, -22, 7, 26, 34,
1386 -26, -34, 34, 26, -34, -26, 18, 34,
1387 -18, -34, 34, 18, -34, -18, 34, 34,
1388 -34, -34, 11, 35, -11, -35, 35, 11,
1389 -35, -11, 0, 29, 0, -29, 29, 0,
1390 -29, 0, -19, 22, 19, -22, 22, -19,
1391 -22, 19, -15, 26, 15, -26, 26, -15,
1392 -26, 15, 0, 37, 0, -37, 37, 0,
1393 -37, 0, 27, 44, -27, -44, 44, 27,
1394 -44, -27, 36, 44, -36, -44, 44, 36,
1395 -44, -36, 18, 44, -18, -44, 44, 18,
1396 -44, -18, -10, 33, 10, -33, 33, -10,
1397 -33, 10, 45, 45, -45, -45, 0, 0,
1398 ]};
1399
1400 const DT_3_2: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1401 0, 0, 0, 2, 0, -2, 2, 0,
1402 -2, 0, 2, 2, -2, -2, 6, 6,
1403 -6, -6, 0, 6, 0, -6, 6, 0,
1404 -6, 0, -4, 4, 4, -4, 10, -6,
1405 -10, 6, 0, -12, 0, 12, -6, -12,
1406 6, -12, -6, 12, 6, 12, -14, 0,
1407 14, 0, 12, 12, -12, -12, 0, -18,
1408 0, 18, 14, -12, -14, 12, -18, -6,
1409 18, -6, -18, 6, 18, 6, -10, -18,
1410 10, -18, -10, 18, 10, 18, -22, 0,
1411 22, 0, 0, -24, 0, 24, -22, -12,
1412 22, -12, -22, 12, 22, 12, -8, -24,
1413 8, -24, -8, 24, 8, 24, -26, -6,
1414 26, -6, -26, 6, 26, 6, -28, 0,
1415 28, 0, 20, 20, -20, -20, -14, -26,
1416 14, 26, -30, -12, 30, 12, -10, -32,
1417 10, 32, -18, -32, 18, 32, -26, -26,
1418 26, 26, -34, -20, 34, 20, -38, -12,
1419 38, 12, -32, -32, 32, 32, 32, 32,
1420 -22, -40, -34, -34, 34, 34,
1421 ]};
1422
1423 const DT_3_3: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1424 0, 0, 0, 2, 0, -2, 2, 0,
1425 -2, 0, 4, 4, -4, -4, 10, 10,
1426 -10, -10, 0, 10, 0, -10, 10, 0,
1427 -10, 0, -6, 6, 6, -6, 14, -8,
1428 -14, 8, -18, 0, 18, 0, 10, -16,
1429 -10, 16, 0, -24, 0, 24, -24, -8,
1430 24, -8, -24, 8, 24, 8, 18, 18,
1431 -18, -18, 20, -16, -20, 16, -14, -26,
1432 14, -26, -14, 26, 14, 26, -30, 0,
1433 30, 0, 0, -34, 0, 34, -34, -8,
1434 34, -8, -34, 8, 34, 8, -30, -18,
1435 30, -18, -30, 18, 30, 18, -10, -34,
1436 10, -34, -10, 34, 10, 34, -20, -34,
1437 20, 34, -40, 0, 40, 0, 30, 30,
1438 -30, -30, -40, -18, 40, 18, 0, -44,
1439 0, 44, -16, -44, 16, 44, -36, -36,
1440 -36, -36, 36, 36, -26, -44, 26, 44,
1441 -46, -26, 46, 26, -52, -18, 52, 18,
1442 -20, -54, -44, -44, 44, 44, -32, -54,
1443 -46, -46, -46, -46, 46, 46,
1444 ]};
1445
1446 const DT_3_4: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1447 0, 0, 0, 4, 0, -4, 4, 0,
1448 -4, 0, 4, 4, -4, -4, 12, 12,
1449 -12, -12, 0, 12, 0, -12, 12, 0,
1450 -12, 0, -8, 8, 8, -8, 8, -16,
1451 -8, 16, 0, -24, 0, 24, -24, -8,
1452 24, -8, -24, 8, 24, 8, 20, -16,
1453 -20, 16, -28, 0, 28, 0, -16, -24,
1454 16, -24, -16, 24, 16, 24, 0, -32,
1455 0, 32, -28, -16, 28, -16, -28, 16,
1456 28, 16, -8, -32, 8, -32, -32, -8,
1457 32, -8, -32, 8, 32, 8, -8, 32,
1458 8, 32, 24, 24, -24, -24, 24, -24,
1459 -24, 24, -20, -32, 20, 32, -40, 0,
1460 40, 0, -40, -16, 40, 16, 0, -44,
1461 0, -44, -44, 0, 44, 0, 0, 44,
1462 0, 44, -32, -32, 32, 32, -16, -44,
1463 16, 44, -24, -44, -44, -24, 44, 24,
1464 24, 44, -48, -16, 48, 16, -36, -36,
1465 -36, -36, 36, 36, 36, 36, -20, -52,
1466 40, 40, -40, -40, -32, -52,
1467 ]};
1468
1469 const DT_3_5: IviDeltaCB = IviDeltaCB{ quad_radix: 13, data: &[
1470 0, 0, 2, 2, -2, -2, 6, 6,
1471 -6, -6, 12, 12, -12, -12, 20, 20,
1472 -20, -20, 32, 32, -32, -32, 46, 46,
1473 -46, -46, 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, 0, 0,
1489 0, 0, 0, 0, 0, 0,
1490 ]};
1491
1492 const IVI3_DELTA_CBS: [&IviDeltaCB; 24] = [
1493 &DT_1_1, &DT_1_2, &DT_1_3, &DT_1_4, &DT_1_5, &DT_1_6, &DT_1_7, &DT_1_8,
1494 &DT_2_1, &DT_2_2, &DT_2_3, &DT_2_4, &DT_2_5, &DT_2_6, &DT_2_7, &DT_2_8,
1495 &DT_3_1, &DT_3_2, &DT_3_3, &DT_3_4, &DT_3_5, &DT_3_5, &DT_3_5, &DT_3_5
1496 ];