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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//!

/// 24 bits broken into 3x RGB components.
///
/// Unlike with [`NcChannel`], operations involving `NcRgb`
/// ignores the last 4th byte (the alpha component).
///
/// ## Diagram
///
/// ```txt
/// -------- RRRRRRRR GGGGGGGG BBBBBBBB
/// ```
/// `type in C: no data type`
///
/// See also: [`NcRgba`] and [`NcChannel`] types.
///
/// [`NcChannel`]: crate::NcChannel
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub struct NcRgb(pub c_api::NcRgb_u32);

/// 32 bits broken into 3x RGB components + alpha component.
///
/// ## Diagram
///
/// ```txt
/// AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
/// ```
/// `type in C: no data type`
///
/// See also: [`NcRgb`] and [`NcChannel`] types.
///
/// [`NcRgba`]: crate::NcRgba
/// [`NcChannel`]: crate::NcChannel
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub struct NcRgba(pub c_api::NcRgba_u32);

mod std_impls {
    use super::{
        c_api::{NcRgb_u32, NcRgba_u32},
        NcRgb, NcRgba,
    };

    crate::from_primitive![NcRgb, NcRgb_u32];
    crate::unit_impl_from![NcRgb, NcRgb_u32];
    crate::unit_impl_fmt![bases+display; NcRgb];

    impl From<[u8; 3]> for NcRgb {
        fn from(array: [u8; 3]) -> Self {
            Self(
                (array[0] as NcRgb_u32) << 16
                    | (array[1] as NcRgb_u32) << 8
                    | array[2] as NcRgb_u32,
            )
        }
    }
    impl From<NcRgb> for [u8; 3] {
        #[inline]
        fn from(rgb: NcRgb) -> Self {
            [
                ((rgb.0 & 0xff0000) >> 16) as u8,
                ((rgb.0 & 0x00ff00) >> 8) as u8,
                (rgb.0 & 0x0000ff) as u8,
            ]
        }
    }
    impl From<NcRgb> for (u8, u8, u8) {
        #[inline]
        fn from(rgb: NcRgb) -> Self {
            (
                ((rgb.0 & 0xff0000) >> 16) as u8,
                ((rgb.0 & 0x00ff00) >> 8) as u8,
                (rgb.0 & 0x0000ff) as u8,
            )
        }
    }
    impl From<(u8, u8, u8)> for NcRgb {
        fn from(tuple: (u8, u8, u8)) -> Self {
            Self((tuple.0 as NcRgb_u32) << 16 | (tuple.1 as NcRgb_u32) << 8 | tuple.2 as NcRgb_u32)
        }
    }

    crate::from_primitive![NcRgba, NcRgba_u32];
    crate::unit_impl_from![NcRgba, NcRgba_u32];
    crate::unit_impl_fmt![bases+display; NcRgba];
}

pub(crate) mod c_api {

    /// 24 bits broken into 3x RGB components.
    ///
    /// It's recommended to use [`NcRgb`] instead.
    ///
    /// Unlike with [`NcChannel_u32`], operations involving `NcRgb_u32`
    /// ignores the last 4th byte (the alpha component).
    ///
    /// ## Diagram
    ///
    /// ```txt
    /// -------- RRRRRRRR GGGGGGGG BBBBBBBB
    /// ```
    /// `type in C: no data type`
    ///
    /// See also: [`NcRgba_u32`] and [`NcChannel_u32`] types.
    ///
    /// [`NcRgb`]: crate::NcRgb
    /// [`NcChannel_u32`]: crate::c_api::NcChannel_u32
    pub type NcRgb_u32 = u32;

    /// 32 bits broken into 3x RGB components plus one alpha component.
    ///
    /// It's recommended to use [`NcRgba`] instead.
    ///
    /// ## Diagram
    ///
    /// ```txt
    /// AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
    /// ```
    /// `type in C: no data type`
    ///
    /// See also: [`NcRgb_u32`] and [`NcChannel_u32`] types.
    ///
    /// [`NcRgba`]: crate::NcRgba
    /// [`NcChannel_u32`]: crate::c_api::NcChannel_u32
    pub type NcRgba_u32 = u32;

    // MAYBE?
    // // NcBgra
    // //
    // /// 32 bits broken into 3x 8bpp BGR channels + 8ppp alpha.
    // ///
    // /// ## Diagram
    // ///
    // /// ```txt
    // /// AAAAAAAA BBBBBBBB GGGGGGGG RRRRRRRR
    // /// ```
    // ///
    // /// `type in C: no data type`
    // ///
    // /// See also: [`NcRgba`], [`NcRgb`] and [`NcChannel`] types.
    // pub type NcBgra = u32;
}