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