}
}
-fn read_palette(br: &mut ByteReader, size: u64, pal: &mut Vec<u16>) -> DemuxerResult<u64> {
+fn read_palette(br: &mut ByteReader, size: u64, pal: &mut [u8; 1024]) -> DemuxerResult<u64> {
let _seed = br.read_u32be()?;
let _flags = br.read_u16be()?;
let palsize = (br.read_u16be()? as usize) + 1;
validate!(palsize <= 256);
validate!((palsize as u64) * 8 + 8 == size);
- pal.resize(palsize * 4, 0);
for i in 0..palsize {
let a = br.read_u16be()?;
let r = br.read_u16be()?;
let g = br.read_u16be()?;
let b = br.read_u16be()?;
- pal[i * 4] = a;
- pal[i * 4 + 1] = r;
- pal[i * 4 + 2] = g;
- pal[i * 4 + 3] = b;
+ pal[i * 4] = (r >> 8) as u8;
+ pal[i * 4 + 1] = (g >> 8) as u8;
+ pal[i * 4 + 2] = (b >> 8) as u8;
+ pal[i * 4 + 3] = (a >> 8) as u8;
}
Ok(size)
}
}
fn read_ctab(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
- read_palette(&mut dmx.src, size, &mut dmx.pal)
+ let mut pal = [0; 1024];
+ let size = read_palette(&mut dmx.src, size, &mut pal)?;
+ dmx.pal = Some(Arc::new(pal));
+ Ok(size)
}
fn read_meta(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
println!("Unknown stream type");
track.stream_type = StreamType::Data;
}
-
+
Ok(KNOWN_HDLR_SIZE)
}
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();
- read_palette(br, max_pal_size, &mut track.pal)?;
+ 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 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
cur_track: usize,
tb_den: u32,
duration: u32,
- pal: Vec<u16>,
+ pal: Option<Arc<[u8; 1024]>>,
}
struct Track {
cur_sample: usize,
samples_left: usize,
last_offset: u64,
- pal: Vec<u16>,
+ pal: Option<Arc<[u8; 1024]>>,
}
impl Track {
cur_sample: 0,
samples_left: 0,
last_offset: 0,
- pal: Vec::new(),
+ pal: None,
}
}
read_chunk_list!(track; "trak", read_trak, TRAK_CHUNK_HANDLERS);
}
let track = &mut self.tracks[self.cur_track];
self.cur_track += 1;
+ let first = track.cur_sample == 0;
if let Some((pts, offset, size)) = track.get_next_chunk() {
let str = strmgr.get_stream(track.track_str_id);
if str.is_none() { return Err(DemuxerError::InvalidData); }
let stream = str.unwrap();
self.src.seek(SeekFrom::Start(offset))?;
- let pkt = self.src.read_packet(stream, pts, false, size)?;
+ let mut pkt = self.src.read_packet(stream, pts, false, size)?;
+ if let Some(ref pal) = track.pal {
+ let side_data = NASideData::Palette(first, pal.clone());
+ pkt.add_side_data(side_data);
+ }
return Ok(pkt);
}
}
}
}
+impl<'a> NAOptionHandler for MOVDemuxer<'a> {
+ fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
+ fn set_options(&mut self, _options: &[NAOption]) { }
+ fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
+}
+
impl<'a> MOVDemuxer<'a> {
fn new(io: &'a mut ByteReader<'a>) -> Self {
MOVDemuxer {
cur_track: 0,
tb_den: 0,
duration: 0,
- pal: Vec::new(),
+ pal: None,
}
}
fn read_root(&mut self, strmgr: &mut StreamManager) -> 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::*;