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