diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2025-06-06 12:08:15 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2025-06-06 12:08:15 +1000 |
commit | 1a800b67d74c409fd2e4b6c11e04548b5bf5d999 (patch) | |
tree | 765634fbd5709cd48ccbc05c1852d4a9042fceb9 | |
parent | bf79b358c0e0224fb06e35a0286ef10671f0d075 (diff) |
attempt at improving GCC ?saturation accuracy
[skip ci]
-rw-r--r-- | source/core/StarColor.cpp | 18 | ||||
-rw-r--r-- | source/core/StarColor.hpp | 4 | ||||
-rw-r--r-- | 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<ImageOperation> 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<SaturationShiftImageOperation>()) { - 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<BrightnessMultiplyImageOperation>()) { image.forEachPixel([&op](unsigned, unsigned, Vec4B& pixel) { if (pixel[3] != 0) { |