[Bf-blender-cvs] [1fdaf58] master: Optimisation to rgb <-> hsv/l conversion

Antony Riakiotakis noreply at git.blender.org
Mon Jul 21 09:26:43 CEST 2014


Commit: 1fdaf5862feab049d6e8e60cd5f1469a17b9cda5
Author: Antony Riakiotakis
Date:   Mon Jul 21 09:26:39 2014 +0200
Branches: master
https://developer.blender.org/rB1fdaf5862feab049d6e8e60cd5f1469a17b9cda5

Optimisation to rgb <-> hsv/l conversion

Basically avoid redundant computations. Gives ~1-4% speedup in the compositor depending on the use case.

For more info see: http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv

Reviewers: psy-fi, sergey

Subscribers: campbellbarton

Differential Revision: https://developer.blender.org/D596

===================================================================

M	source/blender/blenlib/intern/math_color.c

===================================================================

diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 57a48bb..3dd8aab 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -37,112 +37,38 @@
 
 void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b)
 {
-	if (s != 0.0f) {
-		float i, f, p;
-		h = (h - floorf(h)) * 6.0f;
-
-		i = floorf(h);
-		f = h - i;
-
-		/* avoid computing q/t when not needed */
-		p = (v * (1.0f - s));
-#define q   (v * (1.0f - (s * f)))
-#define t   (v * (1.0f - (s * (1.0f - f))))
-
-		/* faster to compare floats then int conversion */
-		if (i < 1.0f) {
-			*r = v;
-			*g = t;
-			*b = p;
-		}
-		else if (i < 2.0f) {
-			*r = q;
-			*g = v;
-			*b = p;
-		}
-		else if (i < 3.0f) {
-			*r = p;
-			*g = v;
-			*b = t;
-		}
-		else if (i < 4.0f) {
-			*r = p;
-			*g = q;
-			*b = v;
-		}
-		else if (i < 5.0f) {
-			*r = t;
-			*g = p;
-			*b = v;
-		}
-		else {
-			*r = v;
-			*g = p;
-			*b = q;
-		}
+	float nr, ng, nb;
 
-#undef q
-#undef t
+	nr =        fabsf(h * 6.0f - 3.0f) - 1.0f;
+	ng = 2.0f - fabsf(h * 6.0f - 2.0f);
+	nb = 2.0f - fabsf(h * 6.0f - 4.0f);
 
-	}
-	else {
-		*r = v;
-		*g = v;
-		*b = v;
-	}
+	CLAMP(nr, 0.0f, 1.0f);
+	CLAMP(nb, 0.0f, 1.0f);
+	CLAMP(ng, 0.0f, 1.0f);
+
+	*r = ((nr - 1.0f) * s + 1.0f) * v;
+	*g = ((ng - 1.0f) * s + 1.0f) * v;
+	*b = ((nb - 1.0f) * s + 1.0f) * v;
 }
 
-/* HSL to rgb conversion from https://en.wikipedia.org/wiki/HSL_and_HSV */
 void hsl_to_rgb(float h, float s, float l, float *r, float *g, float *b)
 {
-	float i, f, c;
-	h = (h - floorf(h)) * 6.0f;
-	c = (l > 0.5f) ? (2.0f * (1.0f - l) * s) : (2.0f * l * s);
-	i = floorf(h);
-	f = h - i;
+	float nr, ng, nb, chroma;
 
-#define x2 (c * f)
-#define x1 (c * (1.0f - f))
+	nr =        fabsf(h * 6.0f - 3.0f) - 1.0f;
+	ng = 2.0f - fabsf(h * 6.0f - 2.0f);
+	nb = 2.0f - fabsf(h * 6.0f - 4.0f);
 
-	/* faster to compare floats then int conversion */
-	if (i < 1.0f) {
-		*r = c;
-		*g = x2;
-		*b = 0;
-	}
-	else if (i < 2.0f) {
-		*r = x1;
-		*g = c;
-		*b = 0;
-	}
-	else if (i < 3.0f) {
-		*r = 0;
-		*g = c;
-		*b = x2;
-	}
-	else if (i < 4.0f) {
-		*r = 0;
-		*g = x1;
-		*b = c;
-	}
-	else if (i < 5.0f) {
-		*r = x2;
-		*g = 0;
-		*b = c;
-	}
-	else {
-		*r = c;
-		*g = 0;
-		*b = x1;
-	}
+	CLAMP(nr, 0.0f, 1.0f);
+	CLAMP(nb, 0.0f, 1.0f);
+	CLAMP(ng, 0.0f, 1.0f);
 
-#undef x1
-#undef x2
+	chroma = (1.0f - fabsf(2.0f * l - 1.0f)) * s;
 
-	f = l - 0.5f * c;
-	*r += f;
-	*g += f;
-	*b += f;
+	*r = (nr - 0.5f) * chroma + l;
+	*g = (ng - 0.5f) * chroma + l;
+	*b = (nb - 0.5f) * chroma + l;
 }
 
 /* convenience function for now */
@@ -284,57 +210,23 @@ void hex_to_rgb(char *hexcol, float *r, float *g, float *b)
 
 void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv)
 {
-	float h, s, v;
-	float cmax, cmin;
-
-	cmax = r;
-	cmin = r;
-	cmax = (g > cmax ? g : cmax);
-	cmin = (g < cmin ? g : cmin);
-	cmax = (b > cmax ? b : cmax);
-	cmin = (b < cmin ? b : cmin);
-
-	v = cmax; /* value */
-	if (cmax != 0.0f) {
-		float cdelta;
-
-		cdelta = cmax - cmin;
-		s = cdelta / cmax;
-
-		if (s != 0.0f) {
-			float rc, gc, bc;
-
-			rc = (cmax - r) / cdelta;
-			gc = (cmax - g) / cdelta;
-			bc = (cmax - b) / cdelta;
-
-			if (r == cmax) {
-				h = bc - gc;
-				if (h < 0.0f) {
-					h += 6.0f;
-				}
-			}
-			else if (g == cmax) {
-				h = 2.0f + rc - bc;
-			}
-			else {
-				h = 4.0f + gc - rc;
-			}
-
-			h *= (1.0f / 6.0f);
-		}
-		else {
-			h = 0.0f;
-		}
+	float k = 0.0f;
+	float chroma;
+
+	if (g < b) {
+		SWAP(float, g, b);
+		k = -1.0f;
 	}
-	else {
-		h = 0.0f;
-		s = 0.0f;
+	if (r < g) {
+		SWAP(float, r, g);
+		k = -2.0f * 6e-1f - k;
 	}
 
-	*lh = h;
-	*ls = s;
-	*lv = v;
+	chroma = r - min_ff(g, b);
+
+	*lh = fabsf(k + (g - b) / (6.0f * chroma + 1e-20f));
+	*ls = chroma / (r + 1e-20f);
+	*lv = r;
 }
 
 /* convenience function for now */




More information about the Bf-blender-cvs mailing list