hsv to rgb and vice versa functions - randomcrap - random crap programs of varying quality
 (HTM) git clone git://git.codemadness.org/randomcrap
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d15b0b1cff53d00bd6ce18c9744c3250138e8aa9
 (DIR) parent 70c955341f0ad64c911cbe4004f2416e51e4ae84
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Tue, 13 Feb 2024 20:35:51 +0100
       
       hsv to rgb and vice versa functions
       
       Diffstat:
         A hsv.c                               |     105 +++++++++++++++++++++++++++++++
       
       1 file changed, 105 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/hsv.c b/hsv.c
       @@ -0,0 +1,105 @@
       +/* HSV to RGB and vice versa.
       +   Adapted from https://github.com/python/cpython/blob/3.9/Lib/colorsys.py */
       +#include <stdio.h>
       +
       +/* input and output is in range 0.0 to 1.0 */
       +void
       +rgbtohsv(double r, double g, double b, double *h, double *s, double *v)
       +{
       +        double minc, maxc, rc, gc, bc;
       +
       +        minc = maxc = r;
       +        if (g > maxc)
       +                maxc = g;
       +        if (b > maxc)
       +                maxc = b;
       +
       +        if (g < minc)
       +                minc = g;
       +        if (b < minc)
       +                minc = b;
       +
       +        *v = maxc;
       +        if (minc == maxc) {
       +                *h = *s = 0.0;
       +                return;
       +        }
       +
       +        *s = (maxc - minc) / maxc;
       +        rc = (maxc - r) / (maxc - minc);
       +        gc = (maxc - g) / (maxc - minc);
       +        bc = (maxc - b) / (maxc - minc);
       +
       +        if (r == maxc)
       +                *h = bc - bc;
       +        else if (g == maxc)
       +                *h = 2.0 + rc - bc;
       +        else
       +                *h = 4.0 + gc - rc;
       +
       +        *h = (*h / 6.0);
       +        /* truncate / mod 1.0, similar to fmod() */
       +        *h = *h - ((double)(int)*h); 
       +}
       +
       +/* input and output is in range 0.0 to 1.0 */
       +void
       +hsvtorgb(double h, double s, double v, double *r, double *g, double *b)
       +{
       +        double f, p, q, t;
       +        int i;
       +
       +        if (s == 0.0) {
       +                *r = *g = *b = v;
       +                return;
       +        }
       +
       +        i = h * 6.0; /* truncates to int */
       +        f = (h * 6.0) - i;
       +        p = v * (1.0 - s);
       +        q = v * (1.0 - s * f);
       +        t = v * (1.0 - s * (1.0 - f));
       +        i = i % 6;
       +
       +        switch (i) {
       +        case 0:        *r = v; *g = t;        *b = p; break;
       +        case 1:        *r = q;        *g = v;        *b = p;        break;
       +        case 2:        *r = p;        *g = v;        *b = t;        break;
       +        case 3:        *r = p;        *g = q;        *b = v;        break;
       +        case 4:        *r = t;        *g = p;        *b = v;        break;
       +        default:*r = v;        *g = p;        *b = q;        break;
       +        }
       +}
       +
       +int
       +main(void)
       +{
       +        double r, g, b;
       +        double h, s, v;
       +
       +        h = 156.3;
       +        s = 100.0;
       +        v = 100.0;
       +
       +        /* convert to range 0.0 - 1.0 */
       +        h /= 360.0;
       +        s /= 100.0;
       +        v /= 100.0;
       +
       +        hsvtorgb(h, s, v, &r, &g, &b);
       +
       +        printf("#%02x%02x%02x\n", (int)(r * 255.0), (int)(g * 255.0), (int)(b * 255.0));
       +
       +        r = 0.0;
       +        g = 255.0;
       +        b = 154.1;
       +
       +        r /= 255.0;
       +        g /= 255.0;
       +        b /= 255.0;
       +
       +        rgbtohsv(r, g, b, &h, &s, &v);
       +        printf("hsv: (%f, %f, %f)\n", h * 360.0, s * 100.0, v * 100.0);
       +
       +        return 0;
       +}