pub mod block;
pub mod compress;
pub mod filter;
pub mod format;
pub mod tiles;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Extent {
D1 { width: usize },
D2 { width: usize, height: usize },
D3 {
width: usize,
height: usize,
depth: usize,
},
D1Array { width: usize, layers: usize },
D2Array {
width: usize,
height: usize,
layers: usize,
},
}
impl Extent {
pub fn width(&self) -> usize {
match *self {
Extent::D1 { width } => width,
Extent::D2 { width, .. } => width,
Extent::D3 { width, .. } => width,
Extent::D1Array { width, .. } => width,
Extent::D2Array { width, .. } => width,
}
}
pub fn height(&self) -> usize {
match *self {
Extent::D1 { .. } => 1,
Extent::D2 { height, .. } => height,
Extent::D3 { height, .. } => height,
Extent::D1Array { .. } => 1,
Extent::D2Array { height, .. } => height,
}
}
pub fn depth(&self) -> usize {
match *self {
Extent::D1 { .. } => 1,
Extent::D2 { .. } => 1,
Extent::D3 { depth, .. } => depth,
Extent::D1Array { .. } => 1,
Extent::D2Array { .. } => 1,
}
}
pub fn layers(&self) -> usize {
match *self {
Extent::D1 { .. } => 1,
Extent::D2 { .. } => 1,
Extent::D3 { .. } => 1,
Extent::D1Array { layers, .. } => layers,
Extent::D2Array { layers, .. } => layers,
}
}
pub fn dimensions(self) -> Dimensions {
match self {
Extent::D1 { .. } => Dimensions::D1,
Extent::D2 { .. } => Dimensions::D2,
Extent::D3 { .. } => Dimensions::D3,
Extent::D1Array { .. } => Dimensions::D1,
Extent::D2Array { .. } => Dimensions::D2,
}
}
pub fn raw_size(self) -> [usize; 3] {
match self {
Extent::D1 { width } => [width, 1, 1],
Extent::D2 { width, height } => [width, height, 1],
Extent::D3 {
width,
height,
depth,
} => [width, height, depth],
Extent::D1Array { width, layers } => [width, 1, layers],
Extent::D2Array {
width,
height,
layers,
} => [width, height, layers],
}
}
pub fn from_raw_size(value: [usize; 3], dimensions: Dimensions) -> Option<Self> {
match dimensions {
Dimensions::D1 => {
if value[1] != 1 || value[2] != 1 {
return None;
}
Some(Extent::D1 { width: value[0] })
}
Dimensions::D2 => {
if value[2] != 1 {
return None;
}
Some(Extent::D2 {
width: value[0],
height: value[1],
})
}
Dimensions::D3 => Some(Extent::D3 {
width: value[0],
height: value[1],
depth: value[2],
}),
Dimensions::D1Array => {
if value[1] != 1 {
return None;
}
Some(Extent::D1Array {
width: value[0],
layers: value[2],
})
}
Dimensions::D2Array => Some(Extent::D2Array {
width: value[0],
height: value[1],
layers: value[2],
}),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Dimensions {
D1,
D2,
D3,
D1Array,
D2Array,
}
pub struct Image2DRef<'a, T> {
width: usize,
height: usize,
stride: usize,
pixels: &'a [T],
}
impl<T> Copy for Image2DRef<'_, T> {}
impl<T> Clone for Image2DRef<'_, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T> Image2DRef<'a, T> {
pub fn new(width: usize, height: usize, pixels: &'a [T]) -> Self {
assert!(pixels.len() >= height * width);
Image2DRef {
width,
height,
stride: width,
pixels,
}
}
pub fn with_stride(width: usize, height: usize, stride: usize, pixels: &'a [T]) -> Self {
let plane_len = len2([width, height], stride);
assert!(pixels.len() >= plane_len);
Image2DRef {
width,
height,
stride,
pixels,
}
}
pub fn from_row(pixels: &'a [T]) -> Self {
Image2DRef {
width: pixels.len(),
height: 1,
stride: pixels.len(),
pixels,
}
}
pub fn width(&self) -> usize {
self.width
}
pub fn height(&self) -> usize {
self.height
}
pub fn as_ref(&self) -> Image2DRef<'_, T> {
*self
}
pub fn get(&self, x: usize, y: usize) -> &'a T {
assert!(x < self.width);
assert!(y < self.height);
&self.pixels[y * self.stride + x]
}
pub fn row(&self, y: usize) -> &'a [T] {
assert!(y < self.height);
&self.pixels[y * self.stride..][..self.width]
}
pub fn get_range(&self, x: usize, y: usize, w: usize, h: usize) -> Image2DRef<'a, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
Image2DRef {
width: w,
height: h,
stride: self.stride,
pixels: &self.pixels[y * self.stride + x..],
}
}
pub fn get_rect(&self, rect: crate::math::Rect<usize>) -> Image2DRef<'a, T> {
self.get_range(rect.x, rect.y, rect.w, rect.h)
}
pub fn pixels(&self) -> &'a [T] {
self.pixels
}
pub fn iter_rows(&self) -> impl DoubleEndedIterator<Item = &'a [T]> + use<'a, T> {
let Self {
width,
height,
stride,
pixels,
} = *self;
let plane_len = len2([width, height], stride);
pixels[..plane_len]
.chunks(stride)
.map(move |row| &row[..width])
}
pub fn iter_pixels(&self) -> impl DoubleEndedIterator<Item = &'a T> + use<'a, T> {
let Self {
width,
height,
stride,
pixels,
} = *self;
let plane_len = len2([width, height], stride);
pixels[..plane_len]
.chunks(stride)
.flat_map(move |row| &row[..width])
}
pub fn into_matrix<const W: usize, const H: usize>(self) -> [[T; W]; H]
where
T: Copy,
{
assert_eq!(self.width, W);
assert_eq!(self.height, H);
let mut colors = [[self.pixels[0]; W]; H];
for (y, row) in colors.iter_mut().enumerate() {
row.copy_from_slice(self.row(y));
}
colors
}
}
pub struct Image2DMut<'a, T> {
width: usize,
height: usize,
stride: usize,
pixels: &'a mut [T],
}
impl<'a, T> Image2DMut<'a, T> {
pub fn new(width: usize, height: usize, pixels: &'a mut [T]) -> Self {
assert!(pixels.len() >= height * width);
Image2DMut {
width,
height,
stride: width,
pixels,
}
}
pub fn with_stride(width: usize, height: usize, stride: usize, pixels: &'a mut [T]) -> Self {
let plane_len = len2([width, height], stride);
assert!(pixels.len() >= plane_len);
Image2DMut {
width,
height,
stride,
pixels,
}
}
pub fn from_row(pixels: &'a mut [T]) -> Self {
Image2DMut {
width: pixels.len(),
height: 1,
stride: pixels.len(),
pixels,
}
}
pub fn reborrow(&mut self) -> Image2DMut<'_, T> {
Image2DMut {
width: self.width,
height: self.height,
stride: self.stride,
pixels: &mut *self.pixels,
}
}
pub fn width(&self) -> usize {
self.width
}
pub fn height(&self) -> usize {
self.height
}
pub fn as_ref(&self) -> Image2DRef<'_, T> {
Image2DRef {
width: self.width,
height: self.height,
stride: self.stride,
pixels: &*self.pixels,
}
}
pub fn as_mut(&mut self) -> Image2DMut<'_, T> {
Image2DMut {
width: self.width,
height: self.height,
stride: self.stride,
pixels: &mut *self.pixels,
}
}
pub fn get(&self, x: usize, y: usize) -> &T {
&self.pixels[y * self.stride + x]
}
pub fn row(&self, y: usize) -> &'_ [T] {
assert!(y < self.height);
&self.pixels[y * self.stride..][..self.width]
}
pub fn get_mut(&mut self, x: usize, y: usize) -> &mut T {
&mut self.pixels[y * self.stride + x]
}
pub fn row_mut(&mut self, y: usize) -> &'_ mut [T] {
assert!(y < self.height);
&mut self.pixels[y * self.stride..][..self.width]
}
pub fn set(&mut self, x: usize, y: usize, value: T) {
self.pixels[y * self.stride + x] = value;
}
pub fn pixels(&self) -> &[T] {
&*self.pixels
}
pub fn pixels_mut(&mut self) -> &mut [T] {
&mut *self.pixels
}
pub fn iter_rows(&self) -> impl Iterator<Item = &'_ [T]> + use<'_, T> {
let Self {
width,
height,
stride,
ref pixels,
} = *self;
let plane_len = len2([width, height], stride);
pixels[..plane_len]
.chunks(stride)
.map(move |row| &row[..width])
}
pub fn iter_rows_mut(&mut self) -> impl Iterator<Item = &mut [T]> + use<'_, T> {
let Self {
width,
height,
stride,
ref mut pixels,
} = *self;
let plane_len = len2([width, height], stride);
pixels[..plane_len]
.chunks_mut(stride)
.map(move |row| &mut row[..width])
}
pub fn into_iter_rows(self) -> impl Iterator<Item = &'a mut [T]> + use<'a, T> {
let Self {
width,
height,
stride,
pixels,
} = self;
let plane_len = len2([width, height], stride);
pixels[..plane_len]
.chunks_mut(stride)
.map(move |row| &mut row[..width])
}
pub fn iter_pixels(&self) -> impl Iterator<Item = &T> + use<'_, T> {
let Self {
width,
height,
stride,
ref pixels,
} = *self;
let plane_len = len2([width, height], stride);
pixels[..plane_len]
.chunks(stride)
.flat_map(move |row| &row[..width])
}
pub fn iter_pixels_mut(&mut self) -> impl Iterator<Item = &'_ mut T> + use<'_, T> {
let Self {
width,
height,
stride,
ref mut pixels,
} = *self;
let plane_len = len2([width, height], stride);
pixels[..plane_len]
.chunks_mut(stride)
.flat_map(move |row| &mut row[..width])
}
pub fn into_iter_pixels(self) -> impl Iterator<Item = &'a mut T> + use<'a, T> {
let Self {
width,
height,
stride,
pixels,
} = self;
let plane_len = len2([width, height], stride);
pixels[..plane_len]
.chunks_mut(stride)
.flat_map(move |row| &mut row[..width])
}
pub fn get_range(&mut self, x: usize, y: usize, w: usize, h: usize) -> Image2DRef<'_, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
Image2DRef {
width: w,
height: h,
stride: self.stride,
pixels: &self.pixels[y * self.stride + x..],
}
}
pub fn get_rect(&mut self, rect: crate::math::Rect<usize>) -> Image2DRef<'_, T> {
self.get_range(rect.x, rect.y, rect.w, rect.h)
}
pub fn get_range_mut(&mut self, x: usize, y: usize, w: usize, h: usize) -> Image2DMut<'_, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
Image2DMut {
width: w,
height: h,
stride: self.stride,
pixels: &mut self.pixels[y * self.stride + x..],
}
}
pub fn get_rect_mut(&mut self, rect: crate::math::Rect<usize>) -> Image2DMut<'_, T> {
self.get_range_mut(rect.x, rect.y, rect.w, rect.h)
}
pub fn copy_from(&mut self, src: Image2DRef<'_, T>)
where
T: Copy,
{
assert_eq!(src.width, self.width);
assert_eq!(src.height, self.height);
for j in 0..src.height {
self.row_mut(j).copy_from_slice(src.row(j));
}
}
pub fn copy_from_matrix<const W: usize, const H: usize>(&mut self, matrix: &[[T; W]; H])
where
T: Copy,
{
assert_eq!(self.width, W);
assert_eq!(self.height, H);
for (y, row) in matrix.iter().enumerate() {
self.row_mut(y).copy_from_slice(row);
}
}
}
pub struct Image3DRef<'a, T> {
width: usize,
height: usize,
depth: usize,
row_stride: usize,
plane_stride: usize,
pixels: &'a [T],
}
impl<T> Copy for Image3DRef<'_, T> {}
impl<T> Clone for Image3DRef<'_, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T> Image3DRef<'a, T> {
pub fn new(width: usize, height: usize, depth: usize, pixels: &'a [T]) -> Self {
assert!(pixels.len() >= depth * height * width);
Image3DRef {
width,
height,
depth,
row_stride: width,
plane_stride: width * height,
pixels,
}
}
pub fn with_stride(
width: usize,
height: usize,
depth: usize,
row_stride: usize,
plane_stride: usize,
pixels: &'a [T],
) -> Self {
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
assert!(pixels.len() >= volume_len);
Image3DRef {
width,
height,
depth,
row_stride,
plane_stride,
pixels,
}
}
pub fn from_row(pixels: &'a [T]) -> Self {
Image3DRef {
width: pixels.len(),
height: 1,
depth: 1,
row_stride: pixels.len(),
plane_stride: pixels.len(),
pixels,
}
}
pub fn from_plane(plane: Image2DRef<'a, T>) -> Self {
let plane_len = len2([plane.width, plane.height], plane.stride);
Image3DRef {
width: plane.width,
height: plane.height,
depth: 1,
row_stride: plane.stride,
plane_stride: plane_len,
pixels: plane.pixels,
}
}
pub fn width(&self) -> usize {
self.width
}
pub fn height(&self) -> usize {
self.height
}
pub fn depth(&self) -> usize {
self.depth
}
pub fn get(&self, x: usize, y: usize, z: usize) -> &'a T {
assert!(x < self.width);
assert!(y < self.height);
assert!(z < self.depth);
&self.pixels[z * self.plane_stride + y * self.row_stride + x]
}
pub fn row(&self, y: usize, z: usize) -> &'a [T] {
assert!(y < self.height);
assert!(z < self.depth);
&self.pixels[z * self.plane_stride + y * self.row_stride..][..self.width]
}
pub fn get_plane_xy(&self, z: usize) -> Image2DRef<'a, T> {
assert!(z < self.depth);
Image2DRef {
width: self.width,
height: self.height,
stride: self.row_stride,
pixels: &self.pixels[z * self.plane_stride..],
}
}
pub fn get_plane_xz(&self, y: usize) -> Image2DRef<'a, T> {
assert!(y < self.height);
Image2DRef {
width: self.width,
height: self.depth,
stride: self.plane_stride,
pixels: &self.pixels[y * self.row_stride..],
}
}
pub fn get_range_xy(
&self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
) -> Image2DRef<'a, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
assert!(z < self.depth);
Image2DRef {
width: w,
height: h,
stride: self.row_stride,
pixels: &self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn get_range_xz(
&self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
) -> Image2DRef<'a, T> {
assert!(x + w <= self.width);
assert!(y < self.height);
assert!(z + h <= self.depth);
Image2DRef {
width: w,
height: h,
stride: self.plane_stride,
pixels: &self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn get_range(
&self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
d: usize,
) -> Image3DRef<'a, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
assert!(z + d <= self.depth);
Image3DRef {
width: w,
height: h,
depth: d,
row_stride: self.row_stride,
plane_stride: self.plane_stride,
pixels: &self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn pixels(&self) -> &'a [T] {
self.pixels
}
pub fn iter_planes(&self) -> impl DoubleEndedIterator<Item = Image2DRef<'a, T>> + use<'a, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
pixels,
} = *self;
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks(plane_stride)
.map(move |plane| Image2DRef {
width,
height,
stride: row_stride,
pixels: plane,
})
}
pub fn iter_rows(&self) -> impl DoubleEndedIterator<Item = &'a [T]> + use<'a, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
pixels,
} = *self;
let plane_len = len2([width, height], row_stride);
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks(plane_stride)
.flat_map(move |plane| plane[..plane_len].chunks(row_stride))
.map(move |row| &row[..width])
}
pub fn iter_pixels(&self) -> impl DoubleEndedIterator<Item = &'a T> + use<'a, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
pixels,
} = *self;
let plane_len = len2([width, height], row_stride);
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks(plane_stride)
.flat_map(move |plane| plane[..plane_len].chunks(row_stride))
.flat_map(move |row| &row[..width])
}
}
pub struct Image3DMut<'a, T> {
width: usize,
height: usize,
depth: usize,
row_stride: usize,
plane_stride: usize,
pixels: &'a mut [T],
}
impl<'a, T> Image3DMut<'a, T> {
pub fn new(width: usize, height: usize, depth: usize, pixels: &'a mut [T]) -> Self {
assert!(pixels.len() >= height * width * depth);
Image3DMut {
width,
height,
depth,
row_stride: width,
plane_stride: width * height,
pixels,
}
}
pub fn with_stride(
width: usize,
height: usize,
depth: usize,
row_stride: usize,
plane_stride: usize,
pixels: &'a mut [T],
) -> Self {
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
assert!(pixels.len() >= volume_len);
Image3DMut {
width,
height,
depth,
pixels,
row_stride,
plane_stride,
}
}
pub fn from_row(pixels: &'a mut [T]) -> Self {
Image3DMut {
width: pixels.len(),
height: 1,
depth: 1,
row_stride: pixels.len(),
plane_stride: pixels.len(),
pixels,
}
}
pub fn from_plane(plane: Image2DMut<'a, T>) -> Self {
let plane_len = len2([plane.width, plane.height], plane.stride);
Image3DMut {
width: plane.width,
height: plane.height,
depth: 1,
row_stride: plane.stride,
plane_stride: plane_len,
pixels: plane.pixels,
}
}
pub fn width(&self) -> usize {
self.width
}
pub fn height(&self) -> usize {
self.height
}
pub fn depth(&self) -> usize {
self.depth
}
pub fn as_ref(&self) -> Image3DRef<'_, T> {
Image3DRef {
width: self.width,
height: self.height,
depth: self.depth,
row_stride: self.row_stride,
plane_stride: self.plane_stride,
pixels: &*self.pixels,
}
}
pub fn as_mut(&mut self) -> Image3DMut<'_, T> {
Image3DMut {
width: self.width,
height: self.height,
depth: self.depth,
row_stride: self.row_stride,
plane_stride: self.plane_stride,
pixels: &mut *self.pixels,
}
}
pub fn get(&self, x: usize, y: usize, z: usize) -> &T {
assert!(x < self.width);
assert!(y < self.height);
assert!(z < self.depth);
&self.pixels[z * self.plane_stride + y * self.row_stride + x]
}
pub fn get_mut(&mut self, x: usize, y: usize, z: usize) -> &mut T {
assert!(x < self.width);
assert!(y < self.height);
assert!(z < self.depth);
&mut self.pixels[z * self.plane_stride + y * self.row_stride + x]
}
pub fn row(&self, y: usize, z: usize) -> &[T] {
assert!(y < self.height);
assert!(z < self.depth);
&self.pixels[z * self.plane_stride + y * self.row_stride..][..self.width]
}
pub fn row_mut(&mut self, y: usize, z: usize) -> &mut [T] {
assert!(y < self.height);
assert!(z < self.depth);
&mut self.pixels[z * self.plane_stride + y * self.row_stride..][..self.width]
}
pub fn get_plane_xy(&self, z: usize) -> Image2DRef<'_, T> {
assert!(z < self.depth);
Image2DRef {
width: self.width,
height: self.height,
stride: self.row_stride,
pixels: &self.pixels[z * self.plane_stride..],
}
}
pub fn get_plane_xy_mut(&mut self, z: usize) -> Image2DMut<'_, T> {
assert!(z < self.depth);
Image2DMut {
width: self.width,
height: self.height,
stride: self.row_stride,
pixels: &mut self.pixels[z * self.plane_stride..],
}
}
pub fn get_plane_xz(&self, y: usize) -> Image2DRef<'_, T> {
assert!(y < self.height);
Image2DRef {
width: self.width,
height: self.depth,
stride: self.plane_stride,
pixels: &self.pixels[y * self.row_stride..],
}
}
pub fn get_plane_xz_mut(&mut self, y: usize) -> Image2DMut<'_, T> {
assert!(y < self.height);
Image2DMut {
width: self.width,
height: self.depth,
stride: self.plane_stride,
pixels: &mut self.pixels[y * self.row_stride..],
}
}
pub fn get_range_xy(
&self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
) -> Image2DRef<'_, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
assert!(z < self.depth);
Image2DRef {
width: w,
height: h,
stride: self.row_stride,
pixels: &self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn get_range_xy_mut(
&mut self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
) -> Image2DMut<'_, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
assert!(z < self.depth);
Image2DMut {
width: w,
height: h,
stride: self.row_stride,
pixels: &mut self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn get_range_xz(
&self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
) -> Image2DRef<'_, T> {
assert!(x + w <= self.width);
assert!(y < self.height);
assert!(z + h <= self.depth);
Image2DRef {
width: w,
height: h,
stride: self.plane_stride,
pixels: &self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn get_range_xz_mut(
&mut self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
) -> Image2DMut<'_, T> {
assert!(x + w <= self.width);
assert!(y < self.height);
assert!(z + h <= self.depth);
Image2DMut {
width: w,
height: h,
stride: self.plane_stride,
pixels: &mut self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn get_range(
&self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
d: usize,
) -> Image3DRef<'_, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
assert!(z + d <= self.depth);
Image3DRef {
width: w,
height: h,
depth: d,
row_stride: self.row_stride,
plane_stride: self.plane_stride,
pixels: &self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn get_range_mut(
&mut self,
x: usize,
y: usize,
z: usize,
w: usize,
h: usize,
d: usize,
) -> Image3DMut<'_, T> {
assert!(x + w <= self.width);
assert!(y + h <= self.height);
assert!(z + d <= self.depth);
Image3DMut {
width: w,
height: h,
depth: d,
row_stride: self.row_stride,
plane_stride: self.plane_stride,
pixels: &mut self.pixels[z * self.plane_stride + y * self.row_stride + x..],
}
}
pub fn pixels(&self) -> &[T] {
self.pixels
}
pub fn pixels_mut(&mut self) -> &mut [T] {
self.pixels
}
pub fn iter_planes(&self) -> impl DoubleEndedIterator<Item = Image2DRef<'_, T>> + use<'_, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
ref pixels,
} = *self;
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks(plane_stride)
.map(move |plane| Image2DRef {
width,
height,
stride: row_stride,
pixels: plane,
})
}
pub fn iter_planes_mut(
&mut self,
) -> impl DoubleEndedIterator<Item = Image2DMut<'_, T>> + use<'_, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
ref mut pixels,
} = *self;
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks_mut(plane_stride)
.map(move |plane| Image2DMut {
width,
height,
stride: row_stride,
pixels: plane,
})
}
pub fn into_iter_planes(
self,
) -> impl DoubleEndedIterator<Item = Image2DMut<'a, T>> + use<'a, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
pixels,
} = self;
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks_mut(plane_stride)
.map(move |plane| Image2DMut {
width,
height,
stride: row_stride,
pixels: plane,
})
}
pub fn iter_rows(&self) -> impl DoubleEndedIterator<Item = &[T]> + use<'_, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
ref pixels,
} = *self;
let plane_len = len2([width, height], row_stride);
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks(plane_stride)
.flat_map(move |plane| plane[..plane_len].chunks(row_stride))
.map(move |row| &row[..width])
}
pub fn iter_rows_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut [T]> + use<'_, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
ref mut pixels,
} = *self;
let plane_len = len2([width, height], row_stride);
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks_mut(plane_stride)
.flat_map(move |plane| plane[..plane_len].chunks_mut(row_stride))
.map(move |row| &mut row[..width])
}
pub fn into_iter_rows(self) -> impl DoubleEndedIterator<Item = &'a mut [T]> + use<'a, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
pixels,
} = self;
let plane_len = len2([width, height], row_stride);
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks_mut(plane_stride)
.flat_map(move |plane| plane[..plane_len].chunks_mut(row_stride))
.map(move |row| &mut row[..width])
}
pub fn iter_pixels(&self) -> impl DoubleEndedIterator<Item = &T> + use<'_, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
ref pixels,
} = *self;
let plane_len = len2([width, height], row_stride);
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks(plane_stride)
.flat_map(move |plane| plane[..plane_len].chunks(row_stride))
.flat_map(move |row| &row[..width])
}
pub fn iter_pixels_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut T> + use<'_, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
ref mut pixels,
} = *self;
let plane_len = len2([width, height], row_stride);
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks_mut(plane_stride)
.flat_map(move |plane| plane[..plane_len].chunks_mut(row_stride))
.flat_map(move |row| &mut row[..width])
}
pub fn into_iter_pixels(self) -> impl DoubleEndedIterator<Item = &'a mut T> + use<'a, T> {
let Self {
width,
height,
depth,
row_stride,
plane_stride,
pixels,
} = self;
let plane_len = len2([width, height], row_stride);
let volume_len = len3([width, height, depth], [row_stride, plane_stride]);
pixels[..volume_len]
.chunks_mut(plane_stride)
.flat_map(move |plane| plane[..plane_len].chunks_mut(row_stride))
.flat_map(move |row| &mut row[..width])
}
}
pub struct ImageRef<'a, T> {
dimensions: Dimensions,
extent: [usize; 3],
stride: [usize; 2],
pixels: &'a [T],
}
impl<'a, T> Copy for ImageRef<'a, T> {}
impl<'a, T> Clone for ImageRef<'a, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T> ImageRef<'a, T> {
pub fn new(dimensions: Dimensions, extent: [usize; 3], pixels: &'a [T]) -> Self {
let len = match dimensions {
Dimensions::D1 => {
assert_eq!(extent[1], 1);
assert_eq!(extent[2], 1);
extent[0]
}
Dimensions::D2 => {
assert_eq!(extent[2], 1);
extent[0] * extent[1]
}
Dimensions::D3 => extent[0] * extent[1] * extent[2],
Dimensions::D1Array => {
assert_eq!(extent[2], 1);
extent[0] * extent[1]
}
Dimensions::D2Array => extent[0] * extent[1] * extent[2],
};
assert_eq!(pixels.len(), len);
ImageRef {
dimensions,
extent,
stride: [extent[0], extent[0] * extent[1]],
pixels,
}
}
pub fn with_stride(
dimensions: Dimensions,
extent: [usize; 3],
stride: [usize; 2],
pixels: &'a [T],
) -> Self {
let len = match dimensions {
Dimensions::D1 => {
assert_eq!(extent[1], 1);
assert_eq!(extent[2], 1);
extent[0]
}
Dimensions::D2 | Dimensions::D1Array => {
assert_eq!(extent[2], 1);
len2([extent[0], extent[1]], stride[0])
}
Dimensions::D3 | Dimensions::D2Array => len3(extent, stride),
};
assert_eq!(pixels.len(), len);
ImageRef {
dimensions,
extent,
stride,
pixels,
}
}
pub fn new_1d(width: usize, pixels: &'a [T]) -> Self {
ImageRef::new(Dimensions::D1, [width, 1, 1], pixels)
}
pub fn new_2d(width: usize, height: usize, pixels: &'a [T]) -> Self {
ImageRef::new(Dimensions::D2, [width, height, 1], pixels)
}
pub fn new_3d(width: usize, height: usize, depth: usize, pixels: &'a [T]) -> Self {
ImageRef::new(Dimensions::D3, [width, height, depth], pixels)
}
pub fn new_1d_array(width: usize, layers: usize, pixels: &'a [T]) -> Self {
ImageRef::new(Dimensions::D1Array, [width, layers, 1], pixels)
}
pub fn new_2d_array(width: usize, height: usize, layers: usize, pixels: &'a [T]) -> Self {
ImageRef::new(Dimensions::D2Array, [width, height, layers], pixels)
}
pub fn with_stride_2d(width: usize, height: usize, stride: usize, pixels: &'a [T]) -> Self {
ImageRef::with_stride(Dimensions::D2, [width, height, 1], [stride, 0], pixels)
}
pub fn with_stride_3d(
width: usize,
height: usize,
depth: usize,
row_stride: usize,
plane_stride: usize,
pixels: &'a [T],
) -> Self {
ImageRef::with_stride(
Dimensions::D3,
[width, height, depth],
[row_stride, plane_stride],
pixels,
)
}
pub fn with_stride_1d_array(
width: usize,
layers: usize,
stride: usize,
pixels: &'a [T],
) -> Self {
ImageRef::with_stride(Dimensions::D1Array, [width, layers, 1], [stride, 0], pixels)
}
pub fn with_stride_2d_array(
width: usize,
height: usize,
layers: usize,
row_stride: usize,
layer_stride: usize,
pixels: &'a [T],
) -> Self {
ImageRef::with_stride(
Dimensions::D2Array,
[width, height, layers],
[row_stride, layer_stride],
pixels,
)
}
pub fn dimensions(&self) -> Dimensions {
self.dimensions
}
pub fn extent(&self) -> Extent {
match self.dimensions {
Dimensions::D1 => Extent::D1 {
width: self.extent[0],
},
Dimensions::D2 => Extent::D2 {
width: self.extent[0],
height: self.extent[1],
},
Dimensions::D3 => Extent::D3 {
width: self.extent[0],
height: self.extent[1],
depth: self.extent[2],
},
Dimensions::D1Array => Extent::D1Array {
width: self.extent[0],
layers: self.extent[1],
},
Dimensions::D2Array => Extent::D2Array {
width: self.extent[0],
height: self.extent[1],
layers: self.extent[2],
},
}
}
pub fn raw_extent(&self) -> [usize; 3] {
self.extent
}
pub fn width(&self) -> usize {
self.extent[0]
}
pub fn height(&self) -> usize {
match self.dimensions {
Dimensions::D1 | Dimensions::D1Array => 1,
_ => self.extent[1],
}
}
pub fn depth(&self) -> usize {
match self.dimensions {
Dimensions::D1 | Dimensions::D1Array | Dimensions::D2 | Dimensions::D2Array => 1,
Dimensions::D3 => self.extent[2],
}
}
pub fn layers(&self) -> usize {
match self.dimensions {
Dimensions::D1 | Dimensions::D2 | Dimensions::D3 => 1,
Dimensions::D1Array => self.extent[1],
Dimensions::D2Array => self.extent[2],
}
}
pub fn layer_ref(&self, layer: usize) -> ImageRef<'a, T> {
match self.dimensions {
Dimensions::D1 => {
assert_eq!(layer, 0);
ImageRef::new_1d(self.extent[0], self.pixels)
}
Dimensions::D2 => {
assert_eq!(layer, 0);
ImageRef::new_2d(self.extent[0], self.extent[1], self.pixels)
}
Dimensions::D3 => {
assert_eq!(layer, 0);
ImageRef::new_3d(self.extent[0], self.extent[1], self.extent[2], self.pixels)
}
Dimensions::D1Array => {
assert!(layer < self.extent[1]);
ImageRef::new_1d(
self.extent[0],
&self.pixels[layer * self.extent[0]..][..self.extent[0]],
)
}
Dimensions::D2Array => {
assert!(layer < self.extent[2]);
ImageRef::new_2d(
self.extent[0],
self.extent[1],
&self.pixels[layer * self.extent[0] * self.extent[1]..]
[..self.extent[0] * self.extent[1]],
)
}
}
}
pub fn as_ref_3d(&self) -> Image3DRef<'a, T> {
Image3DRef {
width: self.extent[0],
height: self.extent[1],
depth: self.extent[2],
row_stride: self.stride[0],
plane_stride: self.stride[1],
pixels: self.pixels,
}
}
pub fn plane_ref(&self, layer: usize) -> Image2DRef<'a, T> {
match self.dimensions {
Dimensions::D1 | Dimensions::D1Array => {
assert!(layer < self.extent[1]);
Image2DRef {
width: self.extent[0],
height: 1,
stride: self.stride[0],
pixels: &self.pixels[layer * self.stride[0]..],
}
}
Dimensions::D2 | Dimensions::D2Array => {
assert!(layer < self.extent[2]);
Image2DRef {
width: self.extent[0],
height: self.extent[1],
stride: self.stride[0],
pixels: &self.pixels[layer * self.stride[1]..],
}
}
Dimensions::D3 => {
assert!(layer < self.extent[2]);
Image2DRef {
width: self.extent[0],
height: self.extent[1],
stride: self.stride[0],
pixels: &self.pixels[layer * self.stride[1]..],
}
}
}
}
pub fn iter_planes(&self) -> impl DoubleEndedIterator<Item = Image2DRef<'a, T>> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks(sizes.plane_stride))
.map(move |plane| Image2DRef {
width: sizes.width,
height: sizes.height,
stride: sizes.row_stride,
pixels: plane,
})
}
pub fn iter_rows(&self) -> impl DoubleEndedIterator<Item = &'a [T]> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks(sizes.plane_stride))
.flat_map(move |plane| plane[..sizes.plane_len].chunks(sizes.row_stride))
.map(move |row| &row[..sizes.width])
}
pub fn iter_pixels(&self) -> impl DoubleEndedIterator<Item = &'a T> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks(sizes.plane_stride))
.flat_map(move |plane| plane[..sizes.plane_len].chunks(sizes.row_stride))
.flat_map(move |row| &row[..sizes.width])
}
}
pub struct ImageMut<'a, T> {
dimensions: Dimensions,
extent: [usize; 3],
stride: [usize; 2],
pixels: &'a mut [T],
}
impl<'a, T> ImageMut<'a, T> {
pub fn new(dimensions: Dimensions, extent: [usize; 3], pixels: &'a mut [T]) -> Self {
let len = match dimensions {
Dimensions::D1 => {
assert_eq!(extent[1], 1);
assert_eq!(extent[2], 1);
extent[0]
}
Dimensions::D2 => {
assert_eq!(extent[2], 1);
extent[0] * extent[1]
}
Dimensions::D3 => extent[0] * extent[1] * extent[2],
Dimensions::D1Array => {
assert_eq!(extent[2], 1);
extent[0] * extent[1]
}
Dimensions::D2Array => extent[0] * extent[1] * extent[2],
};
assert_eq!(pixels.len(), len);
ImageMut {
dimensions,
extent,
stride: [extent[0], extent[0] * extent[1]],
pixels,
}
}
pub fn with_stride(
dimensions: Dimensions,
extent: [usize; 3],
stride: [usize; 2],
pixels: &'a mut [T],
) -> Self {
let len = match dimensions {
Dimensions::D1 => {
assert_eq!(extent[1], 1);
assert_eq!(extent[2], 1);
extent[0]
}
Dimensions::D2 | Dimensions::D1Array => {
assert_eq!(extent[2], 1);
if extent[1] != 0 && extent[0] != 0 {
(extent[1] - 1) * stride[0] + extent[0]
} else {
0
}
}
Dimensions::D3 | Dimensions::D2Array => {
if extent[2] != 0 && extent[1] != 0 && extent[0] != 0 {
(extent[2] - 1) * stride[1] + (extent[1] - 1) * stride[0] + extent[0]
} else {
0
}
}
};
assert_eq!(pixels.len(), len);
ImageMut {
dimensions,
extent,
stride,
pixels,
}
}
pub fn new_1d(width: usize, pixels: &'a mut [T]) -> Self {
ImageMut::new(Dimensions::D1, [width, 1, 1], pixels)
}
pub fn new_2d(width: usize, height: usize, pixels: &'a mut [T]) -> Self {
ImageMut::new(Dimensions::D2, [width, height, 1], pixels)
}
pub fn new_3d(width: usize, height: usize, depth: usize, pixels: &'a mut [T]) -> Self {
ImageMut::new(Dimensions::D3, [width, height, depth], pixels)
}
pub fn new_1d_array(width: usize, layers: usize, pixels: &'a mut [T]) -> Self {
ImageMut::new(Dimensions::D1Array, [width, layers, 1], pixels)
}
pub fn new_2d_array(width: usize, height: usize, layers: usize, pixels: &'a mut [T]) -> Self {
ImageMut::new(Dimensions::D2Array, [width, height, layers], pixels)
}
pub fn with_stride_2d(width: usize, height: usize, stride: usize, pixels: &'a mut [T]) -> Self {
ImageMut::with_stride(Dimensions::D2, [width, height, 1], [stride, 0], pixels)
}
pub fn with_stride_3d(
width: usize,
height: usize,
depth: usize,
row_stride: usize,
plane_stride: usize,
pixels: &'a mut [T],
) -> Self {
ImageMut::with_stride(
Dimensions::D3,
[width, height, depth],
[row_stride, plane_stride],
pixels,
)
}
pub fn with_stride_1d_array(
width: usize,
layers: usize,
stride: usize,
pixels: &'a mut [T],
) -> Self {
ImageMut::with_stride(Dimensions::D1Array, [width, layers, 1], [stride, 0], pixels)
}
pub fn with_stride_2d_array(
width: usize,
height: usize,
layers: usize,
row_stride: usize,
layer_stride: usize,
pixels: &'a mut [T],
) -> Self {
ImageMut::with_stride(
Dimensions::D2Array,
[width, height, layers],
[row_stride, layer_stride],
pixels,
)
}
pub fn dimensions(&self) -> Dimensions {
self.dimensions
}
pub fn extent(&self) -> [usize; 3] {
self.extent
}
pub fn as_ref(&self) -> ImageRef<'_, T> {
ImageRef {
dimensions: self.dimensions,
extent: self.extent,
stride: self.stride,
pixels: &*self.pixels,
}
}
pub fn as_mut(&mut self) -> ImageMut<'_, T> {
ImageMut {
dimensions: self.dimensions,
extent: self.extent,
stride: self.stride,
pixels: &mut *self.pixels,
}
}
pub fn layers(&self) -> usize {
match self.dimensions {
Dimensions::D1 | Dimensions::D2 | Dimensions::D3 => 1,
Dimensions::D1Array => self.extent[1],
Dimensions::D2Array => self.extent[2],
}
}
pub fn layer_ref(&self, layer: usize) -> ImageRef<'_, T> {
match self.dimensions {
Dimensions::D1 => {
assert_eq!(layer, 0);
ImageRef::new_1d(self.extent[0], self.pixels)
}
Dimensions::D2 => {
assert_eq!(layer, 0);
ImageRef::new_2d(self.extent[0], self.extent[1], self.pixels)
}
Dimensions::D3 => {
assert_eq!(layer, 0);
ImageRef::new_3d(self.extent[0], self.extent[1], self.extent[2], self.pixels)
}
Dimensions::D1Array => {
assert!(layer < self.extent[1]);
ImageRef::new_1d(
self.extent[0],
&self.pixels[layer * self.extent[0]..][..self.extent[0]],
)
}
Dimensions::D2Array => {
assert!(layer < self.extent[2]);
ImageRef::new_2d(
self.extent[0],
self.extent[1],
&self.pixels[layer * self.extent[0] * self.extent[1]..]
[..self.extent[0] * self.extent[1]],
)
}
}
}
pub fn layer_mut(&mut self, layer: usize) -> ImageMut<'_, T> {
match self.dimensions {
Dimensions::D1 => {
assert_eq!(layer, 0);
ImageMut::new_1d(self.extent[0], &mut *self.pixels)
}
Dimensions::D2 => {
assert_eq!(layer, 0);
ImageMut::new_2d(self.extent[0], self.extent[1], &mut *self.pixels)
}
Dimensions::D3 => {
assert_eq!(layer, 0);
ImageMut::new_3d(
self.extent[0],
self.extent[1],
self.extent[2],
&mut *self.pixels,
)
}
Dimensions::D1Array => {
assert!(layer < self.extent[1]);
ImageMut::new_1d(
self.extent[0],
&mut self.pixels[layer * self.extent[0]..][..self.extent[0]],
)
}
Dimensions::D2Array => {
assert!(layer < self.extent[2]);
ImageMut::new_2d(
self.extent[0],
self.extent[1],
&mut self.pixels[layer * self.extent[0] * self.extent[1]..]
[..self.extent[0] * self.extent[1]],
)
}
}
}
pub fn as_ref_3d(&self) -> Image3DRef<'_, T> {
Image3DRef {
width: self.extent[0],
height: self.extent[1],
depth: self.extent[2],
row_stride: self.stride[0],
plane_stride: self.stride[1],
pixels: &*self.pixels,
}
}
pub fn as_mut_3d(&mut self) -> Image3DMut<'_, T> {
Image3DMut {
width: self.extent[0],
height: self.extent[1],
depth: self.extent[2],
row_stride: self.stride[0],
plane_stride: self.stride[1],
pixels: &mut *self.pixels,
}
}
pub fn plane_ref(&self, layer: usize) -> Image2DRef<'_, T> {
match self.dimensions {
Dimensions::D1 | Dimensions::D1Array => {
assert!(layer < self.extent[1]);
Image2DRef {
width: self.extent[0],
height: 1,
stride: self.stride[0],
pixels: &self.pixels[layer * self.stride[0]..],
}
}
Dimensions::D2 | Dimensions::D2Array => {
assert!(layer < self.extent[2]);
Image2DRef {
width: self.extent[0],
height: self.extent[1],
stride: self.stride[0],
pixels: &self.pixels[layer * self.stride[1]..],
}
}
Dimensions::D3 => {
assert!(layer < self.extent[2]);
Image2DRef {
width: self.extent[0],
height: self.extent[1],
stride: self.stride[0],
pixels: &self.pixels[layer * self.stride[1]..],
}
}
}
}
pub fn plane_mut(&mut self, layer: usize) -> Image2DMut<'_, T> {
match self.dimensions {
Dimensions::D1 | Dimensions::D1Array => {
assert!(layer < self.extent[1]);
Image2DMut {
width: self.extent[0],
height: 1,
stride: self.stride[0],
pixels: &mut self.pixels[layer * self.stride[0]..],
}
}
Dimensions::D2 | Dimensions::D2Array => {
assert!(layer < self.extent[2]);
Image2DMut {
width: self.extent[0],
height: self.extent[1],
stride: self.stride[0],
pixels: &mut self.pixels[layer * self.stride[1]..],
}
}
Dimensions::D3 => {
assert!(layer < self.extent[2]);
Image2DMut {
width: self.extent[0],
height: self.extent[1],
stride: self.stride[0],
pixels: &mut self.pixels[layer * self.stride[1]..],
}
}
}
}
pub fn iter_planes(&self) -> impl DoubleEndedIterator<Item = Image2DRef<'_, T>> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks(sizes.plane_stride))
.map(move |plane| Image2DRef {
width: sizes.width,
height: sizes.height,
stride: sizes.row_stride,
pixels: plane,
})
}
pub fn iter_planes_mut(&mut self) -> impl DoubleEndedIterator<Item = Image2DMut<'_, T>> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks_mut(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks_mut(sizes.plane_stride))
.map(move |plane| Image2DMut {
width: sizes.width,
height: sizes.height,
stride: sizes.row_stride,
pixels: plane,
})
}
pub fn into_iter_planes(self) -> impl DoubleEndedIterator<Item = Image2DMut<'a, T>> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks_mut(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks_mut(sizes.plane_stride))
.map(move |plane| Image2DMut {
width: sizes.width,
height: sizes.height,
stride: sizes.row_stride,
pixels: plane,
})
}
pub fn iter_rows(&self) -> impl DoubleEndedIterator<Item = &'_ [T]> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks(sizes.plane_stride))
.flat_map(move |plane| plane[..sizes.plane_len].chunks(sizes.row_stride))
.map(move |row| &row[..sizes.width])
}
pub fn iter_rows_mut(&mut self) -> impl DoubleEndedIterator<Item = &'_ mut [T]> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks_mut(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks_mut(sizes.plane_stride))
.flat_map(move |plane| plane[..sizes.plane_len].chunks_mut(sizes.row_stride))
.map(move |row| &mut row[..sizes.width])
}
pub fn into_iter_rows(self) -> impl DoubleEndedIterator<Item = &'a mut [T]> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks_mut(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks_mut(sizes.plane_stride))
.flat_map(move |plane| plane[..sizes.plane_len].chunks_mut(sizes.row_stride))
.map(move |row| &mut row[..sizes.width])
}
pub fn iter_pixels(&self) -> impl DoubleEndedIterator<Item = &'_ T> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks(sizes.plane_stride))
.flat_map(move |plane| plane[..sizes.plane_len].chunks(sizes.row_stride))
.flat_map(move |row| &row[..sizes.width])
}
pub fn iter_pixels_mut(&mut self) -> impl DoubleEndedIterator<Item = &'_ mut T> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks_mut(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks_mut(sizes.plane_stride))
.flat_map(move |plane| plane[..sizes.plane_len].chunks_mut(sizes.row_stride))
.flat_map(move |row| &mut row[..sizes.width])
}
pub fn into_iter_pixels(self) -> impl DoubleEndedIterator<Item = &'a mut T> {
let sizes = sizes(self.dimensions, self.extent, self.stride);
self.pixels[..sizes.total_len]
.chunks_mut(sizes.layer_stride)
.flat_map(move |layer| layer[..sizes.layer_len].chunks_mut(sizes.plane_stride))
.flat_map(move |plane| plane[..sizes.plane_len].chunks_mut(sizes.row_stride))
.flat_map(move |row| &mut row[..sizes.width])
}
}
fn len2(extent: [usize; 2], stride: usize) -> usize {
if extent[0] == 0 || extent[1] == 0 {
0
} else {
(extent[1] - 1) * stride + extent[0]
}
}
fn len3(extent: [usize; 3], stride: [usize; 2]) -> usize {
if extent[0] == 0 || extent[1] == 0 || extent[2] == 0 {
0
} else {
(extent[2] - 1) * stride[1] + (extent[1] - 1) * stride[0] + extent[0]
}
}
struct Sizes {
total_len: usize,
layer_stride: usize,
layer_len: usize,
plane_stride: usize,
plane_len: usize,
row_stride: usize,
height: usize,
width: usize,
}
fn sizes(dimensions: Dimensions, extent: [usize; 3], stride: [usize; 2]) -> Sizes {
let total_len = match dimensions {
Dimensions::D1 => extent[0],
Dimensions::D2 | Dimensions::D1Array => len2([extent[0], extent[1]], stride[0]),
Dimensions::D3 | Dimensions::D2Array => len3(extent, stride),
};
let layer_stride = match dimensions {
Dimensions::D1 | Dimensions::D2 | Dimensions::D3 => total_len,
Dimensions::D1Array => stride[0],
Dimensions::D2Array => stride[1],
};
let layer_len = match dimensions {
Dimensions::D1 | Dimensions::D2 | Dimensions::D3 => total_len,
Dimensions::D1Array => extent[0],
Dimensions::D2Array => len2([extent[0], extent[1]], stride[0]),
};
let plane_stride = match dimensions {
Dimensions::D1 | Dimensions::D1Array | Dimensions::D2 | Dimensions::D2Array => total_len,
Dimensions::D3 => stride[1],
};
let plane_len = match dimensions {
Dimensions::D1 | Dimensions::D1Array | Dimensions::D2 | Dimensions::D2Array => layer_len,
Dimensions::D3 => len2([extent[0], extent[1]], stride[0]),
};
let row_stride = match dimensions {
Dimensions::D1 | Dimensions::D1Array => plane_len,
Dimensions::D2 | Dimensions::D2Array | Dimensions::D3 => stride[0],
};
let height = match dimensions {
Dimensions::D1 | Dimensions::D1Array => 1,
Dimensions::D2 | Dimensions::D2Array | Dimensions::D3 => extent[1],
};
let width = extent[0];
Sizes {
total_len,
layer_stride,
layer_len,
plane_stride,
plane_len,
row_stride,
height,
width,
}
}