1#[derive(Debug, Clone, Copy, Eq, PartialEq)]
3pub struct ImageInfo {
4 pub pixel_format: PixelFormat,
6
7 pub size: glam::UVec2,
9
10 pub stride: glam::UVec2,
12}
13
14#[derive(Copy, Clone, Debug, Eq, PartialEq)]
16pub enum PixelFormat {
17 Mono8,
19
20 MonoAlpha8(Alpha),
22
23 Bgr8,
25
26 Bgra8(Alpha),
28
29 Rgb8,
31
32 Rgba8(Alpha),
34}
35
36#[derive(Copy, Clone, Debug, Eq, PartialEq)]
40pub enum Alpha {
41 Unpremultiplied,
43
44 Premultiplied,
46}
47
48impl ImageInfo {
49 pub fn new(pixel_format: PixelFormat, width: u32, height: u32) -> Self {
54 let stride_x = u32::from(pixel_format.bytes_per_pixel());
55 let stride_y = stride_x * width;
56 Self {
57 pixel_format,
58 size: glam::UVec2::new(width, height),
59 stride: glam::UVec2::new(stride_x, stride_y),
60 }
61 }
62
63 pub fn mono8(width: u32, height: u32) -> Self {
65 Self::new(PixelFormat::Mono8, width, height)
66 }
67
68 pub fn mono_alpha8(width: u32, height: u32) -> Self {
70 Self::new(PixelFormat::MonoAlpha8(Alpha::Unpremultiplied), width, height)
71 }
72
73 pub fn mono_alpha8_premultiplied(width: u32, height: u32) -> Self {
75 Self::new(PixelFormat::MonoAlpha8(Alpha::Premultiplied), width, height)
76 }
77
78 pub fn bgr8(width: u32, height: u32) -> Self {
80 Self::new(PixelFormat::Bgr8, width, height)
81 }
82
83 pub fn bgra8(width: u32, height: u32) -> Self {
85 Self::new(PixelFormat::Bgra8(Alpha::Unpremultiplied), width, height)
86 }
87
88 pub fn bgra8_premultiplied(width: u32, height: u32) -> Self {
90 Self::new(PixelFormat::Bgra8(Alpha::Premultiplied), width, height)
91 }
92
93 pub fn rgb8(width: u32, height: u32) -> Self {
95 Self::new(PixelFormat::Rgb8, width, height)
96 }
97
98 pub fn rgba8(width: u32, height: u32) -> Self {
100 Self::new(PixelFormat::Rgba8(Alpha::Unpremultiplied), width, height)
101 }
102
103 pub fn rgba8_premultiplied(width: u32, height: u32) -> Self {
105 Self::new(PixelFormat::Rgba8(Alpha::Premultiplied), width, height)
106 }
107
108 pub fn byte_size(self) -> u64 {
110 if self.stride.y >= self.stride.x {
111 u64::from(self.stride.y) * u64::from(self.size.y)
112 } else {
113 u64::from(self.stride.x) * u64::from(self.size.x)
114 }
115 }
116}
117
118impl PixelFormat {
119 pub fn channels(self) -> u8 {
121 match self {
122 PixelFormat::Mono8 => 1,
123 PixelFormat::MonoAlpha8(_) => 1,
124 PixelFormat::Bgr8 => 3,
125 PixelFormat::Bgra8(_) => 4,
126 PixelFormat::Rgb8 => 3,
127 PixelFormat::Rgba8(_) => 4,
128 }
129 }
130
131 const fn byte_depth(self) -> u8 {
133 1
134 }
135
136 pub fn bytes_per_pixel(self) -> u8 {
138 self.byte_depth() * self.channels()
139 }
140
141 pub fn alpha(self) -> Option<Alpha> {
145 match self {
146 PixelFormat::Mono8 => None,
147 PixelFormat::MonoAlpha8(a) => Some(a),
148 PixelFormat::Bgr8 => None,
149 PixelFormat::Bgra8(a) => Some(a),
150 PixelFormat::Rgb8 => None,
151 PixelFormat::Rgba8(a) => Some(a),
152 }
153 }
154}