]> git.nihav.org Git - nihav.git/blobdiff - nihav-indeo/src/codecs/indeo5.rs
indeo5: fix band size check
[nihav.git] / nihav-indeo / src / codecs / indeo5.rs
index 933958d787b32cb3832142cdf557421d1d0700a1..0c6d65eeed8c48d9dcbf1b89969fb07c5505adfe 100644 (file)
@@ -2,6 +2,7 @@ use nihav_core::io::bitreader::*;
 use nihav_core::formats;
 use nihav_core::frame::*;
 use nihav_core::codecs::*;
+use nihav_codec_support::codecs::ZIGZAG;
 use super::ivi::*;
 use super::ivibr::*;
 
@@ -179,10 +180,11 @@ impl IndeoXParser for Indeo5Parser {
         let data_size: usize;
         if (band_flags & 0x80) != 0 {
             data_size       = br.read(24)? as usize;
+            validate!(data_size >= 4);
         } else {
             data_size = 0;
         }
-        validate!(data_size <= ((br.left() / 8) as usize));
+        validate!(data_size <= ((br.left() / 8) as usize) + 4);
 
         let num_corr: usize;
         let mut corr_map: [u8; CORR_MAP_SIZE] = [0; CORR_MAP_SIZE];
@@ -264,6 +266,7 @@ impl IndeoXParser for Indeo5Parser {
         Ok(BandHeader::new(plane_no, band_no, self.mb_size[band_id], self.blk_size[band_id], self.is_hpel[band_id], inherit_mv, has_qdelta, inherit_qd, band_q, rvmap_idx, num_corr, corr_map, blk_cb, tr, txtype))
     }
 
+    #[allow(clippy::cognitive_complexity)]
     fn decode_mb_info(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, band: &BandHeader, tile: &mut IVITile, ref_tile: Option<&IVITile>, mv_scale: u8) -> DecoderResult<()> {
         let mut mv_x = 0;
         let mut mv_y = 0;
@@ -276,7 +279,7 @@ impl IndeoXParser for Indeo5Parser {
                     if pic_hdr.ftype.is_intra() {
                         mb.mtype = MBType::Intra;
                     } else if band.inherit_mv {
-                        if let Some(ref tileref) = ref_tile {
+                        if let Some(tileref) = ref_tile {
                             mb.mtype = tileref.mb[mb_idx].mtype;
                         } else {
                             return Err(DecoderError::MissingReference);
@@ -292,7 +295,7 @@ impl IndeoXParser for Indeo5Parser {
                     let q;
                     if band.has_qdelta {
                         if band.inherit_qd {
-                            if let Some(ref tileref) = ref_tile {
+                            if let Some(tileref) = ref_tile {
                                 mb.qd = tileref.mb[mb_idx].qd;
                                 q = calc_quant(band.quant, mb.qd);
                             } else {
@@ -324,7 +327,7 @@ impl IndeoXParser for Indeo5Parser {
 
                     if mb.mtype != MBType::Intra {
                         if band.inherit_mv {
-                            if let Some(ref tileref) = ref_tile {
+                            if let Some(tileref) = ref_tile {
                                 let mx = tileref.mb[mb_idx].mv_x;
                                 let my = tileref.mb[mb_idx].mv_y;
                                 if mv_scale == 0 {
@@ -365,7 +368,7 @@ impl IndeoXParser for Indeo5Parser {
                         }
                     }
                     if band.inherit_mv {
-                        if let Some(ref tileref) = ref_tile {
+                        if let Some(tileref) = ref_tile {
                             let mx = tileref.mb[mb_idx].mv_x;
                             let my = tileref.mb[mb_idx].mv_y;
                             if mv_scale == 0 {
@@ -497,10 +500,10 @@ struct Indeo5Decoder {
 }
 
 impl Indeo5Decoder {
-    fn new() -> Self {
+    fn new(scalable: bool) -> Self {
         Indeo5Decoder {
             info:   NACodecInfo::new_dummy(),
-            dec:    IVIDecoder::new(),
+            dec:    IVIDecoder::new(scalable),
             ip:     Indeo5Parser::new(),
         }
     }
@@ -535,6 +538,12 @@ impl NADecoder for Indeo5Decoder {
     }
 }
 
+impl NAOptionHandler for Indeo5Decoder {
+    fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
+    fn set_options(&mut self, _options: &[NAOption]) { }
+    fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
+}
+
 const INDEO5_PICTURE_SIZE_TAB: [[usize; 2]; 15] = [
     [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144],
     [240, 180], [640, 240], [704, 240], [80, 60], [88, 72], [0, 0], [0, 0], [0, 0]
@@ -715,23 +724,28 @@ const INDEO5_QSCALE4_INTER: [u8; 24] = [
 ];
 
 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
-    Box::new(Indeo5Decoder::new())
+    Box::new(Indeo5Decoder::new(false))
+}
+
+pub fn get_decoder_scalable() -> Box<dyn NADecoder + Send> {
+    Box::new(Indeo5Decoder::new(true))
 }
 
 #[cfg(test)]
 mod test {
     use nihav_core::codecs::RegisteredDecoders;
     use nihav_core::demuxers::RegisteredDemuxers;
-    use nihav_core::test::dec_video::*;
-    use crate::indeo_register_all_codecs;
+    use nihav_codec_support::test::dec_video::*;
+    use crate::indeo_register_all_decoders;
     use nihav_commonfmt::generic_register_all_demuxers;
     #[test]
     fn test_indeo5() {
         let mut dmx_reg = RegisteredDemuxers::new();
         generic_register_all_demuxers(&mut dmx_reg);
         let mut dec_reg = RegisteredDecoders::new();
-        indeo_register_all_codecs(&mut dec_reg);
+        indeo_register_all_decoders(&mut dec_reg);
 
+        // sample: https://samples.mplayerhq.hu/V-codecs/IV50/sample.avi
         test_decoding("avi", "indeo5", "assets/Indeo/IV5/sample.avi", Some(100),
                       &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
                            [0xd73ef6e2, 0x099dc18f, 0x46450af9, 0x1b390a48],