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