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