1use std::marker::PhantomData;
2use std::num::NonZeroU32;
3
4use crate::pixels::PixelExt;
5use crate::{error, ImageView, ImageViewMut};
6
7#[derive(Debug)]
8enum BufferContainer<'a> {
9 MutU8(&'a mut [u8]),
10 VecU8(Vec<u8>),
11}
12
13impl<'a> BufferContainer<'a> {
14 fn as_vec(&self) -> Vec<u8> {
15 match self {
16 Self::MutU8(slice) => slice.to_vec(),
17 Self::VecU8(vec) => vec.clone(),
18 }
19 }
20}
21
22#[derive(Debug)]
24pub struct Image<'a, P: PixelExt> {
25 width: NonZeroU32,
26 height: NonZeroU32,
27 buffer: BufferContainer<'a>,
28 pixel_type: PhantomData<P>,
29}
30
31impl<'a, P: PixelExt> Image<'a, P> {
32 pub fn new(width: NonZeroU32, height: NonZeroU32) -> Self {
34 let pixels_count = (width.get() * height.get()) as usize;
35 let buffer = BufferContainer::VecU8(vec![0; pixels_count * P::size()]);
36 Self {
37 width,
38 height,
39 buffer,
40 pixel_type: PhantomData,
41 }
42 }
43
44 pub unsafe fn from_vec_u8(width: NonZeroU32, height: NonZeroU32, buffer: Vec<u8>) -> Self {
45 let size = (width.get() * height.get()) as usize * P::size();
46 if buffer.len() < size {
47 error!();
48 }
49 Self {
50 width,
51 height,
52 buffer: BufferContainer::VecU8(buffer),
53 pixel_type: PhantomData,
54 }
55 }
56
57 pub unsafe fn from_slice_u8(
58 width: NonZeroU32,
59 height: NonZeroU32,
60 buffer: &'a mut [u8],
61 ) -> Self {
62 let size = (width.get() * height.get()) as usize * P::size();
63 if buffer.len() < size {
64 error!();
65 }
66 Self {
67 width,
68 height,
69 buffer: BufferContainer::MutU8(buffer),
70 pixel_type: PhantomData,
71 }
72 }
73
74 pub fn copy(&self) -> Image<'static, P> {
76 Image {
77 width: self.width,
78 height: self.height,
79 buffer: BufferContainer::VecU8(self.buffer.as_vec()),
80 pixel_type: self.pixel_type,
81 }
82 }
83
84 #[inline(always)]
85 pub fn width(&self) -> NonZeroU32 {
86 self.width
87 }
88
89 #[inline(always)]
90 pub fn height(&self) -> NonZeroU32 {
91 self.height
92 }
93
94 #[inline(always)]
96 pub fn buffer(&self) -> &[u8] {
97 match &self.buffer {
98 BufferContainer::MutU8(p) => p,
99 BufferContainer::VecU8(v) => v,
100 }
101 }
102
103 #[inline(always)]
105 pub fn buffer_mut(&mut self) -> &mut [u8] {
106 match &mut self.buffer {
107 BufferContainer::MutU8(p) => p,
108 BufferContainer::VecU8(ref mut v) => v.as_mut_slice(),
109 }
110 }
111
112 #[inline(always)]
113 pub fn into_vec(self) -> Vec<u8> {
114 match self.buffer {
115 BufferContainer::MutU8(p) => p.into(),
116 BufferContainer::VecU8(v) => v,
117 }
118 }
119
120 #[inline(always)]
121 pub unsafe fn view(&self) -> ImageView<P> {
122 ImageView::new(self.width, self.height, self.buffer())
123 }
124
125 #[inline(always)]
126 pub unsafe fn view_mut(&mut self) -> ImageViewMut<P> {
127 ImageViewMut::new(self.width, self.height, self.buffer_mut())
128 }
129}
130
131pub(crate) struct InnerImage<'a, P>
133where
134 P: PixelExt,
135{
136 width: NonZeroU32,
137 height: NonZeroU32,
138 pixels: &'a mut [P],
139}
140
141impl<'a, P> InnerImage<'a, P>
142where
143 P: PixelExt,
144{
145 pub fn new(width: NonZeroU32, height: NonZeroU32, pixels: &'a mut [P]) -> Self {
146 Self {
147 width,
148 height,
149 pixels,
150 }
151 }
152
153 #[inline(always)]
154 pub unsafe fn src_view(&self) -> ImageView<P> {
155 ImageView::from_pixels(self.width, self.height, self.pixels)
156 }
157
158 #[inline(always)]
159 pub unsafe fn dst_view(&mut self) -> ImageViewMut<P> {
160 ImageViewMut::from_pixels(self.width, self.height, self.pixels)
161 }
162}