[Bf-blender-cvs] [128506eeb1a] master: BLI Color: YUV to/from rgb colorspace option

Aaron Carlisle noreply at git.blender.org
Mon Apr 30 00:01:02 CEST 2018


Commit: 128506eeb1a2d87393061b4c9783289a5e4b3275
Author: Aaron Carlisle
Date:   Sun Apr 29 18:00:45 2018 -0400
Branches: master
https://developer.blender.org/rB128506eeb1a2d87393061b4c9783289a5e4b3275

BLI Color: YUV to/from rgb colorspace option

This commit does two things:

- Adds an option to do the calculation in different color spaces (BT601
or BT709).
- Changes the default caluclation from legacy BT601 to BT709.

This affects several areas:

- UI areas (mainly scopes)
- ViewLevelsNode
- Several other nodes that use `COM_ConvertOperation.h`

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

M	source/blender/blenkernel/intern/colortools.c
M	source/blender/blenlib/BLI_math_color.h
M	source/blender/blenlib/intern/math_color.c
M	source/blender/compositor/operations/COM_CalculateMeanOperation.cpp
M	source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp
M	source/blender/compositor/operations/COM_ConvertOperation.cpp
M	source/blender/editors/interface/interface_draw.c
M	source/blender/editors/space_image/image_draw.c
M	tests/gtests/blenlib/BLI_math_color_test.cc

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

diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 0fe429312db..e7fa4cee587 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1034,7 +1034,7 @@ static void save_sample_line(Scopes *scopes, const int idx, const float fx, cons
 	float yuv[3];
 
 	/* vectorscope*/
-	rgb_to_yuv(rgb[0], rgb[1], rgb[2], &yuv[0], &yuv[1], &yuv[2]);
+	rgb_to_yuv(rgb[0], rgb[1], rgb[2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709);
 	scopes->vecscope[idx + 0] = yuv[1];
 	scopes->vecscope[idx + 1] = yuv[2];
 
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 34fc52c12c0..72d29164988 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -51,6 +51,10 @@ extern "C" {
 #define BLI_YCC_ITU_BT709   1
 #define BLI_YCC_JFIF_0_255  2
 
+/* YUV */
+#define BLI_YUV_ITU_BT601   0
+#define BLI_YUV_ITU_BT709   1
+
 /******************* Conversion to RGB ********************/
 
 void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
@@ -58,14 +62,14 @@ void hsv_to_rgb_v(const float hsv[3], float r_rgb[3]);
 void hsl_to_rgb(float h, float c, float l, float *r, float *g, float *b);
 void hsl_to_rgb_v(const float hcl[3], float r_rgb[3]);
 void hex_to_rgb(char *hexcol, float *r, float *g, float *b);
-void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
+void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb, int colorspace);
 void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, int colorspace);
 void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b, int colorspace);
 void cpack_to_rgb(unsigned int col, float *r, float *g, float *b);
 
 /***************** Conversion from RGB ********************/
 
-void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv);
+void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv, int colorspace);
 void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, int colorspace);
 void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
 void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]);
@@ -164,4 +168,3 @@ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *o
 #endif
 
 #endif /* __BLI_MATH_COLOR_H__ */
-
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 6d7d24c79c3..a091595bc6c 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -83,24 +83,45 @@ void hsl_to_rgb_v(const float hsl[3], float r_rgb[3])
 	hsl_to_rgb(hsl[0], hsl[1], hsl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
 }
 
-void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv)
+void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv, int colorspace)
 {
 	float y, u, v;
-	y = 0.299f * r + 0.587f * g + 0.114f * b;
-	u = -0.147f * r - 0.289f * g + 0.436f * b;
-	v = 0.615f * r - 0.515f * g - 0.100f * b;
+
+	switch (colorspace) {
+		case BLI_YUV_ITU_BT601:
+			y = 0.299f * r + 0.587f * g + 0.114f * b;
+			u = -0.147f * r - 0.289f * g + 0.436f * b;
+			v = 0.615f * r - 0.515f * g - 0.100f * b;
+			break;
+		case BLI_YUV_ITU_BT709:
+		default:
+			y = 0.2126f * r + 0.7152f * g + 0.0722f * b;
+			u = -0.09991f * r - 0.33609f * g + 0.436f * b;
+			v = 0.615f * r - 0.55861f * g - 0.05639f * b;
+			break;
+	}
 
 	*ly = y;
 	*lu = u;
 	*lv = v;
 }
 
