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