]> git.nihav.org Git - nihav.git/blobdiff - nihav-core/src/io/bitreader.rs
y4m: if no colourspace is specified it should be YUV 4:2:0
[nihav.git] / nihav-core / src / io / bitreader.rs
index 11633266068024d02fc339bba23be465033944a4..c4f9f6c8a3490edeccb1ed4385e495f15ee940a7 100644 (file)
@@ -1,6 +1,6 @@
 //! Bitstream reader functionality.
 //!
-//! Bitstream reader operates on `&[u8]` and allows to read bits from the slice in different modes. 
+//! Bitstream reader operates on `&[u8]` and allows to read bits from the slice in different modes.
 //!
 //! # Examples
 //!
@@ -9,7 +9,7 @@
 //! use nihav_core::io::bitreader::{BitReader,BitReaderMode};
 //!
 //! # use nihav_core::io::bitreader::BitReaderResult;
-//! # fn foo() -> BitReaderResult<u32> { 
+//! # fn foo() -> BitReaderResult<u32> {
 //! let bits: [u8; 4] = [ 42, 43, 44, 45 ];
 //! let mut br = BitReader::new(&bits, BitReaderMode::BE);
 //! let value = br.read(17)?;
@@ -22,7 +22,7 @@
 //! use nihav_core::io::bitreader::{BitReader,BitReaderMode};
 //!
 //! # use nihav_core::io::bitreader::BitReaderResult;
-//! # fn foo() -> BitReaderResult<()> { 
+//! # fn foo() -> BitReaderResult<()> {
 //! let bits: [u8; 4] = [ 42, 43, 44, 45 ];
 //! let mut br = BitReader::new(&bits, BitReaderMode::BE);
 //! let num_skip_bits = br.read(3)?;
@@ -35,7 +35,7 @@
 
 
 /// Bitstream reading modes.
-#[derive(Debug)]
+#[derive(Debug,Clone,Copy)]
 pub enum BitReaderMode {
     /// The stream is big endian MSB first.
     BE,
@@ -48,7 +48,7 @@ pub enum BitReaderMode {
 }
 
 /// A list specifying general bitstream reading errors.
-#[derive(Debug)]
+#[derive(Debug,Clone,Copy)]
 pub enum BitReaderError {
     /// The reader is at the end of bitstream.
     BitstreamEnd,
@@ -64,7 +64,7 @@ use self::BitReaderError::*;
 pub type BitReaderResult<T> = Result<T, BitReaderError>;
 
 /// Bitstream reader.
-#[derive(Debug)]
+#[derive(Debug,Clone)]
 pub struct BitReader<'a> {
     cache: u64,
     bits:  u8,
@@ -77,7 +77,7 @@ pub struct BitReader<'a> {
 impl<'a> BitReader<'a> {
 
     /// Constructs a new instance of bitstream reader.
-    /// 
+    ///
     /// # Examples
     ///
     /// ```
@@ -90,6 +90,9 @@ impl<'a> BitReader<'a> {
         BitReader{ cache: 0, pos: 0, bits: 0, src, mode }
     }
 
+    /// Returns the data bitstream reader uses.
+    pub fn get_data(&self) -> &'a [u8] { self.src }
+
     /// Reports the current bit position in the bitstream (usually simply the number of bits read so far).
     pub fn tell(&self) -> usize {
         self.pos * 8 - (self.bits as usize)
@@ -210,7 +213,7 @@ impl<'a> BitReader<'a> {
     /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
     ///
     /// # use nihav_core::io::bitreader::BitReaderResult;
-    /// # fn foo() -> BitReaderResult<u32> { 
+    /// # fn foo() -> BitReaderResult<u32> {
     /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
     /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
     /// let value = br.read(17)?;
@@ -270,7 +273,7 @@ impl<'a> BitReader<'a> {
     /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
     ///
     /// # use nihav_core::io::bitreader::BitReaderResult;
-    /// # fn foo() -> BitReaderResult<u32> { 
+    /// # fn foo() -> BitReaderResult<u32> {
     /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
     /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
     /// let peek_value = br.peek(8); // this should return 42
@@ -302,8 +305,11 @@ impl<'a> BitReader<'a> {
         self.reset_cache();
         self.pos += ((skip_bits / 32) * 4) as usize;
         skip_bits &= 0x1F;
-        self.refill()?;
         if skip_bits > 0 {
+            self.refill()?;
+            if u32::from(self.bits) < skip_bits {
+                return Err(BitstreamEnd);
+            }
             self.skip_cache(skip_bits as u8);
         }
         Ok(())
@@ -318,7 +324,7 @@ impl<'a> BitReader<'a> {
     /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
     ///
     /// # use nihav_core::io::bitreader::BitReaderResult;
-    /// # fn foo() -> BitReaderResult<u32> { 
+    /// # fn foo() -> BitReaderResult<u32> {
     /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
     /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
     /// br.seek(16)?;
@@ -343,7 +349,7 @@ impl<'a> BitReader<'a> {
     /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
     ///
     /// # use nihav_core::io::bitreader::BitReaderResult;
-    /// # fn foo() -> BitReaderResult<()> { 
+    /// # fn foo() -> BitReaderResult<()> {
     /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
     /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
     /// br.skip(17)?; // now reader is at bit position 17