-void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb)
+void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb, int colorspace)
 {
 	float r, g, b;
-	r = y + 1.140f * v;
-	g = y - 0.394f * u - 0.581f * v;
-	b = y + 2.032f * u;
+
+	switch (colorspace) {
+		case BLI_YUV_ITU_BT601:
+			r = y + 1.140f * v;
+			g = y - 0.394f * u - 0.581f * v;
+			b = y + 2.032f * u;
+			break;
+		case BLI_YUV_ITU_BT709:
+			r = y + 1.28033f * v;
+			g = y - 0.21482f * u - 0.38059f * v;
+			b = y + 2.12798f * u;
+			break;
+	}
 
 	*lr = r;
 	*lg = g;
diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp
index d26dcd17750..ecbc7a9a93d 100644
--- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp
+++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp
@@ -121,7 +121,7 @@ void CalculateMeanOperation::calculateMean(MemoryBuffer *tile)
 				case 5:
 				{
 					float yuv[3];
-					rgb_to_yuv(buffer[offset], buffer[offset + 1], buffer[offset + 2], &yuv[0], &yuv[1], &yuv[2]);
+					rgb_to_yuv(buffer[offset], buffer[offset + 1], buffer[offset + 2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709);
 					sum += yuv[0];
 					break;
 				}
diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp
index 6b238e53d7b..56b402f2b3b 100644
--- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp
+++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp
@@ -87,7 +87,7 @@ void *CalculateStandardDeviationOperation::initializeTileData(rcti *rect)
 					case 5:  /* luminance */
 					{
 						float yuv[3];
-						rgb_to_yuv(buffer[offset], buffer[offset + 1], buffer[offset + 2], &yuv[0], &yuv[1], &yuv[2]);
+						rgb_to_yuv(buffer[offset], buffer[offset + 1], buffer[offset + 2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709);
 						sum += (yuv[0] - mean) * (yuv[0] - mean);
 						break;
 					}
diff --git a/source/blender/compositor/operations/COM_ConvertOperation.cpp b/source/blender/compositor/operations/COM_ConvertOperation.cpp
index 8b8e8408208..327015c1139 100644
--- a/source/blender/compositor/operations/COM_ConvertOperation.cpp
+++ b/source/blender/compositor/operations/COM_ConvertOperation.cpp
@@ -241,7 +241,7 @@ void ConvertRGBToYUVOperation::executePixelSampled(float output[4], float x, flo
 {
 	float inputColor[4];
 	this->m_inputOperation->readSampled(inputColor, x, y, sampler);
-	rgb_to_yuv(inputColor[0], inputColor[1], inputColor[2], &output[0], &output[1], &output[2]);
+	rgb_to_yuv(inputColor[0], inputColor[1], inputColor[2], &output[0], &output[1], &output[2], BLI_YUV_ITU_BT709);
 	output[3] = inputColor[3];
 }
 
@@ -258,7 +258,7 @@ void ConvertYUVToRGBOperation::executePixelSampled(float output[4], float x, flo
 {
 	float inputColor[4];
 	this->m_inputOperation->readSampled(inputColor, x, y, sampler);
-	yuv_to_rgb(inputColor[0], inputColor[1], inputColor[2], &output[0], &output[1], &output[2]);
+	yuv_to_rgb(inputColor[0], inputColor[1], inputColor[2], &output[0], &output[1], &output[2], BLI_YUV_ITU_BT709);
 	output[3] = inputColor[3];
 }
 
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 9a05c12e00a..7583dc654bb 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -831,7 +831,7 @@ static void vectorscope_draw_target(float centerx, float centery, float diam, co
 	float tangle = 0.f, tampli;
 	float dangle, dampli, dangle2, dampli2;
 
-	rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v);
+	rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v, BLI_YUV_ITU_BT709);
 	if (u > 0 && v >= 0) tangle = atanf(v / u);
 	else if (u > 0 && v < 0) tangle = atanf(v / u) + 2.0f * (float)M_PI;
 	else if (u < 0) tangle = atanf(v / u) + (float)M_PI;
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 4d4beb07f00..594938b82aa 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -360,11 +360,11 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
 	if (channels == 1) {
 		if (fp) {
 			rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val);
-			rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v);
+			rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v, BLI_YUV_ITU_BT709);
 		}
 		else if (cp) {
 			rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &hue, &sat, &val);
-			rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &lum, &u, &v);
+			rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &lum, &u, &v, BLI_YUV_ITU_BT709);
 		}
 		
 		BLI_snprintf(str, sizeof(str), "V:%-.4f", val);
@@ -379,7 +379,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
 	}
 	else if (channels >= 3) {
 		rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val);
-		rgb_to_yuv(finalcol[0], finalcol[1], finalcol[2], &lum, &u, &v);
+		rgb_to_yuv(finalcol[0], finalcol[1], finalcol[2], &lum, &u, &v, BLI_YUV_ITU_BT709);
 
 		BLI_snprintf(str, sizeof(str), "H:%-.4f", hue);
 		BLF_position(blf_mono_font, dx, dy, 0);
diff --git a/tests/gtests/blenlib/BLI_math_color_test.cc b/tests/gtests/blenlib/BLI_math_color_test.cc
index 2118822a9d8..8989e6740a5 100644
--- a/tests/gtests/blenlib/BLI_math_color_test.cc
+++ b/tests/gtests/blenlib/BLI_math_color_test.cc
@@ -27,9 +27,9 @@ TEST(math_color, RGBToYUVRoundtrip)
 	float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
 	float yuv[3], rgb[3];
 	rgb_to_yuv(orig_rgb[0], orig_rgb[1], orig_rgb[2],
-	           &yuv[0], &yuv[1], &yuv[2]);
+	           &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709);
 	yuv_to_rgb(yuv[0], yuv[1], yuv[2],
-	           &rgb[0], &rgb[1], &rgb[2]);
+	           &rgb[0], &rgb[1], &rgb[2], BLI_YUV_ITU_BT709);
 	EXPECT_V3_NEAR(orig_rgb, rgb, 1e-4);
 }



More information about the Bf-blender-cvs mailing list