]> git.nihav.org Git - nihav.git/blame - nihav-llaudio/src/codecs/flacenc.rs
baseline JPEG decoder
[nihav.git] / nihav-llaudio / src / codecs / flacenc.rs
CommitLineData
c11ad64e
KS
1use nihav_core::codecs::*;
2use nihav_core::io::bitwriter::*;
3use nihav_core::io::intcode::*;
4use nihav_codec_support::dsp::lpc::*;
5
6fn to_unsigned(val: i32) -> u32 {
7 if val >= 0 {
8 val as u32 * 2
9 } else {
10 -val as u32 * 2 - 1
11 }
12}
13
14fn calc_header_crc(hdr: &mut [u8]) {
15 let mut crc = 0u8;
16 let len = hdr.len() - 1;
17 for &byte in hdr[..len].iter() {
18 crc = CRC8_TABLE[(crc ^ byte) as usize];
19 }
20 hdr[len] = crc;
21}
22
23fn calc_frame_crc(buf: &mut Vec<u8>) {
24 let mut crc = 0;
25 for &byte in buf.iter() {
26 crc = (crc << 8) ^ CRC16_TABLE[(((crc >> 8) as u8) ^ byte) as usize];
27 }
28 buf.push((crc >> 8) as u8);
29 buf.push(crc as u8);
30}
31
32#[derive(Clone,Copy,Debug,PartialEq)]
33#[allow(dead_code)]
34enum StereoMode {
35 Normal,
36 LeftSide,
37 SideRight,
38 MidSide,
39}
40
41fn find_stereo_mode(samp1: &[i32], samp2: &[i32]) -> StereoMode {
42 let mut sums = [0; 3];
43 for (&l, &r) in samp1.iter().zip(samp2.iter()) {
44 sums[0] += l.abs() + r.abs();
45 sums[1] += l.abs() + (l - r).abs();
46 let b = l - r;
47 let a = r + (b >> 1);
48 sums[2] += a.abs() + b.abs();
49 }
50 let mut best_idx = 0;
51 let mut best_val = sums[0];
52 for (i, &val) in sums.iter().enumerate() {
53 if val <= best_val {
54 best_val = val;
55 best_idx = i;
56 }
57 }
58 match best_idx {
59 0 => StereoMode::Normal,
60 1 => StereoMode::LeftSide,
61 _ => StereoMode::MidSide,
62 }
63}
64
65fn apply_stereo(samp1: &mut [i32], samp2: &mut [i32], smode: StereoMode) {
66 match smode {
67 StereoMode::Normal => {},
68 StereoMode::LeftSide => {
69 for (l, r) in samp1.iter_mut().zip(samp2.iter_mut()) {
70 *r = *l - *r;
71 }
72 },
73 StereoMode::SideRight => {
74 for (l, r) in samp1.iter_mut().zip(samp2.iter_mut()) {
75 *l -= *r;
76 }
77 },
78 StereoMode::MidSide => {
79 for (l, r) in samp1.iter_mut().zip(samp2.iter_mut()) {
80 let b = *l - *r;
81 *l = *r + (b >> 1);
82 *r = b;
83 }
84 },
85 };
86}
87
88fn apply_fixed_filter(dst: &mut [u32], src: &[i32], order: i8) {
89 match order {
90 -1 => {
91 let mut last = src[0];
92 for (dst, &cur) in dst[1..].iter_mut().zip(src[1..].iter()) {
93 *dst = to_unsigned(cur - last);
94 last = cur;
95 }
96 },
97 -2 => {
98 let mut last0 = src[1];
99 let mut last1 = src[0];
100 for (dst, &cur) in dst[2..].iter_mut().zip(src[2..].iter()) {
101 *dst = to_unsigned(cur - 2 * last0 + last1);
102 last1 = last0;
103 last0 = cur;
104 }
105 },
106 -3 => {
107 let mut last0 = src[2];
108 let mut last1 = src[1];
109 let mut last2 = src[0];
110 for (dst, &cur) in dst[3..].iter_mut().zip(src[3..].iter()) {
111 *dst = to_unsigned(cur - 3 * last0 + 3 * last1 - last2);
112 last2 = last1;
113 last1 = last0;
114 last0 = cur;
115 }
116 },
117 -4 => {
118 let mut last0 = src[3];
119 let mut last1 = src[2];
120 let mut last2 = src[1];
121 let mut last3 = src[0];
122 for (dst, &cur) in dst[4..].iter_mut().zip(src[4..].iter()) {
123 *dst = to_unsigned(cur - 4 * last0 + 6 * last1 - 4 * last2 + last3);
124 last3 = last2;
125 last2 = last1;
126 last1 = last0;
127 last0 = cur;
128 }
129 },
130 _ => unreachable!(),
131 };
132}
133
134fn apply_lpc(dst: &mut [u32], src: &[i32], filter: &[i32], shift: u8) {
135 let order = filter.len();
136
137 for (i, dst) in dst[order..src.len()].iter_mut().enumerate() {
138 let sum = src[i..].iter().zip(filter.iter()).fold(0, |acc, (&c, &f)| acc + i64::from(c) * i64::from(f));
139 *dst = to_unsigned(src[i + order] - ((sum >> shift) as i32));
140 }
141}
142
143fn encode_residual(bw: &mut BitWriter, src: &[u32]) {
144 let sum = src.iter().fold(0, |acc, &x| acc + x) / (src.len() as u32);
145
146 let k = (31 - sum.max(1).leading_zeros()) as u8;
147 if k < 16 {
148 bw.write(0, 2);
149 bw.write(0, 4); // 1 partition
150 bw.write(u32::from(k), 4);
151 } else {
152 bw.write(1, 2);
153 bw.write(0, 4); // 1 partition
154 bw.write(u32::from(k), 5);
155 }
156 for &samp in src.iter() {
157 bw.write_code(UintCodeType::Rice(k), samp);
158 }
159}
160
161#[derive(Default)]
162struct FLACEncoder {
163 stream: Option<NAStreamRef>,
164 channels: usize,
165 srate: u32,
166 block_len: usize,
167 order: i8,
168 samples: Vec<Vec<i32>>,
169 flush: bool,
170 cur_pos: usize,
171 tmp: Vec<u32>,
172 ffilter: [f64; 32],
173 ifilter: [i32; 32],
174}
175
176fn nsamples_code(nsamp: usize) -> u8 {
177 match nsamp {
178 192 => 1,
179 576 => 2,
180 1152 => 3,
181 2304 => 4,
182 4608 => 5,
183 256 => 8,
184 512 => 9,
185 1024 => 10,
186 2048 => 11,
187 4096 => 12,
188 8192 => 13,
189 16384 => 14,
190 32768 => 15,
191 0..=255 => 6,
192 _ => 7,
193 }
194}
195
196fn encode_nsamples_esc(bw: &mut BitWriter, nsamp: usize, code: u8) {
197 match code {
198 6 => {
199 bw.write((nsamp - 1) as u32, 8);
200 },
201 7 => {
202 bw.write((nsamp - 1) as u32, 16);
203 },
204 _ => {},
205 };
206}
207
208fn write_utf8(bw: &mut BitWriter, val: usize) {
209 let val = val as u32;
210 let lz = 32 - val.leading_zeros();
211 match lz {
212 0..=7 => {
213 bw.write(val, 8);
214 },
215 8..=11 => {
216 bw.write(0xC0 | (val >> 6), 8);
217 bw.write(0x80 | (val & 0x3F), 8);
218 },
219 12..=16 => {
220 bw.write(0xE0 | ( val >> 12), 8);
221 bw.write(0x80 | ((val >> 6) & 0x3F), 8);
222 bw.write(0x80 | ( val & 0x3F), 8);
223 },
224 17..=21 => {
225 bw.write(0xF0 | ( val >> 18), 8);
226 bw.write(0x80 | ((val >> 12) & 0x3F), 8);
227 bw.write(0x80 | ((val >> 6) & 0x3F), 8);
228 bw.write(0x80 | ( val & 0x3F), 8);
229 },
230 22..=26 => {
231 bw.write(0xF8 | ( val >> 24), 8);
232 bw.write(0x80 | ((val >> 18) & 0x3F), 8);
233 bw.write(0x80 | ((val >> 12) & 0x3F), 8);
234 bw.write(0x80 | ((val >> 6) & 0x3F), 8);
235 bw.write(0x80 | ( val & 0x3F), 8);
236 },
237 _ => {
238 bw.write(0xFC | ( val >> 30), 8);
239 bw.write(0x80 | ((val >> 24) & 0x3F), 8);
240 bw.write(0x80 | ((val >> 18) & 0x3F), 8);
241 bw.write(0x80 | ((val >> 12) & 0x3F), 8);
242 bw.write(0x80 | ((val >> 6) & 0x3F), 8);
243 bw.write(0x80 | ( val & 0x3F), 8);
244 },
245 };
246}
247
248const DEFAULT_BLOCK_LEN: usize = 4096;
249
250impl FLACEncoder {
251 fn new() -> Self { Self::default() }
252 fn encode_packet(&mut self) -> EncoderResult<NAPacket> {
253 if self.samples[0].is_empty() || (!self.flush && self.samples[0].len() < self.block_len) {
254 return Err(EncoderError::TryAgain);
255 }
256
257 let nsamples = self.samples[0].len().min(self.block_len);
258
259 let mut bw = BitWriter::new(Vec::with_capacity(1024), BitWriterMode::BE);
260 bw.write(0x3FFE, 14);
261 bw.write0(); // reserved
262 bw.write1(); // blocking strategy - variable
263 let scode = nsamples_code(nsamples);
264 bw.write(u32::from(scode), 4);
265 bw.write(0x0, 4); // sample rate - read the stream info
266 let smode = if self.channels == 2 {
267 let (l, r) = self.samples.split_at_mut(1);
268 let smode = find_stereo_mode(&l[0][..nsamples], &r[0][..nsamples]);
269 apply_stereo(&mut l[0][..nsamples], &mut r[0][..nsamples], smode);
270 smode
271 } else {
272 StereoMode::Normal
273 };
274 let chan_idx = match smode {
275 StereoMode::Normal => (self.channels as u32) - 1,
276 StereoMode::LeftSide => 8,
277 StereoMode::SideRight => 9,
278 StereoMode::MidSide => 10,
279 };
280 bw.write(chan_idx, 4);
281 bw.write(0x4, 3); // 16 bits per sample
282 bw.write0(); // reserved
283 write_utf8(&mut bw, self.cur_pos);
284 encode_nsamples_esc(&mut bw, nsamples, scode);
285 // optional bits per sample
286 bw.write(0x00, 8); // header CRC placeholder
287 let hdr_crc_pos = bw.tell() >> 3;
288 for chan in 0..self.channels {
289 let samp_bits = match (smode, chan) {
290 (StereoMode::LeftSide, 1) |
291 (StereoMode::SideRight, 0) |
292 (StereoMode::MidSide, 1) => 16 + 1,
293 _ => 16,
294 };
295 self.encode_channel(&mut bw, chan, nsamples, samp_bits);
296 }
297
298 let mut dbuf = bw.end();
299 calc_header_crc(&mut dbuf[..hdr_crc_pos]);
300 calc_frame_crc(&mut dbuf);
301 let ts = NATimeInfo::new(None, None, Some(nsamples as u64), 1, self.srate);
302
303 for samp in self.samples.iter_mut() {
304 samp.drain(..nsamples);
305 }
306 self.cur_pos += nsamples;
307
308 Ok(NAPacket::new(self.stream.clone().unwrap(), ts, true, dbuf))
309 }
310 fn encode_channel(&mut self, bw: &mut BitWriter, chan: usize, nsamples: usize, samp_bits: u8) {
311 let samp = &self.samples[chan][..nsamples];
312
313 let s0 = samp[0];
314 let mut same = true;
315 for &s in samp[1..].iter() {
316 if s != s0 {
317 same = false;
318 break;
319 }
320 }
321
322 bw.write0();
323 if !same {
324 match self.order {
325 0 => {
326 bw.write(1, 6);
327 bw.write0(); // no wasted bits
328 for &el in samp.iter() {
329 bw.write_s(i32::from(el), samp_bits);
330 }
331 },
332 -1 | -2 | -3 | -4 => {
333 let order = -self.order as usize;
334
335 apply_fixed_filter(&mut self.tmp, samp, self.order);
336
337 bw.write(8 | (order as u32), 6);
338 bw.write0(); // no wasted bits
339 for &el in samp[..order].iter() {
340 bw.write_s(i32::from(el), samp_bits);
341 }
342 encode_residual(bw, &self.tmp[order..nsamples]);
343 },
344 _ => {
345 let order = self.order as usize;
346 calc_lpc_filter(samp, &mut self.ffilter[..order]);
347
348 let mut filter_prec = 12;
349 let scale = f64::from(1 << filter_prec);
350
351 let maxval = (self.ffilter[..order].iter().fold(0.0, |acc: f64, &el| acc.max(el.abs())) * scale) as i32;
352 let mut mask = 0;
353 for (dst, &src) in self.ifilter[..order].iter_mut().zip(&self.ffilter) {
354 *dst = (src * scale) as i32;
355 mask |= *dst;
356 }
357 let mut zbits = mask.trailing_zeros();
358 let mut filter_bits = 33 - maxval.leading_zeros() - zbits;
359 if filter_bits > 15 {
360 let sub = filter_bits - 15;
361 zbits += sub;
362 filter_bits = 15;
363 }
364 filter_prec -= zbits;
365 if zbits > 0 {
366 for el in self.ifilter[..order].iter_mut() {
367 *el >>= zbits;
368 }
369 }
370
371 apply_lpc(&mut self.tmp, samp, &self.ifilter[..order], filter_prec as u8);
372
373 bw.write(0x20 | ((order - 1) as u32), 6);
374 bw.write0(); // no wasted bits
375 for &el in samp[..order].iter() {
376 bw.write_s(i32::from(el), samp_bits);
377 }
378 bw.write(filter_bits - 1, 4);
379 bw.write(filter_prec, 5);
380 for &coef in self.ifilter[..order].iter().rev() {
381 bw.write_s(coef, filter_bits as u8);
382 }
383 encode_residual(bw, &self.tmp[order..nsamples]);
384 },
385 };
386 } else {
387 bw.write(0, 6);
388 bw.write0(); // no wasted bits
389 bw.write(u32::from(s0 as u16), samp_bits);
390 }
391 }
392}
393
394impl NAEncoder for FLACEncoder {
395 fn negotiate_format(&self, encinfo: &EncodeParameters) -> EncoderResult<EncodeParameters> {
396 match encinfo.format {
397 NACodecTypeInfo::None => {
398 let mut ofmt = EncodeParameters::default();
399 ofmt.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 1, SND_S16_FORMAT, DEFAULT_BLOCK_LEN));
400 Ok(ofmt)
401 },
402 NACodecTypeInfo::Video(_) => Err(EncoderError::FormatError),
403 NACodecTypeInfo::Audio(ainfo) => {
404 let mut outinfo = ainfo;
405 outinfo.channels = outinfo.channels.max(1).min(8);
406 if outinfo.format != SND_S16P_FORMAT && outinfo.format != SND_S16_FORMAT {
407 outinfo.format = SND_S16P_FORMAT;
408 }
409 if outinfo.block_len == 0 {
410 outinfo.block_len = DEFAULT_BLOCK_LEN;
411 }
412 outinfo.block_len = outinfo.block_len.max(2).min(65535);
413 let mut ofmt = *encinfo;
414 ofmt.format = NACodecTypeInfo::Audio(outinfo);
415 Ok(ofmt)
416 }
417 }
418 }
419 fn init(&mut self, stream_id: u32, encinfo: EncodeParameters) -> EncoderResult<NAStreamRef> {
420 match encinfo.format {
421 NACodecTypeInfo::None => Err(EncoderError::FormatError),
422 NACodecTypeInfo::Video(_) => Err(EncoderError::FormatError),
423 NACodecTypeInfo::Audio(ainfo) => {
424 if ainfo.format != SND_S16P_FORMAT && ainfo.format != SND_S16_FORMAT {
425 return Err(EncoderError::FormatError);
426 }
427 if ainfo.block_len == 0 {
428 self.block_len = DEFAULT_BLOCK_LEN;
429 } else {
430 if ainfo.block_len < 2 || ainfo.block_len > 65535 {
431 return Err(EncoderError::FormatError);
432 }
433 self.block_len = ainfo.block_len;
434 }
435 if ainfo.channels == 0 || ainfo.channels > 8 {
436 return Err(EncoderError::FormatError);
437 }
438 self.channels = ainfo.channels as usize;
439
440 let soniton = SND_S16P_FORMAT;
441 let out_ainfo = NAAudioInfo::new(ainfo.sample_rate, ainfo.channels, soniton, self.block_len);
442 let info = NACodecInfo::new("flac", NACodecTypeInfo::Audio(out_ainfo), None);
443 let mut stream = NAStream::new(StreamType::Audio, stream_id, info, 1, ainfo.sample_rate, 0);
444 stream.set_num(stream_id as usize);
445 let stream = stream.into_ref();
446
447 self.stream = Some(stream.clone());
448 self.srate = ainfo.sample_rate;
449
450 self.samples.clear();
451 for _ in 0..self.channels {
452 self.samples.push(Vec::with_capacity(DEFAULT_BLOCK_LEN));
453 }
454 self.tmp.resize(self.block_len, 0);
455
456 Ok(stream)
457 },
458 }
459 }
460 fn encode(&mut self, frm: &NAFrame) -> EncoderResult<()> {
461 let buf = frm.get_buffer();
462 if let Some(ref abuf) = buf.get_abuf_i16() {
463 let src = abuf.get_data();
464 let len = abuf.get_length();
465 if abuf.get_step() == 1 {
466 let astride = abuf.get_stride();
467 let mut off = 0;
468 for dst in self.samples.iter_mut() {
469 dst.reserve(len);
470 for &samp in src[off..][..len].iter() {
471 dst.push(i32::from(samp));
472 }
473 off += astride;
474 }
475 } else {
476 for dst in self.samples.iter_mut() {
477 dst.reserve(len);
478 }
479 let mut src = src.iter();
480 for _ in 0..len {
481 for dst in self.samples.iter_mut() {
482 dst.push(i32::from(*src.next().unwrap()));
483 }
484 }
485 }
486 Ok(())
487 } else {
488 Err(EncoderError::InvalidParameters)
489 }
490 }
491 fn get_packet(&mut self) -> EncoderResult<Option<NAPacket>> {
492 if let Ok(pkt) = self.encode_packet() {
493 Ok(Some(pkt))
494 } else {
495 Ok(None)
496 }
497 }
498 fn flush(&mut self) -> EncoderResult<()> {
499 self.flush = true;
500 Ok(())
501 }
502}
503
504const ENCODER_OPTS: &[NAOptionDefinition] = &[
505 NAOptionDefinition {
506 name: "order", description: "LPC order",
507 opt_type: NAOptionDefinitionType::Int(Some(-4), Some(32)) },
508 NAOptionDefinition {
509 name: "block_size", description: "block size",
510 opt_type: NAOptionDefinitionType::Int(Some(2), Some(65535)) },
511];
512
513impl NAOptionHandler for FLACEncoder {
514 fn get_supported_options(&self) -> &[NAOptionDefinition] { ENCODER_OPTS }
515 fn set_options(&mut self, options: &[NAOption]) {
516 for option in options.iter() {
517 for opt_def in ENCODER_OPTS.iter() {
518 if opt_def.check(option).is_ok() {
519 match option.name {
520 "order" => {
521 if let NAValue::Int(val) = option.value {
522 self.order = val as i8;
523 }
524 },
525 "block_size" => {
526 if let NAValue::Int(val) = option.value {
527 self.block_len = val as usize;
528 self.tmp.resize(self.block_len, 0);
529 }
530 },
531 _ => {},
532 };
533 }
534 }
535 }
536 }
537 fn query_option_value(&self, name: &str) -> Option<NAValue> {
538 match name {
539 "order" => Some(NAValue::Int(i64::from(self.order))),
540 "block_size" => Some(NAValue::Int(self.block_len as i64)),
541 _ => None,
542 }
543 }
544}
545
546pub fn get_encoder() -> Box<dyn NAEncoder + Send> {
547 Box::new(FLACEncoder::new())
548}
549
550#[cfg(test)]
551mod test {
552 use nihav_core::codecs::*;
553 use nihav_core::demuxers::*;
554 use nihav_core::muxers::*;
555 use nihav_codec_support::test::enc_video::*;
556 use crate::*;
557
558 #[test]
559 fn test_flac_encoder_verbatim() {
560 let enc_options = &[
561 NAOption{name: "order", value: NAValue::Int(0)},
562 ];
563 test_flac_encoder("uncompr.flac", enc_options,
564 &[0xcd9767ee, 0xf8a86d20, 0x317944aa, 0xd9044f5c]);
565 }
566 #[test]
567 fn test_flac_encoder_fixed1() {
568 let enc_options = &[
569 NAOption{name: "order", value: NAValue::Int(-1)},
570 ];
571 test_flac_encoder("fixed1.flac", enc_options,
572 &[0xcf654f93, 0x1db0bb07, 0xbc0cd9c3, 0xf9d2cc4e]);
573 }
574 #[test]
575 fn test_flac_encoder_fixed4() {
576 let enc_options = &[
577 NAOption{name: "order", value: NAValue::Int(-4)},
578 ];
579 test_flac_encoder("fixed1.flac", enc_options,
580 &[0xbc2fba7f, 0x6f9406ee, 0x98be1f67, 0xe2b86b2d]);
581 }
582 #[test]
583 fn test_flac_encoder_lpc10() {
584 let enc_options = &[
585 NAOption{name: "order", value: NAValue::Int(10)},
586 ];
587 test_flac_encoder("lpc10.flac", enc_options,
588 &[0xb6736f2e, 0xb61dda7a, 0xeb4037db, 0x8ee4afb9]);
589 }
590
591 fn test_flac_encoder(name: &'static str, enc_options: &[NAOption], hash: &[u32; 4]) {
592 let mut dmx_reg = RegisteredDemuxers::new();
593 llaudio_register_all_demuxers(&mut dmx_reg);
594 let mut dec_reg = RegisteredDecoders::new();
595 llaudio_register_all_decoders(&mut dec_reg);
596 let mut mux_reg = RegisteredMuxers::new();
597 llaudio_register_all_muxers(&mut mux_reg);
598 let mut enc_reg = RegisteredEncoders::new();
599 llaudio_register_all_encoders(&mut enc_reg);
600
601 let dec_config = DecoderTestParams {
602 demuxer: "flac",
603 in_name: "assets/LLaudio/luckynight.flac",
604 stream_type: StreamType::Audio,
605 limit: Some(10),
606 dmx_reg, dec_reg,
607 };
608 let enc_config = EncoderTestParams {
609 muxer: "flac",
610 enc_name: "flac",
611 out_name: name,
612 mux_reg, enc_reg,
613 };
614 let dst_ainfo = NAAudioInfo {
615 sample_rate: 0,
616 channels: 0,
617 format: SND_S16_FORMAT,
618 block_len: 0,
619 };
620 let enc_params = EncodeParameters {
621 format: NACodecTypeInfo::Audio(dst_ainfo),
622 quality: 0,
623 bitrate: 0,
624 tb_num: 0,
625 tb_den: 0,
626 flags: 0,
627 };
628// test_encoding_to_file(&dec_config, &enc_config, enc_params, enc_options);
629
630 test_encoding_md5(&dec_config, &enc_config, enc_params, enc_options,
631 hash);
632 }
633}
634
635const CRC8_TABLE: [u8; 256] = [
636 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
637 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
638 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
639 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
640 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
641 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
642 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
643 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
644 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
645 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
646 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
647 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
648 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
649 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
650 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
651 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
652 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
653 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
654 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
655 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
656 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
657 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
658 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
659 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
660 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
661 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
662 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
663 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
664 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
665 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
666 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
667 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
668];
669
670const CRC16_TABLE: [u16; 256] = [
671 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
672 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
673 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
674 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
675 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
676 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
677 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
678 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
679 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
680 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
681 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
682 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
683 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
684 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
685 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
686 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
687 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
688 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
689 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
690 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
691 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
692 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
693 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
694 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
695 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
696 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
697 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
698 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
699 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
700 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
701 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
702 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
703];