show_image/
image_types.rs

1use std::sync::Arc;
2
3use crate::error::ImageDataError;
4use crate::ImageInfo;
5
6/// Trait for borrowing image data from a struct.
7pub trait AsImageView {
8	/// Get an image view for the object.
9	fn as_image_view(&self) -> Result<ImageView, ImageDataError>;
10}
11
12/// Get the image info of an object that implements [`AsImageView`].
13pub fn image_info(image: &impl AsImageView) -> Result<ImageInfo, ImageDataError> {
14	Ok(image.as_image_view()?.info())
15}
16
17/// Borrowed view of image data,
18#[derive(Debug, Copy, Clone)]
19pub struct ImageView<'a> {
20	info: ImageInfo,
21	data: &'a [u8],
22}
23
24impl<'a> ImageView<'a> {
25	/// Create a new image view from image information and a data slice.
26	pub fn new(info: ImageInfo, data: &'a [u8]) -> Self {
27		Self { info, data }
28	}
29
30	/// Get the image information.
31	pub fn info(&self) -> ImageInfo {
32		self.info
33	}
34
35	/// Get the image data as byte slice.
36	pub fn data(&self) -> &[u8] {
37		self.data
38	}
39}
40
41impl<'a> AsImageView for ImageView<'a> {
42	fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
43		Ok(*self)
44	}
45}
46
47/// Owning image that can be sent to another thread.
48///
49/// The image is backed by either a [`Box`] or [`Arc`].
50/// It can either directly own the data or through a [`dyn AsImageView`].
51pub enum Image {
52	/// An image backed by a `Box<[u8]>`.
53	Box(BoxImage),
54
55	/// An image backed by an `Arc<[u8]>`.
56	Arc(ArcImage),
57
58	/// An image backed by a `Box<dyn AsImageView>`.
59	BoxDyn(Box<dyn AsImageView + Send>),
60
61	/// An image backed by an `Arc<dyn AsImageView>`.
62	ArcDyn(Arc<dyn AsImageView + Sync + Send>),
63
64	/// An invalid image that will always fail the conversion to [`ImageView`].
65	Invalid(ImageDataError),
66}
67
68impl Clone for Image {
69	fn clone(&self) -> Self {
70		match self {
71			Self::Box(x) => Self::Box(x.clone()),
72			Self::Arc(x) => Self::Arc(x.clone()),
73			// We can not clone Box<dyn AsImageView> directly, but we can clone the data or the error.
74			Self::BoxDyn(x) => match x.as_image_view() {
75				Ok(view) => Self::Box(BoxImage::new(view.info, view.data.into())),
76				Err(error) => Self::Invalid(error),
77			},
78			Self::ArcDyn(x) => Self::ArcDyn(x.clone()),
79			Self::Invalid(x) => Self::Invalid(x.clone()),
80		}
81	}
82}
83
84impl<T: AsImageView> AsImageView for Box<T> {
85	fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
86		self.as_ref().as_image_view()
87	}
88}
89
90impl<T: AsImageView> AsImageView for Arc<T> {
91	fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
92		self.as_ref().as_image_view()
93	}
94}
95
96/// Image backed by a `Box<[u8]>`.
97#[derive(Debug, Clone)]
98pub struct BoxImage {
99	info: ImageInfo,
100	data: Box<[u8]>,
101}
102
103/// Image backed by an `Arc<[u8]>`.
104#[derive(Debug, Clone)]
105pub struct ArcImage {
106	info: ImageInfo,
107	data: Arc<[u8]>,
108}
109
110impl Image {
111	/// Get a non-owning view of the image data.
112	pub fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
113		match self {
114			Self::Box(x) => Ok(x.as_view()),
115			Self::Arc(x) => Ok(x.as_view()),
116			Self::BoxDyn(x) => x.as_image_view(),
117			Self::ArcDyn(x) => x.as_image_view(),
118			Self::Invalid(e) => Err(e.clone()),
119		}
120	}
121}
122
123impl AsImageView for Image {
124	fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
125		self.as_image_view()
126	}
127}
128
129impl BoxImage {
130	/// Create a new image from image information and a boxed slice.
131	pub fn new(info: ImageInfo, data: Box<[u8]>) -> Self {
132		Self { info, data }
133	}
134
135	/// Get a non-owning view of the image data.
136	pub fn as_view(&self) -> ImageView {
137		ImageView::new(self.info, &self.data)
138	}
139
140	/// Get the image information.
141	pub fn info(&self) -> ImageInfo {
142		self.info
143	}
144
145	/// Get the image data as byte slice.
146	pub fn data(&self) -> &[u8] {
147		&self.data
148	}
149}
150
151impl AsImageView for BoxImage {
152	fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
153		Ok(self.as_view())
154	}
155}
156
157impl ArcImage {
158	/// Create a new image from image information and a Arc-wrapped slice.
159	pub fn new(info: ImageInfo, data: Arc<[u8]>) -> Self {
160		Self { info, data }
161	}
162
163	/// Get a non-owning view of the image data.
164	pub fn as_view(&self) -> ImageView {
165		ImageView::new(self.info, &self.data)
166	}
167
168	/// Get the image information.
169	pub fn info(&self) -> ImageInfo {
170		self.info
171	}
172
173	/// Get the image data as byte slice.
174	pub fn data(&self) -> &[u8] {
175		&self.data
176	}
177}
178
179impl AsImageView for ArcImage {
180	fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
181		Ok(self.as_view())
182	}
183}
184
185impl From<ImageView<'_>> for BoxImage {
186	fn from(other: ImageView) -> Self {
187		Self {
188			info: other.info,
189			data: other.data.into(),
190		}
191	}
192}
193
194impl From<&'_ ImageView<'_>> for BoxImage {
195	fn from(other: &ImageView) -> Self {
196		Self {
197			info: other.info,
198			data: other.data.into(),
199		}
200	}
201}
202
203impl From<ImageView<'_>> for ArcImage {
204	fn from(other: ImageView) -> Self {
205		Self {
206			info: other.info,
207			data: other.data.into(),
208		}
209	}
210}
211
212impl From<&'_ ImageView<'_>> for ArcImage {
213	fn from(other: &ImageView) -> Self {
214		Self {
215			info: other.info,
216			data: other.data.into(),
217		}
218	}
219}
220
221impl From<ImageView<'_>> for Image {
222	fn from(other: ImageView) -> Self {
223		Self::Box(BoxImage::from(other))
224	}
225}
226
227impl From<&'_ ImageView<'_>> for Image {
228	fn from(other: &ImageView) -> Self {
229		Self::Box(BoxImage::from(other))
230	}
231}
232
233impl From<BoxImage> for ArcImage {
234	fn from(other: BoxImage) -> Self {
235		Self {
236			info: other.info,
237			data: other.data.into(),
238		}
239	}
240}
241
242impl From<BoxImage> for Image {
243	fn from(other: BoxImage) -> Self {
244		Self::Box(other)
245	}
246}
247
248impl From<ArcImage> for Image {
249	fn from(other: ArcImage) -> Self {
250		Self::Arc(other)
251	}
252}
253
254impl From<Box<dyn AsImageView + Send>> for Image {
255	fn from(other: Box<dyn AsImageView + Send>) -> Self {
256		Self::BoxDyn(other)
257	}
258}
259
260impl From<Arc<dyn AsImageView + Sync + Send>> for Image {
261	fn from(other: Arc<dyn AsImageView + Sync + Send>) -> Self {
262		Self::ArcDyn(other)
263	}
264}
265
266impl<T> From<Box<T>> for Image
267where
268	T: AsImageView + Send + 'static,
269{
270	fn from(other: Box<T>) -> Self {
271		Self::BoxDyn(other)
272	}
273}
274
275impl<T> From<Arc<T>> for Image
276where
277	T: AsImageView + Send + Sync + 'static,
278{
279	fn from(other: Arc<T>) -> Self {
280		Self::ArcDyn(other)
281	}
282}