hsv.c - 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
       ---
       hsv.c (1886B)
       ---
            1 /* HSV to RGB and vice versa.
            2    Adapted from https://github.com/python/cpython/blob/3.9/Lib/colorsys.py */
            3 #include <stdio.h>
            4 
            5 /* input and output is in range 0.0 to 1.0 */
            6 void
            7 rgbtohsv(double r, double g, double b, double *h, double *s, double *v)
            8 {
            9         double minc, maxc, rc, gc, bc;
           10 
           11         minc = maxc = r;
           12         if (g > maxc)
           13                 maxc = g;
           14         if (b > maxc)
           15                 maxc = b;
           16 
           17         if (g < minc)
           18                 minc = g;
           19         if (b < minc)
           20                 minc = b;
           21 
           22         *v = maxc;
           23         if (minc == maxc) {
           24                 *h = *s = 0.0;
           25                 return;
           26         }
           27 
           28         *s = (maxc - minc) / maxc;
           29         rc = (maxc - r) / (maxc - minc);
           30         gc = (maxc - g) / (maxc - minc);
           31         bc = (maxc - b) / (maxc - minc);
           32 
           33         if (r == maxc)
           34                 *h = bc - bc;
           35         else if (g == maxc)
           36                 *h = 2.0 + rc - bc;
           37         else
           38                 *h = 4.0 + gc - rc;
           39 
           40         *h = (*h / 6.0);
           41         /* truncate / mod 1.0, similar to fmod() */
           42         *h = *h - ((double)(int)*h); 
           43 }
           44 
           45 /* input and output is in range 0.0 to 1.0 */
           46 void
           47 hsvtorgb(double h, double s, double v, double *r, double *g, double *b)
           48 {
           49         double f, p, q, t;
           50         int i;
           51 
           52         if (s == 0.0) {
           53                 *r = *g = *b = v;
           54                 return;
           55         }
           56 
           57         i = h * 6.0; /* truncates to int */
           58         f = (h * 6.0) - i;
           59         p = v * (1.0 - s);
           60         q = v * (1.0 - s * f);
           61         t = v * (1.0 - s * (1.0 - f));
           62         i = i % 6;
           63 
           64         switch (i) {
           65         case 0:        *r = v; *g = t;        *b = p; break;
           66         case 1:        *r = q;        *g = v;        *b = p;        break;
           67         case 2:        *r = p;        *g = v;        *b = t;        break;
           68         case 3:        *r = p;        *g = q;        *b = v;        break;
           69         case 4:        *r = t;        *g = p;        *b = v;        break;
           70         default:*r = v;        *g = p;        *b = q;        break;
           71         }
           72 }
           73 
           74 int
           75 main(void)
           76 {
           77         double r, g, b;
           78         double h, s, v;
           79 
           80         h = 156.3;
           81         s = 100.0;
           82         v = 100.0;
           83 
           84         /* convert to range 0.0 - 1.0 */
           85         h /= 360.0;
           86         s /= 100.0;
           87         v /= 100.0;
           88 
           89         hsvtorgb(h, s, v, &r, &g, &b);
           90 
           91         printf("#%02x%02x%02x\n", (int)(r * 255.0), (int)(g * 255.0), (int)(b * 255.0));
           92 
           93         r = 0.0;
           94         g = 255.0;
           95         b = 154.1;
           96 
           97         r /= 255.0;
           98         g /= 255.0;
           99         b /= 255.0;
          100 
          101         rgbtohsv(r, g, b, &h, &s, &v);
          102         printf("hsv: (%f, %f, %f)\n", h * 360.0, s * 100.0, v * 100.0);
          103 
          104         return 0;
          105 }