6d7877b4a2f8cd1d6dc948e5d44dab0b581f4eee
[nihav.git] / nihav-realmedia / src / codecs / cook.rs
1 use std::rc::Rc;
2 use std::cell::RefCell;
3 use nihav_core::formats::*;
4 use nihav_core::frame::*;
5 use nihav_core::codecs::*;
6 use nihav_core::dsp::fft::FFTMode;
7 use nihav_core::dsp::mdct::IMDCT;
8 use nihav_core::io::bitreader::*;
9 use nihav_core::io::byteio::{ByteReader, MemoryReader};
10 use nihav_core::io::codebook::*;
11 use nihav_core::io::intcode::*;
12 use std::f32::consts;
13 use std::mem::swap;
14
15 #[derive(Debug,Clone,Copy,PartialEq)]
16 enum Mode {
17 Mono,
18 Stereo,
19 JointStereo,
20 }
21
22 impl Mode {
23 fn get_channels(&self) -> usize {
24 match *self {
25 Mode::Mono => 1,
26 _ => 2,
27 }
28 }
29 }
30
31 struct CookBookReader {
32 bits: &'static [u8],
33 codes: &'static [u16],
34 }
35 impl CodebookDescReader<u16> for CookBookReader {
36 fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] }
37 fn code(&mut self, idx: usize) -> u32 { self.codes[idx] as u32 }
38 fn sym (&mut self, idx: usize) -> u16 { idx as u16 }
39 fn len(&mut self) -> usize { self.bits.len() }
40 }
41
42 struct Codebooks {
43 cpl_cb: [Codebook<u16>; 5],
44 quant_cb: Vec<Codebook<u16>>,
45 vq_cb: [Codebook<u16>; 7],
46 }
47
48 impl Codebooks {
49 fn new() -> Self {
50 let mut cpl0 = CookBookReader { codes: COOK_CPL_2BITS_CODES, bits: COOK_CPL_2BITS_BITS };
51 let mut cpl1 = CookBookReader { codes: COOK_CPL_3BITS_CODES, bits: COOK_CPL_3BITS_BITS };
52 let mut cpl2 = CookBookReader { codes: COOK_CPL_4BITS_CODES, bits: COOK_CPL_4BITS_BITS };
53 let mut cpl3 = CookBookReader { codes: COOK_CPL_5BITS_CODES, bits: COOK_CPL_5BITS_BITS };
54 let mut cpl4 = CookBookReader { codes: COOK_CPL_6BITS_CODES, bits: COOK_CPL_6BITS_BITS };
55 let cpl_cb = [Codebook::new(&mut cpl0, CodebookMode::MSB).unwrap(),
56 Codebook::new(&mut cpl1, CodebookMode::MSB).unwrap(),
57 Codebook::new(&mut cpl2, CodebookMode::MSB).unwrap(),
58 Codebook::new(&mut cpl3, CodebookMode::MSB).unwrap(),
59 Codebook::new(&mut cpl4, CodebookMode::MSB).unwrap()];
60 let mut quant_cb: Vec<Codebook<u16>> = Vec::with_capacity(COOK_QUANT_CODES.len());
61 for i in 0..COOK_QUANT_CODES.len() {
62 let mut quant = CookBookReader { codes: COOK_QUANT_CODES[i], bits: COOK_QUANT_BITS[i] };
63 quant_cb.push(Codebook::new(&mut quant, CodebookMode::MSB).unwrap());
64 }
65 let mut vq0 = CookBookReader { codes: COOK_VQ0_CODES, bits: COOK_VQ0_BITS };
66 let mut vq1 = CookBookReader { codes: COOK_VQ1_CODES, bits: COOK_VQ1_BITS };
67 let mut vq2 = CookBookReader { codes: COOK_VQ2_CODES, bits: COOK_VQ2_BITS };
68 let mut vq3 = CookBookReader { codes: COOK_VQ3_CODES, bits: COOK_VQ3_BITS };
69 let mut vq4 = CookBookReader { codes: COOK_VQ4_CODES, bits: COOK_VQ4_BITS };
70 let mut vq5 = CookBookReader { codes: COOK_VQ5_CODES, bits: COOK_VQ5_BITS };
71 let mut vq6 = CookBookReader { codes: COOK_VQ6_CODES, bits: COOK_VQ6_BITS };
72 let vq_cb = [Codebook::new(&mut vq0, CodebookMode::MSB).unwrap(),
73 Codebook::new(&mut vq1, CodebookMode::MSB).unwrap(),
74 Codebook::new(&mut vq2, CodebookMode::MSB).unwrap(),
75 Codebook::new(&mut vq3, CodebookMode::MSB).unwrap(),
76 Codebook::new(&mut vq4, CodebookMode::MSB).unwrap(),
77 Codebook::new(&mut vq5, CodebookMode::MSB).unwrap(),
78 Codebook::new(&mut vq6, CodebookMode::MSB).unwrap()];
79 Codebooks {
80 cpl_cb: cpl_cb,
81 quant_cb: quant_cb,
82 vq_cb: vq_cb,
83 }
84 }
85 }
86
87 struct CookDSP {
88 imdct: IMDCT,
89 window: [f32; 1024],
90 out: [f32; 2048],
91 size: usize,
92 pow_tab: [f32; 128],
93 hpow_tab: [f32; 128],
94 gain_tab: [f32; 23],
95 }
96
97 impl CookDSP {
98 fn new(samples: usize) -> Self {
99 let fsamples = samples as f32;
100 let mut window: [f32; 1024] = [0.0; 1024];
101 let factor = consts::PI / (2.0 * fsamples);
102 let scale = (2.0 / fsamples).sqrt() / 32768.0;
103 for k in 0..samples {
104 window[k] = (factor * ((k as f32) + 0.5)).sin() * scale;
105 }
106 let mut pow_tab: [f32; 128] = [0.0; 128];
107 let mut hpow_tab: [f32; 128] = [0.0; 128];
108 for i in 0..128 {
109 pow_tab[i] = 2.0f32.powf((i as f32) - 64.0);
110 hpow_tab[i] = 2.0f32.powf(((i as f32) - 64.0) * 0.5);
111 }
112 let mut gain_tab: [f32; 23] = [0.0; 23];
113 for i in 0..23 {
114 gain_tab[i] = pow_tab[i + 53].powf(8.0 / fsamples);
115 }
116 let size = samples;
117 CookDSP { imdct: IMDCT::new(FFTMode::SplitRadix, samples*2, false), window: window, out: [0.0; 2048], size, pow_tab, hpow_tab, gain_tab }
118 }
119 }
120
121 trait ClipCat {
122 fn clip_cat(&self) -> usize;
123 }
124
125 impl ClipCat for i32 {
126 fn clip_cat(&self) -> usize { ((*self).max(0) as usize).min(NUM_CATEGORIES - 1) }
127 }
128
129 const BAND_SIZE: usize = 20;
130 const MAX_SAMPLES: usize = MAX_SUBBANDS * BAND_SIZE;
131 const MAX_PAIRS: usize = 5;
132 const MAX_SUBBANDS: usize = 52;
133 const NUM_CATEGORIES: usize = 8;
134
135 #[derive(Clone,Copy)]
136 struct CookChannelPair {
137 start_ch: usize,
138 mode: Mode,
139 samples: usize,
140 subbands: usize,
141 js_start: usize,
142 js_bits: u8,
143 vector_bits: u8,
144
145 decouple: [u8; BAND_SIZE],
146 category: [u8; MAX_SUBBANDS * 2],
147
148 block: [[f32; MAX_SAMPLES * 2]; 2],
149 delay: [[f32; MAX_SAMPLES]; 2],
150 gains: [[i32; 9]; 2],
151 prev_gains: [[i32; 9]; 2],
152 qindex: [i8; MAX_SUBBANDS * 2],
153 }
154
155 impl CookChannelPair {
156 fn new() -> Self {
157 CookChannelPair {
158 start_ch: 0,
159 mode: Mode::Mono,
160 samples: 0,
161 subbands: 0,
162 js_start: 0,
163 js_bits: 0,
164 vector_bits: 0,
165
166 decouple: [0; BAND_SIZE],
167 category: [0; MAX_SUBBANDS * 2],
168
169 block: [[0.0; MAX_SAMPLES * 2]; 2],
170 delay: [[0.0; MAX_SAMPLES]; 2],
171 gains: [[0; 9]; 2],
172 prev_gains: [[0; 9]; 2],
173 qindex: [0; MAX_SUBBANDS * 2],
174 }
175 }
176 fn read_hdr_v1(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
177 let ver = br.read_u32be()?;
178 let micro_ver = ver & 0xFF;
179 self.samples = br.read_u16be()? as usize;
180 validate!(self.samples > 0 && ((self.samples & (self.samples - 1)) == 0));
181 self.subbands = br.read_u16be()? as usize;
182 validate!(self.subbands <= MAX_SUBBANDS);
183 match micro_ver {
184 1 => {
185 self.mode = Mode::Mono;
186 self.js_start = 0;
187 self.js_bits = 0;
188 },
189 2 => {
190 self.mode = Mode::Stereo;
191 self.js_start = 0;
192 self.js_bits = 0;
193 },
194 3 => {
195 self.mode = Mode::JointStereo;
196 let _delay = br.read_u32be()?;
197 self.js_start = br.read_u16be()? as usize;
198 self.js_bits = br.read_u16be()? as u8;
199 validate!(self.js_start < MAX_SUBBANDS);
200 validate!((self.js_bits >= 2) && (self.js_bits <= 6));
201 },
202 _ => { return Err(DecoderError::InvalidData);}
203 }
204 Ok(())
205 }
206 fn read_hdr_v2(&mut self, br: &mut ByteReader) -> DecoderResult<u32> {
207 let ver = br.read_u32be()?;
208 validate!((ver >> 24) == 2);
209 self.samples = br.read_u16be()? as usize;
210 self.subbands = br.read_u16be()? as usize;
211 validate!(self.subbands <= MAX_SUBBANDS);
212 let _delay = br.read_u32be()?;
213 self.js_start = br.read_u16be()? as usize;
214 validate!(self.js_start < MAX_SUBBANDS);
215 let js_bits = br.read_u16be()?;
216 let chmap = br.read_u32be()?;
217 if chmap.count_ones() == 1 {
218 self.js_bits = 0;
219 self.mode = Mode::Mono;
220 } else {
221 validate!((js_bits >= 2) && (js_bits <= 6));
222 self.js_bits = js_bits as u8;
223 self.mode = Mode::JointStereo;
224 }
225 Ok(chmap)
226 }
227 fn bitalloc(&mut self, num_vectors: usize, bits: usize) {
228 let avail_bits = (if bits > self.samples { self.samples + ((bits - self.samples) * 5) / 8 } else { bits }) as i32;
229 let total_subbands = self.subbands + self.js_start;
230
231 let mut bias: i32 = -32;
232 for i in 0..6 {
233 let mut sum = 0;
234 for j in 0..total_subbands {
235 let idx = ((32 >> i) + bias - (self.qindex[j] as i32)) / 2;
236 sum += COOK_EXP_BITS[idx.clip_cat()];
237 }
238 if sum >= (avail_bits - 32) {
239 bias += 32 >> i;
240 }
241 }
242
243 let mut exp_index1: [usize; MAX_SUBBANDS * 2] = [0; MAX_SUBBANDS * 2];
244 let mut exp_index2: [usize; MAX_SUBBANDS * 2] = [0; MAX_SUBBANDS * 2];
245 let mut sum = 0;
246 for i in 0..total_subbands {
247 let idx = ((bias - (self.qindex[i] as i32)) / 2).clip_cat();
248 sum += COOK_EXP_BITS[idx];
249 exp_index1[i] = idx;
250 exp_index2[i] = idx;
251 }
252
253 let mut tbias1 = sum;
254 let mut tbias2 = sum;
255 let mut tcat: [usize; 128*2] = [0; 128*2];
256 let mut tcat_idx1 = 128;
257 let mut tcat_idx2 = 128;
258 for _ in 1..(1 << self.vector_bits) {
259 if tbias1 + tbias2 > avail_bits * 2 {
260 let mut max = -999999;
261 let mut idx = total_subbands + 1;
262 for j in 0..total_subbands {
263 if exp_index1[j] >= (NUM_CATEGORIES - 1) { continue; }
264 let t = -2 * (exp_index1[j] as i32) - (self.qindex[j] as i32) + bias;
265 if t >= max {
266 max = t;
267 idx = j;
268 }
269 }
270 if idx >= total_subbands { break; }
271 tcat[tcat_idx1] = idx;
272 tcat_idx1 += 1;
273 tbias1 -= COOK_EXP_BITS[exp_index1[idx]] - COOK_EXP_BITS[exp_index1[idx] + 1];
274 exp_index1[idx] += 1;
275 } else {
276 let mut min = 999999;
277 let mut idx = total_subbands + 1;
278 for j in 0..total_subbands {
279 if exp_index2[j] == 0 { continue; }
280 let t = -2 * (exp_index2[j] as i32) - (self.qindex[j] as i32) + bias;
281 if t < min {
282 min = t;
283 idx = j;
284 }
285 }
286 if idx >= total_subbands { break; }
287 tcat_idx2 -= 1;
288 tcat[tcat_idx2] = idx;
289 tbias2 -= COOK_EXP_BITS[exp_index2[idx]] - COOK_EXP_BITS[exp_index2[idx] - 1];
290 exp_index2[idx] -= 1;
291 }
292 }
293 for i in 0..total_subbands {
294 self.category[i] = exp_index2[i] as u8;
295 }
296
297 for _ in 0..num_vectors {
298 let idx = tcat[tcat_idx2];
299 tcat_idx2 += 1;
300 self.category[idx] = (self.category[idx] + 1).min((NUM_CATEGORIES - 1) as u8) as u8;
301 }
302 }
303 fn decode_channel_data(&mut self, dsp: &mut CookDSP, rnd: &mut RND, codebooks: &Codebooks, src: &[u8], buf: &mut [u8], channel: usize) -> DecoderResult<()> {
304 // decrypt
305 for (i, b) in src.iter().enumerate() {
306 buf[i] = b ^ COOK_XOR_KEY[i & 3];
307 }
308 let mut br = BitReader::new(buf, src.len(), BitReaderMode::BE);
309
310 let num_gains = br.read_code(UintCodeType::UnaryOnes)? as usize;
311 validate!(num_gains <= 8);
312
313 swap(&mut self.gains[channel], &mut self.prev_gains[channel]);
314 self.block[channel] = [0.0; MAX_SAMPLES * 2];
315
316 // gains
317 let mut ipos = 0;
318 for _ in 0..num_gains {
319 let idx = br.read(3)? as usize;
320 let val;
321 if br.read_bool()? {
322 val = (br.read(4)? as i32) - 7;
323 } else {
324 val = -1;
325 }
326 validate!(idx >= ipos);
327 while ipos <= idx {
328 self.prev_gains[channel][ipos] = val;
329 ipos += 1;
330 }
331 }
332 while ipos <= 8 {
333 self.prev_gains[channel][ipos] = 0;
334 ipos += 1;
335 }
336
337 // coupling information
338 if self.mode == Mode::JointStereo {
339 let cstart = COOK_CPL_BAND[self.js_start] as usize;
340 let cend = COOK_CPL_BAND[self.subbands - 1] as usize;
341 if br.read_bool()? {
342 let cb = &codebooks.cpl_cb[(self.js_bits - 2) as usize];
343 for i in cstart..cend+1 {
344 self.decouple[i] = br.read_cb(cb)? as u8;
345 }
346 } else {
347 for i in cstart..cend+1 {
348 self.decouple[i] = br.read(self.js_bits)? as u8;
349 }
350 }
351 }
352
353 // envelope
354 let tot_subbands = self.subbands + self.js_start;
355 self.qindex[0] = (br.read(6)? as i8) - 6;
356 for i in 1..tot_subbands {
357 let mut pos = i;
358 if pos >= self.js_start * 2 {
359 pos -= self.js_start;
360 } else {
361 pos >>= 1;
362 }
363 let ipos = ((pos as i8) - 1).max(0).min(12);
364 let cb = &codebooks.quant_cb[ipos as usize];
365 self.qindex[i] = (br.read_cb(cb)? as i8) + self.qindex[i - 1] - 12;
366 validate!((self.qindex[i] >= -63) && (self.qindex[i] <= 63));
367 }
368 let num_vectors = br.read(self.vector_bits)? as usize;
369 self.bitalloc(num_vectors, br.left() as usize);
370
371 // coefficients
372 self.block[channel] = [0.0; MAX_SAMPLES * 2];
373 let mut off = 0;
374 for sb in 0..tot_subbands {
375 let mut coef_index: [u8; BAND_SIZE] = [0; BAND_SIZE];
376 let mut coef_sign: [bool; BAND_SIZE] = [false; BAND_SIZE];
377 let cat = self.category[sb] as usize;
378 if (cat < NUM_CATEGORIES - 1) && br.left() > 0 {
379 unpack_band(&mut br, codebooks, &mut coef_index, &mut coef_sign, cat)?;
380 }
381 for i in 0..BAND_SIZE {
382 let val;
383 if coef_index[i] == 0 {
384 let v = COOK_DITHER_TAB[cat];
385 val = if !rnd.get_sign() { v } else { -v };
386 } else {
387 let v = COOK_QUANT_CENTROID[cat][coef_index[i] as usize];
388 val = if !coef_sign[i] { v } else { -v };
389 }
390 self.block[channel][off + i] = val * dsp.hpow_tab[(self.qindex[sb] + 64) as usize];
391 }
392 off += BAND_SIZE;
393 }
394
395 Ok(())
396 }
397 fn decode(&mut self, dsp: &mut CookDSP, rnd: &mut RND, codebooks: &Codebooks, src: &[u8], buf: &mut [u8], abuf: &mut NABufferType) -> DecoderResult<()> {
398 if self.mode == Mode::Stereo {
399 let mut schunk = src.chunks(src.len() / 2);
400 self.decode_channel_data(dsp, rnd, codebooks, schunk.next().unwrap(), buf, 0)?;
401 self.decode_channel_data(dsp, rnd, codebooks, schunk.next().unwrap(), buf, 1)?;
402 } else {
403 self.decode_channel_data(dsp, rnd, codebooks, src, buf, 0)?;
404 }
405 // uncouple joint stereo channels
406 if self.mode == Mode::JointStereo {
407 for i in 0..self.js_start {
408 for j in 0..BAND_SIZE {
409 self.block[1][i * BAND_SIZE + j] = self.block[0][(i * 2 + 1) * BAND_SIZE + j];
410 self.block[0][i * BAND_SIZE + j] = self.block[0][(i * 2) * BAND_SIZE + j];
411 }
412 }
413 let scale_idx = (self.js_bits as usize) - 2;
414 let scale_off = (1 << self.js_bits) as usize;
415 for i in self.js_start..self.subbands {
416 let idx = self.decouple[COOK_CPL_BAND[i] as usize] as usize;
417 let doff = i * BAND_SIZE;
418 let soff = (i + self.js_start) * BAND_SIZE;
419 let m1 = COOK_CPL_SCALES[scale_idx][ 1 + idx];
420 let m2 = COOK_CPL_SCALES[scale_idx][scale_off - 1 - idx];
421 for j in 0..BAND_SIZE {
422 self.block[0][doff + j] = self.block[0][soff + j] * m1;
423 self.block[1][doff + j] = self.block[0][soff + j] * m2;
424 }
425 }
426 for i in (self.subbands * BAND_SIZE)..MAX_SAMPLES {
427 self.block[0][i] = 0.0;
428 self.block[1][i] = 0.0;
429 }
430 self.gains[1] = self.gains[0];
431 self.prev_gains[1] = self.prev_gains[0];
432 }
433 for ch in 0..self.mode.get_channels() {
434 let off = abuf.get_offset(ch + self.start_ch);
435 let mut adata = abuf.get_abuf_f32().unwrap();
436 let output = adata.get_data_mut().unwrap();
437 let dst = &mut output[off..];
438
439 dsp.imdct.imdct(&self.block[ch], &mut dsp.out);
440
441 let prev_gain = dsp.pow_tab[(self.prev_gains[ch][0] + 64) as usize];
442 let mut cur_gain = 0.0;
443 let mut cur_gain2 = 0.0;
444 let mut gain_idx = 0;
445 let eighthmask = (self.samples >> 3) - 1;
446 for (i, out) in dst.iter_mut().take(self.samples).enumerate() {
447 *out = dsp.out[i + self.samples] * prev_gain * dsp.window[i]
448 - self.delay[ch][i] * dsp.window[self.samples - i - 1];
449 if (i & eighthmask) == 0 {
450 if (self.gains[ch][gain_idx] == 0) && (self.gains[ch][gain_idx + 1] == 0) {
451 cur_gain = 1.0;
452 cur_gain2 = 1.0;
453 } else {
454 cur_gain = dsp.pow_tab[(self.gains[ch][gain_idx] + 64) as usize];
455 cur_gain2 = dsp.gain_tab[(self.gains[ch][gain_idx + 1] - self.gains[ch][gain_idx] + 11) as usize];
456 }
457 gain_idx += 1;
458 }
459 *out *= cur_gain;
460 cur_gain *= cur_gain2;
461 }
462 for i in 0..self.samples { self.delay[ch][i] = dsp.out[i]; }
463 }
464 Ok(())
465 }
466 }
467
468 const COOK_VQ_GROUP_SIZE: [usize; 7] = [ 2, 2, 2, 4, 4, 5, 5 ];
469 const COOK_NUM_VQ_GROUPS: [usize; 7] = [ 10, 10, 10, 5, 5, 4, 4 ];
470 const COOK_VQ_INV_RADIX: [u32; 7] = [ 74899, 104858, 149797, 209716, 262144, 349526, 524288 ];
471 const COOK_VQ_MULT: [u32; 7] = [ 13, 9, 6, 4, 3, 2, 1 ];
472 fn unpack_band(br: &mut BitReader, codebooks: &Codebooks, coef_index: &mut [u8; BAND_SIZE], coef_sign: &mut [bool; BAND_SIZE], cat: usize) -> DecoderResult<()> {
473 let cb = &codebooks.vq_cb[cat];
474 let group_size = COOK_VQ_GROUP_SIZE[cat];
475 let mult = COOK_VQ_MULT[cat] + 1;
476 for i in 0..COOK_NUM_VQ_GROUPS[cat] {
477 let ret = br.read_cb(cb);
478 let mut val;
479 if let Ok(v) = ret {
480 val = v as u32;
481 } else {
482 let left = br.left() as u32;
483 br.skip(left)?;
484 break;
485 }
486 let mut nnz = 0;
487 for j in (0..group_size).rev() {
488 let t = (val * COOK_VQ_INV_RADIX[cat]) >> 20;
489 coef_index[i * group_size + j] = (val - t * mult) as u8;
490 if coef_index[i * group_size + j] != 0 {
491 nnz += 1;
492 }
493 val = t;
494 }
495 if (br.left() as usize) < nnz {
496 let left = br.left() as u32;
497 br.skip(left)?;
498 break;
499 }
500 for j in 0..group_size {
501 if coef_index[i * group_size + j] != 0 {
502 coef_sign[i * group_size + j] = br.read_bool()?;
503 } else {
504 coef_sign[i * group_size + j] = false;
505 }
506 }
507 }
508 Ok(())
509 }
510
511 struct RND {
512 state: u32,
513 }
514
515 impl RND {
516 fn new() -> Self {
517 Self { state: 0xC0DECC00 }
518 }
519 fn get_sign(&mut self) -> bool {
520 self.state = (self.state & 0xFFFF).wrapping_mul(36969).wrapping_add(self.state >> 16);
521 (self.state & 0x10000) != 0
522 }
523 }
524
525 struct CookDecoder {
526 info: Rc<NACodecInfo>,
527 chmap: NAChannelMap,
528 src: [u8; 65536],
529 num_pairs: usize,
530 pairs: [CookChannelPair; MAX_PAIRS],
531 channels: usize,
532 samples: usize,
533 codebooks: Codebooks,
534 rnd: RND,
535 dsp: CookDSP,
536 }
537
538 impl CookDecoder {
539 fn new() -> Self {
540 CookDecoder {
541 info: NACodecInfo::new_dummy(),
542 chmap: NAChannelMap::new(),
543 src: [0; 65536],
544 num_pairs: 0,
545 channels: 0,
546 samples: 0,
547 pairs: [CookChannelPair::new(); MAX_PAIRS],
548 codebooks: Codebooks::new(),
549 rnd: RND::new(),
550 dsp: CookDSP::new(1024),
551 }
552 }
553 }
554
555 impl NADecoder for CookDecoder {
556 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
557 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
558 let edata = info.get_extradata().unwrap();
559 validate!(edata.len() >= 4);
560
561 let mut mr = MemoryReader::new_read(&edata);
562 let mut br = ByteReader::new(&mut mr);
563 let ver = br.peek_u32be()?;
564
565 let maj_ver = ver >> 24;
566 let mut chmap: u32 = 0;
567 match maj_ver {
568 1 => {
569 self.num_pairs = 1;
570 self.pairs[0].read_hdr_v1(&mut br)?;
571 self.channels = self.pairs[0].mode.get_channels();
572 if ainfo.get_channels() == 1 { // forced mono
573 self.pairs[0].mode = Mode::Mono;
574 self.channels = 1;
575 chmap = 0x4;
576 } else {
577 chmap = 0x3;
578 }
579 },
580 2 => {
581 self.num_pairs = (edata.len() - (br.tell() as usize)) / 20;
582 validate!(self.num_pairs <= MAX_PAIRS);
583 let mut start_ch = 0;
584 for i in 0..self.num_pairs {
585 let pair_chmap = self.pairs[i].read_hdr_v2(&mut br)?;
586 self.pairs[i].start_ch = start_ch;
587 validate!((chmap & pair_chmap) == 0);
588 start_ch += self.pairs[i].mode.get_channels();
589 }
590 self.channels = start_ch;
591 },
592 _ => { return Err(DecoderError::InvalidData); }
593 };
594
595 self.samples = self.pairs[0].samples / self.pairs[0].mode.get_channels();
596 validate!((self.samples >= 16) && (self.samples <= 1024));
597 if self.samples != self.dsp.size {
598 self.dsp = CookDSP::new(self.samples);
599 }
600 self.chmap = NAChannelMap::from_ms_mapping(chmap);
601
602 for i in 1..self.num_pairs {
603 validate!((self.pairs[i].samples / self.pairs[i].mode.get_channels()) == self.samples);
604 }
605
606 let vector_bits = match self.samples {
607 16 | 32 | 64 | 128 | 256 => 5,
608 512 => 6,
609 1024 => 7,
610 _ => unreachable!(),
611 };
612 for pair in self.pairs.iter_mut() {
613 match pair.mode {
614 Mode::Mono => {
615 pair.vector_bits = 5;
616 },
617 Mode::Stereo => {
618 pair.vector_bits = 5;
619 pair.samples >>= 1;
620 },
621 Mode::JointStereo => {
622 pair.vector_bits = vector_bits;
623 pair.samples >>= 1;
624 },
625 };
626 }
627
628 let ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), self.channels as u8,
629 SND_F32P_FORMAT, self.samples);
630 self.info = info.replace_info(NACodecTypeInfo::Audio(ainfo));
631
632 Ok(())
633 } else {
634 Err(DecoderError::InvalidData)
635 }
636 }
637 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
638 let info = pkt.get_stream().get_info();
639 validate!(info.get_properties().is_audio());
640 let pktbuf = pkt.get_buffer();
641 validate!(pktbuf.len() > self.num_pairs * 2);
642
643 let mut seg_size: [usize; MAX_PAIRS] = [0; MAX_PAIRS];
644 let mut seg_start: [usize; MAX_PAIRS+1] = [0; MAX_PAIRS+1];
645
646 let ainfo = self.info.get_properties().get_audio_info().unwrap();
647
648 seg_size[0] = pktbuf.len() - (self.num_pairs - 1);
649 for i in 1..self.num_pairs {
650 seg_size[i] = (pktbuf[pktbuf.len() - self.num_pairs + i] as usize) * 2;
651 validate!(seg_size[i] != 0);
652 let ret = seg_size[0].checked_sub(seg_size[i]);
653 if let Some(val) = ret {
654 seg_size[0] = val;
655 } else {
656 return Err(DecoderError::InvalidData);
657 }
658 }
659 validate!(seg_size[0] != 0);
660 seg_start[0] = 0;
661 for i in 0..self.num_pairs {
662 seg_start[i + 1] = seg_start[i] + seg_size[i];
663 }
664
665 let mut abuf = alloc_audio_buffer(ainfo, self.samples, self.chmap.clone())?;
666
667 for pair in 0..self.num_pairs {
668 self.pairs[pair].decode(&mut self.dsp, &mut self.rnd, &self.codebooks, &pktbuf[seg_start[pair]..seg_start[pair + 1]], &mut self.src, &mut abuf)?;
669 }
670
671 let mut frm = NAFrame::new_from_pkt(pkt, self.info.replace_info(NACodecTypeInfo::Audio(ainfo)), abuf);
672 frm.set_keyframe(true);
673 Ok(Rc::new(RefCell::new(frm)))
674 }
675 }
676
677 pub fn get_decoder() -> Box<NADecoder> {
678 Box::new(CookDecoder::new())
679 }
680
681 #[cfg(test)]
682 mod test {
683 use nihav_core::codecs::RegisteredDecoders;
684 use nihav_core::demuxers::RegisteredDemuxers;
685 use nihav_core::test::dec_video::*;
686 use crate::codecs::realmedia_register_all_codecs;
687 use crate::demuxers::realmedia_register_all_demuxers;
688 #[test]
689 fn test_cook() {
690 let mut dmx_reg = RegisteredDemuxers::new();
691 realmedia_register_all_demuxers(&mut dmx_reg);
692 let mut dec_reg = RegisteredDecoders::new();
693 realmedia_register_all_codecs(&mut dec_reg);
694
695 // let file = "assets/RV/rv30_weighted_mc.rm";
696 let file = "assets/RV/multichannel.rma";
697 test_decode_audio("realmedia", file, Some(2000), "cook", &dmx_reg, &dec_reg);
698 }
699 }
700
701 const COOK_XOR_KEY: [u8; 4] = [ 0x37, 0xC5, 0x11, 0xF2 ];
702
703 const COOK_CPL_2BITS_BITS: &[u8; 3] = &[ 2, 1, 2 ];
704 const COOK_CPL_2BITS_CODES: &[u16; 3] = &[ 0x02, 0x00, 0x03 ];
705 const COOK_CPL_3BITS_BITS: &[u8; 7] = &[ 6, 5, 2, 1, 3, 4, 6 ];
706 const COOK_CPL_3BITS_CODES: &[u16; 7] = &[ 0x3e, 0x1e, 0x02, 0x00, 0x06, 0x0e, 0x3f ];
707 const COOK_CPL_4BITS_BITS: &[u8; 15] = &[ 8, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7, 8, 8 ];
708 const COOK_CPL_4BITS_CODES: &[u16; 15] = &[
709 0xfc, 0xfd, 0x7c, 0x3c, 0x1c, 0x0c, 0x04, 0x00,
710 0x05, 0x0d, 0x1d, 0x3d, 0x7d, 0xfe, 0xff
711 ];
712 const COOK_CPL_5BITS_BITS: &[u8; 31] = &[
713 10, 10, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 3, 1,
714 3, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 10, 10
715 ];
716 const COOK_CPL_5BITS_CODES: &[u16; 31] = &[
717 0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x01F8, 0x01F9, 0x00F8, 0x00F9,
718 0x0078, 0x0079, 0x0038, 0x0039, 0x0018, 0x0019, 0x0004, 0x0000,
719 0x0005, 0x001A, 0x001B, 0x003A, 0x003B, 0x007A, 0x007B, 0x00FA,
720 0x00FB, 0x01FA, 0x01FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF
721 ];
722 const COOK_CPL_6BITS_BITS: &[u8; 63] = &[
723 16, 15, 14, 13, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9,
724 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 5, 5, 3, 1,
725 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9,
726 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 13, 14, 14, 16
727 ];
728 const COOK_CPL_6BITS_CODES: &[u16; 63] = &[
729 0xFFFE, 0x7FFE, 0x3FFC, 0x1FFC, 0x0FFC, 0x07F6, 0x07F7, 0x07F8,
730 0x07F9, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x01F0, 0x01F1, 0x01F2,
731 0x01F3, 0x01F4, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x0070, 0x0071,
732 0x0072, 0x0073, 0x0034, 0x0035, 0x0016, 0x0017, 0x0004, 0x0000,
733 0x000A, 0x0018, 0x0019, 0x0036, 0x0037, 0x0074, 0x0075, 0x0076,
734 0x0077, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x01F5, 0x01F6, 0x01F7,
735 0x01F8, 0x03F6, 0x03F7, 0x03F8, 0x03F9, 0x03FA, 0x07FA, 0x07FB,
736 0x07FC, 0x07FD, 0x0FFD, 0x1FFD, 0x3FFD, 0x3FFE, 0xFFFF
737 ];
738
739 const COOK_QUANT_BITS: [&[u8; 24]; 13] = [
740 &[ 4, 6, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 5, 7, 8, 9, 11, 11, 12, 12, 12, 12 ],
741 &[ 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 7, 9, 11, 12, 13, 15, 15, 15, 16, 16 ],
742 &[ 12, 10, 8, 6, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 4, 5, 5, 7, 9, 11, 13, 14, 14 ],
743 &[ 13, 10, 9, 9, 7, 7, 5, 5, 4, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7, 9, 11, 13, 13, 13 ],
744 &[ 12, 13, 10, 8, 6, 6, 5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 6, 7, 9, 11, 14, 14 ],
745 &[ 12, 11, 9, 8, 8, 7, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5, 7, 8, 10, 13, 14, 14 ],
746 &[ 15, 16, 15, 12, 10, 8, 6, 5, 4, 3, 3, 3, 2, 3, 4, 5, 5, 7, 9, 11, 13, 16, 16, 16 ],
747 &[ 14, 14, 11, 10, 9, 7, 7, 5, 5, 4, 3, 3, 2, 3, 3, 4, 5, 7, 9, 9, 12, 14, 15, 15 ],
748 &[ 9, 9, 9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 13 ],
749 &[ 14, 12, 10, 8, 6, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 8, 8, 9, 11, 14, 14, 14 ],
750 &[ 13, 10, 9, 8, 6, 6, 5, 4, 4, 4, 3, 3, 2, 3, 4, 5, 6, 8, 9, 9, 11, 12, 14, 14 ],
751 &[ 16, 13, 12, 11, 9, 6, 5, 5, 4, 4, 4, 3, 2, 3, 3, 4, 5, 7, 8, 10, 14, 16, 16, 16 ],
752 &[ 13, 14, 14, 14, 10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9, 11, 14, 14, 14 ],
753 ];
754 const COOK_QUANT_CODES: [&[u16; 24]; 13] = [
755 &[ 0x0006, 0x003e, 0x001c, 0x001d, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x0000, 0x0001,
756 0x0002, 0x000d, 0x001e, 0x007e, 0x00fe, 0x01fe, 0x07fc, 0x07fd, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff ],
757 &[ 0x03fe, 0x00fe, 0x003e, 0x001c, 0x001d, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
758 0x000d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x0ffe, 0x1ffe, 0x7ffc, 0x7ffd, 0x7ffe, 0xfffe, 0xffff ],
759 &[ 0x0ffe, 0x03fe, 0x00fe, 0x003e, 0x001c, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x0000,
760 0x0001, 0x0002, 0x000c, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffe, 0x3ffe, 0x3fff ],
761 &[ 0x1ffc, 0x03fe, 0x01fc, 0x01fd, 0x007c, 0x007d, 0x001c, 0x001d, 0x000a, 0x0000, 0x0001, 0x0002,
762 0x0003, 0x0004, 0x000b, 0x000c, 0x000d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffd, 0x1ffe, 0x1fff ],
763 &[ 0x0ffe, 0x1ffe, 0x03fe, 0x00fe, 0x003c, 0x003d, 0x001a, 0x001b, 0x000a, 0x000b, 0x0000, 0x0001,
764 0x0002, 0x0003, 0x0004, 0x000c, 0x001c, 0x001d, 0x003e, 0x007e, 0x01fe, 0x07fe, 0x3ffe, 0x3fff ],
765 &[ 0x0ffe, 0x07fe, 0x01fe, 0x00fc, 0x00fd, 0x007c, 0x001c, 0x000a, 0x000b, 0x0000, 0x0001, 0x0002,
766 0x0003, 0x0004, 0x000c, 0x000d, 0x001d, 0x001e, 0x007d, 0x00fe, 0x03fe, 0x1ffe, 0x3ffe, 0x3fff ],
767 &[ 0x7ffc, 0xfffc, 0x7ffd, 0x0ffe, 0x03fe, 0x00fe, 0x003e, 0x001c, 0x000c, 0x0002, 0x0003, 0x0004,
768 0x0000, 0x0005, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffe, 0xfffd, 0xfffe, 0xffff ],
769 &[ 0x3ffc, 0x3ffd, 0x07fe, 0x03fe, 0x01fc, 0x007c, 0x007d, 0x001c, 0x001d, 0x000c, 0x0002, 0x0003,
770 0x0000, 0x0004, 0x0005, 0x000d, 0x001e, 0x007e, 0x01fd, 0x01fe, 0x0ffe, 0x3ffe, 0x7ffe, 0x7fff ],
771 &[ 0x01fc, 0x01fd, 0x01fe, 0x00fc, 0x007c, 0x003c, 0x001c, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003,
772 0x0004, 0x0005, 0x000d, 0x001d, 0x003d, 0x007d, 0x00fd, 0x03fe, 0x07fe, 0x0ffe, 0x1ffe, 0x1fff ],
773 &[ 0x3ffc, 0x0ffe, 0x03fe, 0x00fc, 0x003c, 0x003d, 0x001c, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003,
774 0x0004, 0x0005, 0x000d, 0x001d, 0x003e, 0x00fd, 0x00fe, 0x01fe, 0x07fe, 0x3ffd, 0x3ffe, 0x3fff ],
775 &[ 0x1ffe, 0x03fe, 0x01fc, 0x00fc, 0x003c, 0x003d, 0x001c, 0x000a, 0x000b, 0x000c, 0x0002, 0x0003,
776 0x0000, 0x0004, 0x000d, 0x001d, 0x003e, 0x00fd, 0x01fd, 0x01fe, 0x07fe, 0x0ffe, 0x3ffe, 0x3fff ],
777 &[ 0xfffc, 0x1ffe, 0x0ffe, 0x07fe, 0x01fe, 0x003e, 0x001c, 0x001d, 0x000a, 0x000b, 0x000c, 0x0002,
778 0x0000, 0x0003, 0x0004, 0x000d, 0x001e, 0x007e, 0x00fe, 0x03fe, 0x3ffe, 0xfffd, 0xfffe, 0xffff ],
779 &[ 0x1ffc, 0x3ffa, 0x3ffb, 0x3ffc, 0x03fe, 0x00fe, 0x007c, 0x007d, 0x001c, 0x000c, 0x0002, 0x0003,
780 0x0000, 0x0004, 0x0005, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x3ffd, 0x3ffe, 0x3fff ],
781 ];
782
783 const COOK_VQ0_BITS: &[u8; 191] = &[
784 1, 4, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10,
785 11, 11, 4, 5, 6, 7, 7, 8, 8, 9, 9, 9,
786 9, 10, 11, 11, 5, 6, 7, 8, 8, 9, 9, 9,
787 9, 10, 10, 10, 11, 12, 6, 7, 8, 9, 9, 9,
788 9, 10, 10, 10, 10, 11, 12, 13, 7, 7, 8, 9,
789 9, 9, 10, 10, 10, 10, 11, 11, 12, 13, 8, 8,
790 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 13, 14,
791 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13,
792 13, 15, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12,
793 12, 13, 14, 15, 9, 9, 9, 10, 10, 10, 11, 11,
794 12, 13, 12, 14, 15, 16, 9, 9, 10, 10, 10, 10,
795 11, 12, 12, 14, 14, 16, 16, 0, 9, 9, 10, 10,
796 11, 11, 12, 13, 13, 14, 14, 15, 0, 0, 10, 10,
797 10, 11, 11, 12, 12, 13, 15, 15, 16, 0, 0, 0,
798 11, 11, 11, 12, 13, 13, 13, 15, 16, 16, 0, 0,
799 0, 0, 11, 11, 12, 13, 13, 14, 15, 16, 16
800 ];
801 const COOK_VQ0_CODES: &[u16; 191] = &[
802 0x0000, 0x0008, 0x002c, 0x002d, 0x0062, 0x0063, 0x00d4, 0x00d5,
803 0x00d6, 0x01c6, 0x01c7, 0x03ca, 0x07d6, 0x07d7, 0x0009, 0x0014,
804 0x002e, 0x0064, 0x0065, 0x00d7, 0x00d8, 0x01c8, 0x01c9, 0x01ca,
805 0x01cb, 0x03cb, 0x07d8, 0x07d9, 0x0015, 0x002f, 0x0066, 0x00d9,
806 0x00da, 0x01cc, 0x01cd, 0x01ce, 0x01cf, 0x03cc, 0x03cd, 0x03ce,
807 0x07da, 0x0fe4, 0x0030, 0x0067, 0x00db, 0x01d0, 0x01d1, 0x01d2,
808 0x01d3, 0x03cf, 0x03d0, 0x03d1, 0x03d2, 0x07db, 0x0fe5, 0x1fea,
809 0x0068, 0x0069, 0x00dc, 0x01d4, 0x01d5, 0x01d6, 0x03d3, 0x03d4,
810 0x03d5, 0x03d6, 0x07dc, 0x07dd, 0x0fe6, 0x1feb, 0x00dd, 0x00de,
811 0x01d7, 0x01d8, 0x01d9, 0x03d7, 0x03d8, 0x03d9, 0x03da, 0x07de,
812 0x07df, 0x0fe7, 0x1fec, 0x3ff2, 0x00df, 0x00e0, 0x01da, 0x01db,
813 0x03db, 0x03dc, 0x07e0, 0x07e1, 0x07e2, 0x0fe8, 0x0fe9, 0x1fed,
814 0x1fee, 0x7ff4, 0x00e1, 0x00e2, 0x01dc, 0x01dd, 0x03dd, 0x03de,
815 0x07e3, 0x07e4, 0x07e5, 0x0fea, 0x0feb, 0x1fef, 0x3ff3, 0x7ff5,
816 0x01de, 0x01df, 0x01e0, 0x03df, 0x03e0, 0x03e1, 0x07e6, 0x07e7,
817 0x0fec, 0x1ff0, 0x0fed, 0x3ff4, 0x7ff6, 0xfff8, 0x01e1, 0x01e2,
818 0x03e2, 0x03e3, 0x03e4, 0x03e5, 0x07e8, 0x0fee, 0x0fef, 0x3ff5,
819 0x3ff6, 0xfff9, 0xfffa, 0xfffa, 0x01e3, 0x01e4, 0x03e6, 0x03e7,
820 0x07e9, 0x07ea, 0x0ff0, 0x1ff1, 0x1ff2, 0x3ff7, 0x3ff8, 0x7ff7,
821 0x7ff7, 0xfffa, 0x03e8, 0x03e9, 0x03ea, 0x07eb, 0x07ec, 0x0ff1,
822 0x0ff2, 0x1ff3, 0x7ff8, 0x7ff9, 0xfffb, 0x3ff8, 0x7ff7, 0x7ff7,
823 0x07ed, 0x07ee, 0x07ef, 0x0ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x7ffa,
824 0xfffc, 0xfffd, 0xfffb, 0xfffb, 0x3ff8, 0x7ff7, 0x07f0, 0x07f1,
825 0x0ff4, 0x1ff7, 0x1ff8, 0x3ff9, 0x7ffb, 0xfffe, 0xffff
826 ];
827 const COOK_VQ1_BITS: &[u8; 97] = &[
828 1, 4, 5, 6, 7, 8, 8, 9, 10, 10, 4, 5,
829 6, 7, 7, 8, 8, 9, 9, 11, 5, 5, 6, 7,
830 8, 8, 9, 9, 10, 11, 6, 6, 7, 8, 8, 9,
831 9, 10, 11, 12, 7, 7, 8, 8, 9, 9, 10, 11,
832 11, 13, 8, 8, 8, 9, 9, 10, 10, 11, 12, 14,
833 8, 8, 8, 9, 10, 11, 11, 12, 13, 15, 9, 9,
834 9, 10, 11, 12, 12, 14, 14, 0, 9, 9, 9, 10,
835 11, 12, 14, 16, 0, 0, 10, 10, 11, 12, 13, 14, 16
836 ];
837 const COOK_VQ1_CODES: &[u16; 97] = &[
838 0x0000, 0x0008, 0x0014, 0x0030, 0x006a, 0x00e2, 0x00e3, 0x01e4,
839 0x03ec, 0x03ed, 0x0009, 0x0015, 0x0031, 0x006b, 0x006c, 0x00e4,
840 0x00e5, 0x01e5, 0x01e6, 0x07f0, 0x0016, 0x0017, 0x0032, 0x006d,
841 0x00e6, 0x00e7, 0x01e7, 0x01e8, 0x03ee, 0x07f1, 0x0033, 0x0034,
842 0x006e, 0x00e8, 0x00e9, 0x01e9, 0x01ea, 0x03ef, 0x07f2, 0x0ff6,
843 0x006f, 0x0070, 0x00ea, 0x00eb, 0x01eb, 0x01ec, 0x03f0, 0x07f3,
844 0x07f4, 0x1ffa, 0x00ec, 0x00ed, 0x00ee, 0x01ed, 0x01ee, 0x03f1,
845 0x03f2, 0x07f5, 0x0ff7, 0x3ffa, 0x00ef, 0x00f0, 0x00f1, 0x01ef,
846 0x03f3, 0x07f6, 0x07f7, 0x0ff8, 0x1ffb, 0x7ffe, 0x01f0, 0x01f1,
847 0x01f2, 0x03f4, 0x07f8, 0x0ff9, 0x0ffa, 0x3ffb, 0x3ffc, 0x0000,
848 0x01f3, 0x01f4, 0x01f5, 0x03f5, 0x07f9, 0x0ffb, 0x3ffd, 0xfffe,
849 0x0000, 0x0000, 0x03f6, 0x03f7, 0x07fa, 0x0ffc, 0x1ffc, 0x3ffe,
850 0xffff
851 ];
852 const COOK_VQ2_BITS: &[u8; 48] = &[
853 1, 4, 5, 7, 8, 9, 10, 3, 4, 5, 7, 8,
854 9, 10, 5, 5, 6, 7, 8, 10, 10, 7, 6, 7,
855 8, 9, 10, 12, 8, 8, 8, 9, 10, 12, 14, 8,
856 9, 9, 10, 11, 15, 16, 9, 10, 11, 12, 13, 16
857 ];
858 const COOK_VQ2_CODES: &[u16; 48] = &[
859 0x0000, 0x000a, 0x0018, 0x0074, 0x00f2, 0x01f4, 0x03f6, 0x0004, 0x000b, 0x0019, 0x0075, 0x00f3,
860 0x01f5, 0x03f7, 0x001a, 0x001b, 0x0038, 0x0076, 0x00f4, 0x03f8, 0x03f9, 0x0077, 0x0039, 0x0078,
861 0x00f5, 0x01f6, 0x03fa, 0x0ffc, 0x00f6, 0x00f7, 0x00f8, 0x01f7, 0x03fb, 0x0ffd, 0x3ffe, 0x00f9,
862 0x01f8, 0x01f9, 0x03fc, 0x07fc, 0x7ffe, 0xfffe, 0x01fa, 0x03fd, 0x07fd, 0x0ffe, 0x1ffe, 0xffff
863 ];
864 const COOK_VQ3_BITS: &[u8; 607] = &[
865 2, 4, 6, 8, 10, 5, 5, 6, 8, 10, 7, 8,
866 8, 10, 12, 9, 9, 10, 12, 15, 10, 11, 13, 16,
867 16, 5, 6, 8, 10, 11, 5, 6, 8, 10, 12, 7,
868 7, 8, 10, 13, 9, 9, 10, 12, 15, 12, 11, 13,
869 16, 16, 7, 9, 10, 12, 15, 7, 8, 10, 12, 13,
870 9, 9, 11, 13, 16, 11, 11, 12, 14, 16, 12, 12,
871 14, 16, 0, 9, 11, 12, 16, 16, 9, 10, 13, 15,
872 16, 10, 11, 12, 16, 16, 13, 13, 16, 16, 16, 16,
873 16, 15, 16, 0, 11, 13, 16, 16, 15, 11, 13, 15,
874 16, 16, 13, 13, 16, 16, 0, 14, 16, 16, 16, 0,
875 16, 16, 0, 0, 0, 4, 6, 8, 10, 13, 6, 6,
876 8, 10, 13, 9, 8, 10, 12, 16, 10, 10, 11, 15,
877 16, 13, 12, 14, 16, 16, 5, 6, 8, 11, 13, 6,
878 6, 8, 10, 13, 8, 8, 9, 11, 14, 10, 10, 12,
879 12, 16, 13, 12, 13, 15, 16, 7, 8, 9, 12, 16,
880 7, 8, 10, 12, 14, 9, 9, 10, 13, 16, 11, 10,
881 12, 15, 16, 13, 13, 16, 16, 0, 9, 11, 13, 16,
882 16, 9, 10, 12, 15, 16, 10, 11, 13, 16, 16, 13,
883 12, 16, 16, 16, 16, 16, 16, 16, 0, 11, 13, 16,
884 16, 16, 11, 13, 16, 16, 16, 12, 13, 15, 16, 0,
885 16, 16, 16, 16, 0, 16, 16, 0, 0, 0, 6, 8,
886 11, 13, 16, 8, 8, 10, 12, 16, 11, 10, 11, 13,
887 16, 12, 13, 13, 15, 16, 16, 16, 14, 16, 0, 6,
888 8, 10, 13, 16, 8, 8, 10, 12, 16, 10, 10, 11,
889 13, 16, 13, 12, 13, 16, 16, 14, 14, 14, 16, 0,
890 8, 9, 11, 13, 16, 8, 9, 11, 16, 14, 10, 10,
891 12, 15, 16, 12, 12, 13, 16, 16, 15, 16, 16, 16,
892 0, 10, 12, 15, 16, 16, 10, 12, 12, 14, 16, 12,
893 12, 13, 16, 16, 14, 15, 16, 16, 0, 16, 16, 16,
894 0, 0, 12, 15, 15, 16, 0, 13, 13, 16, 16, 0,
895 14, 16, 16, 16, 0, 16, 16, 16, 0, 0, 0, 0,
896 0, 0, 0, 8, 10, 13, 15, 16, 10, 11, 13, 16,
897 16, 13, 13, 14, 16, 16, 16, 16, 16, 16, 16, 16,
898 16, 16, 16, 0, 8, 10, 11, 15, 16, 9, 10, 12,
899 16, 16, 12, 12, 15, 16, 16, 16, 14, 16, 16, 16,
900 16, 16, 16, 16, 0, 9, 11, 14, 16, 16, 10, 11,
901 13, 16, 16, 14, 13, 14, 16, 16, 16, 15, 15, 16,
902 0, 16, 16, 16, 0, 0, 11, 13, 16, 16, 16, 11,
903 13, 15, 16, 16, 13, 16, 16, 16, 0, 16, 16, 16,
904 16, 0, 16, 16, 0, 0, 0, 15, 16, 16, 16, 0,
905 14, 16, 16, 16, 0, 16, 16, 16, 0, 0, 16, 16,
906 0, 0, 0, 0, 0, 0, 0, 0, 9, 13, 16, 16,
907 16, 11, 13, 16, 16, 16, 14, 15, 16, 16, 0, 15,
908 16, 16, 16, 0, 16, 16, 0, 0, 0, 9, 13, 15,
909 15, 16, 12, 13, 14, 16, 16, 16, 15, 16, 16, 0,
910 16, 16, 16, 16, 0, 16, 16, 0, 0, 0, 11, 13,
911 15, 16, 0, 12, 14, 16, 16, 0, 16, 16, 16, 16,
912 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16,
913 16, 16, 16, 0, 16, 16, 16, 16, 0, 16, 16, 16,
914 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0,
915 16, 16, 0, 0, 0, 16, 16
916 ];
917 const COOK_VQ3_CODES: &[u16; 607] = &[
918 0x0000, 0x0004, 0x0022, 0x00c6, 0x03b0, 0x000c, 0x000d, 0x0023, 0x00c7, 0x03b1, 0x005c, 0x00c8,
919 0x00c9, 0x03b2, 0x0fa4, 0x01c2, 0x01c3, 0x03b3, 0x0fa5, 0x7f72, 0x03b4, 0x07b2, 0x1f9a, 0xff24,
920 0xff25, 0x000e, 0x0024, 0x00ca, 0x03b5, 0x07b3, 0x000f, 0x0025, 0x00cb, 0x03b6, 0x0fa6, 0x005d,
921 0x005e, 0x00cc, 0x03b7, 0x1f9b, 0x01c4, 0x01c5, 0x03b8, 0x0fa7, 0x7f73, 0x0fa8, 0x07b4, 0x1f9c,
922 0xff26, 0xff27, 0x005f, 0x01c6, 0x03b9, 0x0fa9, 0x7f74, 0x0060, 0x00cd, 0x03ba, 0x0faa, 0x1f9d,
923 0x01c7, 0x01c8, 0x07b5, 0x1f9e, 0xff28, 0x07b6, 0x07b7, 0x0fab, 0x3fa2, 0xff29, 0x0fac, 0x0fad,
924 0x3fa3, 0xff2a, 0x3fa2, 0x01c9, 0x07b8, 0x0fae, 0xff2b, 0xff2c, 0x01ca, 0x03bb, 0x1f9f, 0x7f75,
925 0xff2d, 0x03bc, 0x07b9, 0x0faf, 0xff2e, 0xff2f, 0x1fa0, 0x1fa1, 0xff30, 0xff31, 0xff32, 0xff33,
926 0xff34, 0x7f76, 0xff35, 0xff31, 0x07ba, 0x1fa2, 0xff36, 0xff37, 0x7f77, 0x07bb, 0x1fa3, 0x7f78,
927 0xff38, 0xff39, 0x1fa4, 0x1fa5, 0xff3a, 0xff3b, 0xff2e, 0x3fa4, 0xff3c, 0xff3d, 0xff3e, 0xff31,
928 0xff3f, 0xff40, 0xff30, 0xff31, 0xff31, 0x0005, 0x0026, 0x00ce, 0x03bd, 0x1fa6, 0x0027, 0x0028,
929 0x00cf, 0x03be, 0x1fa7, 0x01cb, 0x00d0, 0x03bf, 0x0fb0, 0xff41, 0x03c0, 0x03c1, 0x07bc, 0x7f79,
930 0xff42, 0x1fa8, 0x0fb1, 0x3fa5, 0xff43, 0xff44, 0x0010, 0x0029, 0x00d1, 0x07bd, 0x1fa9, 0x002a,
931 0x002b, 0x00d2, 0x03c2, 0x1faa, 0x00d3, 0x00d4, 0x01cc, 0x07be, 0x3fa6, 0x03c3, 0x03c4, 0x0fb2,
932 0x0fb3, 0xff45, 0x1fab, 0x0fb4, 0x1fac, 0x7f7a, 0xff46, 0x0061, 0x00d5, 0x01cd, 0x0fb5, 0xff47,
933 0x0062, 0x00d6, 0x03c5, 0x0fb6, 0x3fa7, 0x01ce, 0x01cf, 0x03c6, 0x1fad, 0xff48, 0x07bf, 0x03c7,
934 0x0fb7, 0x7f7b, 0xff49, 0x1fae, 0x1faf, 0xff4a, 0xff4b, 0x7f7b, 0x01d0, 0x07c0, 0x1fb0, 0xff4c,
935 0xff4d, 0x01d1, 0x03c8, 0x0fb8, 0x7f7c, 0xff4e, 0x03c9, 0x07c1, 0x1fb1, 0xff4f, 0xff50, 0x1fb2,
936 0x0fb9, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff52, 0x07c2, 0x1fb3, 0xff58,
937 0xff59, 0xff5a, 0x07c3, 0x1fb4, 0xff5b, 0xff5c, 0xff5d, 0x0fba, 0x1fb5, 0x7f7d, 0xff5e, 0xff4f,
938 0xff5f, 0xff60, 0xff61, 0xff62, 0xff52, 0xff63, 0xff64, 0xff51, 0xff52, 0xff52, 0x002c, 0x00d7,
939 0x07c4, 0x1fb6, 0xff65, 0x00d8, 0x00d9, 0x03ca, 0x0fbb, 0xff66, 0x07c5, 0x03cb, 0x07c6, 0x1fb7,
940 0xff67, 0x0fbc, 0x1fb8, 0x1fb9, 0x7f7e, 0xff68, 0xff69, 0xff6a, 0x3fa8, 0xff6b, 0x7f7e, 0x002d,
941 0x00da, 0x03cc, 0x1fba, 0xff6c, 0x00db, 0x00dc, 0x03cd, 0x0fbd, 0xff6d, 0x03ce, 0x03cf, 0x07c7,
942 0x1fbb, 0xff6e, 0x1fbc, 0x0fbe, 0x1fbd, 0xff6f, 0xff70, 0x3fa9, 0x3faa, 0x3fab, 0xff71, 0xff6f,
943 0x00dd, 0x01d2, 0x07c8, 0x1fbe, 0xff72, 0x00de, 0x01d3, 0x07c9, 0xff73, 0x3fac, 0x03d0, 0x03d1,
944 0x0fbf, 0x7f7f, 0xff74, 0x0fc0, 0x0fc1, 0x1fbf, 0xff75, 0xff76, 0x7f80, 0xff77, 0xff78, 0xff79,
945 0xff75, 0x03d2, 0x0fc2, 0x7f81, 0xff7a, 0xff7b, 0x03d3, 0x0fc3, 0x0fc4, 0x3fad, 0xff7c, 0x0fc5,
946 0x0fc6, 0x1fc0, 0xff7d, 0xff7e, 0x3fae, 0x7f82, 0xff7f, 0xff80, 0xff80, 0xff81, 0xff82, 0xff83,
947 0xff80, 0xff80, 0x0fc7, 0x7f83, 0x7f84, 0xff84, 0xff7a, 0x1fc1, 0x1fc2, 0xff85, 0xff86, 0x3fad,
948 0x3faf, 0xff87, 0xff88, 0xff89, 0xff7d, 0xff8a, 0xff8b, 0xff8c, 0xff80, 0xff80, 0x3fae, 0x7f82,
949 0xff7f, 0xff80, 0xff80, 0x00df, 0x03d4, 0x1fc3, 0x7f85, 0xff8d, 0x03d5, 0x07ca, 0x1fc4, 0xff8e,
950 0xff8f, 0x1fc5, 0x1fc6, 0x3fb0, 0xff90, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97,
951 0xff98, 0xff99, 0xff9a, 0xff95, 0x00e0, 0x03d6, 0x07cb, 0x7f86, 0xff9b, 0x01d4, 0x03d7, 0x0fc8,
952 0xff9c, 0xff9d, 0x0fc9, 0x0fca, 0x7f87, 0xff9e, 0xff9f, 0xffa0, 0x3fb1, 0xffa1, 0xffa2, 0xffa3,
953 0xffa4, 0xffa5, 0xffa6, 0xffa7, 0xffa2, 0x01d5, 0x07cc, 0x3fb2, 0xffa8, 0xffa9, 0x03d8, 0x07cd,
954 0x1fc7, 0xffaa, 0xffab, 0x3fb3, 0x1fc8, 0x3fb4, 0xffac, 0xffad, 0xffae, 0x7f88, 0x7f89, 0xffaf,
955 0xffaf, 0xffb0, 0xffb1, 0xffb2, 0xffaf, 0xffaf, 0x07ce, 0x1fc9, 0xffb3, 0xffb4, 0xffb5, 0x07cf,
956 0x1fca, 0x7f8a, 0xffb6, 0xffb7, 0x1fcb, 0xffb8, 0xffb9, 0xffba, 0xffba, 0xffbb, 0xffbc, 0xffbd,
957 0xffbe, 0xffbe, 0xffbf, 0xffc0, 0xffbd, 0xffbe, 0xffbe, 0x7f8b, 0xffc1, 0xffc2, 0xffc3, 0xffb4,
958 0x3fb5, 0xffc4, 0xffc5, 0xffc6, 0xffb6, 0xffc7, 0xffc8, 0xffc9, 0xffba, 0xffba, 0xffca, 0xffcb,
959 0xffbd, 0xffbe, 0xffbe, 0xffbb, 0xffbc, 0xffbd, 0xffbe, 0xffbe, 0x01d6, 0x1fcc, 0xffcc, 0xffcd,
960 0xffce, 0x07d0, 0x1fcd, 0xffcf, 0xffd0, 0xffd1, 0x3fb6, 0x7f8c, 0xffd2, 0xffd3, 0xff90, 0x7f8d,
961 0xffd4, 0xffd5, 0xffd6, 0xff95, 0xffd7, 0xffd8, 0xff94, 0xff95, 0xff95, 0x01d7, 0x1fce, 0x7f8e,
962 0x7f8f, 0xffd9, 0x0fcb, 0x1fcf, 0x3fb7, 0xffda, 0xffdb, 0xffdc, 0x7f90, 0xffdd, 0xffde, 0xff9e,
963 0xffdf, 0xffe0, 0xffe1, 0xffe2, 0xffa2, 0xffe3, 0xffe4, 0xffa1, 0xffa2, 0xffa2, 0x07d1, 0x1fd0,
964 0x7f91, 0xffe5, 0xffa8, 0x0fcc, 0x3fb8, 0xffe6, 0xffe7, 0xffaa, 0xffe8, 0xffe9, 0xffea, 0xffeb,
965 0xffac, 0xffec, 0xffed, 0xffee, 0xffaf, 0xffaf, 0xffae, 0x7f88, 0x7f89, 0xffaf, 0xffaf, 0xffef,
966 0xfff0, 0xfff1, 0xfff2, 0xffb4, 0xfff3, 0xfff4, 0xfff5, 0xfff6, 0xffb6, 0xfff7, 0xfff8, 0xfff9,
967 0xffba, 0xffba, 0xfffa, 0xfffb, 0xffbd, 0xffbe, 0xffbe, 0xffbb, 0xffbc, 0xffbd, 0xffbe, 0xffbe,
968 0xfffc, 0xfffd, 0xffb3, 0xffb4, 0xffb4, 0xfffe, 0xffff
969 ];
970 const COOK_VQ4_BITS: &[u8; 246] = &[
971 2, 4, 7, 10, 4, 5, 7, 10, 7, 8, 10, 14,
972 11, 11, 15, 15, 4, 5, 9, 12, 5, 5, 8, 12,
973 8, 7, 10, 15, 11, 11, 15, 15, 7, 9, 12, 15,
974 8, 8, 12, 15, 10, 10, 13, 15, 14, 14, 15, 0,
975 11, 13, 15, 15, 11, 13, 15, 15, 14, 15, 15, 0,
976 15, 15, 0, 0, 4, 5, 9, 13, 5, 6, 9, 13,
977 9, 9, 11, 15, 14, 13, 15, 15, 4, 6, 9, 12,
978 5, 6, 9, 13, 9, 8, 11, 15, 13, 12, 15, 15,
979 7, 9, 12, 15, 7, 8, 11, 15, 10, 10, 14, 15,
980 14, 15, 15, 0, 10, 12, 15, 15, 11, 13, 15, 15,
981 15, 15, 15, 0, 15, 15, 0, 0, 6, 9, 13, 14,
982 8, 9, 12, 15, 12, 12, 15, 15, 15, 15, 15, 0,
983 7, 9, 13, 15, 8, 9, 12, 15, 11, 12, 15, 15,
984 15, 15, 15, 0, 9, 11, 15, 15, 9, 11, 15, 15,
985 14, 14, 15, 0, 15, 15, 0, 0, 14, 15, 15, 0,
986 14, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0,
987 9, 12, 15, 15, 12, 13, 15, 15, 15, 15, 15, 0,
988 15, 15, 0, 0, 10, 12, 15, 15, 12, 14, 15, 15,
989 15, 15, 15, 0, 15, 15, 0, 0, 14, 15, 15, 0,
990 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0,
991 15, 15, 0, 0, 15, 15
992 ];
993 const COOK_VQ4_CODES: &[u16; 246] = &[
994 0x0000, 0x0004, 0x006c, 0x03e6, 0x0005, 0x0012, 0x006d, 0x03e7, 0x006e, 0x00e8, 0x03e8, 0x3fc4,
995 0x07e0, 0x07e1, 0x7fa4, 0x7fa5, 0x0006, 0x0013, 0x01e2, 0x0fda, 0x0014, 0x0015, 0x00e9, 0x0fdb,
996 0x00ea, 0x006f, 0x03e9, 0x7fa6, 0x07e2, 0x07e3, 0x7fa7, 0x7fa8, 0x0070, 0x01e3, 0x0fdc, 0x7fa9,
997 0x00eb, 0x00ec, 0x0fdd, 0x7faa, 0x03ea, 0x03eb, 0x1fd6, 0x7fab, 0x3fc5, 0x3fc6, 0x7fac, 0x1fd6,
998 0x07e4, 0x1fd7, 0x7fad, 0x7fae, 0x07e5, 0x1fd8, 0x7faf, 0x7fb0, 0x3fc7, 0x7fb1, 0x7fb2, 0x1fd6,
999 0x7fb3, 0x7fb4, 0x1fd6, 0x1fd6, 0x0007, 0x0016, 0x01e4, 0x1fd9, 0x0017, 0x0032, 0x01e5, 0x1fda,
1000 0x01e6, 0x01e7, 0x07e6, 0x7fb5, 0x3fc8, 0x1fdb, 0x7fb6, 0x7fb7, 0x0008, 0x0033, 0x01e8, 0x0fde,
1001 0x0018, 0x0034, 0x01e9, 0x1fdc, 0x01ea, 0x00ed, 0x07e7, 0x7fb8, 0x1fdd, 0x0fdf, 0x7fb9, 0x7fba,
1002 0x0071, 0x01eb, 0x0fe0, 0x7fbb, 0x0072, 0x00ee, 0x07e8, 0x7fbc, 0x03ec, 0x03ed, 0x3fc9, 0x7fbd,
1003 0x3fca, 0x7fbe, 0x7fbf, 0x3fc9, 0x03ee, 0x0fe1, 0x7fc0, 0x7fc1, 0x07e9, 0x1fde, 0x7fc2, 0x7fc3,
1004 0x7fc4, 0x7fc5, 0x7fc6, 0x3fc9, 0x7fc7, 0x7fc8, 0x3fc9, 0x3fc9, 0x0035, 0x01ec, 0x1fdf, 0x3fcb,
1005 0x00ef, 0x01ed, 0x0fe2, 0x7fc9, 0x0fe3, 0x0fe4, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fca,
1006 0x0073, 0x01ee, 0x1fe0, 0x7fcf, 0x00f0, 0x01ef, 0x0fe5, 0x7fd0, 0x07ea, 0x0fe6, 0x7fd1, 0x7fd2,
1007 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd1, 0x01f0, 0x07eb, 0x7fd6, 0x7fd7, 0x01f1, 0x07ec, 0x7fd8, 0x7fd9,
1008 0x3fcc, 0x3fcd, 0x7fda, 0x7fda, 0x7fdb, 0x7fdc, 0x7fda, 0x7fda, 0x3fce, 0x7fdd, 0x7fde, 0x7fd6,
1009 0x3fcf, 0x7fdf, 0x7fe0, 0x7fd8, 0x7fe1, 0x7fe2, 0x7fda, 0x7fda, 0x3fcc, 0x3fcd, 0x7fda, 0x7fda,
1010 0x01f2, 0x0fe7, 0x7fe3, 0x7fe4, 0x0fe8, 0x1fe1, 0x7fe5, 0x7fe6, 0x7fe7, 0x7fe8, 0x7fe9, 0x7fca,
1011 0x7fea, 0x7feb, 0x7fca, 0x7fca, 0x03ef, 0x0fe9, 0x7fec, 0x7fed, 0x0fea, 0x3fd0, 0x7fee, 0x7fef,
1012 0x7ff0, 0x7ff1, 0x7ff2, 0x7fd1, 0x7ff3, 0x7ff4, 0x7fd1, 0x7fd1, 0x3fd1, 0x7ff5, 0x7ff6, 0x7fd6,
1013 0x7ff7, 0x7ff8, 0x7ff9, 0x7fd8, 0x7ffa, 0x7ffb, 0x7fda, 0x7fda, 0x3fcc, 0x3fcd, 0x7fda, 0x7fda,
1014 0x7ffc, 0x7ffd, 0x7fd6, 0x7fd6, 0x7ffe, 0x7fff
1015 ];
1016 const COOK_VQ5_BITS: &[u8; 230] = &[
1017 2, 4, 8, 4, 5, 9, 9, 10, 14, 4, 6, 11,
1018 5, 6, 12, 10, 11, 15, 9, 11, 15, 10, 13, 15,
1019 14, 15, 0, 4, 6, 12, 6, 7, 12, 12, 12, 15,
1020 5, 7, 13, 6, 7, 13, 12, 13, 15, 10, 12, 15,
1021 11, 13, 15, 15, 15, 0, 8, 13, 15, 11, 12, 15,
1022 15, 15, 0, 10, 13, 15, 12, 15, 15, 15, 15, 0,
1023 15, 15, 0, 15, 15, 0, 0, 0, 0, 4, 5, 11,
1024 5, 7, 12, 11, 12, 15, 6, 7, 13, 7, 8, 14,
1025 12, 14, 15, 11, 13, 15, 12, 13, 15, 15, 15, 0,
1026 5, 6, 13, 7, 8, 15, 12, 14, 15, 6, 8, 14,
1027 7, 8, 15, 14, 15, 15, 12, 12, 15, 12, 13, 15,
1028 15, 15, 0, 9, 13, 15, 12, 13, 15, 15, 15, 0,
1029 11, 13, 15, 13, 13, 15, 15, 15, 0, 14, 15, 0,
1030 15, 15, 0, 0, 0, 0, 8, 10, 15, 11, 12, 15,
1031 15, 15, 0, 10, 12, 15, 12, 13, 15, 15, 15, 0,
1032 14, 15, 0, 15, 15, 0, 0, 0, 0, 8, 12, 15,
1033 12, 13, 15, 15, 15, 0, 11, 13, 15, 13, 15, 15,
1034 15, 15, 0, 15, 15, 0, 15, 15, 0, 0, 0, 0,
1035 14, 15, 0, 15, 15, 0, 0, 0, 0, 15, 15, 0,
1036 15, 15
1037 ];
1038 const COOK_VQ5_CODES: &[u16; 230] = &[
1039 0x0000, 0x0004, 0x00f0, 0x0005, 0x0012, 0x01f0, 0x01f1, 0x03e8, 0x3fce, 0x0006, 0x0030, 0x07de,
1040 0x0013, 0x0031, 0x0fd2, 0x03e9, 0x07df, 0x7fb0, 0x01f2, 0x07e0, 0x7fb1, 0x03ea, 0x1fd2, 0x7fb2,
1041 0x3fcf, 0x7fb3, 0x0031, 0x0007, 0x0032, 0x0fd3, 0x0033, 0x0070, 0x0fd4, 0x0fd5, 0x0fd6, 0x7fb4,
1042 0x0014, 0x0071, 0x1fd3, 0x0034, 0x0072, 0x1fd4, 0x0fd7, 0x1fd5, 0x7fb5, 0x03eb, 0x0fd8, 0x7fb6,
1043 0x07e1, 0x1fd6, 0x7fb7, 0x7fb8, 0x7fb9, 0x0072, 0x00f1, 0x1fd7, 0x7fba, 0x07e2, 0x0fd9, 0x7fbb,
1044 0x7fbc, 0x7fbd, 0x0070, 0x03ec, 0x1fd8, 0x7fbe, 0x0fda, 0x7fbf, 0x7fc0, 0x7fc1, 0x7fc2, 0x0072,
1045 0x7fc3, 0x7fc4, 0x0071, 0x7fc5, 0x7fc6, 0x0072, 0x0034, 0x0072, 0x0072, 0x0008, 0x0015, 0x07e3,
1046 0x0016, 0x0073, 0x0fdb, 0x07e4, 0x0fdc, 0x7fc7, 0x0035, 0x0074, 0x1fd9, 0x0075, 0x00f2, 0x3fd0,
1047 0x0fdd, 0x3fd1, 0x7fc8, 0x07e5, 0x1fda, 0x7fc9, 0x0fde, 0x1fdb, 0x7fca, 0x7fcb, 0x7fcc, 0x00f2,
1048 0x0017, 0x0036, 0x1fdc, 0x0076, 0x00f3, 0x7fcd, 0x0fdf, 0x3fd2, 0x7fce, 0x0037, 0x00f4, 0x3fd3,
1049 0x0077, 0x00f5, 0x7fcf, 0x3fd4, 0x7fd0, 0x7fd1, 0x0fe0, 0x0fe1, 0x7fd2, 0x0fe2, 0x1fdd, 0x7fd3,
1050 0x7fd4, 0x7fd5, 0x00f5, 0x01f3, 0x1fde, 0x7fd6, 0x0fe3, 0x1fdf, 0x7fd7, 0x7fd8, 0x7fd9, 0x00f3,
1051 0x07e6, 0x1fe0, 0x7fda, 0x1fe1, 0x1fe2, 0x7fdb, 0x7fdc, 0x7fdd, 0x00f5, 0x3fd5, 0x7fde, 0x00f4,
1052 0x7fdf, 0x7fe0, 0x00f5, 0x0077, 0x00f5, 0x00f5, 0x00f6, 0x03ed, 0x7fe1, 0x07e7, 0x0fe4, 0x7fe2,
1053 0x7fe3, 0x7fe4, 0x0073, 0x03ee, 0x0fe5, 0x7fe5, 0x0fe6, 0x1fe3, 0x7fe6, 0x7fe7, 0x7fe8, 0x00f2,
1054 0x3fd6, 0x7fe9, 0x0074, 0x7fea, 0x7feb, 0x00f2, 0x0075, 0x00f2, 0x00f2, 0x00f7, 0x0fe7, 0x7fec,
1055 0x0fe8, 0x1fe4, 0x7fed, 0x7fee, 0x7fef, 0x00f3, 0x07e8, 0x1fe5, 0x7ff0, 0x1fe6, 0x7ff1, 0x7ff2,
1056 0x7ff3, 0x7ff4, 0x00f5, 0x7ff5, 0x7ff6, 0x00f4, 0x7ff7, 0x7ff8, 0x00f5, 0x0077, 0x00f5, 0x00f5,
1057 0x3fd7, 0x7ff9, 0x0036, 0x7ffa, 0x7ffb, 0x00f3, 0x0076, 0x00f3, 0x00f3, 0x7ffc, 0x7ffd, 0x0000,
1058 0x7ffe, 0x7fff
1059 ];
1060 const COOK_VQ6_BITS: &[u8; 32] = &[
1061 1, 4, 4, 6, 4, 6, 6, 8, 4, 6, 6, 8,
1062 6, 9, 8, 10, 4, 6, 7, 8, 6, 9, 8, 11,
1063 6, 9, 8, 10, 8, 10, 9, 11
1064 ];
1065 const COOK_VQ6_CODES: &[u16; 32] = &[
1066 0x0000, 0x0008, 0x0009, 0x0034, 0x000a, 0x0035, 0x0036, 0x00f6,
1067 0x000b, 0x0037, 0x0038, 0x00f7, 0x0039, 0x01fa, 0x00f8, 0x03fc,
1068 0x000c, 0x003a, 0x007a, 0x00f9, 0x003b, 0x01fb, 0x00fa, 0x07fe,
1069 0x003c, 0x01fc, 0x00fb, 0x03fd, 0x00fc, 0x03fe, 0x01fd, 0x07ff
1070 ];
1071
1072 const COOK_CPL_SCALE2: &[f32; 5] = &[
1073 1.0, 0.953020632266998, 0.70710676908493, 0.302905440330505, 0.0
1074 ];
1075 const COOK_CPL_SCALE3: &[f32; 9] = &[
1076 1.0, 0.981279790401459, 0.936997592449188, 0.875934481620789, 0.70710676908493,
1077 0.482430040836334, 0.349335819482803, 0.192587479948997, 0.0
1078 ];
1079 const COOK_CPL_SCALE4: &[f32; 17] = &[
1080 1.0, 0.991486728191376, 0.973249018192291, 0.953020632266998, 0.930133521556854,
1081 0.903453230857849, 0.870746195316315, 0.826180458068848, 0.70710676908493,
1082 0.563405573368073, 0.491732746362686, 0.428686618804932, 0.367221474647522,
1083 0.302905440330505, 0.229752898216248, 0.130207896232605, 0.0
1084 ];
1085 const COOK_CPL_SCALE5: &[f32; 33] = &[
1086 1.0, 0.995926380157471, 0.987517595291138, 0.978726446628571, 0.969505727291107,
1087 0.95979779958725, 0.949531257152557, 0.938616216182709, 0.926936149597168,
1088 0.914336204528809, 0.900602877140045, 0.885426938533783, 0.868331849575043,
1089 0.84851086139679, 0.824381768703461, 0.791833400726318, 0.70710676908493,
1090 0.610737144947052, 0.566034197807312, 0.529177963733673, 0.495983630418777,
1091 0.464778542518616, 0.434642940759659, 0.404955863952637, 0.375219136476517,
1092 0.344963222742081, 0.313672333955765, 0.280692428350449, 0.245068684220314,
1093 0.205169528722763, 0.157508864998817, 0.0901700109243393, 0.0
1094 ];
1095 const COOK_CPL_SCALE6: &[f32; 65] = &[
1096 1.0, 0.998005926609039, 0.993956744670868, 0.989822506904602, 0.985598564147949,
1097 0.981279790401459, 0.976860702037811, 0.972335040569305, 0.967696130275726,
1098 0.962936460971832, 0.958047747612000, 0.953020632266998, 0.947844684123993,
1099 0.942508161067963, 0.936997592449188, 0.931297719478607, 0.925390899181366,
1100 0.919256627559662, 0.912870943546295, 0.906205296516418, 0.899225592613220,
1101 0.891890347003937, 0.884148240089417, 0.875934481620789, 0.867165684700012,
1102 0.857730865478516, 0.847477376461029, 0.836184680461884, 0.823513329029083,
1103 0.808890223503113, 0.791194140911102, 0.767520070075989, 0.707106769084930,
1104 0.641024887561798, 0.611565053462982, 0.587959706783295, 0.567296981811523,
1105 0.548448026180267, 0.530831515789032, 0.514098942279816, 0.498019754886627,
1106 0.482430040836334, 0.467206478118896, 0.452251672744751, 0.437485188245773,
1107 0.422837972640991, 0.408248275518417, 0.393658757209778, 0.379014074802399,
1108 0.364258885383606, 0.349335819482803, 0.334183186292648, 0.318732559680939,
1109 0.302905440330505, 0.286608695983887, 0.269728302955627, 0.252119421958923,
1110 0.233590632677078, 0.213876649737358, 0.192587479948997, 0.169101938605309,
1111 0.142307326197624, 0.109772264957428, 0.0631198287010193, 0.0
1112 ];
1113 const COOK_CPL_SCALES: [&[f32]; 5] = [
1114 COOK_CPL_SCALE2, COOK_CPL_SCALE3, COOK_CPL_SCALE4, COOK_CPL_SCALE5, COOK_CPL_SCALE6
1115 ];
1116
1117 const COOK_CPL_BAND: [u8; MAX_SUBBANDS - 1] = [
1118 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13,
1119 13, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17,
1120 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19,
1121 19, 19, 19
1122 ];
1123
1124 const COOK_DITHER_TAB: [f32; 9] = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.176777, 0.25, 0.707107, 1.0 ];
1125
1126 const COOK_QUANT_CENTROID: [[f32; 14]; 7] = [
1127 [ 0.000, 0.392, 0.761, 1.120, 1.477, 1.832, 2.183, 2.541, 2.893, 3.245, 3.598, 3.942, 4.288, 4.724 ],
1128 [ 0.000, 0.544, 1.060, 1.563, 2.068, 2.571, 3.072, 3.562, 4.070, 4.620, 0.000, 0.000, 0.000, 0.000 ],
1129 [ 0.000, 0.746, 1.464, 2.180, 2.882, 3.584, 4.316, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 ],
1130 [ 0.000, 1.006, 2.000, 2.993, 3.985, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 ],
1131 [ 0.000, 1.321, 2.703, 3.983, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 ],
1132 [ 0.000, 1.657, 3.491, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 ],
1133 [ 0.000, 1.964, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 ]
1134 ];
1135
1136 const COOK_EXP_BITS: [i32; NUM_CATEGORIES] = [ 52, 47, 43, 37, 29, 22, 16, 0 ];