1 use nihav_core::io::byteio::{ByteReader,MemoryReader};
2 use nihav_core::io::bitreader::*;
3 use nihav_core::io::codebook::*;
4 use nihav_core::codecs::*;
5 use nihav_codec_support::codecs::ZIGZAG;
15 const ROW_SHIFT: u8 = 8;
16 const COL_SHIFT: u8 = 14;
18 fn idct_row(row: &mut [i16]) {
19 let in0 = ((i32::from(row[0])) << 11) + (1 << (ROW_SHIFT - 1));
20 let in1 = (i32::from(row[4])) << 11;
21 let in2 = i32::from(row[6]);
22 let in3 = i32::from(row[2]);
23 let in4 = i32::from(row[1]);
24 let in5 = i32::from(row[7]);
25 let in6 = i32::from(row[5]);
26 let in7 = i32::from(row[3]);
28 let tmp = W7 * (in4 + in5);
29 let a4 = tmp + (W1 - W7) * in4;
30 let a5 = tmp - (W1 + W7) * in5;
32 let tmp = W3 * (in6 + in7);
33 let a6 = tmp - (W3 - W5) * in6;
34 let a7 = tmp - (W3 + W5) * in7;
39 let t1 = W6 * (in2 + in3);
40 let a2 = t1 - (W2 + W6) * in2;
41 let a3 = t1 + (W2 - W6) * in3;
51 let b2 = (W8 * (b4 + t2) + 128) >> 8;
52 let b4 = (W8 * (b4 - t2) + 128) >> 8;
54 row[0] = ((b7 + b1) >> ROW_SHIFT) as i16;
55 row[7] = ((b7 - b1) >> ROW_SHIFT) as i16;
56 row[1] = ((b3 + b2) >> ROW_SHIFT) as i16;
57 row[6] = ((b3 - b2) >> ROW_SHIFT) as i16;
58 row[2] = ((b0 + b4) >> ROW_SHIFT) as i16;
59 row[5] = ((b0 - b4) >> ROW_SHIFT) as i16;
60 row[3] = ((b5 + b6) >> ROW_SHIFT) as i16;
61 row[4] = ((b5 - b6) >> ROW_SHIFT) as i16;
64 #[allow(clippy::erasing_op)]
65 #[allow(clippy::identity_op)]
66 fn idct_col(blk: &mut [i16; 64], off: usize) {
67 let in0 = ((i32::from(blk[off + 0*8])) << 8) + (1 << (COL_SHIFT - 1));
68 let in1 = (i32::from(blk[off + 4*8])) << 8;
69 let in2 = i32::from(blk[off + 6*8]);
70 let in3 = i32::from(blk[off + 2*8]);
71 let in4 = i32::from(blk[off + 1*8]);
72 let in5 = i32::from(blk[off + 7*8]);
73 let in6 = i32::from(blk[off + 5*8]);
74 let in7 = i32::from(blk[off + 3*8]);
76 let tmp = W7 * (in4 + in5);
77 let a4 = (tmp + (W1 - W7) * in4) >> 3;
78 let a5 = (tmp - (W1 + W7) * in5) >> 3;
80 let tmp = W3 * (in6 + in7);
81 let a6 = (tmp - (W3 - W5) * in6) >> 3;
82 let a7 = (tmp - (W3 + W5) * in7) >> 3;
87 let t1 = W6 * (in2 + in3);
88 let a2 = (t1 - (W2 + W6) * in2) >> 3;
89 let a3 = (t1 + (W2 - W6) * in3) >> 3;
99 let b2 = (W8 * (b4 + t2) + 128) >> 8;
100 let b4 = (W8 * (b4 - t2) + 128) >> 8;
102 blk[off + 0*8] = ((b7 + b1) >> COL_SHIFT) as i16;
103 blk[off + 7*8] = ((b7 - b1) >> COL_SHIFT) as i16;
104 blk[off + 1*8] = ((b3 + b2) >> COL_SHIFT) as i16;
105 blk[off + 6*8] = ((b3 - b2) >> COL_SHIFT) as i16;
106 blk[off + 2*8] = ((b0 + b4) >> COL_SHIFT) as i16;
107 blk[off + 5*8] = ((b0 - b4) >> COL_SHIFT) as i16;
108 blk[off + 3*8] = ((b5 + b6) >> COL_SHIFT) as i16;
109 blk[off + 4*8] = ((b5 - b6) >> COL_SHIFT) as i16;
112 fn idct(blk: &mut [i16; 64]) {
113 for i in 0..8 { idct_row(&mut blk[i*8..(i+1)*8]); }
114 for i in 0..8 { idct_col(blk, i); }
117 fn put_block(blk: &[i16; 64], dst: &mut [u8], stride: usize) {
118 for (drow, srow) in dst.chunks_mut(stride).zip(blk.chunks(8)) {
119 for (del, &pix) in drow.iter_mut().zip(srow.iter()) {
120 *del = pix.max(0).min(255) as u8;
125 #[derive(Clone,Copy,Default)]
126 struct ComponentInfo {
132 #[derive(Debug,PartialEq)]
146 info: NACodecInfoRef,
147 quant: [[i16; 64]; 4],
148 qselect: [u8; MAX_CHROMATONS],
149 comp_id: [u8; MAX_CHROMATONS],
150 subsamp: [u8; MAX_CHROMATONS],
151 codebook: [[Option<Codebook<u8>>; 4]; 2],
158 fn read_dc(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<i16> {
159 let cat = br.read_cb(cb)?;
164 let add_bits = br.read(cat)? as i16;
165 let pivot = 1 << (cat - 1);
166 if add_bits < pivot {
167 Ok(add_bits + 1 - pivot * 2)
174 fn read_ac(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<(usize, i16)> {
175 let val = br.read_cb(cb)?;
176 let run = usize::from(val >> 4);
178 let level = if cat != 0 {
180 let add_bits = br.read(cat)? as i16;
181 let pivot = 1 << (cat - 1);
182 if add_bits < pivot {
183 add_bits + 1 - pivot * 2
188 validate!(run == 0 || run == 15);
194 fn read_block(br: &mut BitReader, blk: &mut [i16; 64], dc_cb: &Codebook<u8>, ac_cb: &Codebook<u8>, ss: usize, se: usize, qmat: &[i16; 64]) -> DecoderResult<()> {
196 blk[0] = read_dc(br, dc_cb)?;
201 let (run, level) = read_ac(br, ac_cb)?;
202 if run == 0 && level == 0 {
207 blk[ZIGZAG[idx]] = level * qmat[idx];
215 let dummy_info = NACodecInfo::new_dummy();
220 qselect: [0; MAX_CHROMATONS],
221 subsamp: [0; MAX_CHROMATONS],
222 comp_id: [0; MAX_CHROMATONS],
223 codebook: [[None, None, None, None], [None, None, None, None]],
230 fn reset(&mut self) {
231 self.quant = [[0; 64]; 4];
232 self.codebook = [[None, None, None, None], [None, None, None, None]];
238 fn parse_sof(&mut self, br: &mut ByteReader) -> DecoderResult<NABufferType> {
239 validate!(self.width == 0);
241 let len = br.read_u16be()? as usize;
242 validate!(len >= 11);
243 let p = br.read_byte()?;
246 return Err(DecoderError::NotImplemented);
248 let y = br.read_u16be()? as usize;
249 let x = br.read_u16be()? as usize;
252 return Err(DecoderError::NotImplemented);
257 let nf = br.read_byte()? as usize;
259 validate!(len == 8 + nf * 3);
260 if nf > MAX_CHROMATONS {
261 return Err(DecoderError::NotImplemented);
266 let c = br.read_byte()?;
268 let hv = br.read_byte()?;
269 let t = br.read_byte()?;
272 self.subsamp[i] = hv;
274 validate!(hs == 1 || hs == 2);
276 validate!(vs == 1 || vs == 2);
277 max_h = max_h.max(hs);
278 max_v = max_v.max(vs);
280 let mut chromatons = [None; MAX_CHROMATONS];
281 for (i, chr) in chromatons[..nf].iter_mut().enumerate() {
282 let h_ss = match max_h / (self.subsamp[i] >> 4) {
287 let v_ss = match max_v / (self.subsamp[i] & 0xF) {
290 _ => return Err(DecoderError::InvalidData),
293 *chr = Some(NAPixelChromaton {
299 next_elem: (p + 7) >> 3,
304 validate!(self.comp_id[i] != self.comp_id[j]);
307 let formaton = NAPixelFormaton {
308 model: ColorModel::YUV(YUVSubmodel::YUVJ),
309 components: nf as u8,
310 comp_info: chromatons,
313 alpha: nf == 2 || nf == 4,
316 let vinfo = NAVideoInfo::new(x, y, false, formaton);
317 Ok(alloc_video_buffer(vinfo, 4)?)
320 fn decode_scan(&mut self, src: &[u8], mut buf: NAVideoBufferRef<u8>, ci: &[ComponentInfo], ss: usize, se: usize) -> DecoderResult<usize> {
321 let num_components = ci.len();
322 let mut last_dc = [1024; MAX_CHROMATONS];
323 let mut dc_cbs = Vec::with_capacity(num_components);
324 let mut ac_cbs = Vec::with_capacity(num_components);
325 let mut qmats = [&self.quant[0]; MAX_CHROMATONS];
326 for (i, cinfo) in ci.iter().enumerate() {
327 dc_cbs.push(if let Some(ref cb) = self.codebook[0][cinfo.dc_table_id] {
329 } else { unreachable!(); });
330 ac_cbs.push(if let Some(ref cb) = self.codebook[1][cinfo.ac_table_id] {
332 } else { unreachable!(); });
333 qmats[i] = &self.quant[self.qselect[cinfo.component_id] as usize];
336 let frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
338 let mut br = BitReader::new(src, BitReaderMode::BE);
340 let mut offs = frm.offset;
341 let mut nblks = [0; MAX_CHROMATONS];
342 let mut xstep = [0; MAX_CHROMATONS];
343 let mut ystep = [0; MAX_CHROMATONS];
346 for i in 0..num_components {
347 let hs = (self.subsamp[i] >> 4) as usize;
348 let vs = (self.subsamp[i] & 0xF) as usize;
349 hstep = hstep.max(hs * 8);
350 vstep = vstep.max(vs * 8);
357 for _y in (0..self.height).step_by(vstep) {
358 for x in 0..(self.width + hstep - 1) / hstep {
359 for i in 0..num_components {
360 blocks = [[0; 64]; 4];
361 for blk in blocks[..nblks[i]].iter_mut() {
362 read_block(&mut br, blk, dc_cbs[i], ac_cbs[i], ss, se, qmats[i])?;
363 blk[0] += last_dc[i];
367 match self.subsamp[i] {
369 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
372 put_block(&blocks[0], &mut frm.data[offs[i] + x * 16..], frm.stride[i]);
373 put_block(&blocks[1], &mut frm.data[offs[i] + x * 16 + 8..], frm.stride[i]);
376 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
377 put_block(&blocks[1], &mut frm.data[offs[i] + x * 8 + frm.stride[i] * 8..], frm.stride[i]);
380 #[allow(clippy::needless_range_loop)]
382 put_block(&blocks[j], &mut frm.data[offs[i] + x * 16 + (j & 1) * 8 + (j >> 1) * 8 * frm.stride[i]..], frm.stride[i]);
389 for i in 0..num_components {
390 offs[i] += frm.stride[i] * ystep[i];
394 Ok((br.tell() + 7) / 8)
398 struct HuffDescReader<'a> {
404 impl<'a> CodebookDescReader<u8> for HuffDescReader<'a> {
405 fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] }
406 fn code(&mut self, idx: usize) -> u32 { u32::from(self.codes[idx]) }
407 fn sym (&mut self, idx: usize) -> u8 { self.syms[idx] }
408 fn len(&mut self) -> usize { self.syms.len() }
411 fn generate_cb(lens: &[u8; 16], syms: &[u8]) -> DecoderResult<Codebook<u8>> {
412 let mut codes = [0; 256];
413 let mut bits = [0; 256];
415 let mut iter = bits.iter_mut();
416 for (i, &len) in lens.iter().enumerate() {
418 *iter.next().unwrap() = (i + 1) as u8;
422 let mut si = bits[0];
424 while idx < syms.len() {
425 while idx < syms.len() && bits[idx] == si {
430 while idx < syms.len() && bits[idx] != si {
436 let mut cbr = HuffDescReader { codes: &codes, bits: &bits, syms };
437 Ok(Codebook::new(&mut cbr, CodebookMode::MSB)?)
440 fn build_default_cb(dc: bool, idx: usize) -> DecoderResult<Codebook<u8>> {
442 generate_cb(&DC_LENS[idx], &DC_SYMS)
444 generate_cb(&AC_LENS[idx], AC_SYMS[idx])
448 impl NADecoder for JPEGDecoder {
449 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
450 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
451 let w = vinfo.get_width();
452 let h = vinfo.get_height();
453 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, YUV420_FORMAT));
454 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
457 Err(DecoderError::InvalidData)
460 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
461 let src = pkt.get_buffer();
462 if src.len() <= 4 { return Err(DecoderError::ShortData); }
464 let mut bufinfo = NABufferType::None;
465 let mut mr = MemoryReader::new_read(&src);
466 let mut br = ByteReader::new(&mut mr);
467 let start_tag = br.read_u16be()?;
468 validate!(start_tag == 0xFFD8);
470 let mut jtype = JPEGType::None;
471 let mut arith = false;
474 let tag = br.read_u16be()?;
476 0xFFC0 => { //baseline DCT header
477 jtype = JPEGType::Baseline;
479 bufinfo = self.parse_sof(&mut br)?;
482 jtype = JPEGType::Extended;
484 bufinfo = self.parse_sof(&mut br)?;
487 jtype = JPEGType::Progressive;
489 bufinfo = self.parse_sof(&mut br)?;
492 jtype = JPEGType::Lossless;
494 bufinfo = self.parse_sof(&mut br)?;
497 jtype = JPEGType::Differential;
499 bufinfo = self.parse_sof(&mut br)?;
502 jtype = JPEGType::DiffProgressive;
504 bufinfo = self.parse_sof(&mut br)?;
507 jtype = JPEGType::DiffLossless;
509 bufinfo = self.parse_sof(&mut br)?;
511 0xFFC8 => return Err(DecoderError::NotImplemented),
513 jtype = JPEGType::Extended;
515 bufinfo = self.parse_sof(&mut br)?;
518 jtype = JPEGType::Progressive;
520 bufinfo = self.parse_sof(&mut br)?;
523 jtype = JPEGType::Lossless;
525 bufinfo = self.parse_sof(&mut br)?;
528 jtype = JPEGType::Differential;
530 bufinfo = self.parse_sof(&mut br)?;
533 jtype = JPEGType::DiffProgressive;
535 bufinfo = self.parse_sof(&mut br)?;
538 jtype = JPEGType::DiffLossless;
540 bufinfo = self.parse_sof(&mut br)?;
542 0xFFC4 => { //huff table
544 let len = u64::from(br.read_u16be()?);
546 let end = br.tell() + len - 2;
547 let mut lens = [0; 16];
548 let mut syms = [0; 256];
549 while br.tell() < end {
550 let tctn = br.read_byte()? as usize;
551 let tclass = tctn >> 4;
552 validate!(tclass < 2);
555 br.read_buf(&mut lens)?;
556 let mut tot_len = 0usize;
557 for &el in lens.iter() {
558 tot_len += usize::from(el);
560 validate!(tot_len > 0 && tot_len <= 256);
561 br.read_buf(&mut syms[..tot_len])?;
562 self.codebook[tclass][id] = Some(generate_cb(&lens, &syms[..tot_len])?);
564 validate!(br.tell() == end);
566 0xFFCC => { // arith coding conditioning
567 return Err(DecoderError::NotImplemented);
569 0xFFD0..=0xFFD7 => return Err(DecoderError::NotImplemented),
571 0xFFDA => { //start of scan
572 let len = br.read_u16be()? as usize;
573 let ns = br.read_byte()? as usize;
574 validate!(len == ns * 2 + 6);
575 let mut ci = [ComponentInfo::default(); MAX_CHROMATONS];
576 for info in ci[..ns].iter_mut() {
577 let id = br.read_byte()?;
578 let mut found = false;
579 for (i, &c_id) in self.comp_id.iter().enumerate() {
581 info.component_id = i;
587 let tdta = br.read_byte()? as usize;
588 let dc_id = tdta >> 4;
589 validate!(dc_id < 4);
590 if self.codebook[0][dc_id].is_none() {
591 validate!(dc_id < 2);
592 self.codebook[0][dc_id] = Some(build_default_cb(true, dc_id)?);
594 let ac_id = tdta & 0xF;
595 validate!(ac_id < 4);
596 if self.codebook[1][ac_id].is_none() {
597 validate!(ac_id < 2);
598 self.codebook[1][ac_id] = Some(build_default_cb(false, ac_id)?);
600 info.dc_table_id = dc_id;
601 info.ac_table_id = ac_id;
603 let ss = br.read_byte()? as usize;
604 let se = br.read_byte()? as usize;
605 let ahal = br.read_byte()?;
609 JPEGType::Baseline | JPEGType::Extended => {
611 return Err(DecoderError::NotImplemented);
613 validate!(ss == 0 && se == 63);
614 validate!(ah == 0 && al == 0);
615 if let Some(buf) = bufinfo.get_vbuf() {
616 let max_size = src.len() - (br.tell() as usize);
618 self.buf.reserve(max_size);
620 let b = br.read_byte()?;
624 let b2 = br.read_byte()?;
628 br.seek(std::io::SeekFrom::Current(-2))?;
634 let mut data = Vec::new();
635 std::mem::swap(&mut self.buf, &mut data);
636 let ret = self.decode_scan(&data, buf, &ci[..ns], ss, se);
637 std::mem::swap(&mut self.buf, &mut data);
639 } else { unreachable!(); }
641 JPEGType::Progressive => {
642 validate!(ss < 64 && se < 64 && se >= ss);
643 validate!(ah < 14 && al < 14);
644 return Err(DecoderError::NotImplemented);
646 JPEGType::Lossless => {
647 validate!(ss >= 1 && ss < 8 && se == 0);
649 return Err(DecoderError::NotImplemented);
651 _ => return Err(DecoderError::NotImplemented),
653 let tag = br.peek_u16be()?;
654 validate!((tag >= 0xFFD0 && tag <= 0xFFD7) || (tag == 0xFFD9));
656 0xFFDB => { //quant tables
657 let mut len = br.read_u16be()? as usize;
658 validate!(len >= 64 + 3);
661 let pt = br.read_byte()?;
662 let precision = pt >> 4;
663 validate!(precision < 2);
664 let id = (pt & 0xF) as usize;
666 let qsize = if precision == 0 { 64 } else { 64 * 2 } + 1;
667 validate!(len >= qsize);
669 for el in self.quant[id].iter_mut() {
670 *el = i16::from(br.read_byte()?);
673 for el in self.quant[id].iter_mut() {
674 *el = br.read_u16be()? as i16;
680 0xFFDC => { //number of lines
681 return Err(DecoderError::NotImplemented);
684 let len = br.read_u16be()?;
686 let ri = br.read_u16be()?;
688 println!("restart interval {}", ri);
689 return Err(DecoderError::NotImplemented);
692 0xFFDE => return Err(DecoderError::NotImplemented),
693 0xFFDF => return Err(DecoderError::NotImplemented),
694 0xFFE0..=0xFFEF => { // application data
695 let len = br.read_u16be()? as usize;
697 br.read_skip(len - 2)?;
699 0xFFF0..=0xFFF6 => return Err(DecoderError::NotImplemented),
701 //jtype = JPEGType::JPEGLS;
703 return Err(DecoderError::NotImplemented);
705 0xFFF8 => return Err(DecoderError::NotImplemented), //JPEG-LS parameters
706 0xFFF9..=0xFFFD => return Err(DecoderError::NotImplemented),
707 0xFFFE => { //comment
708 let len = br.read_u16be()? as usize;
710 br.read_skip(len - 2)?;
712 0xFF01 => return Err(DecoderError::NotImplemented),
713 0xFF02..=0xFFBF => return Err(DecoderError::NotImplemented),
714 _ => return Err(DecoderError::InvalidData),
717 validate!(jtype != JPEGType::None);
719 if let NABufferType::None = bufinfo {
720 return Err(DecoderError::InvalidData);
723 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
724 frm.set_keyframe(true);
725 frm.set_frame_type(FrameType::I);
728 fn flush(&mut self) {
732 impl NAOptionHandler for JPEGDecoder {
733 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
734 fn set_options(&mut self, _options: &[NAOption]) { }
735 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
738 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
739 Box::new(JPEGDecoder::new())
744 use nihav_core::codecs::RegisteredDecoders;
745 use nihav_core::demuxers::RegisteredDemuxers;
746 use nihav_codec_support::test::dec_video::*;
747 use crate::generic_register_all_decoders;
748 use crate::generic_register_all_demuxers;
751 let mut dmx_reg = RegisteredDemuxers::new();
752 generic_register_all_demuxers(&mut dmx_reg);
753 let mut dec_reg = RegisteredDecoders::new();
754 generic_register_all_decoders(&mut dec_reg);
755 // sample: self-created with avconv
756 test_decoding("avi", "jpeg", "assets/Misc/mjpeg.avi", Some(1), &dmx_reg,
757 &dec_reg, ExpectedTestResult::MD5Frames(vec![
758 [0xe07f7128, 0x8c55eb5d, 0x03bfdee5, 0x358b24a4],
759 [0xd3ec3f92, 0x1664c56d, 0xfc049754, 0xf65165b9]]));
763 const DC_LENS: [[u8; 16]; 2] = [
764 [ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ],
765 [ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ]
767 const DC_SYMS: [u8; 12] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
768 const AC_LENS: [[u8; 16]; 2] = [
769 [ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 ],
770 [ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 ]
772 const AC_SYMS: [&[u8]; 2] = [
774 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
775 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
776 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
777 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
778 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
779 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
780 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
781 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
782 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
783 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
784 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
785 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
786 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
787 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
788 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
789 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
790 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
791 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
792 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
793 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
797 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
798 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
799 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
800 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
801 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
802 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
803 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
804 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
805 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
806 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
807 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
808 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
809 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
810 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
811 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
812 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
813 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
814 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
815 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
816 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,