Skip to main content

zune_core/
colorspace.rs

1/*
2 * Copyright (c) 2023.
3 *
4 * This software is free software;
5 *
6 * You can redistribute it or modify it under terms of the MIT, Apache License or Zlib license
7 */
8
9//! Image Colorspace information and manipulation utilities.
10
11/// All possible image colorspaces
12/// Some of them aren't yet supported exist here.
13#[allow(clippy::upper_case_acronyms)]
14#[derive(Copy, Clone, Debug, Eq, PartialEq)]
15#[non_exhaustive]
16pub enum ColorSpace {
17    /// Red, Green , Blue
18    RGB,
19    /// Red, Green, Blue, Alpha
20    RGBA,
21    /// YUV colorspace
22    YCbCr,
23    /// Grayscale colorspace
24    Luma,
25    /// Grayscale with alpha colorspace
26    LumaA,
27    YCCK,
28    /// Cyan , Magenta, Yellow, Black
29    CMYK,
30    /// Blue, Green, Red
31    BGR,
32    /// Blue, Green, Red, Alpha
33    BGRA,
34    /// The colorspace is unknown
35    Unknown,
36    /// Alpha Red Green Blue
37    ARGB,
38    /// Hue,Saturation,Lightness
39    /// Conversion from RGB to HSL and back matches that of Python [colorsys](https://docs.python.org/3/library/colorsys.html) module
40    /// Color type is expected to be in floating point
41    HSL,
42    /// Hue, Saturation,Value
43    ///
44    /// Conversion from RGB to HSV and back matches that of Python [colorsys](https://docs.python.org/3/library/colorsys.html) module
45    /// Color type is expected to be in floating point
46    HSV,
47    /// Multiple arbitrary image channels.
48    ///
49    /// This introduces **limited** support for multi-band/multichannel images
50    /// that can have n channels.
51    ///
52    /// The library contains optimized and well-supported routines for up to 4 image channels as is
53    /// more common out there, but some pipelines may require multi-band image support.
54    ///
55    /// For operations, multi-band images are assumed to be n-channel images with no alpha
56    /// to allow for generic processing, without necessarily caring for the underlying interpretation
57    MultiBand(core::num::NonZeroU32)
58}
59
60impl ColorSpace {
61    /// Number of color channels present for a certain colorspace
62    ///
63    /// E.g. RGB returns 3 since it contains R,G and B colors to make up a pixel
64    pub const fn num_components(&self) -> usize {
65        match self {
66            Self::RGB | Self::YCbCr | Self::BGR | Self::HSV | Self::HSL => 3,
67            Self::RGBA | Self::YCCK | Self::CMYK | Self::BGRA | Self::ARGB => 4,
68            Self::Luma => 1,
69            Self::LumaA => 2,
70            Self::Unknown => 0,
71            Self::MultiBand(n) => n.get() as usize
72        }
73    }
74
75    pub const fn has_alpha(&self) -> bool {
76        matches!(self, Self::RGBA | Self::LumaA | Self::BGRA | Self::ARGB)
77    }
78
79    pub const fn is_grayscale(&self) -> bool {
80        matches!(self, Self::LumaA | Self::Luma)
81    }
82
83    /// Returns the position of the alpha pixel in a pixel
84    ///
85    ///
86    /// That is for an array of color components say `[0,1,2,3]` if the image has an alpha channel
87    /// and is in RGBA format, this will return `Some(3)`, indicating alpha is found in the third index
88    /// but if the image is in `ARGB` format, it will return `Some(0)` indicating alpha is found in  
89    /// index 0
90    ///
91    /// If an image doesn't have an alpha channel returns `None`
92    ///
93    pub const fn alpha_position(&self) -> Option<usize> {
94        match self {
95            ColorSpace::RGBA => Some(3),
96            ColorSpace::LumaA => Some(1),
97            ColorSpace::BGRA => Some(3),
98            ColorSpace::ARGB => Some(0),
99            _ => None
100        }
101    }
102}
103
104/// Encapsulates all colorspaces supported by
105/// the library
106///
107/// This explicitly leaves out multi-band images
108pub static ALL_COLORSPACES: [ColorSpace; 12] = [
109    ColorSpace::RGB,
110    ColorSpace::RGBA,
111    ColorSpace::LumaA,
112    ColorSpace::Luma,
113    ColorSpace::CMYK,
114    ColorSpace::BGRA,
115    ColorSpace::BGR,
116    ColorSpace::YCCK,
117    ColorSpace::YCbCr,
118    ColorSpace::ARGB,
119    ColorSpace::HSL,
120    ColorSpace::HSV
121];
122
123/// Color characteristics
124///
125/// Gives more information about values in a certain
126/// colorspace
127#[allow(non_camel_case_types)]
128#[derive(Copy, Clone, Debug, PartialEq)]
129pub enum ColorCharacteristics {
130    /// sRGB Transfer function
131    sRGB,
132    /// Rec.709 Transfer function
133    Rec709,
134    /// Pure gamma 2.2 Transfer function, ITU-R 470M
135    Gamma2p2,
136    /// Pure gamma 2.8 Transfer function, ITU-R 470BG
137    Gamma2p8,
138    /// Smpte 428 Transfer function
139    Smpte428,
140    /// Log100 Transfer function
141    Log100,
142    /// Log100Sqrt10 Transfer function
143    Log100Sqrt10,
144    /// Bt1361 Transfer function
145    Bt1361,
146    /// Smpte 240 Transfer function
147    Smpte240,
148    /// IEC 61966 Transfer function
149    Iec61966,
150    /// Linear transfer function
151    Linear,
152    /// Perceptual Quantizer (SMPTE ST 2084) - standard for HDR10
153    PQ,
154    /// Hybrid Log-Gamma (ARIB STD-B67) - broadcast HDR
155    HLG,
156    /// Fallback for unknown cICP transfer functions
157    Unknown(u8),
158}
159/// Represents a single channel color primary.
160///
161/// This can be viewed as a 3D coordinate of the color primary
162/// for a given colorspace
163#[derive(Default, Debug, Copy, Clone)]
164pub struct SingleColorPrimary {
165    pub x: f64,
166    pub y: f64,
167    pub z: f64
168}
169/// A collection of red,green and blue color primaries placed
170/// in one struct for easy manipulation
171#[derive(Default, Debug, Copy, Clone)]
172pub struct ColorPrimaries {
173    /// Red color primaries
174    pub red:   SingleColorPrimary,
175    /// Green color primaries
176    pub green: SingleColorPrimary,
177    /// Blue color primaries
178    pub blue:  SingleColorPrimary,
179    
180    pub white_point: SingleColorPrimary
181}
182
183/// Rendering intents indicate what one may want to do with colors outside of it's gamut
184///
185///
186/// Further reading
187///  - [IBM Rendering Intent](https://www.ibm.com/docs/en/i/7.5?topic=management-rendering-intents)
188///  - [ColorGate Blog](https://blog.colorgate.com/en/rendering-intent-explained)   
189#[derive(Eq, PartialEq, Clone, Copy, Debug)]
190pub enum RenderingIntent {
191    AbsoluteColorimetric,
192    Saturation,
193    RelativeColorimetric,
194    Perceptual
195}
196