fix clippy warnings
[nihav.git] / nihav-indeo / src / codecs / ivibr.rs
index a333b3a7dba9f67bb8a7e7286798d57ff9d0fc37..1383f7409dec3f1b72f88fbcc41b5bd13fbe7072 100644 (file)
@@ -488,10 +488,12 @@ pub struct IVIDecoder {
     tiles:      Vec<IVITile>,
     num_tiles:  [[usize; 4]; 4],
     tile_start: [[usize; 4]; 4],
+
+    scalable:   bool,
 }
 
 impl IVIDecoder {
-    pub fn new() -> Self {
+    pub fn new(scalable: bool) -> Self {
         let mut bands: Vec<BandHeader> = Vec::with_capacity(12);
         bands.resize(12, BandHeader::new_empty(42, 42));
         IVIDecoder {
@@ -506,6 +508,8 @@ impl IVIDecoder {
             bands,
             band_tiles: 0,
             tiles: Vec::new(), tile_start: [[0; 4]; 4], num_tiles: [[0; 4]; 4],
+
+            scalable,
         }
     }
 
@@ -601,7 +605,7 @@ impl IVIDecoder {
                 }
                 br.align();
                 validate!(len > 0);
-                let tile_end = tile_start + len * 8;
+                let tile_end = (tile_start & !7) + len * 8;
                 validate!(tile_end > br.tell());
                 validate!(tile_end <= br.tell() + (br.left() as usize));
                 {
@@ -628,6 +632,7 @@ impl IVIDecoder {
                 }
 
                 self.decode_tile(br, &band, tile_no, tr, tr_dc)?;
+                br.align();
 let skip_part = tile_end - br.tell();
 br.skip(skip_part as u32)?;
             } else {
@@ -819,7 +824,6 @@ br.skip(skip_part as u32)?;
             }
             dstidx += stride * band.mb_size;
         }
-        br.align();
         Ok(())
     }
 
@@ -832,7 +836,7 @@ br.skip(skip_part as u32)?;
         unreachable!();
     }
 
