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