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