@@ -16,32 +16,71 @@ pub trait IntoPixel<T, F>: Sized {
1616 }
1717}
1818
19- /// Eight-bit channels in R,G,B order.
19+ /// Three eight-bit channels in R,G,B order.
20+ ///
21+ /// Each channel has 2^8 = 256 distinct values, and each pixel takes three
22+ /// bytes of memory.
2023#[ derive( Copy , Clone , Default ) ]
2124pub struct Rgb888 ;
22- /// 5,6,5-bit channels in R,G,B order .
25+ /// Three channels with 5 bits for R, 6 bits for G, and 5 bits for B .
2326#[ derive( Copy , Clone , Default ) ]
2427pub struct Rgb565 ;
28+ /// Three 5-bit channels plus one-bit alpha (1 = opaque, 0 = transparent).
29+ ///
30+ /// Each color channel has 2^5 = 32 distinct values, and each pixel takes
31+ /// two bytes of memory.
32+ #[ derive( Copy , Clone , Default ) ]
33+ pub struct Rgba5551 ;
2534
26- /// Eight-bit channels in X,R,G,B order, where X is unused.
35+ /// Three eight-bit channels in x,R,G,B order, where x is unused.
36+ ///
37+ /// Each channel has 2^8 = 256 distinct values, and each pixel takes
38+ /// four bytes of memory.
2739#[ derive( Copy , Clone , Default ) ]
2840pub struct Xrgb8888 ;
29- /// Eight-bit channels in R,G,B,A order.
41+
42+ /// Four eight-bit channels in R,G,B,A order.
43+ ///
44+ /// Each channel has 2^8 = 256 distinct values, and each pixel takes
45+ /// four bytes of memory.
3046#[ derive( Copy , Clone , Default ) ]
3147pub struct Rgba8888 ;
32- /// Eight-bit channels in A,R,G,B order.
48+
49+ /// Four eight-bit channels in A,R,G,B order.
50+ ///
51+ /// Each channel has 2^8 = 256 distinct values, and each pixel takes
52+ /// four bytes of memory.
3353#[ derive( Copy , Clone , Default ) ]
3454pub struct Argb8888 ;
35- /// Eight-bit channels in B,G,R,A order.
55+
56+ /// Four eight-bit channels in B,G,R,A order.
57+ ///
58+ /// Each channel has 2^8 = 256 distinct values, and each pixel takes
59+ /// four bytes of memory.
3660#[ derive( Copy , Clone , Default ) ]
3761pub struct Bgra8888 ;
3862
39- /// Four-bit channels in R,G,B,A order.
63+ /// Four four-bit channels in R,G,B,A order.
64+ ///
65+ /// Each channel has 2^4 = 16 distinct values, and the number of different
66+ /// RGB values is 2^12 = 4096. Each pixel takes two bytes.
4067#[ derive( Copy , Clone , Default ) ]
4168pub struct Rgba4444 ;
4269
70+ /// Three channels with 3 bits for R and g and 2 bits for B.
71+ ///
72+ /// Red and green have 2^3 = 8 and blue 2^2 = 4 distinct values. The number of
73+ /// different RGB values is 256, and each pixel takes a single byte.
74+ #[ derive( Copy , Clone , Default ) ]
75+ pub struct Rgb332 ;
76+
77+ /// A single 8-bit luminance channel.
78+ #[ derive( Copy , Clone , Default ) ]
79+ pub struct Lum8 ;
80+
4381// Impls for Color3
4482
83+ // Rgb888
4584impl IntoPixel < u32 , Rgb888 > for Color3 {
4685 fn into_pixel ( self ) -> u32 {
4786 let [ r, g, b] = self . 0 ;
@@ -55,22 +94,34 @@ impl IntoPixel<[u8; 3], Rgb888> for Color3 {
5594 }
5695}
5796
97+ // Rgb565
5898impl IntoPixel < u16 , Rgb565 > for Color3 {
99+ /// Packs `self` into a `u16` in `0bRRRRR_GGGGGG_BBBBB` format.
59100 fn into_pixel ( self ) -> u16 {
60101 let [ r, g, b] = self . 0 ;
61102 ( r as u16 >> 3 & 0x1F ) << 11
62103 | ( g as u16 >> 2 & 0x3F ) << 5
63104 | ( b as u16 >> 3 & 0x1F )
64105 }
65106}
66-
67107impl IntoPixel < [ u8 ; 2 ] , Rgb565 > for Color3 {
108+ /// Packs `self` into two bytes in `[0bGGG_BBBBB, 0bRRRRR_GGG]` format.
109+ // TODO is this correct?
68110 fn into_pixel ( self ) -> [ u8 ; 2 ] {
69111 let c: u16 = self . into_pixel ( ) ;
70112 c. to_ne_bytes ( )
71113 }
72114}
73115
116+ // Rgb332
117+ impl IntoPixel < u8 , Rgb332 > for Color3 {
118+ /// Packs `self` into a single byte in `0bRRR_GGG_BB` format.
119+ fn into_pixel ( self ) -> u8 {
120+ let [ r, g, b] = self . 0 ;
121+ ( r & 0b111_000_00 ) | ( g >> 3 & 0b000_111_00 ) | ( b >> 6 )
122+ }
123+ }
124+
74125// Impls for Color4
75126
76127impl < F > IntoPixel < u32 , F > for Color4
@@ -83,13 +134,26 @@ where
83134 }
84135}
85136
137+ /*
138+ impl<T, F> IntoPixel<T, F> for Color4
139+ where
140+ Color3: IntoPixel<T, F>,
141+ {
142+ fn into_pixel(self) -> T {
143+ self.to_rgb().into_pixel()
144+ }
145+ }*/
146+
147+ // Xrgb8888
86148impl IntoPixel < u32 , Xrgb8888 > for Color4 {
87149 fn into_pixel ( self ) -> u32 {
88150 let [ r, g, b, _] = self . 0 ;
89151 // From [0x00, 0xRR, 0xGG, 0xBB] to 0x00_RR_GG_BB -> big-endian!
90152 u32:: from_be_bytes ( [ 0 , r, g, b] )
91153 }
92154}
155+
156+ // Rgba8888 and permutations
93157impl IntoPixel < [ u8 ; 4 ] , Rgba8888 > for Color4 {
94158 fn into_pixel ( self ) -> [ u8 ; 4 ] {
95159 self . 0
@@ -107,11 +171,8 @@ impl IntoPixel<[u8; 4], Bgra8888> for Color4 {
107171 [ b, g, r, a]
108172 }
109173}
110- impl IntoPixel < [ u8 ; 3 ] , Rgb888 > for Color4 {
111- fn into_pixel ( self ) -> [ u8 ; 3 ] {
112- [ self . r ( ) , self . g ( ) , self . b ( ) ]
113- }
114- }
174+
175+ // Rgba4444
115176impl IntoPixel < [ u8 ; 2 ] , Rgba4444 > for Color4 {
116177 fn into_pixel ( self ) -> [ u8 ; 2 ] {
117178 let c: u16 = self . into_pixel_fmt ( Rgba4444 ) ;
@@ -125,18 +186,41 @@ impl IntoPixel<u16, Rgba4444> for Color4 {
125186 r << 12 | g << 8 | b << 4 | a
126187 }
127188}
128- impl IntoPixel < u16 , Rgb565 > for Color4 {
189+
190+ // Rgba 5551
191+ impl IntoPixel < u16 , Rgba5551 > for Color4 {
192+ /// Packs `self` into a `u16` in a `0bRRRRR_GGGGG_BBBBB_A` format.
193+ /// The alpha value `0xFF` is considered opaque, any other value
194+ /// fully transparent.
129195 fn into_pixel ( self ) -> u16 {
130- self . to_rgb ( ) . into_pixel ( )
196+ let [ r, g, b, a] = self . 0 ;
197+ ( r as u16 >> 3 & 0x1F ) << 11
198+ | ( g as u16 >> 3 & 0x1F ) << 6
199+ | ( b as u16 >> 3 & 0x1F ) << 1
200+ | ( a == 0xFF ) as u16
131201 }
132202}
133- impl IntoPixel < [ u8 ; 2 ] , Rgb565 > for Color4 {
203+ impl IntoPixel < [ u8 ; 2 ] , Rgba5551 > for Color4 {
134204 fn into_pixel ( self ) -> [ u8 ; 2 ] {
135- let c: u16 = self . into_pixel_fmt ( Rgb565 ) ;
205+ let c: u16 = self . into_pixel_fmt ( Rgba5551 ) ;
136206 c. to_ne_bytes ( )
137207 }
138208}
139209
210+ // Rgb332
211+ impl IntoPixel < u8 , Rgb332 > for Color4 {
212+ /// Packs `self` into a single byte in `0bRRR_GGG_BB` format.
213+ fn into_pixel ( self ) -> u8 {
214+ self . to_rgb ( ) . into_pixel ( )
215+ }
216+ }
217+ impl IntoPixel < [ u8 ; 1 ] , Rgb332 > for Color4 {
218+ /// Packs `self` into a single byte in `0bRRR_GGG_BB` format.
219+ fn into_pixel ( self ) -> [ u8 ; 1 ] {
220+ [ self . into_pixel ( ) ]
221+ }
222+ }
223+
140224#[ cfg( test) ]
141225mod tests {
142226 use crate :: math:: { rgb, rgba} ;
@@ -160,6 +244,15 @@ mod tests {
160244 assert_eq ! ( pix, [ 0b000_00010 , 0b01000_001 ] ) ;
161245 }
162246
247+ #[ test]
248+ fn color3_to_rgb332 ( ) {
249+ let pix: u8 = rgb ( 0xFF , 0x00 , 0xFF ) . into_pixel ( ) ;
250+ assert_eq ! ( pix, 0b111_000_11 , "bits: {pix:b}" ) ;
251+
252+ let pix: u8 = rgb ( 0x00 , 0x0FF , 0x00 ) . into_pixel ( ) ;
253+ assert_eq ! ( pix, 0b000_111_00 , "bits: {pix:b}" ) ;
254+ }
255+
163256 #[ test]
164257 fn color4_to_rgba8888 ( ) {
165258 let col = rgba ( 0x11u8 , 0x22 , 0x33 , 0x44 ) ;
@@ -199,4 +292,23 @@ mod tests {
199292 let pix: u16 = COL4 . into_pixel_fmt ( Rgba4444 ) ;
200293 assert_eq ! ( pix, 0x1234 ) ;
201294 }
295+
296+ #[ test]
297+ fn color4_to_rgba5551_u16 ( ) {
298+ let pix: u16 = rgba ( 0x40u8 , 0x20 , 0x10 , 0 ) . into_pixel_fmt ( Rgba5551 ) ;
299+ assert_eq ! ( pix, 0b01000_00100_00010_0_u16 , "bits: {pix:b}" ) ;
300+ let pix: u16 = rgba ( 0x40u8 , 0x20 , 0x10 , 0x80 ) . into_pixel_fmt ( Rgba5551 ) ;
301+ assert_eq ! ( pix, 0b01000_00100_00010_0_u16 , "bits: {pix:b}" ) ;
302+ let pix: u16 = rgba ( 0x40u8 , 0x20 , 0x10 , 0xFF ) . into_pixel_fmt ( Rgba5551 ) ;
303+ assert_eq ! ( pix, 0b01000_00100_00010_1_u16 , "bits: {pix:b}" ) ;
304+ }
305+
306+ #[ test]
307+ fn color4_to_rgba5551_2u8 ( ) {
308+ let pix: [ u8 ; 2 ] = rgba ( 0x40u8 , 0x20 , 0x10 , 0 ) . into_pixel_fmt ( Rgba5551 ) ;
309+ assert_eq ! ( pix, [ 0b00_00010_0 , 0b01000_001 ] ) ;
310+ let pix: [ u8 ; 2 ] =
311+ rgba ( 0x40u8 , 0x20 , 0x10 , 0xFF ) . into_pixel_fmt ( Rgba5551 ) ;
312+ assert_eq ! ( pix, [ 0b00_00010_1 , 0b01000_001 ] ) ;
313+ }
202314}
0 commit comments