Re: [AD] Faster hsv_to_rgb()

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Inspired by your efforts, I rearranged rgb_to_hsv() (conversion the other way) a bit. A call to the new version takes 60% of the time that a call to previous version took. I ran through all possible r,g,b triples, and it gives the same result to a factor within 0.0000001, and I also verified that converting back the hsv values computed by rgb_to_hsv() always gives the original rgb. The patch is attached and I put my test program at http://peg.it.uu.se/~sven/test.c. OK to commit?
Sven
Index: src/color.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/color.c,v
retrieving revision 1.16
diff -u -r1.16 color.c
--- src/color.c	7 Feb 2003 13:29:06 -0000	1.16
+++ src/color.c	16 Apr 2003 20:40:06 -0000
@@ -383,36 +383,53 @@
  */
 void rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
 {
-   float min, max, delta, rc, gc, bc;
+   int delta;
 
-   rc = (float)r / 255.0f;
-   gc = (float)g / 255.0f;
-   bc = (float)b / 255.0f;
-   max = MAX(rc, MAX(gc, bc));
-   min = MIN(rc, MIN(gc, bc));
-   delta = max - min;
-   *v = max;
-
-   if (max != 0.0f)
-      *s = delta / max;
-   else
-      *s = 0.0f;
-
-   if (*s == 0.0f) {
-      *h = 0.0f; 
+   if (r > g) {
+      if (b > r) {
+	 /* b>r>g */
+	 delta = b-g;
+	 *h = 240.0f + ((r-g) * 60) / (float)delta;
+	 *s = (float)delta / (float)b;
+	 *v = (float)b * (1.0f/255.0f);
+      }
+      else {
+	 /* r>g and r>b */
+	 delta = r - MIN(g, b);
+	 *h = ((g-b) * 60) / (float)delta;
+	 if (*h < 0)
+	    *h += 360;
+	 *s = (float)delta / (float)r;
+	 *v = (float)r * (1/255.0f);
+      }
    }
    else {
-      if (rc == max)
-	 *h = (gc - bc) / delta;
-      else if (gc == max)
-	 *h = 2.0f + (bc - rc) / delta;
-      else if (bc == max)
-	 *h = 4.0f + (rc - gc) / delta;
-
-      *h *= 60.0f;
-      if (*h < 0.0f)
-	 *h += 360.0f;
-    }
+      if (b > g) {
+	 /* b>g>=r */
+	 delta = b-r;
+	 *h = 240.0 + ((r-g) * 60) / (float)delta;
+	 *s = (float)delta / (float)b;
+	 *v = (float)b * (1/255.0f);
+      }
+      else {
+	 /* g>=b and g>=r */
+	 delta = g - MIN(r, b);
+	 if (delta == 0) {
+	    *h = 0.0f;
+	    if (g == 0)
+	       *s = *v = 0;
+	    else {
+	       *s = (float)delta / (float)g;
+	       *v = (float)g * (1/255.0f);
+	    }
+	 }
+	 else {
+	    *h = 120.0 + ((b-r) * 60) / (float)delta;
+	    *s = (float)delta / (float)g;
+	    *v = (float)g * (1/255.0f);
+	 }
+      }
+   }
 }
 
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/