Skip to main content

j2k_core/
pixel.rs

1// SPDX-License-Identifier: MIT OR 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    #[must_use]
38    pub const fn layout(self) -> PixelLayout {
39        match self {
40            Self::Rgb8 | Self::Rgb16 => PixelLayout::Rgb,
41            Self::Rgba8 | Self::Rgba16 => PixelLayout::Rgba,
42            Self::Gray8 | Self::Gray16 => PixelLayout::Gray,
43        }
44    }
45
46    /// Return the integer sample type for this pixel format.
47    #[must_use]
48    pub const fn sample(self) -> SampleType {
49        match self {
50            Self::Rgb8 | Self::Rgba8 | Self::Gray8 => SampleType::U8,
51            Self::Rgb16 | Self::Rgba16 | Self::Gray16 => SampleType::U16,
52        }
53    }
54
55    /// Return the number of channels per pixel.
56    #[must_use]
57    pub const fn channels(self) -> usize {
58        match self.layout() {
59            PixelLayout::Rgb => 3,
60            PixelLayout::Rgba => 4,
61            PixelLayout::Gray => 1,
62        }
63    }
64
65    /// Return the number of bytes in one channel sample.
66    #[must_use]
67    pub const fn bytes_per_sample(self) -> usize {
68        match self.sample() {
69            SampleType::U8 => 1,
70            SampleType::U16 => 2,
71        }
72    }
73
74    /// Return the number of bytes in one interleaved pixel.
75    #[must_use]
76    pub const fn bytes_per_pixel(self) -> usize {
77        self.channels() * self.bytes_per_sample()
78    }
79}