Skip to content

Commit 2f4652e

Browse files
authored
Implement (Premul)Rgba8::from_u32 and from_u8_array (#135)
Closes #73. The conversions from the packed u32 are easy to get wrong when implemented manually. (On the other hand, these methods are also easy to use wrong.)
1 parent b0b868e commit 2f4652e

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ This release has an [MSRV][] of 1.82.
1919

2020
* Support for the ACES2065-1 color space. ([#124][] by [@tomcur][])
2121
* A documentation example implementing `ColorSpace`. ([#130][] by [@tomcur][])
22+
* Conversions of `[u8; 4]` and packed `u32` into `Rgba8` and `PremulRgba8` are now provided. ([#135][] by [@tomcur][])
2223

2324
### Fixed
2425

@@ -119,6 +120,7 @@ This is the initial release.
119120
[#128]: https://github.com/linebender/color/pull/128
120121
[#129]: https://github.com/linebender/color/pull/129
121122
[#130]: https://github.com/linebender/color/pull/130
123+
[#135]: https://github.com/linebender/color/pull/135
122124

123125
[Unreleased]: https://github.com/linebender/color/compare/v0.2.2...HEAD
124126
[0.2.2]: https://github.com/linebender/color/releases/tag/v0.2.2

color/src/rgba8.rs

+63-4
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,27 @@ impl Rgba8 {
4141
[self.r, self.g, self.b, self.a]
4242
}
4343

44-
/// Returns the color as a little endian packed value, with `a` as the
45-
/// most significant byte and `r` the least.
44+
/// Convert the `[u8; 4]` byte array into an `Rgba8` color.
45+
///
46+
/// The color values must be given in the order `[r, g, b, a]`.
47+
#[must_use]
48+
pub const fn from_u8_array([r, g, b, a]: [u8; 4]) -> Self {
49+
Self { r, g, b, a }
50+
}
51+
52+
/// Returns the color as a little-endian packed value, with `r` the least significant byte and
53+
/// `a` the most significant.
4654
#[must_use]
4755
pub const fn to_u32(self) -> u32 {
4856
u32::from_ne_bytes(self.to_u8_array())
4957
}
58+
59+
/// Interpret the little-endian packed value as a color, with `r` the least significant byte
60+
/// and `a` the most significant.
61+
#[must_use]
62+
pub const fn from_u32(packed_bytes: u32) -> Self {
63+
Self::from_u8_array(u32::to_ne_bytes(packed_bytes))
64+
}
5065
}
5166

5267
impl From<Rgba8> for AlphaColor<Srgb> {
@@ -90,12 +105,27 @@ impl PremulRgba8 {
90105
[self.r, self.g, self.b, self.a]
91106
}
92107

93-
/// Returns the color as a little endian packed value, with `a` as the
94-
/// most significant byte and `r` the least.
108+
/// Convert the `[u8; 4]` byte array into a `PremulRgba8` color.
109+
///
110+
/// The color values must be given in the order `[r, g, b, a]`.
111+
#[must_use]
112+
pub const fn from_u8_array([r, g, b, a]: [u8; 4]) -> Self {
113+
Self { r, g, b, a }
114+
}
115+
116+
/// Returns the color as a little-endian packed value, with `r` the least significant byte and
117+
/// `a` the most significant.
95118
#[must_use]
96119
pub const fn to_u32(self) -> u32 {
97120
u32::from_ne_bytes(self.to_u8_array())
98121
}
122+
123+
/// Interpret the little-endian packed value as a color, with `r` the least significant byte
124+
/// and `a` the most significant.
125+
#[must_use]
126+
pub const fn from_u32(packed_bytes: u32) -> Self {
127+
Self::from_u8_array(u32::to_ne_bytes(packed_bytes))
128+
}
99129
}
100130

101131
/// This is deprecated and will be removed in 0.3.0.
@@ -134,6 +164,25 @@ mod tests {
134164
assert_eq!(0xffccbbaa_u32.to_le(), p.to_u32());
135165
}
136166

167+
#[test]
168+
fn from_u32() {
169+
let c = Rgba8 {
170+
r: 1,
171+
g: 2,
172+
b: 3,
173+
a: 4,
174+
};
175+
assert_eq!(Rgba8::from_u32(0x04030201_u32.to_le()), c);
176+
177+
let p = PremulRgba8 {
178+
r: 0xaa,
179+
g: 0xbb,
180+
b: 0xcc,
181+
a: 0xff,
182+
};
183+
assert_eq!(PremulRgba8::from_u32(0xffccbbaa_u32.to_le()), p);
184+
}
185+
137186
#[test]
138187
#[cfg(feature = "bytemuck")]
139188
fn bytemuck_to_u32() {
@@ -153,4 +202,14 @@ mod tests {
153202
};
154203
assert_eq!(p.to_u32(), bytemuck::cast(p));
155204
}
205+
206+
#[test]
207+
#[cfg(feature = "bytemuck")]
208+
fn bytemuck_from_u32() {
209+
let c = 0x04030201_u32.to_le();
210+
assert_eq!(Rgba8::from_u32(c), bytemuck::cast(c));
211+
212+
let p = 0xffccbbaa_u32.to_le();
213+
assert_eq!(PremulRgba8::from_u32(p), bytemuck::cast(p));
214+
}
156215
}

0 commit comments

Comments
 (0)