HSV, HSL, HCY: wrap hue around during conversion to RGB
authorEll <ell_se@yahoo.com>
Mon, 18 May 2020 06:53:58 +0000 (09:53 +0300)
committerEll <ell_se@yahoo.com>
Mon, 18 May 2020 06:59:11 +0000 (09:59 +0300)
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
extensions/HSL.c
extensions/HSV.c

index e35229010293cab23fd066f3fd7ac4a27881a594..31cb8b4ae3c045532e46c0280a3dbaf5f990fb31 100644 (file)
@@ -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)
     {
index 0cd1daa0ee7eb987b715f94cd910af71d71c3376..bf48f34c9a307fdf9c50eb8c42b77cfd61879905 100644 (file)
@@ -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);
index 5659386663b0ee3d4e7ff351d4753958fa1c4ca5..ad2e0020758c43763afd942467e8e48fcf8219d5 100644 (file)
@@ -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)