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 #[allow(clippy::erasing_op)]
19 fn idct_row(row: &mut [i16]) {
20 let in0 = ((i32::from(row[0])) << 11) + (1 << (ROW_SHIFT - 1));
21 let in1 = (i32::from(row[4])) << 11;
22 let in2 = i32::from(row[6]);
23 let in3 = i32::from(row[2]);
24 let in4 = i32::from(row[1]);
25 let in5 = i32::from(row[7]);
26 let in6 = i32::from(row[5]);
27 let in7 = i32::from(row[3]);
29 let tmp = W7 * (in4 + in5);
30 let a4 = tmp + (W1 - W7) * in4;
31 let a5 = tmp - (W1 + W7) * in5;
33 let tmp = W3 * (in6 + in7);
34 let a6 = tmp - (W3 - W5) * in6;
35 let a7 = tmp - (W3 + W5) * in7;
40 let t1 = W6 * (in2 + in3);
41 let a2 = t1 - (W2 + W6) * in2;
42 let a3 = t1 + (W2 - W6) * in3;
52 let b2 = (W8 * (b4 + t2) + 128) >> 8;
53 let b4 = (W8 * (b4 - t2) + 128) >> 8;
55 row[0] = ((b7 + b1) >> ROW_SHIFT) as i16;
56 row[7] = ((b7 - b1) >> ROW_SHIFT) as i16;
57 row[1] = ((b3 + b2) >> ROW_SHIFT) as i16;
58 row[6] = ((b3 - b2) >> ROW_SHIFT) as i16;
59 row[2] = ((b0 + b4) >> ROW_SHIFT) as i16;
60 row[5] = ((b0 - b4) >> ROW_SHIFT) as i16;
61 row[3] = ((b5 + b6) >> ROW_SHIFT) as i16;
62 row[4] = ((b5 - b6) >> ROW_SHIFT) as i16;
65 #[allow(clippy::erasing_op)]
66 #[allow(clippy::identity_op)]
67 fn idct_col(blk: &mut [i16; 64], off: usize) {
68 let in0 = ((i32::from(blk[off + 0*8])) << 8) + (1 << (COL_SHIFT - 1));
69 let in1 = (i32::from(blk[off + 4*8])) << 8;
70 let in2 = i32::from(blk[off + 6*8]);
71 let in3 = i32::from(blk[off + 2*8]);
72 let in4 = i32::from(blk[off + 1*8]);
73 let in5 = i32::from(blk[off + 7*8]);
74 let in6 = i32::from(blk[off + 5*8]);
75 let in7 = i32::from(blk[off + 3*8]);
77 let tmp = W7 * (in4 + in5);
78 let a4 = (tmp + (W1 - W7) * in4) >> 3;
79 let a5 = (tmp - (W1 + W7) * in5) >> 3;
81 let tmp = W3 * (in6 + in7);
82 let a6 = (tmp - (W3 - W5) * in6) >> 3;
83 let a7 = (tmp - (W3 + W5) * in7) >> 3;
88 let t1 = W6 * (in2 + in3);
89 let a2 = (t1 - (W2 + W6) * in2) >> 3;
90 let a3 = (t1 + (W2 - W6) * in3) >> 3;
100 let b2 = (W8 * (b4 + t2) + 128) >> 8;
101 let b4 = (W8 * (b4 - t2) + 128) >> 8;
103 blk[off + 0*8] = ((b7 + b1) >> COL_SHIFT) as i16;
104 blk[off + 7*8] = ((b7 - b1) >> COL_SHIFT) as i16;
105 blk[off + 1*8] = ((b3 + b2) >> COL_SHIFT) as i16;
106 blk[off + 6*8] = ((b3 - b2) >> COL_SHIFT) as i16;
107 blk[off + 2*8] = ((b0 + b4) >> COL_SHIFT) as i16;
108 blk[off + 5*8] = ((b0 - b4) >> COL_SHIFT) as i16;
109 blk[off + 3*8] = ((b5 + b6) >> COL_SHIFT) as i16;
110 blk[off + 4*8] = ((b5 - b6) >> COL_SHIFT) as i16;
113 fn idct(blk: &mut [i16; 64]) {
114 for i in 0..8 { idct_row(&mut blk[i*8..(i+1)*8]); }
115 for i in 0..8 { idct_col(blk, i); }
118 fn put_block(blk: &[i16; 64], dst: &mut [u8], stride: usize) {
119 for (drow, srow) in dst.chunks_mut(stride).zip(blk.chunks(8)) {
120 for (del, &pix) in drow.iter_mut().zip(srow.iter()) {
121 *del = pix.max(0).min(255) as u8;
126 #[derive(Clone,Copy,Default)]
127 struct ComponentInfo {
133 #[derive(Debug,PartialEq)]
148 info: NACodecInfoRef,
149 quant: [[i16; 64]; 4],
150 qselect: [u8; MAX_CHROMATONS],
151 comp_id: [u8; MAX_CHROMATONS],
152 subsamp: [u8; MAX_CHROMATONS],
153 codebook: [[Option<Codebook<u8>>; 4]; 2],
160 fn read_dc(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<i16> {
161 let cat = br.read_cb(cb)?;
166 let add_bits = br.read(cat)? as i16;
167 let pivot = 1 << (cat - 1);
168 if add_bits < pivot {
169 Ok(add_bits + 1 - pivot * 2)
176 fn read_ac(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<(usize, i16)> {
177 let val = br.read_cb(cb)?;
178 let run = usize::from(val >> 4);
180 let level = if cat != 0 {
182 let add_bits = br.read(cat)? as i16;
183 let pivot = 1 << (cat - 1);
184 if add_bits < pivot {
185 add_bits + 1 - pivot * 2
190 validate!(run == 0 || run == 15);
196 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<()> {
198 blk[0] = read_dc(br, dc_cb)?;
203 let (run, level) = read_ac(br, ac_cb)?;
204 if run == 0 && level == 0 {
209 blk[ZIGZAG[idx]] = level * qmat[idx];
217 let dummy_info = NACodecInfo::new_dummy();
222 qselect: [0; MAX_CHROMATONS],
223 subsamp: [0; MAX_CHROMATONS],
224 comp_id: [0; MAX_CHROMATONS],
225 codebook: [[None, None, None, None], [None, None, None, None]],
232 fn reset(&mut self) {
233 self.quant = [[0; 64]; 4];
234 self.codebook = [[None, None, None, None], [None, None, None, None]];
240 #[allow(clippy::many_single_char_names)]
241 fn parse_sof(&mut self, br: &mut ByteReader) -> DecoderResult<NABufferType> {
242 validate!(self.width == 0);
244 let len = br.read_u16be()? as usize;
245 validate!(len >= 11);
246 let p = br.read_byte()?;
249 return Err(DecoderError::NotImplemented);
251 let y = br.read_u16be()? as usize;
252 let x = br.read_u16be()? as usize;
255 return Err(DecoderError::NotImplemented);
260 let nf = br.read_byte()? as usize;
262 validate!(len == 8 + nf * 3);
263 if nf > MAX_CHROMATONS {
264 return Err(DecoderError::NotImplemented);
269 let c = br.read_byte()?;
271 let hv = br.read_byte()?;
272 let t = br.read_byte()?;
275 self.subsamp[i] = hv;
277 validate!(hs == 1 || hs == 2);
279 validate!(vs == 1 || vs == 2);
280 max_h = max_h.max(hs);
281 max_v = max_v.max(vs);
283 let mut chromatons = [None; MAX_CHROMATONS];
284 for (i, chr) in chromatons[..nf].iter_mut().enumerate() {
285 let h_ss = match max_h / (self.subsamp[i] >> 4) {
290 let v_ss = match max_v / (self.subsamp[i] & 0xF) {
293 _ => return Err(DecoderError::InvalidData),
296 *chr = Some(NAPixelChromaton {
302 next_elem: (p + 7) >> 3,
307 validate!(self.comp_id[i] != self.comp_id[j]);
310 let formaton = NAPixelFormaton {
311 model: ColorModel::YUV(YUVSubmodel::YUVJ),
312 components: nf as u8,
313 comp_info: chromatons,
316 alpha: nf == 2 || nf == 4,
319 let vinfo = NAVideoInfo::new(x, y, false, formaton);
320 Ok(alloc_video_buffer(vinfo, 4)?)
323 fn decode_scan(&mut self, src: &[u8], mut buf: NAVideoBufferRef<u8>, ci: &[ComponentInfo], ss: usize, se: usize) -> DecoderResult<usize> {
324 let num_components = ci.len();
325 let mut last_dc = [1024; MAX_CHROMATONS];
326 let mut dc_cbs = Vec::with_capacity(num_components);
327 let mut ac_cbs = Vec::with_capacity(num_components);
328 let mut qmats = [&self.quant[0]; MAX_CHROMATONS];
329 for (i, cinfo) in ci.iter().enumerate() {
330 dc_cbs.push(if let Some(ref cb) = self.codebook[0][cinfo.dc_table_id] {
332 } else { unreachable!(); });
333 ac_cbs.push(if let Some(ref cb) = self.codebook[1][cinfo.ac_table_id] {
335 } else { unreachable!(); });
336 qmats[i] = &self.quant[self.qselect[cinfo.component_id] as usize];
339 let frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
341 let mut br = BitReader::new(src, BitReaderMode::BE);
343 let mut offs = frm.offset;
344 let mut nblks = [0; MAX_CHROMATONS];
345 let mut xstep = [0; MAX_CHROMATONS];
346 let mut ystep = [0; MAX_CHROMATONS];
349 for i in 0..num_components {
350 let hs = (self.subsamp[i] >> 4) as usize;
351 let vs = (self.subsamp[i] & 0xF) as usize;
352 hstep = hstep.max(hs * 8);
353 vstep = vstep.max(vs * 8);
360 for _y in (0..self.height).step_by(vstep) {
361 for x in 0..(self.width + hstep - 1) / hstep {
362 for i in 0..num_components {
363 blocks = [[0; 64]; 4];
364 for blk in blocks[..nblks[i]].iter_mut() {
365 read_block(&mut br, blk, dc_cbs[i], ac_cbs[i], ss, se, qmats[i])?;
366 blk[0] += last_dc[i];
370 match self.subsamp[i] {
372 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
375 put_block(&blocks[0], &mut frm.data[offs[i] + x * 16..], frm.stride[i]);
376 put_block(&blocks[1], &mut frm.data[offs[i] + x * 16 + 8..], frm.stride[i]);
379 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
380 put_block(&blocks[1], &mut frm.data[offs[i] + x * 8 + frm.stride[i] * 8..], frm.stride[i]);
384 put_block(&blocks[j], &mut frm.data[offs[i] + x * 16 + (j & 1) * 8 + (j >> 1) * 8 * frm.stride[i]..], frm.stride[i]);
391 for i in 0..num_components {
392 offs[i] += frm.stride[i] * ystep[i];
396 Ok((br.tell() + 7) / 8)
400 struct HuffDescReader<'a> {
406 impl<'a> CodebookDescReader<u8> for HuffDescReader<'a> {
407 fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] }
408 fn code(&mut self, idx: usize) -> u32 { u32::from(self.codes[idx]) }
409 fn sym (&mut self, idx: usize) -> u8 { self.syms[idx] }
410 fn len(&mut self) -> usize { self.syms.len() }
413 fn generate_cb(lens: &[u8; 16], syms: &[u8]) -> DecoderResult<Codebook<u8>> {
414 let mut codes = [0; 256];
415 let mut bits = [0; 256];
417 let mut iter = bits.iter_mut();
418 for (i, &len) in lens.iter().enumerate() {
420 *iter.next().unwrap() = (i + 1) as u8;
424 let mut si = bits[0];
426 while idx < syms.len() {
427 while idx < syms.len() && bits[idx] == si {
432 while idx < syms.len() && bits[idx] != si {
438 let mut cbr = HuffDescReader { codes: &codes, bits: &bits, syms };
439 Ok(Codebook::new(&mut cbr, CodebookMode::MSB)?)
442 fn build_default_cb(dc: bool, idx: usize) -> DecoderResult<Codebook<u8>> {
444 generate_cb(&DC_LENS[idx], &DC_SYMS)
446 generate_cb(&AC_LENS[idx], AC_SYMS[idx])
450 impl NADecoder for JPEGDecoder {
451 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
452 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
453 let w = vinfo.get_width();
454 let h = vinfo.get_height();
455 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, YUV420_FORMAT));
456 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
459 Err(DecoderError::InvalidData)
462 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
463 let src = pkt.get_buffer();
464 if src.len() <= 4 { return Err(DecoderError::ShortData); }
466 let mut bufinfo = NABufferType::None;
467 let mut mr = MemoryReader::new_read(&src);
468 let mut br = ByteReader::new(&mut mr);
469 let start_tag = br.read_u16be()?;
470 validate!(start_tag == 0xFFD8);
472 let mut jtype = JPEGType::None;
473 let mut arith = false;
476 let tag = br.read_u16be()?;
478 0xFFC0 => { //baseline DCT header
479 jtype = JPEGType::Baseline;
481 bufinfo = self.parse_sof(&mut br)?;
484 jtype = JPEGType::Extended;
486 bufinfo = self.parse_sof(&mut br)?;
489 jtype = JPEGType::Progressive;
491 bufinfo = self.parse_sof(&mut br)?;
494 jtype = JPEGType::Lossless;
496 bufinfo = self.parse_sof(&mut br)?;
499 jtype = JPEGType::Differential;
501 bufinfo = self.parse_sof(&mut br)?;
504 jtype = JPEGType::DiffProgressive;
506 bufinfo = self.parse_sof(&mut br)?;
509 jtype = JPEGType::DiffLossless;
511 bufinfo = self.parse_sof(&mut br)?;
513 0xFFC8 => return Err(DecoderError::NotImplemented),
515 jtype = JPEGType::Extended;
517 bufinfo = self.parse_sof(&mut br)?;
520 jtype = JPEGType::Progressive;
522 bufinfo = self.parse_sof(&mut br)?;
525 jtype = JPEGType::Lossless;
527 bufinfo = self.parse_sof(&mut br)?;
530 jtype = JPEGType::Differential;
532 bufinfo = self.parse_sof(&mut br)?;
535 jtype = JPEGType::DiffProgressive;
537 bufinfo = self.parse_sof(&mut br)?;
540 jtype = JPEGType::DiffLossless;
542 bufinfo = self.parse_sof(&mut br)?;
544 0xFFC4 => { //huff table
546 let len = u64::from(br.read_u16be()?);
548 let end = br.tell() + len - 2;
549 let mut lens = [0; 16];
550 let mut syms = [0; 256];
551 while br.tell() < end {
552 let tctn = br.read_byte()? as usize;
553 let tclass = tctn >> 4;
554 validate!(tclass < 2);
557 br.read_buf(&mut lens)?;
558 let mut tot_len = 0usize;
559 for &el in lens.iter() {
560 tot_len += usize::from(el);
562 validate!(tot_len > 0 && tot_len <= 256);
563 br.read_buf(&mut syms[..tot_len])?;
564 self.codebook[tclass][id] = Some(generate_cb(&lens, &syms[..tot_len])?);
566 validate!(br.tell() == end);
568 0xFFCC => { // arith coding conditioning
569 return Err(DecoderError::NotImplemented);
571 0xFFD0..=0xFFD7 => return Err(DecoderError::NotImplemented),
573 0xFFDA => { //start of scan
574 let len = br.read_u16be()? as usize;
575 let ns = br.read_byte()? as usize;
576 validate!(len == ns * 2 + 6);
577 let mut ci = [ComponentInfo::default(); MAX_CHROMATONS];
578 for info in ci[..ns].iter_mut() {
579 let id = br.read_byte()?;
580 let mut found = false;
581 for (i, &c_id) in self.comp_id.iter().enumerate() {
583 info.component_id = i;
589 let tdta = br.read_byte()? as usize;
590 let dc_id = tdta >> 4;
591 validate!(dc_id < 4);
592 if self.codebook[0][dc_id].is_none() {
593 validate!(dc_id < 2);
594 self.codebook[0][dc_id] = Some(build_default_cb(true, dc_id)?);
596 let ac_id = tdta & 0xF;
597 validate!(ac_id < 4);
598 if self.codebook[1][ac_id].is_none() {
599 validate!(ac_id < 2);
600 self.codebook[1][ac_id] = Some(build_default_cb(false, ac_id)?);
602 info.dc_table_id = dc_id;
603 info.ac_table_id = ac_id;
605 let ss = br.read_byte()? as usize;
606 let se = br.read_byte()? as usize;
607 let ahal = br.read_byte()?;
611 JPEGType::Baseline | JPEGType::Extended => {
613 return Err(DecoderError::NotImplemented);
615 validate!(ss == 0 && se == 63);
616 validate!(ah == 0 && al == 0);
617 if let Some(buf) = bufinfo.get_vbuf() {
618 let max_size = src.len() - (br.tell() as usize);
620 self.buf.reserve(max_size);
622 let b = br.read_byte()?;
626 let b2 = br.read_byte()?;
630 br.seek(std::io::SeekFrom::Current(-2))?;
636 let mut data = Vec::new();
637 std::mem::swap(&mut self.buf, &mut data);
638 let ret = self.decode_scan(&data, buf, &ci[..ns], ss, se);
639 std::mem::swap(&mut self.buf, &mut data);
641 } else { unreachable!(); }
643 JPEGType::Progressive => {
644 validate!(ss < 64 && se < 64 && se >= ss);
645 validate!(ah < 14 && al < 14);
646 return Err(DecoderError::NotImplemented);
648 JPEGType::Lossless => {
649 validate!(ss >= 1 && ss < 8 && se == 0);
651 return Err(DecoderError::NotImplemented);
653 _ => return Err(DecoderError::NotImplemented),
655 let tag = br.peek_u16be()?;
656 validate!((tag >= 0xFFD0 && tag <= 0xFFD7) || (tag == 0xFFD9));
658 0xFFDB => { //quant tables
659 let mut len = br.read_u16be()? as usize;
660 validate!(len >= 64 + 3);
663 let pt = br.read_byte()?;
664 let precision = pt >> 4;
665 validate!(precision < 2);
666 let id = (pt & 0xF) as usize;
668 let qsize = if precision == 0 { 64 } else { 64 * 2 } + 1;
669 validate!(len >= qsize);
671 for el in self.quant[id].iter_mut() {
672 *el = i16::from(br.read_byte()?);
675 for el in self.quant[id].iter_mut() {
676 *el = br.read_u16be()? as i16;
682 0xFFDC => { //number of lines
683 return Err(DecoderError::NotImplemented);
686 let len = br.read_u16be()?;
688 let ri = br.read_u16be()?;
690 println!("restart interval {}", ri);
691 return Err(DecoderError::NotImplemented);
694 0xFFDE => return Err(DecoderError::NotImplemented),
695 0xFFDF => return Err(DecoderError::NotImplemented),
696 0xFFE0..=0xFFEF => { // application data
697 let len = br.read_u16be()? as usize;
699 br.read_skip(len - 2)?;
701 0xFFF0..=0xFFF6 => return Err(DecoderError::NotImplemented),
703 //jtype = JPEGType::JPEGLS;
705 return Err(DecoderError::NotImplemented);
707 0xFFF8 => return Err(DecoderError::NotImplemented), //JPEG-LS parameters
708 0xFFF9..=0xFFFD => return Err(DecoderError::NotImplemented),
709 0xFFFE => { //comment
710 let len = br.read_u16be()? as usize;
712 br.read_skip(len - 2)?;
714 0xFF01 => return Err(DecoderError::NotImplemented),
715 0xFF02..=0xFFBF => return Err(DecoderError::NotImplemented),
716 _ => return Err(DecoderError::InvalidData),
719 validate!(jtype != JPEGType::None);
721 if let NABufferType::None = bufinfo {
722 return Err(DecoderError::InvalidData);
725 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
726 frm.set_keyframe(true);
727 frm.set_frame_type(FrameType::I);
730 fn flush(&mut self) {
734 impl NAOptionHandler for JPEGDecoder {
735 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
736 fn set_options(&mut self, _options: &[NAOption]) { }
737 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
740 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
741 Box::new(JPEGDecoder::new())
746 use nihav_core::codecs::RegisteredDecoders;
747 use nihav_core::demuxers::RegisteredDemuxers;
748 use nihav_codec_support::test::dec_video::*;
749 use crate::generic_register_all_decoders;
750 use crate::generic_register_all_demuxers;
753 let mut dmx_reg = RegisteredDemuxers::new();
754 generic_register_all_demuxers(&mut dmx_reg);
755 let mut dec_reg = RegisteredDecoders::new();
756 generic_register_all_decoders(&mut dec_reg);
757 // sample: self-created with avconv
758 test_decoding("avi", "jpeg", "assets/Misc/mjpeg.avi", Some(1), &dmx_reg,
759 &dec_reg, ExpectedTestResult::MD5Frames(vec![
760 [0xe07f7128, 0x8c55eb5d, 0x03bfdee5, 0x358b24a4],
761 [0xd3ec3f92, 0x1664c56d, 0xfc049754, 0xf65165b9]]));
765 const DC_LENS: [[u8; 16]; 2] = [
766 [ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ],
767 [ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ]
769 const DC_SYMS: [u8; 12] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
770 const AC_LENS: [[u8; 16]; 2] = [
771 [ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 ],
772 [ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 ]
774 const AC_SYMS: [&[u8]; 2] = [
776 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
777 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
778 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
779 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
780 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
781 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
782 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
783 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
784 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
785 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
786 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
787 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
788 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
789 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
790 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
791 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
792 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
793 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
794 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
795 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
799 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
800 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
801 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
802 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
803 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
804 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
805 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
806 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
807 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
808 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
809 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
810 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
811 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
812 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
813 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
814 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
815 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
816 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
817 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
818 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,