]> git.nihav.org Git - nihav.git/blame - nihav-misc/src/codecs/mwv1.rs
aac: fix intensity stereo reconstruction for ms_mask_present=0 case
[nihav.git] / nihav-misc / src / codecs / mwv1.rs
CommitLineData
54915296
KS
1use nihav_core::io::byteio::{ByteReader,MemoryReader};
2use nihav_core::io::bitreader::*;
3use nihav_core::io::codebook::*;
4use nihav_core::codecs::*;
5
6#[derive(Clone,Copy)]
7struct BandPos {
8 plane: usize,
9 x: usize,
10 y: usize,
11 w: usize,
12 h: usize,
13 level: u8,
14 ilevel: u8,
15}
16
17struct MWV1Decoder {
18 info: NACodecInfoRef,
19 mode: u32,
20 flags: u32,
21 l_cb: Codebook<u8>,
22 h_cb: Codebook<u8>,
23 bands: Vec<BandPos>,
24 tmp: Vec<f32>,
25 plane: [Vec<f32>; 3],
26 stride: [usize; 3],
27}
28
29#[allow(clippy::too_many_arguments)]
30fn decode_band(br: &mut BitReader, cb: &Codebook<u8>, dst: &mut [f32], w: usize, h: usize, stride: usize, scale: f32, round: bool, zero_skip: bool) -> DecoderResult<()> {
31 let mut ival = 0;
32 let mut zero_run = 0;
33
34 for (y, row) in dst.chunks_mut(stride).take(h).enumerate() {
35 for i in 0..w {
36 let idx = if (y & 1) == 0 { i } else { w - 1 - i };
37 if zero_run > 0 {
38 if !zero_skip {
39 row[idx] = (ival as f32) * scale;
40 }
41 zero_run -= 1;
42 continue;
43 }
44 let val = br.read_cb(cb)?;
45 let diff = match val {
46 0 => {
47 let esc = br.read(8)? as i16 - 0x80;
48 if esc < 0 {
49 esc - 0x7B
50 } else {
51 esc + 0x7C
52 }
53 },
54 1 => {
55 let esc = br.read(12)? as i16 - 0x800;
56 if esc < 0 {
57 esc - 0xFB
58 } else {
59 esc + 0xFC
60 }
61 },
62 2 => {
63 zero_run = br.read(4)? + 4;
64 if zero_skip {
65 continue;
66 }
67 0
68 },
69 3 => {
70 zero_run = br.read(8)? + 20;
71 if zero_skip {
72 continue;
73 }
74 0
75 },
76 4 => {
77 zero_run = br.read(12)? + 276;
78 if zero_skip {
79 continue;
80 }
81 0
82 },
83 0x80 => {
84 let esc = (br.read(16)? ^ 0x8000) as i16;
85 if esc < 0 {
86 esc - 0x8FB
87 } else {
88 esc + 0x8FC
89 }
90 },
91 0xFC | 0xFD | 0xFE | 0xFF => {
92 zero_run = u32::from(val - 0xFC);
93 if zero_skip {
94 continue;
95 }
96 0
97 },
98 _ => {
99 i16::from(val) - 0x80
100 },
101 };
102 if !zero_skip {
103 ival += diff;
104 row[idx] = (ival as f32) * scale;
105 } else {
106 let bias = if !round { 0.0 } else if diff > 0 { 0.5 } else { -0.5 };
107 row[idx] = ((diff as f32) + bias) * scale;
108 }
109 }
110 }
111 validate!(zero_run == 0);
112
113 Ok(())
114}
115
116#[allow(clippy::too_many_arguments)]
117fn decode_band2(br: &mut BitReader, cb: &Codebook<u8>, dst: &mut [f32], w: usize, h: usize, stride: usize, scale: f32, round: bool) -> DecoderResult<()> {
118 const ZERO_RUN_BITS: [u8; 12] = [ 16, 14, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
119 const ZERO_RUN_ADD: [u32; 12] = [
120 0x4839, 0x839, 0x439, 0x239, 0x139, 0xB9, 0x79, 0x59, 0x49, 0x41, 0x3D, 0x3B
121 ];
122
123 let mut zero_run = 0;
124
125 for (y, row) in dst.chunks_mut(stride).take(h).enumerate() {
126 for i in 0..w {
127 let idx = if (y & 1) == 0 { i } else { w - 1 - i };
128
129 if zero_run > 0 {
130 zero_run -= 1;
131 continue;
132 }
133 let val = br.read_cb(cb)?;
134 let ival = match val {
135 0x00..=0x40 => i16::from(val) - 32,
136 0x41..=0x7B => {
137 zero_run = u32::from(val) - 0x41;
138 continue;
139 },
140 0xEF..=0xFA => {
141 let idx = (val - 0xEF) as usize;
142 zero_run = br.read(ZERO_RUN_BITS[idx])? + ZERO_RUN_ADD[idx];
143 continue;
144 },
145 0xFE => {
146 let esc = br.read(14)? as i16 - 0x2000;
147 if esc < 0 {
148 esc - 0x220
149 } else {
150 esc + 0x221
151 }
152 },
153 0xFF => {
154 let esc = br.read(10)? as i16 - 0x200;
155 if esc < 0 {
156 esc - 0x20
157 } else {
158 esc + 0x21
159 }
160 },
161 _ => return Err(DecoderError::InvalidData),
162 };
163 let bias = if !round { 0.0 } else if ival > 0 { 0.5 } else { -0.5 };
164 row[idx] = ((ival as f32) + bias) * scale;
165 }
166 }
167 validate!(zero_run == 0);
168
169 Ok(())
170}
171
172fn combine_bands(lo: &[f32], hi: &[f32], dst: &mut [f32], step: usize, len: usize) {
173 dst[0] = (lo[0] - lo[step]) / 128.0 + (hi[0] + lo[0]) / 16.0;
174 dst[1] = (lo[step] - lo[0]) / 128.0 + (lo[0] - hi[0]) / 16.0;
175 let mut didx = 2;
176 let mut loidx = 0;
177 let mut hiidx = step;
178 for _i in 0..(((len + 1) >> 1) - 2) {
179 let tmp = (lo[loidx] - lo[loidx + 2 * step]) / 128.0;
180 dst[didx] = (lo[loidx + step] + hi[hiidx]) / 16.0 + tmp;
181 dst[didx + 1] = (lo[loidx + step] - hi[hiidx]) / 16.0 - tmp;
182 didx += 2;
183 loidx += step;
184 hiidx += step;
185 }
186 if (len & 1) == 0 {
187 let tmp = (lo[loidx] - lo[loidx + step]) / 128.0;
188 dst[didx] = (lo[loidx + step] + hi[hiidx]) / 16.0 + tmp;
189 dst[didx + 1] = (lo[loidx + step] - hi[hiidx]) / 16.0 - tmp;
190 } else {
191 dst[didx] = lo[loidx + step] / 16.0;
192 }
193}
194
195fn map_index(idx: usize) -> u8 { idx as u8 }
196
197impl MWV1Decoder {
198 fn new() -> Self {
199 let mut cbr = TableCodebookDescReader::new(&L_CODE_BITS, &L_CODE_LENS, map_index);
200 let l_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap();
201 let mut cbr = TableCodebookDescReader::new(&H_CODE_BITS, &H_CODE_LENS, map_index);
202 let h_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap();
203 MWV1Decoder {
204 info: NACodecInfo::new_dummy(),
205 l_cb, h_cb,
206 mode: 0,
207 flags: 0,
208 bands: Vec::new(),
209 plane: [Vec::new(), Vec::new(), Vec::new()],
210 stride: [0; 3],
211 tmp: Vec::new(),
212 }
213 }
214 fn reconstruct(&mut self, frm: &mut NASimpleVideoFrame<u8>) {
215 for band in self.bands.iter() {
216 if band.x == 0 || band.y == 0 {
217 continue;
218 }
219
220 let stride = self.stride[band.plane] << band.ilevel;
221 let dst_yy = [0, 1 << band.ilevel >> 1];
222 for &dst_y in dst_yy.iter() {
223 let dst = &mut self.plane[band.plane][dst_y * self.stride[band.plane]..];
224 for row in dst.chunks_mut(stride).take(band.h) {
225 let (lo, hi) = row.split_at(band.x);
226 let size = band.x + band.w;
227 combine_bands(lo, hi, &mut self.tmp, 1, size);
228 row[..size].copy_from_slice(&self.tmp[..size]);
229 }
230 }
231 let size = band.y + band.h;
232 for x in 0..band.x + band.w {
233 let col = &self.plane[band.plane][x..];
234 combine_bands(col, &col[stride/2..], &mut self.tmp, stride, size);
235 for y in 0..size {
236 self.plane[band.plane][x + y * (stride/2)] = self.tmp[y] * 128.0;
237 }
238 }
239 }
240
241 for plane in 0..3 {
242 let dst = &mut frm.data[frm.offset[plane]..];
243 for (drow, srow) in dst.chunks_mut(frm.stride[plane]).zip(self.plane[plane].chunks(self.stride[plane])) {
244 for (dst, &src) in drow.iter_mut().zip(srow.iter()) {
245 *dst = (src + 128.0).max(0.0).min(255.0) as u8;
246 }
247 }
248 }
249 }
250}
251
252impl NADecoder for MWV1Decoder {
253 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
254 if let NACodecTypeInfo::Video(_vinfo) = info.get_properties() {
255 if let Some(edata) = info.get_extradata() {
256 validate!(edata.len() >= 64);
257 let mut mr = MemoryReader::new_read(edata.as_slice());
258 let mut br = ByteReader::new(&mut mr);
259 let len = br.read_u32be()? as usize;
260 validate!(edata.len() == len);
261 let _ = br.read_u32be()?; //always 7?
262 self.mode = br.read_u32be()?; //pic_fmt
263 let width = br.read_u32be()? as usize;
264 let height = br.read_u32be()? as usize;
265 let _smth = br.read_u16be()?;
266 let _bpp = br.read_u16be()?;
267 let _fmt = br.read_u32le()?;
268 let _unp_size = br.read_u32be()? as usize;
269 br.read_u32be()?; // always zero?
270 br.read_u32be()?; // always zero?
271 br.read_u32be()?; // always zero?
272 br.read_u32be()?; // always zero?
273 self.flags = br.read_u32be()?; // 0x100 - interlaced?
274 let mut levels = [[0; 2]; 3];
275 for plane_lev in levels.iter_mut() {
276 for level in plane_lev.iter_mut() {
277 let lev = br.read_u16be()?;
278 validate!(lev < 32);
279 *level = lev as u8;
280 }
281 }
282 validate!(width > 1 && height > 1);
283 for plane_lev in levels.iter() {
284 if plane_lev[0] != plane_lev[1] {
285 return Err(DecoderError::NotImplemented);
286 }
287 }
288 let max_levels = levels[0][0].max(levels[1][0]).max(levels[2][0]);
289 validate!(max_levels < 8);
290 self.bands = Vec::with_capacity((max_levels as usize) * 9 + 1);
291 self.tmp = vec![0.0; width.max(height)];
292 let mut dim = [[width, height], [width >> 1, height >> 1], [width >> 1, height >> 1]];
293
294 for level in (0..max_levels).rev() {
295 for plane in (0..3).rev() {
296 if level < levels[plane][0] {
297 let bp = BandPos {
298 plane,
299 level,
300 ilevel: levels[plane][0] - level,
301 x: (dim[plane][0] + 1) >> 1,
302 y: (dim[plane][1] + 1) >> 1,
303 w: dim[plane][0] >> 1,
304 h: dim[plane][1] >> 1,
305 };
306 self.bands.push(bp);
307 }
308 }
309 for plane in (0..3).rev() {
310 if level < levels[plane][0] {
311 let bp = BandPos {
312 plane,
313 level,
314 ilevel: levels[plane][0] - level,
315 x: 0,
316 y: (dim[plane][1] + 1) >> 1,
317 w: (dim[plane][0] + 1) >> 1,
318 h: dim[plane][1] >> 1,
319 };
320 self.bands.push(bp);
321 }
322 }
323 for plane in (0..3).rev() {
324 if level < levels[plane][0] {
325 let bp = BandPos {
326 plane,
327 level,
328 ilevel: levels[plane][0] - level,
329 x: (dim[plane][0] + 1) >> 1,
330 y: 0,
331 w: dim[plane][0] >> 1,
332 h: (dim[plane][1] + 1) >> 1,
333 };
334 self.bands.push(bp);
335 }
336 }
337
338 if level != 0 {
339 for plane in 0..3 {
340 if level < levels[plane][0] {
341 dim[plane][0] = (dim[plane][0] + 1) >> 1;
342 dim[plane][1] = (dim[plane][1] + 1) >> 1;
343 }
344 }
345 }
346 }
347 for plane in (0..3).rev() {
348 let bp = BandPos {
349 plane,
350 level: 0,
351 ilevel: levels[plane][0],
352 x: 0,
353 y: 0,
354 w: (dim[plane][0] + 1) >> 1,
355 h: (dim[plane][1] + 1) >> 1,
356 };
357 self.bands.push(bp);
358 }
359 self.bands.reverse();
360
361 self.plane = [vec![0.0; width * height], vec![0.0; width * height / 4], vec![0.0; width * height / 4]];
362 self.stride = [width, width >> 1, width >> 1];
363
364 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(width, height, false, YUV420_FORMAT));
365 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, None).into_ref();
366 Ok(())
367 } else {
368 Err(DecoderError::InvalidData)
369 }
370 } else {
371 Err(DecoderError::InvalidData)
372 }
373 }
374 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
375 let src = pkt.get_buffer();
376 if src.len() <= 26 { return Err(DecoderError::ShortData); }
377
378 let mut br = BitReader::new(&src, BitReaderMode::BE);
379
380 for plane in self.plane.iter_mut() {
381 for el in plane.iter_mut() {
382 *el = 0.0;
383 }
384 }
385
386 let mut has_hdr = false;
387 let mut band_iter = self.bands.iter_mut();
388
389 while br.left() > 5 {
390 let ff = br.read(32)?;
391 validate!(ff == 0xFFFFFFFF);
392 let tag_id = br.read(8)?;
393 match tag_id {
394 0xAA => {
395 validate!(!has_hdr);
396 let size = br.read(32)?;
397 validate!(size >= 6);
398 let end = br.tell() + (size as usize) * 8 - 32;
399 br.read(16)?;
400 if (self.flags & 0x100) == 0 {
401 br.read(16)?;
402 br.read(16)?;
403 }
404 if self.mode > 1 {
405 br.read(8)?;
406 }
407 if self.mode > 4 {
408 let _size = br.read(32)?;
409 }
410
411 validate!(br.tell() <= end);
412 let tail = end - br.tell();
413 br.skip(tail as u32)?;
414 has_hdr = true;
415 },
416 0xAB => {
417 /*validate!(!has_hdr);
418 let size = br.read(32)?;
419 validate!(size >= 6);
420 br.read(16)?;
421 if self.levels == 2 || self.levels == 3 {
422 br.read(16)?;
423 br.read(16)?;
424 }
425 if components > 1 {
426 br.read(8)?;
427 }
428 br.skip((size - 6) * 8)?;
429 has_hdr = true;*/
430 return Err(DecoderError::NotImplemented);
431 },
432 0xD1 => {
433 let next_band = band_iter.next();
434 validate!(next_band.is_some());
435 let band = *next_band.unwrap();
436
437 let scale;
438 let band_mode;
439 let lscale = (1 << band.level) as f32;
440 if self.mode < 3 {
441 /*let _ = br.read(32)?;
442 let _ = br.read(32)?;
443 scale = (br.read(32)? as f32) / 32768.0;*/
444 return Err(DecoderError::NotImplemented);
445 } else {
446 band_mode = br.read(8)? as u8;
447 if band_mode == 0 {
448 scale = 0.0;
449 } else {
450 scale = (br.read(32)? as f32) * lscale / 32768.0;
451 }
452 }
453
454 let dst_y = if band.y != 0 { 1 << band.ilevel >> 1 } else { 0 };
455
456 let dst = &mut self.plane[band.plane][band.x + dst_y * self.stride[band.plane]..];
457 let stride = self.stride[band.plane] << band.ilevel;
458 let round = (band_mode & 8) != 0;
459 match band_mode {
460 0 => {}, // empty band
461 1 | 9 => {
462 decode_band(&mut br, &self.l_cb, dst, band.w, band.h, stride, scale, round, true)?;
463 },
464 2 | 10 => {
465 decode_band2(&mut br, &self.h_cb, dst, band.w, band.h, stride, scale, round)?;
466 },
467 5 => {
468 decode_band(&mut br, &self.l_cb, dst, band.w, band.h, stride, scale, false, false)?;
469 },
470 _ => return Err(DecoderError::InvalidData),
471 };
472 br.align();
473 },
474 0xD2 | 0xDA => {
475 let size = br.read(32)?;
476 validate!(size >= 4);
477 br.skip((size - 4) * 8)?;
478 },
479 0xD7 => {
480 let size = br.read(32)?;
481 validate!(size == 13);
482 br.read(16)?;
483 for _ in 0..3 {
484 br.read(16)?;
485 }
486 br.read(8)?;
487 },
488 0xDD => {
489 return Err(DecoderError::NotImplemented);
490 },
491 _ => {
492 return Err(DecoderError::NotImplemented);
493 },
494 };
495 if tag_id == 0 { break; }
496 }
497
498 let vinfo = self.info.get_properties().get_video_info().unwrap();
499 let bufinfo = alloc_video_buffer(vinfo, 2)?;
500 let mut buf = bufinfo.get_vbuf().unwrap();
501 let mut frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
502
503 self.reconstruct(&mut frm);
504
505 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
506 frm.set_keyframe(true);
507 frm.set_frame_type(FrameType::I);
508 Ok(frm.into_ref())
509 }
510 fn flush(&mut self) {
511 }
512}
513
514impl NAOptionHandler for MWV1Decoder {
515 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
516 fn set_options(&mut self, _options: &[NAOption]) { }
517 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
518}
519
520pub fn get_decoder() -> Box<dyn NADecoder + Send> {
521 Box::new(MWV1Decoder::new())
522}
523
524#[cfg(test)]
525mod test {
526 use nihav_core::codecs::RegisteredDecoders;
527 use nihav_core::demuxers::RegisteredDemuxers;
528 use nihav_codec_support::test::dec_video::*;
529 use crate::misc_register_all_decoders;
530 use nihav_commonfmt::generic_register_all_demuxers;
531 #[test]
532 fn test_mwv1() {
533 let mut dmx_reg = RegisteredDemuxers::new();
534 generic_register_all_demuxers(&mut dmx_reg);
535 let mut dec_reg = RegisteredDecoders::new();
536 misc_register_all_decoders(&mut dec_reg);
537 // sample: https://samples.mplayerhq.hu/V-codecs/MWV1/test.avi
538 test_decoding("avi", "mwv1", "assets/Misc/mwv1.avi", Some(2), &dmx_reg,
539 &dec_reg, ExpectedTestResult::MD5Frames(vec![
540 [0x9f2e0e5b, 0xa767c1ae, 0x8c009dca, 0x7159d0cd],
541 [0xfc00be21, 0x899736d0, 0x6b18dd40, 0x5261af2c],
542 [0xf113305d, 0xffac919f, 0x0b64890e, 0x18c60420]]));
543 }
544}
545
546const L_CODE_BITS: [u16; 256] = [
547 0xFF6B, 0xFF76, 0x0014, 0x00F0, 0xFF77, 0xFF78, 0xFF79, 0xFF7A,
548 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81, 0xFF82,
549 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A,
550 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90, 0xFF91, 0xFF92,
551 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97, 0xFF98, 0xFF99, 0xFF9A,
552 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F, 0xFFA0, 0xFFA1, 0xFFA2,
553 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6, 0xFFA7, 0xFFA8, 0xFFA9, 0xFFAA,
554 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF, 0xFFB0, 0xFFB1, 0xFFB2,
555 0xFFB3, 0xFFB4, 0xFF6C, 0xFFB5, 0xFFB6, 0xFF6D, 0xFFB7, 0xFF6E,
556 0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFF6F, 0xFF5B, 0xFFBC, 0xFF4F,
557 0xFFBD, 0xFF5C, 0xFFBE, 0xFFBF, 0xFF5D, 0xFF50, 0xFF5E, 0xFF70,
558 0xFF5F, 0xFF60, 0xFF61, 0x1FDC, 0xFF51, 0x1FDD, 0x1FDE, 0x1FDF,
559 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x0FE4, 0x0FE5, 0x07E8, 0x0FE6,
560 0x0FE7, 0x07E9, 0x07EA, 0x07EB, 0x07EC, 0x07ED, 0x07EE, 0x03EA,
561 0x03EB, 0x03EC, 0x01F0, 0x01F1, 0x01F2, 0x00F1, 0x00F2, 0x00F3,
562 0x0074, 0x0075, 0x0034, 0x0035, 0x0015, 0x0016, 0x0008, 0x0000,
563 0xFFC0, 0x0002, 0x0009, 0x0017, 0x0018, 0x0036, 0x0037, 0x0076,
564 0x0077, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x01F3, 0x01F4, 0x03ED,
565 0x03EE, 0x03EF, 0x03F0, 0x03F1, 0x03F2, 0x07EF, 0x07F0, 0x07F1,
566 0x03F3, 0x0FE8, 0x0FE9, 0x0FEA, 0x0FEB, 0x0FEC, 0x0FED, 0x1FE4,
567 0x1FE5, 0x1FE6, 0x1FE7, 0xFF52, 0x1FE8, 0x3FD2, 0xFF53, 0x7FA6,
568 0xFF62, 0xFF63, 0xFF54, 0xFF55, 0xFF64, 0xFF65, 0xFF71, 0xFF72,
569 0xFF56, 0xFF57, 0xFF58, 0xFF66, 0xFF67, 0xFF68, 0xFF69, 0xFF73,
570 0xFFC1, 0xFF74, 0xFFC2, 0xFF6A, 0xFF75, 0xFF59, 0xFF4E, 0xFF5A,
571 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7, 0xFFC8, 0xFFC9, 0xFFCA,
572 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF, 0xFFD0, 0xFFD1, 0xFFD2,
573 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7, 0xFFD8, 0xFFD9, 0xFFDA,
574 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF, 0xFFE0, 0xFFE1, 0xFFE2,
575 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7, 0xFFE8, 0xFFE9, 0xFFEA,
576 0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF, 0xFFF0, 0xFFF1, 0xFFF2,
577 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA,
578 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0x0003, 0x0019, 0x0038, 0x0039
579];
580const L_CODE_LENS: [u8; 256] = [
581 16, 16, 5, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
582 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
583 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
584 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
585 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
586 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 13, 13, 13,
587 13, 13, 13, 13, 12, 12, 11, 12, 12, 11, 11, 11, 11, 11, 11, 10,
588 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 2,
589 16, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 10,
590 10, 10, 10, 10, 10, 11, 11, 11, 10, 12, 12, 12, 12, 12, 12, 13,
591 13, 13, 13, 16, 13, 14, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16,
592 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
593 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
594 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
595 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
596 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 3, 5, 6, 6
597];
598const H_CODE_BITS: [u16; 256] = [
599 0xFFFF, 0xFFE5, 0xFFE6, 0xFFE7, 0xFFE8, 0xFFE9, 0xFFEA, 0xFFEB,
600 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF, 0xFFF0, 0xFFE0, 0xFFDB, 0xFFDC,
601 0xFFDA, 0xFFD5, 0xFFD6, 0x1FF6, 0x1FF7, 0x0FEE, 0x0FEF, 0x07E0,
602 0x07E1, 0x03E4, 0x01E4, 0x00E8, 0x006E, 0x0032, 0x0016, 0x0000,
603 0x0000, 0x0001, 0x0017, 0x0033, 0x006F, 0x00E9, 0x01E5, 0x03E5,
604 0x07E2, 0x07E3, 0x07E4, 0x0FF0, 0x1FF8, 0xFFD7, 0xFFD8, 0xFFD9,
605 0xFFDD, 0xFFDE, 0xFFE1, 0xFFE2, 0xFFF1, 0xFFF2, 0xFFE3, 0xFFF3,
606 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB,
607 0xFFFC, 0x0004, 0x000A, 0x0018, 0x0034, 0x0035, 0x0036, 0x0070,
608 0x0071, 0x0072, 0x0073, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE,
609 0x00EF, 0x01E6, 0x01E7, 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC,
610 0x01ED, 0x01EE, 0x03E6, 0x03E7, 0x03E8, 0x03E9, 0x03EA, 0x03EB,
611 0x03EC, 0x03ED, 0x03EE, 0x07E5, 0x07E6, 0x07E7, 0x07E8, 0x07E9,
612 0x07EA, 0x07EB, 0x07EC, 0x07ED, 0x07EE, 0x07EF, 0x07F0, 0x07F1,
613 0x07F2, 0x07F3, 0x07F4, 0x0FF1, 0x0FF2, 0x0FF3, 0x0FF4, 0x0FF5,
614 0x0FF6, 0x0FF7, 0x0FF8, 0x0FF9, 0x0000, 0x0000, 0x0000, 0x0000,
615 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
616 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
617 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
618 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
619 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
620 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
621 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
622 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
623 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
624 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
625 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
626 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
627 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
628 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFDF,
629 0x1FF9, 0x3FF4, 0x0FFA, 0x07F5, 0x00F0, 0x00F1, 0x01EF, 0x01F0,
630 0x01F1, 0x03EF, 0x07F6, 0x0000, 0x0000, 0xFFD4, 0xFFFD, 0xFFFE
631];
632const H_CODE_LENS: [u8; 256] = [
633 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
634 16, 16, 16, 13, 13, 12, 12, 11, 11, 10, 9, 8, 7, 6, 5, 2,
635 0, 2, 5, 6, 7, 8, 9, 10, 11, 11, 11, 12, 13, 16, 16, 16,
636 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
637 16, 3, 4, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8,
638 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10,
639 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
640 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0, 0, 0,
641 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
643 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
644 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
645 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
646 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
647 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
648 13, 14, 12, 11, 8, 8, 9, 9, 9, 10, 11, 0, 0, 16, 16, 16
649];