#[solved] Packing data for a color: Is there a better way than this?

1 messages · Page 1 of 1 (latest)

stark sentinel
#
  const OkLCH = packed struct {
    L : u7,  // [0..100] Perceived Lightness
    C : u7,  // [0..100] Chroma (aka Color Saturation)
    H : u9,  // [0..360] Hue
    a : u7,  // [0..100] Alpha (aka Transparency)
    __unused_bits_31_32 :u2= 0,
  };
```I'm implementing an OkLCH color representation, based on the info in this article, and this is what I have so far.
https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl

My main worry is how all these `u7` are going to be aligned by zig,
or if that does not matter when making it a `packed struct`

I didn't go with floats to represent % because it felt like a waste of space, just to represent 0..1
But I wonder if there is a better way of packing the data 🤔

Do you guys have any insights on this idea?
rotund elm
#

that will turn the layout into

aaaaaaaH|HHHHHHHH|_CCCCCCC|_LLLLLLL```
#

actually wait hang on

#

please hold, i suck at reasoning about endianness

#

okay yeah no i was right

#

@stark sentinel

#

the | denotes a byte boundary

#

this way, accessing the C and H fields will be more efficient

stark sentinel
#

ic

rotund elm
#

with your original layout, the bits look like this

|__aaaaaa|aHHHHHHH|HHCCCCCC|CLLLLLLL
stark sentinel
#

right, so the only efficient one in my version is the A, contrasted with both C and L being efficient?

rotund elm
#
const OkLCH = packed struct {
    L : u7,  // [0..100] Perceived Lightness
    unused_1: u1,
    C : u7,  // [0..100] Chroma (aka Color Saturation)
    unused_2: u1,
    H : u9,  // [0..360] Hue
    a : u7,  // [0..100] Alpha (aka Transparency)
}```
rotund elm
stark sentinel
#

oh true

#

I thought it might not matter because of using an u32 internally when packed

rotund elm
rotund elm
stark sentinel
#

@rotund elm I just discovered that C never goes above 0.37 🤔
What if I made it an u9, that uses 0..370?
Could it be rearranged to still be efficient?

rotund elm
#

let me think

#

yes

#
  const OkLCH = packed struct(u32) {
    L : u7,  // [0..100] Perceived Lightness
    C : u9,  // [0..370] Chroma (aka Color Saturation)
    H : u7,  // [0..360] Hue
    a : u9,  // [0..100] Alpha (aka Transparency)
  };```
stark sentinel
#

H, and a look like typo

rotund elm
#

oh yeah hang on

#
    L : u7,  // [0..100] Perceived Lightness
    C : u9,  // [0..370] Chroma (aka Color Saturation)
    a : u7,  // [0..100] Alpha (aka Transparency)
    H : u9,  // [0..360] Hua
  };```
stark sentinel
#

does that not change the boundaries, like you mentioned?

rotund elm
#

L and a are just masks on a single byte, C and H are shifts on a word

stark sentinel
#

ah i see

rotund elm
stark sentinel
#

still kinda clean, it seems, yeah

stark sentinel
#

Man, I love zig syntax for structs and packed structs
It makes really complicated things (at least for C) so damn simple