-    fn decode_single_frame<'a>(&mut self, dec: &mut dyn IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult<NABufferType> {
+    fn decode_single_frame(&mut self, dec: &mut dyn IndeoXParser, br: &mut BitReader) -> DecoderResult<NABufferType> {
         let pic_hdr = dec.decode_picture_header(br)?;
         self.ftype = pic_hdr.ftype;
         if pic_hdr.ftype.is_null() {
@@ -876,22 +880,77 @@ br.skip(skip_part as u32)?;
         self.realloc(&pic_hdr)?;
         self.frames[self.cur_frame].realloc(&pic_hdr)?;
 
-        for plane in 0..3 {
-            let num_bands = if plane == 0 { pic_hdr.luma_bands } else { pic_hdr.chroma_bands };
-            for band in 0..num_bands {
-                self.decode_band(&pic_hdr, dec, br, plane, band)?;
+        if !self.scalable {
+            for plane in 0..3 {
+                let num_bands = if plane == 0 { pic_hdr.luma_bands } else { pic_hdr.chroma_bands };
+                for band in 0..num_bands {
+                    self.decode_band(&pic_hdr, dec, br, plane, band)?;
+                }
+                if let NABufferType::Video(ref mut vb) = buftype {
+                    let mut frame = self.frames[self.cur_frame].clone();
+                    if num_bands == 1 {
+                        frame.fill_plane(vb, plane);
+                    } else {
+                        let dplane = if (plane == 1) || (plane == 2) { plane ^ 3 } else { plane };
+                        let (w, h)  = vb.get_dimensions(dplane);
+                        let dstride = vb.get_stride(dplane);
+                        let off     = vb.get_offset(dplane);
+                        let dst = vb.get_data_mut().unwrap();
+                        dec.recombine_plane(&frame.plane_buf[plane], frame.plane_stride[plane], &mut dst[off..], dstride, w, h);
+                    }
+                }
+            }
+        } else {
+            let mut bands_decoded = [[false; 10]; 3];
+            let mut num_decoded = 0;
+
+            let num_bands = [ pic_hdr.luma_bands, pic_hdr.chroma_bands, pic_hdr.chroma_bands ];
+
+            for plane in 0..3 {
+                for band in 0..num_bands[plane] {
+                    if br.peek(8) == 0x01 { // skipped scalable bands
+                        br.skip(8)?;
+                        continue;
+                    }
+                    self.decode_band(&pic_hdr, dec, br, plane, band)?;
+                    bands_decoded[plane][band] = true;
+                    num_decoded += 1;
+                }
+            }
+            if (num_decoded < num_bands[0] + num_bands[1] + num_bands[2]) && (br.left() > 0) {
+                validate!(br.read(8)? == 0x00);
+                while br.peek(8) == 0x00 {
+                    if br.skip(8).is_err() { // happens at the end of data
+                        break;
+                    }
+                }
+                validate!((br.tell() & 31) == 0);
+
+                for plane in 0..3 {
+                    for band in 0..num_bands[plane] {
+                        if bands_decoded[plane][band] || br.left() == 0 {
+                            continue;
+                        }
+                        self.decode_band(&pic_hdr, dec, br, plane, band)?;
+                        bands_decoded[plane][band] = true;
+                        num_decoded += 1;
+                    }
+                }
             }
+
             if let NABufferType::Video(ref mut vb) = buftype {
-                let mut frame = self.frames[self.cur_frame].clone();
-                if num_bands == 1 {
-                    frame.fill_plane(vb, plane);
-                } else {
-                    let dplane = if (plane == 1) || (plane == 2) { plane ^ 3 } else { plane };
-                    let (w, h)  = vb.get_dimensions(dplane);
-                    let dstride = vb.get_stride(dplane);
-                    let off     = vb.get_offset(dplane);
-                    let dst = vb.get_data_mut().unwrap();
-                    dec.recombine_plane(&frame.plane_buf[plane], frame.plane_stride[plane], &mut dst[off..], dstride, w, h);
+                for plane in 0..3 {
+                    let mut frame = self.frames[self.cur_frame].clone();
+                    if num_bands[plane] == 1 {
+                        frame.fill_plane(vb, plane);
+                    } else {
+                        let dplane = if (plane == 1) || (plane == 2) { plane ^ 3 } else { plane };
+                        let (w, h)  = vb.get_dimensions(dplane);
+                        let dstride = vb.get_stride(dplane);
+                        let off     = vb.get_offset(dplane);
+                        let dst = vb.get_data_mut().unwrap();
+                        dec.recombine_plane(&frame.plane_buf[plane], frame.plane_stride[plane], &mut dst[off..], dstride, w, h);
+                    }
                 }
             }
         }
@@ -919,9 +978,8 @@ br.skip(skip_part as u32)?;
         Ok(buftype)
     }
 
-    pub fn decode_frame<'a>(&mut self, dec: &mut dyn IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult<NABufferType> {
-        let res = self.decode_single_frame(dec, br);
-        if res.is_err() { return res; }
+    pub fn decode_frame(&mut self, dec: &mut dyn IndeoXParser, br: &mut BitReader) -> DecoderResult<NABufferType> {
+        let res = self.decode_single_frame(dec, br)?;
         if (self.ftype == IVIFrameType::Intra) && (br.left() > 16) {
             loop {
                 if br.left() < 8 { break; }
@@ -943,7 +1001,12 @@ br.skip(skip_part as u32)?;
                 self.ftype = IVIFrameType::Intra;
             }
         }
-        if let Ok(NABufferType::None) = res {
+        if self.bref.is_some() && self.ftype == IVIFrameType::Inter {
+            let mut bref: Option<NABufferType> = Some(res);
+            mem::swap(&mut bref, &mut self.bref);
+            return Ok(bref.unwrap());
+        }
+        if let NABufferType::None = res {
             if self.bref.is_some() {
                 let mut bref: Option<NABufferType> = None;
                 mem::swap(&mut bref, &mut self.bref);
@@ -951,7 +1014,7 @@ br.skip(skip_part as u32)?;
                 return Ok(bref.unwrap());
             }
         }
-        res
+        Ok(res)
     }
 
     pub fn flush(&mut self) {