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
// SPDX-License-Identifier: Apache-2.0
use crate::sample::SampleType;
/// Channel layout independent of sample width.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum PixelLayout {
/// Three-channel red, green, blue layout.
Rgb,
/// Four-channel red, green, blue, alpha layout.
Rgba,
/// Single-channel grayscale layout.
Gray,
}
/// Concrete interleaved pixel format.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum PixelFormat {
/// Interleaved 8-bit RGB.
Rgb8,
/// Interleaved 8-bit RGBA.
Rgba8,
/// 8-bit grayscale.
Gray8,
/// Interleaved 16-bit RGB.
Rgb16,
/// Interleaved 16-bit RGBA.
Rgba16,
/// 16-bit grayscale.
Gray16,
}
impl PixelFormat {
/// Return the channel layout for this pixel format.
pub const fn layout(self) -> PixelLayout {
match self {
Self::Rgb8 | Self::Rgb16 => PixelLayout::Rgb,
Self::Rgba8 | Self::Rgba16 => PixelLayout::Rgba,
Self::Gray8 | Self::Gray16 => PixelLayout::Gray,
}
}
/// Return the integer sample type for this pixel format.
pub const fn sample(self) -> SampleType {
match self {
Self::Rgb8 | Self::Rgba8 | Self::Gray8 => SampleType::U8,
Self::Rgb16 | Self::Rgba16 | Self::Gray16 => SampleType::U16,
}
}
/// Return the number of channels per pixel.
pub const fn channels(self) -> usize {
match self.layout() {
PixelLayout::Rgb => 3,
PixelLayout::Rgba => 4,
PixelLayout::Gray => 1,
}
}
/// Return the number of bytes in one channel sample.
pub const fn bytes_per_sample(self) -> usize {
match self.sample() {
SampleType::U8 => 1,
SampleType::U16 => 2,
}
}
/// Return the number of bytes in one interleaved pixel.
pub const fn bytes_per_pixel(self) -> usize {
self.channels() * self.bytes_per_sample()
}
}