rusty_av2d 0.2.2

Pure-Rust AV2 video decoder, no C/FFI. Byte-identical to the AVM reference decoder across a 45-clip conformance corpus.
Documentation
use std::ops::{Add, AddAssign, Sub, SubAssign};

use crate::include::common::bitdepth::BitDepth;
use crate::pixels::Pixels;
use crate::strided::Strided;

#[derive(Clone, Copy)]
#[repr(C)]
pub struct WithOffset<T> {
    pub data: T,
    pub offset: usize,
}

impl<T> WithOffset<T> {
    pub fn map<U>(self, map: impl FnOnce(T) -> U) -> WithOffset<U> {
        WithOffset {
            data: map(self.data),
            offset: self.offset,
        }
    }

    pub fn as_ref<'a>(&'a self) -> WithOffset<&'a T> {
        WithOffset {
            data: &self.data,
            offset: self.offset,
        }
    }
}
impl<T> AddAssign<usize> for WithOffset<T> {
    #[cfg_attr(debug_assertions, track_caller)]
    fn add_assign(&mut self, rhs: usize) {
        self.offset += rhs;
    }
}

impl<T> SubAssign<usize> for WithOffset<T> {
    #[cfg_attr(debug_assertions, track_caller)]
    fn sub_assign(&mut self, rhs: usize) {
        self.offset -= rhs;
    }
}

impl<T> AddAssign<isize> for WithOffset<T> {
    #[cfg_attr(debug_assertions, track_caller)]
    fn add_assign(&mut self, rhs: isize) {
        self.offset = self.offset.wrapping_add_signed(rhs);
    }
}

impl<T> SubAssign<isize> for WithOffset<T> {
    #[cfg_attr(debug_assertions, track_caller)]
    fn sub_assign(&mut self, rhs: isize) {
        self.offset = self.offset.wrapping_add_signed(-rhs);
    }
}

impl<T> Add<usize> for WithOffset<T> {
    type Output = Self;

    #[cfg_attr(debug_assertions, track_caller)]
    fn add(mut self, rhs: usize) -> Self::Output {
        self += rhs;
        self
    }
}

impl<T> Sub<usize> for WithOffset<T> {
    type Output = Self;

    #[cfg_attr(debug_assertions, track_caller)]
    fn sub(mut self, rhs: usize) -> Self::Output {
        self -= rhs;
        self
    }
}

impl<T> Add<isize> for WithOffset<T> {
    type Output = Self;

    #[cfg_attr(debug_assertions, track_caller)]
    fn add(mut self, rhs: isize) -> Self::Output {
        self += rhs;
        self
    }
}

impl<T> Sub<isize> for WithOffset<T> {
    type Output = Self;

    #[cfg_attr(debug_assertions, track_caller)]
    fn sub(mut self, rhs: isize) -> Self::Output {
        self -= rhs;
        self
    }
}

impl<P: Pixels> WithOffset<P> {
    #[inline] // Inline to see bounds checks in order to potentially elide them.
    #[cfg_attr(debug_assertions, track_caller)]
    pub fn as_ptr<BD: BitDepth>(&self) -> *const BD::Pixel {
        self.data.as_ptr_at::<BD>(self.offset)
    }

    #[inline] // Inline to see bounds checks in order to potentially elide them.
    #[cfg_attr(debug_assertions, track_caller)]
    pub fn as_mut_ptr<BD: BitDepth>(&self) -> *mut BD::Pixel {
        self.data.as_mut_ptr_at::<BD>(self.offset)
    }

    pub fn wrapping_as_ptr<BD: BitDepth>(&self) -> *const BD::Pixel {
        self.data.wrapping_as_ptr_at::<BD>(self.offset)
    }

    pub fn wrapping_as_mut_ptr<BD: BitDepth>(&self) -> *const BD::Pixel {
        self.data.wrapping_as_mut_ptr_at::<BD>(self.offset)
    }
}

impl<S: Strided> Strided for WithOffset<S> {
    fn stride(&self) -> isize {
        self.data.stride()
    }
}