From fcebc451c295fc761002ebd1d5851bbb3a43315d Mon Sep 17 00:00:00 2001 From: Ell Date: Mon, 18 May 2020 09:53:58 +0300 Subject: [PATCH] HSV, HSL, HCY: wrap hue around during conversion to RGB In the conversions from HSV, HSL, and HCY to RGB, wrap the hue value around to the [0,1) range, instead of producing unspecified results outside this range. In particular, hue=1.0 may arise when going through lower precision, such as when decomposing/recomposing an 8-bit image in GIMP (see gimp#5097). --- extensions/HCY.c | 7 +++++-- extensions/HSL.c | 3 +++ extensions/HSV.c | 6 +++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/extensions/HCY.c b/extensions/HCY.c index e352290..31cb8b4 100644 --- a/extensions/HCY.c +++ b/extensions/HCY.c @@ -232,8 +232,11 @@ hcy_to_rgba_step (char *src, if(chroma < EPSILON) { red = green = blue = luma; } else { - hue *= 6.; - H_sec = (int)hue; + hue = fmod (hue, 1.0); + hue += hue < 0.0; + hue *= 6.0; + + H_sec = (int) hue; switch (H_sec) { diff --git a/extensions/HSL.c b/extensions/HSL.c index 0cd1daa..bf48f34 100644 --- a/extensions/HSL.c +++ b/extensions/HSL.c @@ -251,6 +251,9 @@ hsl_to_rgb_step (double *src, double p = 2 * lightness - q; + hue = fmod (hue, 1.0); + hue += hue < 0.0; + red = hue2cpn (p, q, hue + 1.0/3.0); green = hue2cpn (p, q, hue); blue = hue2cpn (p, q, hue - 1.0/3.0); diff --git a/extensions/HSV.c b/extensions/HSV.c index 5659386..ad2e002 100644 --- a/extensions/HSV.c +++ b/extensions/HSV.c @@ -242,7 +242,11 @@ hsv_to_rgba_step (char *src, double chroma, h_tmp, x, min; chroma = saturation * value; - h_tmp = hue * 6.0; + + h_tmp = fmod (hue, 1.0); + h_tmp += h_tmp < 0.0; + h_tmp *= 6.0; + x = chroma * (1.0 - fabs (fmod (h_tmp, 2.0) - 1.0)); if (h_tmp < 1.0) -- 2.30.2