use nihav_core::demuxers::*;
use nihav_registry::register::*;
+use nihav_core::compr::deflate::*;
macro_rules! mktag {
($a:expr, $b:expr, $c:expr, $d:expr) => ({
const MOOV_CHUNK_HANDLERS: &[RootChunkHandler] = &[
RootChunkHandler { ctype: mktag!(b"mvhd"), parse: read_mvhd },
+ RootChunkHandler { ctype: mktag!(b"cmov"), parse: read_cmov },
RootChunkHandler { ctype: mktag!(b"ctab"), parse: read_ctab },
RootChunkHandler { ctype: mktag!(b"trak"), parse: read_trak },
RootChunkHandler { ctype: mktag!(b"meta"), parse: read_meta },
Ok(KNOWN_MVHD_SIZE)
}
+fn read_cmov(dmx: &mut MOVDemuxer, strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
+ let br = &mut dmx.src;
+ validate!(size > 24);
+ let dcom_size = br.read_u32be()?;
+ let dcom_tag = br.read_tag()?;
+ let compr_type = br.read_tag()?;
+ validate!(&dcom_tag == b"dcom" && dcom_size == 12);
+ if &compr_type != b"zlib" {
+ return Err(DemuxerError::NotImplemented);
+ }
+ let cmvd_size = u64::from(br.read_u32be()?);
+ let cmvd_tag = br.read_tag()?;
+ validate!(&cmvd_tag == b"cmvd" && cmvd_size > 14 && cmvd_size == size - 12);
+ let comp_size = (cmvd_size - 12) as usize;
+ let uncomp_size = br.read_u32be()? as usize;
+ validate!(uncomp_size > 8);
+ let mut sbuf = vec![0; comp_size];
+ let mut dbuf = vec![0; uncomp_size];
+ br.read_buf(sbuf.as_mut_slice())?;
+ validate!(sbuf[0] == 0x78);
+ validate!(sbuf[1] == 0x9C);
+ let ret = Inflate::uncompress(&sbuf[2..], dbuf.as_mut_slice());
+ if ret.is_err() {
+ return Err(DemuxerError::InvalidData);
+ }
+ let len = ret.unwrap();
+ validate!(len == uncomp_size);
+ let mut mr = MemoryReader::new_read(dbuf.as_slice());
+ let mut br = ByteReader::new(&mut mr);
+ let (ctype, csize) = read_chunk_header(&mut br)?;
+ validate!(ctype == mktag!(b"moov"));
+ let mut ddmx = MOVDemuxer::new(&mut br);
+ ddmx.read_moov(strmgr, csize)?;
+ std::mem::swap(&mut dmx.tracks, &mut ddmx.tracks);
+ dmx.duration = ddmx.duration;
+ dmx.tb_den = ddmx.tb_den;
+ std::mem::swap(&mut dmx.pal, &mut ddmx.pal);
+
+ Ok(size)
+}
+
fn read_ctab(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
let mut pal = [0; 1024];
let size = read_palette(&mut dmx.src, size, &mut pal)?;
let _flags = br.read_u24be()?;
let entries = br.read_u32be()?;
validate!(entries > 0);
- let esize = br.read_u32be()? as u64;
+ let esize = u64::from(br.read_u32be()?);
validate!(esize + 8 <= size);
let mut fcc = [0u8; 4];
br.read_buf(&mut fcc)?;
br.read_skip(31)?; // actual compressor name
let depth = br.read_u16be()?;
let ctable_id = br.read_u16be()?;
- validate!((depth <= 8) || (ctable_id == 0xFFFF));
+ let grayscale = depth > 0x20 || depth == 1;
+ let depth = if grayscale { depth & 0x1F } else { depth };
+ validate!(depth <= 8 || (ctable_id == 0xFFFF));
if ctable_id == 0 {
let max_pal_size = start_pos + size - br.tell();
let mut pal = [0; 1024];
read_palette(br, max_pal_size, &mut pal)?;
track.pal = Some(Arc::new(pal));
+ } else if (depth <= 8) && !grayscale {
+ match depth & 0x1F {
+ 2 => {
+ let mut pal = [0; 1024];
+ (&mut pal[..4 * 4]).copy_from_slice(&MOV_DEFAULT_PAL_2BIT);
+ track.pal = Some(Arc::new(pal));
+ },
+ 4 => {
+ let mut pal = [0; 1024];
+ (&mut pal[..16 * 4]).copy_from_slice(&MOV_DEFAULT_PAL_4BIT);
+ track.pal = Some(Arc::new(pal));
+ },
+ 8 => {
+ track.pal = Some(Arc::new(MOV_DEFAULT_PAL_8BIT));
+ },
+ _ => {},
+ };
+ } else if grayscale && ctable_id != 0xFFFF {
+ let mut pal = [0; 1024];
+ let cdepth = depth & 0x1F;
+ let size = 1 << cdepth;
+ for i in 0..size {
+ let mut clr = ((size - 1 - i) as u8) << (8 - cdepth);
+ let mut off = 8 - cdepth;
+ while off >= cdepth {
+ clr |= clr >> (8 - off);
+ off -= cdepth;
+ }
+ if off > 0 {
+ clr |= clr >> (8 - off);
+ }
+ pal[i * 4] = clr;
+ pal[i * 4 + 1] = clr;
+ pal[i * 4 + 2] = clr;
+ }
+ track.pal = Some(Arc::new(pal));
}
// todo other atoms, put as extradata
let cname = if let Some(name) = find_codec_from_mov_video_fourcc(&fcc) {
"unknown"
};
let format = if depth > 8 { RGB24_FORMAT } else { PAL8_FORMAT };
- let vhdr = NAVideoInfo::new(width, height, false, format);
- let edata;
- if br.tell() - start_pos + 4 < size {
+ let mut vhdr = NAVideoInfo::new(width, height, false, format);
+ vhdr.bits = depth as u8;
+ let edata = if br.tell() - start_pos + 4 < size {
//todo skip various common atoms
- let edata_size = br.read_u32be()? as usize;
- let mut buf = vec![0; edata_size];
+ let edata_size = br.read_u32be()? as usize;
+ let mut buf = vec![0; edata_size];
br.read_buf(buf.as_mut_slice())?;
- edata = Some(buf);
- } else {
- edata = None;
- }
+ Some(buf)
+ } else {
+ None
+ };
codec_info = NACodecInfo::new(cname, NACodecTypeInfo::Video(vhdr), edata);
},
StreamType::Audio => {
read_chunk_list!(track; "minf", read_minf, MINF_CHUNK_HANDLERS);
read_chunk_list!(track; "stbl", read_stbl, STBL_CHUNK_HANDLERS);
fn fill_seek_index(&self, seek_index: &mut SeekIndex) {
- if self.keyframes.len() > 0 {
+ if !self.keyframes.is_empty() {
seek_index.mode = SeekIndexMode::Present;
}
for kf_time in self.keyframes.iter() {
}
}
fn get_size(&self, sample_no: usize) -> usize {
- if self.chunk_sizes.len() > 0 {
+ if !self.chunk_sizes.is_empty() {
self.chunk_sizes[sample_no] as usize
- } else if self.sample_map.len() > 0 {
+ } else if !self.sample_map.is_empty() {
let mut nsamp = 0;
for (idx, samples) in self.sample_map.iter() {
if *idx as usize <= self.cur_chunk {
self.samples_left = 0;
if self.stream_type == StreamType::Audio {
self.cur_chunk = self.cur_sample;
- } else if self.chunk_offsets.len() != self.chunk_sizes.len() && self.sample_map.len() > 0{
+ } else if self.chunk_offsets.len() != self.chunk_sizes.len() && !self.sample_map.is_empty() {
let mut csamp = 0;
self.cur_chunk = 0;
let mut cmap = self.sample_map.iter();
fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
self.read_root(strmgr)?;
validate!(self.mdat_pos > 0);
- validate!(self.tracks.len() > 0);
+ validate!(!self.tracks.is_empty());
for track in self.tracks.iter() {
track.fill_seek_index(seek_index);
}
}
fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
- if self.tracks.len() == 0 {
+ if self.tracks.is_empty() {
return Err(DemuxerError::EOF);
}
for _ in 0..self.tracks.len() {
return Ok(pkt);
}
}
- return Err(DemuxerError::EOF);
+ Err(DemuxerError::EOF)
}
fn seek(&mut self, time: u64, seek_index: &SeekIndex) -> DemuxerResult<()> {
fn get_name(&self) -> &'static str { "mov" }
}
+const MOV_DEFAULT_PAL_2BIT: [u8; 4 * 4] = [
+ 0x93, 0x65, 0x5E, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00,
+ 0xDF, 0xD0, 0xAB, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+];
+const MOV_DEFAULT_PAL_4BIT: [u8; 16 * 4] = [
+ 0xFF, 0xFB, 0xFF, 0x00,
+ 0xEF, 0xD9, 0xBB, 0x00,
+ 0xE8, 0xC9, 0xB1, 0x00,
+ 0x93, 0x65, 0x5E, 0x00,
+ 0xFC, 0xDE, 0xE8, 0x00,
+ 0x9D, 0x88, 0x91, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00,
+ 0x47, 0x48, 0x37, 0x00,
+ 0x7A, 0x5E, 0x55, 0x00,
+ 0xDF, 0xD0, 0xAB, 0x00,
+ 0xFF, 0xFB, 0xF9, 0x00,
+ 0xE8, 0xCA, 0xC5, 0x00,
+ 0x8A, 0x7C, 0x77, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+];
+const MOV_DEFAULT_PAL_8BIT: [u8; 256 * 4] = [
+ 0xFF, 0xFF, 0xFF, 0x00,
+ 0xFF, 0xFF, 0xCC, 0x00,
+ 0xFF, 0xFF, 0x99, 0x00,
+ 0xFF, 0xFF, 0x66, 0x00,
+ 0xFF, 0xFF, 0x33, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00,
+ 0xFF, 0xCC, 0xFF, 0x00,
+ 0xFF, 0xCC, 0xCC, 0x00,
+ 0xFF, 0xCC, 0x99, 0x00,
+ 0xFF, 0xCC, 0x66, 0x00,
+ 0xFF, 0xCC, 0x33, 0x00,
+ 0xFF, 0xCC, 0x00, 0x00,
+ 0xFF, 0x99, 0xFF, 0x00,
+ 0xFF, 0x99, 0xCC, 0x00,
+ 0xFF, 0x99, 0x99, 0x00,
+ 0xFF, 0x99, 0x66, 0x00,
+ 0xFF, 0x99, 0x33, 0x00,
+ 0xFF, 0x99, 0x00, 0x00,
+ 0xFF, 0x66, 0xFF, 0x00,
+ 0xFF, 0x66, 0xCC, 0x00,
+ 0xFF, 0x66, 0x99, 0x00,
+ 0xFF, 0x66, 0x66, 0x00,
+ 0xFF, 0x66, 0x33, 0x00,
+ 0xFF, 0x66, 0x00, 0x00,
+ 0xFF, 0x33, 0xFF, 0x00,
+ 0xFF, 0x33, 0xCC, 0x00,
+ 0xFF, 0x33, 0x99, 0x00,
+ 0xFF, 0x33, 0x66, 0x00,
+ 0xFF, 0x33, 0x33, 0x00,
+ 0xFF, 0x33, 0x00, 0x00,
+ 0xFF, 0x00, 0xFF, 0x00,
+ 0xFF, 0x00, 0xCC, 0x00,
+ 0xFF, 0x00, 0x99, 0x00,
+ 0xFF, 0x00, 0x66, 0x00,
+ 0xFF, 0x00, 0x33, 0x00,
+ 0xFF, 0x00, 0x00, 0x00,
+ 0xCC, 0xFF, 0xFF, 0x00,
+ 0xCC, 0xFF, 0xCC, 0x00,
+ 0xCC, 0xFF, 0x99, 0x00,
+ 0xCC, 0xFF, 0x66, 0x00,
+ 0xCC, 0xFF, 0x33, 0x00,
+ 0xCC, 0xFF, 0x00, 0x00,
+ 0xCC, 0xCC, 0xFF, 0x00,
+ 0xCC, 0xCC, 0xCC, 0x00,
+ 0xCC, 0xCC, 0x99, 0x00,
+ 0xCC, 0xCC, 0x66, 0x00,
+ 0xCC, 0xCC, 0x33, 0x00,
+ 0xCC, 0xCC, 0x00, 0x00,
+ 0xCC, 0x99, 0xFF, 0x00,
+ 0xCC, 0x99, 0xCC, 0x00,
+ 0xCC, 0x99, 0x99, 0x00,
+ 0xCC, 0x99, 0x66, 0x00,
+ 0xCC, 0x99, 0x33, 0x00,
+ 0xCC, 0x99, 0x00, 0x00,
+ 0xCC, 0x66, 0xFF, 0x00,
+ 0xCC, 0x66, 0xCC, 0x00,
+ 0xCC, 0x66, 0x99, 0x00,
+ 0xCC, 0x66, 0x66, 0x00,
+ 0xCC, 0x66, 0x33, 0x00,
+ 0xCC, 0x66, 0x00, 0x00,
+ 0xCC, 0x33, 0xFF, 0x00,
+ 0xCC, 0x33, 0xCC, 0x00,
+ 0xCC, 0x33, 0x99, 0x00,
+ 0xCC, 0x33, 0x66, 0x00,
+ 0xCC, 0x33, 0x33, 0x00,
+ 0xCC, 0x33, 0x00, 0x00,
+ 0xCC, 0x00, 0xFF, 0x00,
+ 0xCC, 0x00, 0xCC, 0x00,
+ 0xCC, 0x00, 0x99, 0x00,
+ 0xCC, 0x00, 0x66, 0x00,
+ 0xCC, 0x00, 0x33, 0x00,
+ 0xCC, 0x00, 0x00, 0x00,
+ 0x99, 0xFF, 0xFF, 0x00,
+ 0x99, 0xFF, 0xCC, 0x00,
+ 0x99, 0xFF, 0x99, 0x00,
+ 0x99, 0xFF, 0x66, 0x00,
+ 0x99, 0xFF, 0x33, 0x00,
+ 0x99, 0xFF, 0x00, 0x00,
+ 0x99, 0xCC, 0xFF, 0x00,
+ 0x99, 0xCC, 0xCC, 0x00,
+ 0x99, 0xCC, 0x99, 0x00,
+ 0x99, 0xCC, 0x66, 0x00,
+ 0x99, 0xCC, 0x33, 0x00,
+ 0x99, 0xCC, 0x00, 0x00,
+ 0x99, 0x99, 0xFF, 0x00,
+ 0x99, 0x99, 0xCC, 0x00,
+ 0x99, 0x99, 0x99, 0x00,
+ 0x99, 0x99, 0x66, 0x00,
+ 0x99, 0x99, 0x33, 0x00,
+ 0x99, 0x99, 0x00, 0x00,
+ 0x99, 0x66, 0xFF, 0x00,
+ 0x99, 0x66, 0xCC, 0x00,
+ 0x99, 0x66, 0x99, 0x00,
+ 0x99, 0x66, 0x66, 0x00,
+ 0x99, 0x66, 0x33, 0x00,
+ 0x99, 0x66, 0x00, 0x00,
+ 0x99, 0x33, 0xFF, 0x00,
+ 0x99, 0x33, 0xCC, 0x00,
+ 0x99, 0x33, 0x99, 0x00,
+ 0x99, 0x33, 0x66, 0x00,
+ 0x99, 0x33, 0x33, 0x00,
+ 0x99, 0x33, 0x00, 0x00,
+ 0x99, 0x00, 0xFF, 0x00,
+ 0x99, 0x00, 0xCC, 0x00,
+ 0x99, 0x00, 0x99, 0x00,
+ 0x99, 0x00, 0x66, 0x00,
+ 0x99, 0x00, 0x33, 0x00,
+ 0x99, 0x00, 0x00, 0x00,
+ 0x66, 0xFF, 0xFF, 0x00,
+ 0x66, 0xFF, 0xCC, 0x00,
+ 0x66, 0xFF, 0x99, 0x00,
+ 0x66, 0xFF, 0x66, 0x00,
+ 0x66, 0xFF, 0x33, 0x00,
+ 0x66, 0xFF, 0x00, 0x00,
+ 0x66, 0xCC, 0xFF, 0x00,
+ 0x66, 0xCC, 0xCC, 0x00,
+ 0x66, 0xCC, 0x99, 0x00,
+ 0x66, 0xCC, 0x66, 0x00,
+ 0x66, 0xCC, 0x33, 0x00,
+ 0x66, 0xCC, 0x00, 0x00,
+ 0x66, 0x99, 0xFF, 0x00,
+ 0x66, 0x99, 0xCC, 0x00,
+ 0x66, 0x99, 0x99, 0x00,
+ 0x66, 0x99, 0x66, 0x00,
+ 0x66, 0x99, 0x33, 0x00,
+ 0x66, 0x99, 0x00, 0x00,
+ 0x66, 0x66, 0xFF, 0x00,
+ 0x66, 0x66, 0xCC, 0x00,
+ 0x66, 0x66, 0x99, 0x00,
+ 0x66, 0x66, 0x66, 0x00,
+ 0x66, 0x66, 0x33, 0x00,
+ 0x66, 0x66, 0x00, 0x00,
+ 0x66, 0x33, 0xFF, 0x00,
+ 0x66, 0x33, 0xCC, 0x00,
+ 0x66, 0x33, 0x99, 0x00,
+ 0x66, 0x33, 0x66, 0x00,
+ 0x66, 0x33, 0x33, 0x00,
+ 0x66, 0x33, 0x00, 0x00,
+ 0x66, 0x00, 0xFF, 0x00,
+ 0x66, 0x00, 0xCC, 0x00,
+ 0x66, 0x00, 0x99, 0x00,
+ 0x66, 0x00, 0x66, 0x00,
+ 0x66, 0x00, 0x33, 0x00,
+ 0x66, 0x00, 0x00, 0x00,
+ 0x33, 0xFF, 0xFF, 0x00,
+ 0x33, 0xFF, 0xCC, 0x00,
+ 0x33, 0xFF, 0x99, 0x00,
+ 0x33, 0xFF, 0x66, 0x00,
+ 0x33, 0xFF, 0x33, 0x00,
+ 0x33, 0xFF, 0x00, 0x00,
+ 0x33, 0xCC, 0xFF, 0x00,
+ 0x33, 0xCC, 0xCC, 0x00,
+ 0x33, 0xCC, 0x99, 0x00,
+ 0x33, 0xCC, 0x66, 0x00,
+ 0x33, 0xCC, 0x33, 0x00,
+ 0x33, 0xCC, 0x00, 0x00,
+ 0x33, 0x99, 0xFF, 0x00,
+ 0x33, 0x99, 0xCC, 0x00,
+ 0x33, 0x99, 0x99, 0x00,
+ 0x33, 0x99, 0x66, 0x00,
+ 0x33, 0x99, 0x33, 0x00,
+ 0x33, 0x99, 0x00, 0x00,
+ 0x33, 0x66, 0xFF, 0x00,
+ 0x33, 0x66, 0xCC, 0x00,
+ 0x33, 0x66, 0x99, 0x00,
+ 0x33, 0x66, 0x66, 0x00,
+ 0x33, 0x66, 0x33, 0x00,
+ 0x33, 0x66, 0x00, 0x00,
+ 0x33, 0x33, 0xFF, 0x00,
+ 0x33, 0x33, 0xCC, 0x00,
+ 0x33, 0x33, 0x99, 0x00,
+ 0x33, 0x33, 0x66, 0x00,
+ 0x33, 0x33, 0x33, 0x00,
+ 0x33, 0x33, 0x00, 0x00,
+ 0x33, 0x00, 0xFF, 0x00,
+ 0x33, 0x00, 0xCC, 0x00,
+ 0x33, 0x00, 0x99, 0x00,
+ 0x33, 0x00, 0x66, 0x00,
+ 0x33, 0x00, 0x33, 0x00,
+ 0x33, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0xFF, 0x00,
+ 0x00, 0xFF, 0xCC, 0x00,
+ 0x00, 0xFF, 0x99, 0x00,
+ 0x00, 0xFF, 0x66, 0x00,
+ 0x00, 0xFF, 0x33, 0x00,
+ 0x00, 0xFF, 0x00, 0x00,
+ 0x00, 0xCC, 0xFF, 0x00,
+ 0x00, 0xCC, 0xCC, 0x00,
+ 0x00, 0xCC, 0x99, 0x00,
+ 0x00, 0xCC, 0x66, 0x00,
+ 0x00, 0xCC, 0x33, 0x00,
+ 0x00, 0xCC, 0x00, 0x00,
+ 0x00, 0x99, 0xFF, 0x00,
+ 0x00, 0x99, 0xCC, 0x00,
+ 0x00, 0x99, 0x99, 0x00,
+ 0x00, 0x99, 0x66, 0x00,
+ 0x00, 0x99, 0x33, 0x00,
+ 0x00, 0x99, 0x00, 0x00,
+ 0x00, 0x66, 0xFF, 0x00,
+ 0x00, 0x66, 0xCC, 0x00,
+ 0x00, 0x66, 0x99, 0x00,
+ 0x00, 0x66, 0x66, 0x00,
+ 0x00, 0x66, 0x33, 0x00,
+ 0x00, 0x66, 0x00, 0x00,
+ 0x00, 0x33, 0xFF, 0x00,
+ 0x00, 0x33, 0xCC, 0x00,
+ 0x00, 0x33, 0x99, 0x00,
+ 0x00, 0x33, 0x66, 0x00,
+ 0x00, 0x33, 0x33, 0x00,
+ 0x00, 0x33, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00,
+ 0x00, 0x00, 0xCC, 0x00,
+ 0x00, 0x00, 0x99, 0x00,
+ 0x00, 0x00, 0x66, 0x00,
+ 0x00, 0x00, 0x33, 0x00,
+ 0xEE, 0x00, 0x00, 0x00,
+ 0xDD, 0x00, 0x00, 0x00,
+ 0xBB, 0x00, 0x00, 0x00,
+ 0xAA, 0x00, 0x00, 0x00,
+ 0x88, 0x00, 0x00, 0x00,
+ 0x77, 0x00, 0x00, 0x00,
+ 0x55, 0x00, 0x00, 0x00,
+ 0x44, 0x00, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0xEE, 0x00, 0x00,
+ 0x00, 0xDD, 0x00, 0x00,
+ 0x00, 0xBB, 0x00, 0x00,
+ 0x00, 0xAA, 0x00, 0x00,
+ 0x00, 0x88, 0x00, 0x00,
+ 0x00, 0x77, 0x00, 0x00,
+ 0x00, 0x55, 0x00, 0x00,
+ 0x00, 0x44, 0x00, 0x00,
+ 0x00, 0x22, 0x00, 0x00,
+ 0x00, 0x11, 0x00, 0x00,
+ 0x00, 0x00, 0xEE, 0x00,
+ 0x00, 0x00, 0xDD, 0x00,
+ 0x00, 0x00, 0xBB, 0x00,
+ 0x00, 0x00, 0xAA, 0x00,
+ 0x00, 0x00, 0x88, 0x00,
+ 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x55, 0x00,
+ 0x00, 0x00, 0x44, 0x00,
+ 0x00, 0x00, 0x22, 0x00,
+ 0x00, 0x00, 0x11, 0x00,
+ 0xEE, 0xEE, 0xEE, 0x00,
+ 0xDD, 0xDD, 0xDD, 0x00,
+ 0xBB, 0xBB, 0xBB, 0x00,
+ 0xAA, 0xAA, 0xAA, 0x00,
+ 0x88, 0x88, 0x88, 0x00,
+ 0x77, 0x77, 0x77, 0x00,
+ 0x55, 0x55, 0x55, 0x00,
+ 0x44, 0x44, 0x44, 0x00,
+ 0x22, 0x22, 0x22, 0x00,
+ 0x11, 0x11, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+];
+
#[cfg(test)]
mod test {
use super::*;