Oklab: Fix rollover error (#1529)

* oklab: Removed unnecessary type conversions

* oklab: Fixed rollover error in color conversion
This commit is contained in:
xkns 2022-11-24 18:15:10 +01:00 committed by GitHub
parent 80aafa22ec
commit 7a31e2bb6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 8 deletions

View File

@ -8,6 +8,11 @@ inline uint8_t clamp(int x)
return (x<0) ? 0 : ((x>255) ? 255 : uint8_t(x)); return (x<0) ? 0 : ((x>255) ? 255 : uint8_t(x));
} }
inline double clamp(double x)
{
return std::max(0.0, std::min(x, 1.0));
}
void ColorSys::rgb2hsl(uint8_t red, uint8_t green, uint8_t blue, uint16_t & hue, float & saturation, float & luminance) void ColorSys::rgb2hsl(uint8_t red, uint8_t green, uint8_t blue, uint16_t & hue, float & saturation, float & luminance)
{ {
QColor color(red,green,blue); QColor color(red,green,blue);
@ -60,9 +65,9 @@ void ColorSys::yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t &r, uint8_t &g,
void ColorSys::rgb2okhsv(uint8_t red, uint8_t green, uint8_t blue, double & hue, double & saturation, double & value) void ColorSys::rgb2okhsv(uint8_t red, uint8_t green, uint8_t blue, double & hue, double & saturation, double & value)
{ {
ok_color::HSV color = ok_color::srgb_to_okhsv({ static_cast<float>(red) / 255.F, ok_color::HSV color = ok_color::srgb_to_okhsv({ static_cast<double>(red) / 255.0,
static_cast<float>(green) / 255.F, static_cast<double>(green) / 255.0,
static_cast<float>(blue) / 255.F static_cast<double>(blue) / 255.0
}); });
hue = color.h; hue = color.h;
saturation = color.s; saturation = color.s;
@ -71,8 +76,9 @@ void ColorSys::rgb2okhsv(uint8_t red, uint8_t green, uint8_t blue, double & hue,
void ColorSys::okhsv2rgb(double hue, double saturation, double value, uint8_t & red, uint8_t & green, uint8_t & blue) void ColorSys::okhsv2rgb(double hue, double saturation, double value, uint8_t & red, uint8_t & green, uint8_t & blue)
{ {
ok_color::RGB color = ok_color::okhsv_to_srgb({ static_cast<float>(hue), static_cast<float>(saturation), static_cast<float>(value) }); ok_color::RGB color = ok_color::okhsv_to_srgb({ hue, saturation, value });
red = static_cast<uint8_t>(std::lround(color.r * 255)); // okhsv_to_srgb can output rgb colors with slightly negative components. Clamping them before casting prevents rollover errors
green = static_cast<uint8_t>(std::lround(color.g * 255)); red = static_cast<uint8_t>(std::lround(clamp(color.r) * 255.0));
blue = static_cast<uint8_t>(std::lround(color.b * 255)); green = static_cast<uint8_t>(std::lround(clamp(color.g) * 255.0));
blue = static_cast<uint8_t>(std::lround(clamp(color.b) * 255.0));
} }

View File

@ -4,7 +4,7 @@
#include <utils/ColorSys.h> #include <utils/ColorSys.h>
/// Clamps between 0.f and 1.f. Should generally be branchless /// Clamps between 0.f and 1.f. Should generally be branchless
double clamp(double value) inline double clamp(double value)
{ {
return std::max(0.0, std::min(value, 1.0)); return std::max(0.0, std::min(value, 1.0));
} }