machine_vision_formats/
image_ref.rs

1//! References to image data
2
3use crate::{ImageBufferMutRef, ImageBufferRef, ImageData, ImageMutData, PixelFormat, Stride};
4
5// -----
6
7/// A view of image to have pixel format `FMT`.
8pub struct ImageRef<'a, FMT: PixelFormat> {
9    buf: &'a [u8],
10    width: u32,
11    height: u32,
12    stride: usize,
13    fmt: std::marker::PhantomData<FMT>,
14}
15
16impl<'a, FMT: PixelFormat> ImageRef<'a, FMT> {
17    /// Use a `&[u8]` slice as the backing store for an ImageRef.
18    ///
19    /// Returns None if the buffer is not large enough to store an image of the
20    /// desired properties.
21    pub fn new(width: u32, height: u32, stride: usize, buf: &'a [u8]) -> Option<Self> {
22        let fmt = crate::pixel_format::pixfmt::<FMT>().unwrap();
23        let min_stride = fmt.bits_per_pixel() as usize * width as usize / 8;
24
25        if height == 0 {
26            return None;
27        }
28        let sz = stride * (height as usize - 1) + min_stride;
29
30        if buf.len() < sz {
31            return None;
32        }
33        Some(Self {
34            width,
35            height,
36            stride,
37            buf,
38            fmt: std::marker::PhantomData,
39        })
40    }
41}
42
43impl<F: PixelFormat> std::fmt::Debug for ImageRef<'_, F> {
44    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
45        f.debug_struct("ImageRef")
46            .field("fmt", &self.fmt)
47            .field("width", &self.width)
48            .field("height", &self.height)
49            .field("stride", &self.stride)
50            .finish_non_exhaustive()
51    }
52}
53
54impl<FMT: PixelFormat> ImageData<FMT> for ImageRef<'_, FMT> {
55    fn width(&self) -> u32 {
56        self.width
57    }
58    fn height(&self) -> u32 {
59        self.height
60    }
61    fn buffer_ref(&self) -> ImageBufferRef<'_, FMT> {
62        ImageBufferRef::new(self.buf)
63    }
64    #[cfg(any(feature = "std", feature = "alloc"))]
65    fn buffer(self) -> crate::ImageBuffer<FMT> {
66        // copy the data
67        self.buffer_ref().to_buffer()
68    }
69}
70
71impl<FMT: PixelFormat> Stride for ImageRef<'_, FMT> {
72    fn stride(&self) -> usize {
73        self.stride
74    }
75}
76
77// -----
78
79/// A view of mutable image to have pixel format `FMT`.
80pub struct ImageRefMut<'a, FMT: PixelFormat> {
81    buf: &'a mut [u8],
82    width: u32,
83    height: u32,
84    stride: usize,
85    fmt: std::marker::PhantomData<FMT>,
86}
87
88impl<'a, FMT: PixelFormat> ImageRefMut<'a, FMT> {
89    /// Use a `&mut [u8]` slice as the backing store for an ImageRefMut.
90    ///
91    /// Returns None if the buffer is not large enough to store an image of the
92    /// desired properties.
93    pub fn new(width: u32, height: u32, stride: usize, buf: &'a mut [u8]) -> Option<Self> {
94        let fmt = crate::pixel_format::pixfmt::<FMT>().unwrap();
95        let min_stride = fmt.bits_per_pixel() as usize * width as usize / 8;
96
97        if height == 0 {
98            return None;
99        }
100        let sz = stride * (height as usize - 1) + min_stride;
101
102        if buf.len() < sz {
103            return None;
104        }
105        Some(Self {
106            width,
107            height,
108            stride,
109            buf,
110            fmt: std::marker::PhantomData,
111        })
112    }
113}
114
115impl<F: PixelFormat> std::fmt::Debug for ImageRefMut<'_, F> {
116    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
117        f.debug_struct("ImageRefMut")
118            .field("fmt", &self.fmt)
119            .field("width", &self.width)
120            .field("height", &self.height)
121            .field("stride", &self.stride)
122            .finish_non_exhaustive()
123    }
124}
125
126impl<FMT: PixelFormat> ImageData<FMT> for ImageRefMut<'_, FMT> {
127    fn width(&self) -> u32 {
128        self.width
129    }
130    fn height(&self) -> u32 {
131        self.height
132    }
133    fn buffer_ref(&self) -> ImageBufferRef<'_, FMT> {
134        ImageBufferRef::new(self.buf)
135    }
136    #[cfg(any(feature = "std", feature = "alloc"))]
137    fn buffer(self) -> crate::ImageBuffer<FMT> {
138        // copy the data
139        self.buffer_ref().to_buffer()
140    }
141}
142
143impl<FMT: PixelFormat> ImageMutData<FMT> for ImageRefMut<'_, FMT> {
144    fn buffer_mut_ref(&mut self) -> ImageBufferMutRef<'_, FMT> {
145        ImageBufferMutRef::new(self.buf)
146    }
147}
148
149impl<FMT: PixelFormat> Stride for ImageRefMut<'_, FMT> {
150    fn stride(&self) -> usize {
151        self.stride
152    }
153}