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 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)]
147 info: NACodecInfoRef,
148 quant: [[i16; 64]; 4],
149 qselect: [u8; MAX_CHROMATONS],
150 comp_id: [u8; MAX_CHROMATONS],
151 subsamp: [u8; MAX_CHROMATONS],
152 codebook: [[Option<Codebook<u8>>; 4]; 2],
159 fn read_dc(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<i16> {
160 let cat = br.read_cb(cb)?;
165 let add_bits = br.read(cat)? as i16;
166 let pivot = 1 << (cat - 1);
167 if add_bits < pivot {
168 Ok(add_bits + 1 - pivot * 2)
175 fn read_ac(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<(usize, i16)> {
176 let val = br.read_cb(cb)?;
177 let run = usize::from(val >> 4);
179 let level = if cat != 0 {
181 let add_bits = br.read(cat)? as i16;
182 let pivot = 1 << (cat - 1);
183 if add_bits < pivot {
184 add_bits + 1 - pivot * 2
189 validate!(run == 0 || run == 15);
195 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<()> {
197 blk[0] = read_dc(br, dc_cb)?;
202 let (run, level) = read_ac(br, ac_cb)?;
203 if run == 0 && level == 0 {
208 blk[ZIGZAG[idx]] = level * qmat[idx];
216 let dummy_info = NACodecInfo::new_dummy();
221 qselect: [0; MAX_CHROMATONS],
222 subsamp: [0; MAX_CHROMATONS],
223 comp_id: [0; MAX_CHROMATONS],
224 codebook: [[None, None, None, None], [None, None, None, None]],
231 fn reset(&mut self) {
232 self.quant = [[0; 64]; 4];
233 self.codebook = [[None, None, None, None], [None, None, None, None]];
239 fn parse_sof(&mut self, br: &mut ByteReader) -> DecoderResult<NABufferType> {
240 validate!(self.width == 0);
242 let len = br.read_u16be()? as usize;
243 validate!(len >= 11);
244 let p = br.read_byte()?;
247 return Err(DecoderError::NotImplemented);
249 let y = br.read_u16be()? as usize;
250 let x = br.read_u16be()? as usize;
253 return Err(DecoderError::NotImplemented);
258 let nf = br.read_byte()? as usize;
260 validate!(len == 8 + nf * 3);
261 if nf > MAX_CHROMATONS {
262 return Err(DecoderError::NotImplemented);
267 let c = br.read_byte()?;
269 let hv = br.read_byte()?;
270 let t = br.read_byte()?;
273 self.subsamp[i] = hv;
275 validate!(hs == 1 || hs == 2);
277 validate!(vs == 1 || vs == 2);
278 max_h = max_h.max(hs);
279 max_v = max_v.max(vs);
281 let mut chromatons = [None; MAX_CHROMATONS];
282 for (i, chr) in chromatons[..nf].iter_mut().enumerate() {
283 let h_ss = match max_h / (self.subsamp[i] >> 4) {
288 let v_ss = match max_v / (self.subsamp[i] & 0xF) {
291 _ => return Err(DecoderError::InvalidData),
294 *chr = Some(NAPixelChromaton {
300 next_elem: (p + 7) >> 3,
305 validate!(self.comp_id[i] != self.comp_id[j]);
308 let formaton = NAPixelFormaton {
309 model: ColorModel::YUV(YUVSubmodel::YUVJ),
310 components: nf as u8,
311 comp_info: chromatons,
314 alpha: nf == 2 || nf == 4,
317 let vinfo = NAVideoInfo::new(x, y, false, formaton);
318 Ok(alloc_video_buffer(vinfo, 4)?)
321 fn decode_scan(&mut self, src: &[u8], mut buf: NAVideoBufferRef<u8>, ci: &[ComponentInfo], ss: usize, se: usize) -> DecoderResult<usize> {
322 let num_components = ci.len();
323 let mut last_dc = [1024; MAX_CHROMATONS];
324 let mut dc_cbs = Vec::with_capacity(num_components);
325 let mut ac_cbs = Vec::with_capacity(num_components);
326 let mut qmats = [&self.quant[0]; MAX_CHROMATONS];
327 for (i, cinfo) in ci.iter().enumerate() {
328 dc_cbs.push(if let Some(ref cb) = self.codebook[0][cinfo.dc_table_id] {
330 } else { unreachable!(); });
331 ac_cbs.push(if let Some(ref cb) = self.codebook[1][cinfo.ac_table_id] {
333 } else { unreachable!(); });
334 qmats[i] = &self.quant[self.qselect[cinfo.component_id] as usize];
337 let frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
339 let mut br = BitReader::new(src, BitReaderMode::BE);
341 let mut offs = frm.offset;
342 let mut nblks = [0; MAX_CHROMATONS];
343 let mut xstep = [0; MAX_CHROMATONS];
344 let mut ystep = [0; MAX_CHROMATONS];
347 for i in 0..num_components {
348 let hs = (self.subsamp[i] >> 4) as usize;
349 let vs = (self.subsamp[i] & 0xF) as usize;
350 hstep = hstep.max(hs * 8);
351 vstep = vstep.max(vs * 8);
358 for _y in (0..self.height).step_by(vstep) {
359 for x in 0..(self.width + hstep - 1) / hstep {
360 for i in 0..num_components {
361 blocks = [[0; 64]; 4];
362 for blk in blocks[..nblks[i]].iter_mut() {
363 read_block(&mut br, blk, dc_cbs[i], ac_cbs[i], ss, se, qmats[i])?;
364 blk[0] += last_dc[i];
368 match self.subsamp[i] {
370 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
373 put_block(&blocks[0], &mut frm.data[offs[i] + x * 16..], frm.stride[i]);
374 put_block(&blocks[1], &mut frm.data[offs[i] + x * 16 + 8..], frm.stride[i]);
377 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
378 put_block(&blocks[1], &mut frm.data[offs[i] + x * 8 + frm.stride[i] * 8..], frm.stride[i]);
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);
638 if let Err(err) = ret {
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 test_decoding("avi", "jpeg", "assets/Misc/mjpeg.avi", Some(1), &dmx_reg,
758 &dec_reg, ExpectedTestResult::MD5Frames(vec![
759 [0xe07f7128, 0x8c55eb5d, 0x03bfdee5, 0x358b24a4],
760 [0xd3ec3f92, 0x1664c56d, 0xfc049754, 0xf65165b9]]));
764 const DC_LENS: [[u8; 16]; 2] = [
765 [ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ],
766 [ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ]
768 const DC_SYMS: [u8; 12] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
769 const AC_LENS: [[u8; 16]; 2] = [
770 [ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 ],
771 [ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 ]
773 const AC_SYMS: [&[u8]; 2] = [
775 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
776 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
777 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
778 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
779 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
780 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
781 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
782 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
783 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
784 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
785 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
786 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
787 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
788 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
789 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
790 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
791 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
792 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
793 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
794 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
798 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
799 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
800 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
801 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
802 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
803 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
804 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
805 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
806 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
807 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
808 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
809 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
810 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
811 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
812 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
813 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
814 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
815 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
816 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
817 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,