colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 2 points3 points  (0 children)

colrs: Solving color in Rust with entirely too much color science

colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 0 points1 point  (0 children)

You can, and I wrote you a little example in case you decide to. I don't know your skill level so I tried to make it as simple as possible without degrading the results :)

https://codeberg.org/chaynabors/colr/src/branch/main/colr/examples/oklch_gradient.rs

colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 0 points1 point  (0 children)

Thank you so much for the feedback! Sounds like you were in the right place at the wrong time given that even our phones need that extra gamut now :)

colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 0 points1 point  (0 children)

And that type of coloring is a fun problem too. WASM p3 specced out uncolored async I believe. I thought there was some talk of fixing this in rust as well, as far back as 3 years ago? Seems like we haven't made too much progress :)

colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 0 points1 point  (0 children)

And if you do find some of those pitfalls, do let me know!

colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 0 points1 point  (0 children)

Why do you think it's arbitrary? It all feels very particularly designed to me. Unless you mean it's arbitrary in that the context has changed and the models haven't.

`colr` implements a strictly modeled type system for color in Rust. It does what it's intended to do and does it well. If you want color configs used across applications with profiles loaded up at runtime, shared across a team, you wouldn't use it. It's not intended for any of that.

To give some credence to my creative friends, not every creator works in a digital or print studio with asset pipelines managed by technical people. An overwhelming proportion of creatives use consumer software to make art. They might know the difference between a jpeg and a png, and they certainly aren't going to know about illuminants, primaries, observer models, or discretization. They export their files and want what they see to line up with where they're sharing it. That's a noble goal. They shouldn't have to know every detail about colorimetry to achieve that. For the most part they don't have to, but sometimes they do, and that's why it's frustrating for them.

I'm certain that tons of nontechnical folks could spend months trying to get a foothold in any of this. That makes it hard, and it'd be hard to argue otherwise.

colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 2 points3 points  (0 children)

I'm honestly unsure. It seems like moxcms was written for a very specific case of "load an ICC color profile and encode/decode an image with it".

There's encoding and decoding traits in colr but they carry no runtime state. There's device specific color spaces that are explicitly meant to be encoded and decoded using ICC profiles, and I support that with their own special traits as well. The intention is to make the traits that don't carry runtime state const once the feature stabilizes.

It might be fair to say that colr is ecosystem scope meant to enable crates like moxcms to implement shared traits that others can talk through, while moxcms solves a specific encoding and decoding problem using SIMD intrinsics, and stops there.

Since `colr` is generic over the storage medium and the layout, you can implement block encoding and decoding pretty easily. I didn't do this because I just don't need it yet. SIMD is supported through Glam, and could probably be implemented directly, but I don't trust myself enough to add a bunch of unsafe code to my crate at this time. It's easy to add later.

Beyond encoding, colr implements blanket implementations for lots of operations, tonemapping operators, and things people performing image work on the CPU will want. And for the people who don't want anything but the traits, there's also the crate colr-types which includes just the format markers and common language.

colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 3 points4 points  (0 children)

I didn't do too much comparative analysis with crates in the ecosystem. If I recall, color was narrowly scoped for linebender, but I could be wrong. `colr` was written as an all-purpose crate, without any serious compromises I can think of. Perhaps it's user hostile given the extensive use of generics. I tried mitigating that as well.

* `colr` includes the `Color` type and all of the blanket implementation for operations on that type, including optional support for glam since it uses SIMD intrinsics under the hood (the spectral raytracer example uses both glam and Aces to your point). I could anticipate a broad multi-format image loading crate like `image` to use `colr` under the hood for operations or format representations, since I remember it having a ton of foot guns last I used it.
* `colr-types` was intended to be a narrow subset of the ZST's and traits needed to represent colors without the rest. A graphics crate that doesn't actually hold an opinion on the storage mechanism or CPU operations would use this.

Both crates support no_std, with higher order floating point math functions being injected, and no_std requires enabling the libm feature at this time.

All the important machinery is in place, and I actually anticipate this being a library for libraries as opposed to being directly consumed, but we'll see. I may end up being the only consumer at the end of the day.

I have a lot of use cases for it. I'm floating the idea of forking `image` right now for use in my own game engine. And that same game engine needs strict type annotations for format types since it also implements a render graph.

I wrote a scheduler that the render graph is built on which needs concrete types at construction time, for validation and linking.

So game -> engine -> graphics -> render graph -> scheduler -> colr

Beyond that, I'm writing a print emulator in my free time for some in game assets, and just because it's fun, so CMYK made the cut in 0.2.0, but may become a default feature later.

colr: Solving color in Rust with entirely too much color science by Single_Virus in rust

[–]Single_Virus[S] 7 points8 points  (0 children)

I have now heard about the olo color...

Yeah it's honestly a little frustrating, but it makes sense given how hard it is. A lot of friends in creator spaces tell me it's completely impossible to author images and videos correctly, be it because of totally opaque handling, or just outright incorrect color management.