diff mbox series

[vsp-tests,08/16] gen-image: Don't copy CSC conversion matrix

Message ID 20250409004758.11014-9-laurent.pinchart@ideasonboard.com (mailing list archive)
State New
Delegated to: Geert Uytterhoeven
Headers show
Series Add color space conversion test | expand

Commit Message

Laurent Pinchart April 9, 2025, 12:47 a.m. UTC
Merge the csc_matrix() function into image_convert_rgb_to_yuv() to avoid
unnecessary copies of the matrix.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/gen-image.c | 105 +++++++++++++++++++++---------------------------
 1 file changed, 46 insertions(+), 59 deletions(-)
diff mbox series

Patch

diff --git a/src/gen-image.c b/src/gen-image.c
index d2d4870a699a..2f854634a986 100644
--- a/src/gen-image.c
+++ b/src/gen-image.c
@@ -758,9 +758,37 @@  static void image_convert_rgb_to_rgb(const struct image *input,
 }
 
 /* RGB to YUV */
-static void csc_matrix(enum v4l2_ycbcr_encoding encoding,
-		       enum v4l2_quantization quantization,
-		       int (*matrix)[3][3])
+static void csc_rgb_to_yuv(const int ccm[3][3], bool full_range,
+			   const uint8_t rgb[3], uint8_t ycbcr[3])
+{
+	int y_min = full_range ? 0 : 16;
+	int y_max = full_range ? 255 : 235;
+	int cbcr_min = full_range ? 0 : 16;
+	int cbcr_max = full_range ? 255 : 240;
+	int div = 1 << 11;
+	int r, g, b;
+	int y, cb, cr;
+
+	r = rgb[0];
+	g = rgb[1];
+	b = rgb[2];
+
+	y  = (ccm[0][0] * r + ccm[0][1] * g + ccm[0][2] * b + y_min * div + div / 2) / div;
+	cb = (ccm[1][0] * r + ccm[1][1] * g + ccm[1][2] * b + 128 * div + div / 2) / div;
+	cr = (ccm[2][0] * r + ccm[2][1] * g + ccm[2][2] * b + 128 * div + div / 2) / div;
+
+#define CLAMP(x, low, high) \
+	((x) < (low) ? (low) : ( (x) > (high) ? (high) : (x) ))
+
+	ycbcr[0] = CLAMP(y, y_min, y_max);
+	ycbcr[1] = CLAMP(cb, cbcr_min, cbcr_max);
+	ycbcr[2] = CLAMP(cr, cbcr_min, cbcr_max);
+}
+
+static void image_convert_rgb_to_yuv(const struct image *input,
+				     struct image *output,
+				     const struct format_info *format,
+				     const struct csc_params *params)
 {
 	/*
 	 * The value of the coefficients has been reverse-engineered by
@@ -802,76 +830,35 @@  static void csc_matrix(enum v4l2_ycbcr_encoding encoding,
 		{  1047, -951, -96   },
 	};
 
-	bool full = quantization == V4L2_QUANTIZATION_FULL_RANGE;
-	unsigned int i;
-	const int (*m)[3][3];
-
-	switch (encoding) {
-	case V4L2_YCBCR_ENC_601:
-	default:
-		m = full ? &bt601_full : &bt601;
-		break;
-	case V4L2_YCBCR_ENC_709:
-		m = full ? &rec709_full : &rec709;
-		break;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(*m); ++i)
-		memcpy((*matrix)[i], (*m)[i], sizeof((*m)[i]));
-}
-
-static void csc_rgb_to_yuv(int m[3][3], enum v4l2_quantization quantization,
-			   const uint8_t rgb[3], uint8_t ycbcr[3])
-{
-	bool full = quantization == V4L2_QUANTIZATION_FULL_RANGE;
-	int y_min = full ? 0 : 16;
-	int y_max = full ? 255 : 235;
-	int cbcr_min = full ? 0 : 16;
-	int cbcr_max = full ? 255 : 240;
-	int div = 1 << 11;
-	int r, g, b;
-	int y, cb, cr;
-
-	r = rgb[0];
-	g = rgb[1];
-	b = rgb[2];
-
-	y  = (m[0][0] * r + m[0][1] * g + m[0][2] * b + y_min * div + div / 2) / div;
-	cb = (m[1][0] * r + m[1][1] * g + m[1][2] * b + 128 * div + div / 2) / div;
-	cr = (m[2][0] * r + m[2][1] * g + m[2][2] * b + 128 * div + div / 2) / div;
-
-#define CLAMP(x, low, high) \
-	((x) < (low) ? (low) : ( (x) > (high) ? (high) : (x) ))
-
-	ycbcr[0] = CLAMP(y, y_min, y_max);
-	ycbcr[1] = CLAMP(cb, cbcr_min, cbcr_max);
-	ycbcr[2] = CLAMP(cr, cbcr_min, cbcr_max);
-}
-
-static void image_convert_rgb_to_yuv(const struct image *input,
-				     struct image *output,
-				     const struct format_info *format,
-				     const struct csc_params *params)
-{
-	int matrix[3][3];
+	bool full_range = params->quantization == V4L2_QUANTIZATION_FULL_RANGE;
+	const int (*matrix)[3][3];
 	const uint8_t *idata = input->data;
 	uint8_t *odata = output->data;
 	unsigned int x;
 	unsigned int y;
 
-	csc_matrix(params->encoding, params->quantization, &matrix);
+	switch (params->encoding) {
+	case V4L2_YCBCR_ENC_601:
+	default:
+		matrix = full_range ? &bt601_full : &bt601;
+		break;
+	case V4L2_YCBCR_ENC_709:
+		matrix = full_range ? &rec709_full : &rec709;
+		break;
+	}
 
 	for (y = 0; y < output->height; ++y) {
-		for (x = 0; x < output->width; ++x) {
-			csc_rgb_to_yuv(matrix, params->quantization,
+		for (x = 0; x < output->width; ++x)
+			csc_rgb_to_yuv(*matrix, full_range,
 				       &idata[3*x], &odata[3*x]);
-		}
+
 		if (format->yuv.xsub == 2) {
 			for (x = 1; x < output->width - 1; x += 2) {
 				odata[3*x + 1] = (odata[3*(x-1) + 1] + odata[3*(x+1) + 1]) / 2;
 				odata[3*x + 2] = (odata[3*(x-1) + 2] + odata[3*(x+1) + 2]) / 2;
 			}
 		}
+
 		idata += 3 * output->width;
 		odata += 3 * output->width;
 	}