Skip to main content

signinum_core/
pixel.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use crate::sample::SampleType;
4
5/// Channel layout independent of sample width.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7#[non_exhaustive]
8pub enum PixelLayout {
9    /// Three-channel red, green, blue layout.
10    Rgb,
11    /// Four-channel red, green, blue, alpha layout.
12    Rgba,
13    /// Single-channel grayscale layout.
14    Gray,
15}
16
17/// Concrete interleaved pixel format.
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19#[non_exhaustive]
20pub enum PixelFormat {
21    /// Interleaved 8-bit RGB.
22    Rgb8,
23    /// Interleaved 8-bit RGBA.
24    Rgba8,
25    /// 8-bit grayscale.
26    Gray8,
27    /// Interleaved 16-bit RGB.
28    Rgb16,
29    /// Interleaved 16-bit RGBA.
30    Rgba16,
31    /// 16-bit grayscale.
32    Gray16,
33}
34
35impl PixelFormat {
36    /// Return the channel layout for this pixel format.
37    pub const fn layout(self) -> PixelLayout {
38        match self {
39            Self::Rgb8 | Self::Rgb16 => PixelLayout::Rgb,
40            Self::Rgba8 | Self::Rgba16 => PixelLayout::Rgba,
41            Self::Gray8 | Self::Gray16 => PixelLayout::Gray,
42        }
43    }
44
45    /// Return the integer sample type for this pixel format.
46    pub const fn sample(self) -> SampleType {
47        match self {
48            Self::Rgb8 | Self::Rgba8 | Self::Gray8 => SampleType::U8,
49            Self::Rgb16 | Self::Rgba16 | Self::Gray16 => SampleType::U16,
50        }
51    }
52
53    /// Return the number of channels per pixel.
54    pub const fn channels(self) -> usize {
55        match self.layout() {
56            PixelLayout::Rgb => 3,
57            PixelLayout::Rgba => 4,
58            PixelLayout::Gray => 1,
59        }
60    }
61
62    /// Return the number of bytes in one channel sample.
63    pub const fn bytes_per_sample(self) -> usize {
64        match self.sample() {
65            SampleType::U8 => 1,
66            SampleType::U16 => 2,
67        }
68    }
69
70    /// Return the number of bytes in one interleaved pixel.
71    pub const fn bytes_per_pixel(self) -> usize {
72        self.channels() * self.bytes_per_sample()
73    }
74}