machine_vision_formats/
owned.rs1#[cfg(not(feature = "std"))]
4use alloc::boxed::Box;
5#[cfg(not(feature = "std"))]
6use alloc::vec;
7#[cfg(not(feature = "std"))]
8use alloc::vec::Vec;
9
10use crate::{
11 ImageBuffer, ImageBufferMutRef, ImageBufferRef, ImageData, ImageMutData, OwnedImageStride,
12 PixelFormat, Stride,
13};
14
15#[derive(Clone)]
19pub struct OImage<FMT: PixelFormat> {
20 buf: Vec<u8>,
21 width: u32,
22 height: u32,
23 stride: usize,
24 fmt: std::marker::PhantomData<FMT>,
25}
26
27impl<FMT: PixelFormat> ImageData<FMT> for OImage<FMT> {
28 fn width(&self) -> u32 {
29 self.width
30 }
31 fn height(&self) -> u32 {
32 self.height
33 }
34 fn buffer_ref(&self) -> ImageBufferRef<'_, FMT> {
35 ImageBufferRef::new(&self.buf)
36 }
37 fn buffer(self) -> ImageBuffer<FMT> {
38 ImageBuffer {
40 data: self.buf,
41 pixel_format: self.fmt,
42 }
43 }
44}
45
46impl<FMT: PixelFormat> ImageMutData<FMT> for OImage<FMT> {
47 fn buffer_mut_ref(&mut self) -> ImageBufferMutRef<'_, FMT> {
48 ImageBufferMutRef::new(&mut self.buf)
49 }
50}
51
52impl<FMT: PixelFormat> Stride for OImage<FMT> {
53 fn stride(&self) -> usize {
54 self.stride
55 }
56}
57
58impl<FMT: PixelFormat> OImage<FMT> {
59 pub fn new(width: u32, height: u32, stride: usize, buf: Vec<u8>) -> Option<Self> {
65 let fmt = crate::pixel_format::pixfmt::<FMT>().unwrap();
66 let min_stride = fmt.bits_per_pixel() as usize * width as usize / 8;
67
68 if height > 0 {
69 let sz = stride * (height as usize - 1) + min_stride;
72 if buf.len() < sz {
73 return None;
74 }
75 }
76
77 Some(Self {
78 width,
79 height,
80 stride,
81 buf,
82 fmt: std::marker::PhantomData,
83 })
84 }
85
86 pub fn zeros(width: u32, height: u32, stride: usize) -> Option<Self> {
88 let fmt = crate::pixel_format::pixfmt::<FMT>().unwrap();
89 let valid_stride = fmt.bits_per_pixel() as usize * width as usize / 8;
90
91 let sz = if height == 0 {
92 0
93 } else {
94 stride * (height as usize - 1) + valid_stride
95 };
96 let buf = vec![0u8; sz];
97 Some(Self {
98 width,
99 height,
100 stride,
101 buf,
102 fmt: std::marker::PhantomData,
103 })
104 }
105
106 pub fn from_owned(orig: impl OwnedImageStride<FMT>) -> Self {
107 let width = orig.width();
108 let height = orig.height();
109 let stride = orig.stride();
110 let buf: Vec<u8> = orig.into(); Self::new(width, height, stride, buf).unwrap()
112 }
113}
114
115fn _test_owned_image_implements_send<F: PixelFormat + Send>() {
117 fn implements<T: Send>() {}
118 implements::<OImage<F>>();
119}
120
121fn _test_owned_image_implements_stride<F: PixelFormat>() {
123 fn implements<T: Stride, F>() {}
124 implements::<OImage<F>, F>();
125}
126
127fn _test_owned_image_implements_into_vec_u8<F: PixelFormat>() {
129 fn implements<T: Into<Vec<u8>>>() {}
130 implements::<OImage<F>>();
131}
132
133impl<F: PixelFormat> std::fmt::Debug for OImage<F> {
134 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
135 f.debug_struct("ImageStruct")
136 .field("fmt", &self.fmt)
137 .field("width", &self.width)
138 .field("height", &self.height)
139 .field("stride", &self.stride)
140 .finish_non_exhaustive()
141 }
142}
143
144impl<F: PixelFormat> OImage<F> {
145 pub fn copy_from<FRAME: crate::ImageStride<F>>(frame: &FRAME) -> OImage<F> {
146 let width = frame.width();
147 let height = frame.height();
148 let stride = frame.stride();
149 let buf = frame.image_data().to_vec(); Self {
152 width,
153 height,
154 stride,
155 buf,
156 fmt: std::marker::PhantomData,
157 }
158 }
159}
160
161impl<F: PixelFormat> From<OImage<F>> for Vec<u8> {
162 fn from(orig: OImage<F>) -> Vec<u8> {
163 orig.buf
164 }
165}
166
167impl<F: PixelFormat> From<Box<OImage<F>>> for Vec<u8> {
168 fn from(orig: Box<OImage<F>>) -> Vec<u8> {
169 orig.buf
170 }
171}
172
173#[test]
174fn test_alloc() {
175 for width in [0, 640] {
177 for height in [0, 480] {
178 let min_stride = (width * 3) as usize; for stride in [min_stride, min_stride + 10] {
180 let img =
182 OImage::<crate::pixel_format::RGB8>::zeros(width, height, stride).unwrap();
183 assert_eq!(img.width(), width);
184 assert_eq!(img.height(), height);
185 assert_eq!(img.stride(), stride);
186
187 let sz = height as usize * stride;
189 let buf = vec![0u8; sz]; let img =
191 OImage::<crate::pixel_format::RGB8>::new(width, height, stride, buf).unwrap();
192 assert_eq!(img.width(), width);
193 assert_eq!(img.height(), height);
194 assert_eq!(img.stride(), stride);
195 }
196 }
197 }
198}