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