blob: 673553f5d38f16ba5a8855bf8a69a86d3419563d [file] [log] [blame]
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::internal_utils::*;
use crate::parser::mp4box::BoxSize;
#[derive(Debug)]
pub struct IBitStream<'a> {
pub data: &'a [u8],
pub bit_offset: usize,
}
impl IBitStream<'_> {
fn read_bit(&mut self) -> AvifResult<u8> {
let byte_offset = self.bit_offset / 8;
if byte_offset >= self.data.len() {
return Err(AvifError::BmffParseFailed("Not enough bits".into()));
}
let byte = self.data[byte_offset];
let shift = 7 - (self.bit_offset % 8);
self.bit_offset += 1;
Ok((byte >> shift) & 0x01)
}
pub(crate) fn read(&mut self, n: usize) -> AvifResult<u32> {
assert!(n <= 32);
let mut value: u32 = 0;
for _i in 0..n {
value <<= 1;
value |= self.read_bit()? as u32;
}
Ok(value)
}
pub(crate) fn read_bool(&mut self) -> AvifResult<bool> {
let bit = self.read_bit()?;
Ok(bit == 1)
}
pub(crate) fn skip(&mut self, n: usize) -> AvifResult<()> {
if checked_add!(self.bit_offset, n)? > checked_mul!(self.data.len(), 8)? {
return Err(AvifError::BmffParseFailed("Not enough bytes".into()));
}
self.bit_offset += n;
Ok(())
}
pub(crate) fn skip_uvlc(&mut self) -> AvifResult<()> {
// See the section 4.10.3. uvlc() of the AV1 specification.
let mut leading_zeros = 0u128; // leadingZeros
while !self.read_bool()? {
leading_zeros += 1;
}
if leading_zeros < 32 {
self.skip(leading_zeros as usize)?; // f(leadingZeros) value;
}
Ok(())
}
pub(crate) fn remaining_bits(&self) -> AvifResult<usize> {
checked_sub!(checked_mul!(self.data.len(), 8)?, self.bit_offset)
}
}
#[derive(Debug)]
pub struct IStream<'a> {
pub data: &'a [u8],
pub offset: usize,
}
impl IStream<'_> {
pub(crate) fn create(data: &[u8]) -> IStream {
IStream { data, offset: 0 }
}
fn check(&self, size: usize) -> AvifResult<()> {
if self.bytes_left()? < size {
return Err(AvifError::BmffParseFailed("".into()));
}
Ok(())
}
pub(crate) fn sub_stream(&mut self, size: &BoxSize) -> AvifResult<IStream> {
let offset = self.offset;
checked_incr!(
self.offset,
match size {
BoxSize::FixedSize(size) => {
self.check(*size)?;
*size
}
BoxSize::UntilEndOfStream => self.bytes_left()?,
}
);
Ok(IStream {
data: &self.data[offset..self.offset],
offset: 0,
})
}
pub(crate) fn sub_bit_stream(&mut self, size: usize) -> AvifResult<IBitStream> {
self.check(size)?;
let offset = self.offset;
checked_incr!(self.offset, size);
Ok(IBitStream {
data: &self.data[offset..self.offset],
bit_offset: 0,
})
}
pub(crate) fn bytes_left(&self) -> AvifResult<usize> {
if self.data.len() < self.offset {
return Err(AvifError::UnknownError("".into()));
}
Ok(self.data.len() - self.offset)
}
pub(crate) fn has_bytes_left(&self) -> AvifResult<bool> {
Ok(self.bytes_left()? > 0)
}
pub(crate) fn get_slice(&mut self, size: usize) -> AvifResult<&[u8]> {
self.check(size)?;
let offset_start = self.offset;
checked_incr!(self.offset, size);
Ok(&self.data[offset_start..offset_start + size])
}
pub(crate) fn get_immutable_vec(&self, size: usize) -> AvifResult<Vec<u8>> {
self.check(size)?;
Ok(self.data[self.offset..self.offset + size].to_vec())
}
fn get_vec(&mut self, size: usize) -> AvifResult<Vec<u8>> {
Ok(self.get_slice(size)?.to_vec())
}
pub(crate) fn read_u8(&mut self) -> AvifResult<u8> {
self.check(1)?;
let value = self.data[self.offset];
checked_incr!(self.offset, 1);
Ok(value)
}
pub(crate) fn read_u16(&mut self) -> AvifResult<u16> {
Ok(u16::from_be_bytes(self.get_slice(2)?.try_into().unwrap()))
}
pub(crate) fn read_u24(&mut self) -> AvifResult<u32> {
Ok(self.read_uxx(3)? as u32)
}
pub(crate) fn read_u32(&mut self) -> AvifResult<u32> {
Ok(u32::from_be_bytes(self.get_slice(4)?.try_into().unwrap()))
}
pub(crate) fn read_u64(&mut self) -> AvifResult<u64> {
Ok(u64::from_be_bytes(self.get_slice(8)?.try_into().unwrap()))
}
pub(crate) fn read_i32(&mut self) -> AvifResult<i32> {
Ok(self.read_u32()? as i32)
}
pub(crate) fn read_i16(&mut self) -> AvifResult<i16> {
Ok(self.read_u16()? as i16)
}
pub(crate) fn skip_u32(&mut self) -> AvifResult<()> {
self.skip(4)
}
pub(crate) fn skip_u64(&mut self) -> AvifResult<()> {
self.skip(8)
}
pub(crate) fn read_fraction(&mut self) -> AvifResult<Fraction> {
Ok(Fraction(self.read_i32()?, self.read_u32()?))
}
pub(crate) fn read_ufraction(&mut self) -> AvifResult<UFraction> {
Ok(UFraction(self.read_u32()?, self.read_u32()?))
}
// Reads size characters of a non-null-terminated string.
pub(crate) fn read_string(&mut self, size: usize) -> AvifResult<String> {
Ok(String::from_utf8(self.get_vec(size)?).unwrap_or("".into()))
}
// Reads an xx-byte unsigner integer.
pub(crate) fn read_uxx(&mut self, xx: u8) -> AvifResult<u64> {
let n: usize = xx.into();
if n == 0 {
return Ok(0);
}
if n > 8 {
return Err(AvifError::NotImplemented);
}
let mut out = [0; 8];
let start = out.len() - n;
out[start..].copy_from_slice(self.get_slice(n)?);
Ok(u64::from_be_bytes(out))
}
// Reads a null-terminated string.
pub(crate) fn read_c_string(&mut self) -> AvifResult<String> {
self.check(1)?;
let null_position = self.data[self.offset..]
.iter()
.position(|&x| x == b'\0')
.ok_or(AvifError::BmffParseFailed("".into()))?;
let range = self.offset..self.offset + null_position;
self.offset += null_position + 1;
Ok(String::from_utf8(self.data[range].to_vec()).unwrap_or("".into()))
}
pub(crate) fn read_version_and_flags(&mut self) -> AvifResult<(u8, u32)> {
let version = self.read_u8()?;
let flags = self.read_u24()?;
Ok((version, flags))
}
pub(crate) fn read_and_enforce_version_and_flags(
&mut self,
enforced_version: u8,
) -> AvifResult<(u8, u32)> {
let (version, flags) = self.read_version_and_flags()?;
if version != enforced_version {
return Err(AvifError::BmffParseFailed("".into()));
}
Ok((version, flags))
}
pub(crate) fn skip(&mut self, size: usize) -> AvifResult<()> {
self.check(size)?;
checked_incr!(self.offset, size);
Ok(())
}
pub(crate) fn rewind(&mut self, size: usize) -> AvifResult<()> {
checked_decr!(self.offset, size);
Ok(())
}
pub(crate) fn read_uleb128(&mut self) -> AvifResult<u32> {
// See the section 4.10.5. of the AV1 specification.
let mut value: u64 = 0;
for i in 0..8 {
// leb128_byte contains 8 bits read from the bitstream.
let leb128_byte = self.read_u8()?;
// The bottom 7 bits are used to compute the variable value.
value |= u64::from(leb128_byte & 0x7F) << (i * 7);
// The most significant bit is used to indicate that there are more
// bytes to be read.
if (leb128_byte & 0x80) == 0 {
// It is a requirement of bitstream conformance that the value
// returned from the leb128 parsing process is less than or
// equal to (1 << 32)-1.
return u32_from_u64(value);
}
}
// It is a requirement of bitstream conformance that the most
// significant bit of leb128_byte is equal to 0 if i is equal to 7.
Err(AvifError::BmffParseFailed(
"uleb value did not terminate after 8 bytes".into(),
))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn read_uxx() {
let mut stream = IStream::create(&[1, 2, 3, 4, 5, 6, 7, 8]);
assert_eq!(stream.read_uxx(0), Ok(0));
assert_eq!(stream.offset, 0);
assert_eq!(stream.read_uxx(1), Ok(1));
assert_eq!(stream.offset, 1);
stream.offset = 0;
assert_eq!(stream.read_uxx(2), Ok(258));
stream.offset = 0;
assert_eq!(stream.read_u16(), Ok(258));
stream.offset = 0;
assert_eq!(stream.read_uxx(3), Ok(66051));
stream.offset = 0;
assert_eq!(stream.read_u24(), Ok(66051));
stream.offset = 0;
assert_eq!(stream.read_uxx(4), Ok(16909060));
stream.offset = 0;
assert_eq!(stream.read_u32(), Ok(16909060));
stream.offset = 0;
assert_eq!(stream.read_uxx(5), Ok(4328719365));
stream.offset = 0;
assert_eq!(stream.read_uxx(6), Ok(1108152157446));
stream.offset = 0;
assert_eq!(stream.read_uxx(7), Ok(283686952306183));
stream.offset = 0;
assert_eq!(stream.read_uxx(8), Ok(72623859790382856));
stream.offset = 0;
assert_eq!(stream.read_u64(), Ok(72623859790382856));
stream.offset = 0;
assert_eq!(stream.read_uxx(9), Err(AvifError::NotImplemented));
}
#[test]
fn read_string() {
let bytes = "abcd\0e".as_bytes();
assert_eq!(IStream::create(bytes).read_string(4), Ok("abcd".into()));
assert_eq!(IStream::create(bytes).read_string(5), Ok("abcd\0".into()));
assert_eq!(IStream::create(bytes).read_string(6), Ok("abcd\0e".into()));
assert!(matches!(
IStream::create(bytes).read_string(8),
Err(AvifError::BmffParseFailed(_))
));
assert_eq!(IStream::create(bytes).read_c_string(), Ok("abcd".into()));
}
}