-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle sRGB encoding/decoding correctly #54
Comments
@leroycep thanks for the feedback! BTW it doesn't look like the link to your module made it in correctly to the issue. WRT to handling encoding correctly per se, do you have any 3rd party prior art with regards to what other 2D libraries or compositing libraries handle? Just looking at this I'm guessing that this is where the issue lies (particularly in downsampling or compositing operations), but at this point I'm more concerned with conformance versus correctness. Like, for example, if pixman is handling this in a more correct way gamma-wise, that's a dead ringer we need to update the operations, otherwise maybe it's up to the consumer to make sure they understand what to do to get gamma correctness. PS: Our compositing operations right now are based off of the operations in the SVG compositing specification. That document doesn't necessarily mention sRGB, but chapter 14 of the SVG 1.1 second edition specification does, mind you. |
Oops, updated my first comment to fix the link. This may just a problem with documentation. In pub fn fromClamped(r: f64, g: f64, b: f64) RGB {
return .{
.r = @intFromFloat(255 * math.clamp(r, 0, 1)),
.g = @intFromFloat(255 * math.clamp(g, 0, 1)),
.b = @intFromFloat(255 * math.clamp(b, 0, 1)),
};
} This is converting Here is the function I implemented for encoding linear floating point numbers into /// Converts a color component from a linear 0..1 space to a compressed 8-bit encoding.
///
/// > [!warn] Alpha is not a color component! It is generally linear even in 8-bit encodings.
pub fn linearToSRGBFloat(comptime F: type, component_linear: F) F {
if (component_linear <= 0.0031308) {
// lower end of the sRGB encoding is linear
return component_linear * 12.92;
} else if (component_linear < 1.0) {
// higher end of value range is exponential
return std.math.pow(F, 1.055 * component_linear, 1.0 / 2.4) - 0.055;
} else {
return 1.0;
}
} (uhh, just noticed that the comment is wrong. I extracted the floating point version from another function that implemented both the encoding and turning it into an integer). |
@leroycep thanks, did some research on this really quick and here's what I came up with:
Given all this I'm slotting this in after we're done line-dash and other v0.5.0 milestone issues as I'm currently focusing on some library API issues and then line-dash, as that's the last missing piece of basic drawing functionality remaining. Hopefully with how we've structured things this should not be too hard to implement. Thanks again for the heads up! |
Hi there,
I've been writing my own software compositing library (targeting real time rendering for wayland applications). Along the way, I discovered that I was handling sRGB encoding/decoding incorrectly. I did a cursory glance at your code, and it seems like eyou are making the same mistake? You can checkout the color module I've created, and I highly recommend the article What Every Coder Should Know About Gamma.
The text was updated successfully, but these errors were encountered: