From 1a800b67d74c409fd2e4b6c11e04548b5bf5d999 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 6 Jun 2025 12:08:15 +1000 Subject: attempt at improving GCC ?saturation accuracy [skip ci] --- source/core/StarColor.cpp | 18 +++++++++--------- source/core/StarColor.hpp | 4 ++-- source/core/StarImageProcessing.cpp | 27 ++++++++++++++++++++------- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/source/core/StarColor.cpp b/source/core/StarColor.cpp index cab4b4f..4238d1d 100644 --- a/source/core/StarColor.cpp +++ b/source/core/StarColor.cpp @@ -324,7 +324,7 @@ Vec3F Color::toRgbF() const { #ifdef __GNUC__ #pragma GCC push_options -#pragma GCC optimize("-fno-fast-math") +#pragma GCC optimize("-fno-fast-math -fassociative-math -freciprocal-math") #endif Vec4F Color::toHsva() const { float h, s, v; @@ -369,14 +369,6 @@ Vec4F Color::toHsva() const { return Vec4F(h, s, v, alphaF()); } -#ifdef __GNUC__ -#pragma GCC pop_options -#endif - -String Color::toHex() const { - auto rgba = toRgba(); - return hexEncode((char*)rgba.ptr(), rgba[3] == 255 ? 3 : 4); -} float Color::hue() const { return toHsva()[0]; @@ -401,6 +393,9 @@ float Color::saturation() const { float Color::value() const { return max(max(m_data[0], m_data[1]), m_data[2]); } +#ifdef __GNUC__ +#pragma GCC pop_options +#endif void Color::setHue(float h) { auto hsva = toHsva(); @@ -453,6 +448,11 @@ float Color::fromLinear(float in) { return (1.0f + a) * powf(in, 1.0f / 2.4f) - a; } +String Color::toHex() const { + auto rgba = toRgba(); + return hexEncode((char*)rgba.ptr(), rgba[3] == 255 ? 3 : 4); +} + void Color::convertToLinear() { setRedF(toLinear(redF())); setGreenF(toLinear(greenF())); diff --git a/source/core/StarColor.hpp b/source/core/StarColor.hpp index 47e6896..e93629e 100644 --- a/source/core/StarColor.hpp +++ b/source/core/StarColor.hpp @@ -107,8 +107,6 @@ public: Vec4F toHsva() const; - String toHex() const; - float hue() const; float saturation() const; float value() const; @@ -123,6 +121,8 @@ public: // Reduce the color toward black by the given amount, from 0.0 to 1.0. void fade(float value); + String toHex() const; + void convertToLinear(); void convertToSRGB(); diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index 1cfd847..b18fcf1 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -354,6 +354,25 @@ StringList imageOperationReferences(List const& operations) { return references; } +#ifdef __GNUC__ +#pragma GCC push_options +#pragma GCC optimize("-fno-fast-math -fassociative-math -freciprocal-math") +#endif +static void processSaturationShift(Image& image, SaturationShiftImageOperation const* op) { + image.forEachPixel([&op](unsigned, unsigned, Vec4B& pixel) { + if (pixel[3] != 0) { + Color color = Color::rgba(pixel); + color.setSaturation(clamp(color.saturation() + op->saturationShiftAmount, 0.0f, 1.0f)); + pixel = color.toRgba(); + } + }); +} +#ifdef __GNUC__ +#pragma GCC pop_options +#endif + + + void processImageOperation(ImageOperation const& operation, Image& image, ImageReferenceCallback refCallback) { if (image.bytesPerPixel() == 3) { // Convert to an image format that has alpha so certain operations function properly @@ -365,13 +384,7 @@ void processImageOperation(ImageOperation const& operation, Image& image, ImageR pixel = Color::hueShiftVec4B(pixel, op->hueShiftAmount); }); } else if (auto op = operation.ptr()) { - image.forEachPixel([&op](unsigned, unsigned, Vec4B& pixel) { - if (pixel[3] != 0) { - Color color = Color::rgba(pixel); - color.setSaturation(clamp(color.saturation() + op->saturationShiftAmount, 0.0f, 1.0f)); - pixel = color.toRgba(); - } - }); + processSaturationShift(image, op); } else if (auto op = operation.ptr()) { image.forEachPixel([&op](unsigned, unsigned, Vec4B& pixel) { if (pixel[3] != 0) { -- cgit v1.2.3