I have this struct:
pub struct Color
{
bgra: u32,
b: u8,
g: u8,
r: u8,
a: u8
}
Is it possible that the b.g.r.a fields are inside the address of the bgra field?
bgra is at offset 0
b is at offset 0
g is at offset 1
r is at offset 2
a is at offset 3
This would save instructions when wanting to extract the red green blue alpha fields.
If not what would be the best way to handle it?
1 Like
No; all struct fields are required to be disjoint. You can do something similar with bytemuck
, though you might have some surprises if you compile for an opposite-endian architecture:
use bytemuck;
#[derive(bytemuck::Pod, bytemuck::Zeroable, Copy, Clone)]
#[repr(C, align(4))]
struct Color {
b: u8,
g: u8,
r: u8,
a: u8,
}
impl Color {
pub fn as_mut_u32(&mut self)->&mut u32 {
bytemuck::cast_mut(self)
}
}
Personally, Iād probably just implement From
/Into<u32>
and trust the optimizer to do its job properly:
#[derive(Copy, Clone)]
#[repr(align(4))]
struct Color {
b: u8,
g: u8,
r: u8,
a: u8,
}
impl From<u32> for Color {
fn from(bgra:u32)->Color {
let [b,g,r,a] = bgra.to_le_bytes(); // Or to_be_bytes, as appropriate
Color { b,g,r,a }
}
}
impl From<Color> for u32 {
fn from(Color { b,g,r,a }: Color)->u32 {
u32::from_le_bytes([b,g,r,a]) // Or from_be_bytes, as appropriate
}
}
4 Likes
system
Closed
July 4, 2024, 9:05am
3
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.