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