Skip to main content

skia_safe/core/
color_type.rs

1use crate::{prelude::*, AlphaType};
2use sb::SkColorType;
3use skia_bindings as sb;
4
5/// Describes how pixel bits encode color. A pixel may be an alpha mask, a grayscale, RGB, or ARGB.
6///
7/// The names of each variant implicitly define the channel ordering and size in memory. Due to
8/// historical reasons the names do not follow 100% identical convention, but are typically labeled
9/// from least significant to most significant.
10///
11/// Unless specified otherwise, a channel's value is treated as an unsigned integer with a range of
12/// [0, 2^N-1] and this is mapped uniformly to a floating point value of [0.0, 1.0]. Some color
13/// types instead store data directly in 32-bit floating point (assumed to be IEEE), or in 16-bit
14/// "half" floating point values.
15///
16/// Note: By default, Skia operates with the assumption of a little-Endian system. The bit patterns
17/// shown in the documentation assume LE byte order.
18#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
19#[repr(i32)]
20pub enum ColorType {
21    /// Unknown or unrepresentable as an SkColorType.
22    Unknown = SkColorType::kUnknown_SkColorType as _,
23    /// Single channel data (8-bit) interpreted as an alpha value. RGB are 0.
24    /// Bits: [A:7..0]
25    Alpha8 = SkColorType::kAlpha_8_SkColorType as _,
26    /// Three channel BGR data (5 bits red, 6 bits green, 5 bits blue) packed into a LE 16-bit word.
27    /// Bits: [R:15..11 G:10..5 B:4..0]
28    RGB565 = SkColorType::kRGB_565_SkColorType as _,
29    /// Four channel ABGR data (4 bits per channel) packed into a LE 16-bit word.
30    /// Bits: [R:15..12 G:11..8 B:7..4 A:3..0]
31    ARGB4444 = SkColorType::kARGB_4444_SkColorType as _,
32    /// Four channel RGBA data (8 bits per channel) packed into a LE 32-bit word.
33    /// Bits: [A:31..24 B:23..16 G:15..8 R:7..0]
34    RGBA8888 = SkColorType::kRGBA_8888_SkColorType as _,
35    /// Three channel RGB data (8 bits per channel) packed into a LE 32-bit word. The remaining bits
36    /// are ignored and alpha is forced to opaque.
37    /// Bits: [x:31..24 B:23..16 G:15..8 R:7..0]
38    RGB888x = SkColorType::kRGB_888x_SkColorType as _,
39    /// Four channel BGRA data (8 bits per channel) packed into a LE 32-bit word. R and B are swapped
40    /// relative to RGBA8888.
41    /// Bits: [A:31..24 R:23..16 G:15..8 B:7..0]
42    BGRA8888 = SkColorType::kBGRA_8888_SkColorType as _,
43    /// Four channel RGBA data (10 bits per color, 2 bits for alpha) packed into a LE 32-bit word.
44    /// Bits: [A:31..30 B:29..20 G:19..10 R:9..0]
45    RGBA1010102 = SkColorType::kRGBA_1010102_SkColorType as _,
46    /// Four channel BGRA data (10 bits per color, 2 bits for alpha) packed into a LE 32-bit word.
47    /// R and B are swapped relative to RGBA1010102.
48    /// Bits: [A:31..30 R:29..20 G:19..10 B:9..0]
49    BGRA1010102 = SkColorType::kBGRA_1010102_SkColorType as _,
50    /// Three channel RGB data (10 bits per channel) packed into a LE 32-bit word. The remaining bits
51    /// are ignored and alpha is forced to opaque.
52    /// Bits: [x:31..30 B:29..20 G:19..10 R:9..0]
53    RGB101010x = SkColorType::kRGB_101010x_SkColorType as _,
54    /// Three channel BGR data (10 bits per channel) packed into a LE 32-bit word. The remaining bits
55    /// are ignored and alpha is forced to opaque. R and B are swapped relative to RGB101010x.
56    /// Bits: [x:31..30 R:29..20 G:19..10 B:9..0]
57    BGR101010x = SkColorType::kBGR_101010x_SkColorType as _,
58    /// Three channel BGR data (10 bits per channel) packed into a LE 32-bit word. The remaining bits
59    /// are ignored and alpha is forced to opaque. Instead of normalizing [0, 1023] to [0.0, 1.0] the
60    /// color channels map to an extended range of [-0.752941, 1.25098].
61    /// Bits: [x:31..30 R:29..20 G:19..10 B:9..0]
62    BGR101010xXR = SkColorType::kBGR_101010x_XR_SkColorType as _,
63    /// Four channel BGRA data (10 bits per channel) packed into a LE 64-bit word. Each channel is
64    /// preceded by 6 bits of padding. Instead of normalizing [0, 1023] to [0.0, 1.0] the color and
65    /// alpha channels map to an extended range of [-0.752941, 1.25098].
66    /// Bits: [A:63..54 x:53..48 R:47..38 x:37..32 G:31..22 x:21..16 B:15..6 x:5..0]
67    BGRA10101010XR = SkColorType::kBGRA_10101010_XR_SkColorType as _,
68    /// Four channel RGBA data (10 bits per channel) packed into a LE 64-bit word. Each channel is
69    /// preceded by 6 bits of padding.
70    /// Bits: [A:63..54 x:53..48 B:47..38 x:37..32 G:31..22 x:21..16 R:15..6 x:5..0]
71    RGBA10x6 = SkColorType::kRGBA_10x6_SkColorType as _,
72    /// Single channel data (8-bit) interpreted as a grayscale value (e.g. replicated to RGB).
73    /// Bits: [G:7..0]
74    Gray8 = SkColorType::kGray_8_SkColorType as _,
75    /// Four channel RGBA data (16-bit half-float per channel) packed into a LE 64-bit word. Values
76    /// are assumed to be in [0.0,1.0] range, unlike RGBAF16.
77    /// Bits: [A:63..48 B:47..32 G:31..16 R:15..0]
78    RGBAF16Norm = SkColorType::kRGBA_F16Norm_SkColorType as _,
79    /// Four channel RGBA data (16-bit half-float per channel) packed into a LE 64-bit word.
80    /// This has extended range compared to RGBAF16Norm.
81    /// Bits: [A:63..48 B:47..32 G:31..16 R:15..0]
82    RGBAF16 = SkColorType::kRGBA_F16_SkColorType as _,
83    /// Three channel RGB data (16-bit half-float per channel) packed into a LE 64-bit word. The last
84    /// 16 bits are ignored and alpha is forced to opaque.
85    /// Bits: [x:63..48 B:47..32 G:31..16 R:15..0]
86    RGBF16F16F16x = SkColorType::kRGB_F16F16F16x_SkColorType as _,
87    /// Four channel RGBA data (32-bit float per channel) packed into a LE 128-bit word.
88    /// Bits: [A:127..96 B:95..64 G:63..32 R:31..0]
89    RGBAF32 = SkColorType::kRGBA_F32_SkColorType as _,
90
91    /// Two channel RG data (8 bits per channel). Blue is forced to 0, alpha is forced to opaque.
92    /// Bits: [G:15..8 R:7..0]
93    R8G8UNorm = SkColorType::kR8G8_unorm_SkColorType as _,
94    /// Single channel data (16-bit half-float) interpreted as alpha. RGB are 0.
95    /// Bits: [A:15..0]
96    A16Float = SkColorType::kA16_float_SkColorType as _,
97    /// Single channel data (16 bits half-float) interpreted as red. G and B are forced to 0, alpha
98    /// is forced to opaque.
99    /// Bits: [R:15..0]
100    R16Float = SkColorType::kR16_float_SkColorType as _,
101    /// Two channel RG data (16-bit half-float per channel) packed into a LE 32-bit word.
102    /// Blue is forced to 0, alpha is forced to opaque.
103    /// Bits: [G:31..16 R:15..0]
104    R16G16Float = SkColorType::kR16G16_float_SkColorType as _,
105    /// Single channel data (16 bits) interpreted as alpha. RGB are 0.
106    /// Bits: [A:15..0]
107    A16UNorm = SkColorType::kA16_unorm_SkColorType as _,
108    // Single channel data (16 bits) interpreted as red. G and B are forced to 0, alpha is forced to
109    // opaque.
110    //   Bits: [R:15..0]
111    R16UNorm = SkColorType::kR16_unorm_SkColorType as _,
112    /// Two channel RG data (16 bits per channel) packed into a LE 32-bit word. B is forced to 0,
113    /// alpha is forced to opaque.
114    /// Bits: [G:31..16 R:15..0]
115    R16G16UNorm = SkColorType::kR16G16_unorm_SkColorType as _,
116    /// Four channel RGBA data (16 bits per channel) packed into a LE 64-bit word.
117    /// Bits: [A:63..48 B:47..32 G:31..16 R:15..0]
118    R16G16B16A16UNorm = SkColorType::kR16G16B16A16_unorm_SkColorType as _,
119    /// Four channel RGBA data (8 bits per channel) packed into a LE 32-bit word. The RGB values are
120    /// assumed to be encoded with the sRGB transfer function.
121    /// Bits: [A:31..24 B:23..16 G:15..8 R:7..0]
122    SRGBA8888 = SkColorType::kSRGBA_8888_SkColorType as _,
123    /// Single channel data (8 bits) interpreted as red. G and B are forced to 0, alpha is forced to
124    /// opaque.
125    /// Bits: [R:7..0]
126    R8UNorm = SkColorType::kR8_unorm_SkColorType as _,
127}
128
129native_transmutable!(SkColorType, ColorType);
130
131impl ColorType {
132    #[deprecated(since = "0.51.0", note = "Use ColorType::N32 ")]
133    pub const fn n32() -> Self {
134        Self::N32
135    }
136
137    pub const N32: Self = unsafe { *((&SkColorType::kN32_SkColorType) as *const _ as *const _) };
138
139    pub const COUNT: usize =
140        unsafe { *((&SkColorType::kLastEnum_SkColorType) as *const _ as *const _) } as usize
141            + 1usize;
142
143    pub fn bytes_per_pixel(self) -> usize {
144        unsafe {
145            sb::SkColorTypeBytesPerPixel(self.into_native())
146                .try_into()
147                .unwrap()
148        }
149    }
150
151    pub fn is_always_opaque(self) -> bool {
152        unsafe { sb::SkColorTypeIsAlwaysOpaque(self.into_native()) }
153    }
154
155    pub fn validate_alpha_type(self, alpha_type: AlphaType) -> Option<AlphaType> {
156        let mut alpha_type_r = AlphaType::Unknown;
157        unsafe {
158            sb::SkColorTypeValidateAlphaType(self.into_native(), alpha_type, &mut alpha_type_r)
159        }
160        .then_some(alpha_type_r)
161    }
162}
163
164#[cfg(test)]
165mod tests {
166    use super::*;
167
168    #[test]
169    fn n32_matches() {
170        assert_eq!(
171            ColorType::from_native_c(skia_bindings::SkColorType::kN32_SkColorType),
172            ColorType::N32
173        );
174    }
175}