From 53b126801836114bc627514233152d01c84118cf Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 10 May 2022 11:12:38 +0300 Subject: [PATCH] tests/color_util: refactor into color_float_apply_matrix() Make process_pixel_using_pipeline() slightly easier to read by extracting a meaningful function. Pure refactoring, no behavioral changes. Compared to previous, flip the scalar multiplication around, so that it matches the mathematical order of matrix-vector multiplication. Also document the layout conventions for lcmsVEC3 and lcmsMAT3. These follow the convention used in LittleCMS for cmsVEC3 and cmsMAT3, and are necessary to understand to review the matrix-vector multiplication for correctness. Signed-off-by: Pekka Paalanen --- tests/color_util.c | 36 +++++++++++++++++++++++++----------- tests/color_util.h | 6 ++++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/tests/color_util.c b/tests/color_util.c index 66a23f3b..44d1e034 100644 --- a/tests/color_util.c +++ b/tests/color_util.c @@ -232,6 +232,29 @@ color_float_apply_curve(enum transfer_fn fn, struct color_float c) return c; } +/* + * Returns the result of the matrix-vector multiplication mat * c. + */ +struct color_float +color_float_apply_matrix(const struct lcmsMAT3 *mat, struct color_float c) +{ + struct color_float result; + unsigned i, j; + + /* + * The matrix has an array of columns, hence i indexes to rows and + * j indexes to columns. + */ + for (i = 0; i < 3; i++) { + result.rgb[i] = 0.0f; + for (j = 0; j < 3; j++) + result.rgb[i] += mat->v[j].n[i] * c.rgb[j]; + } + + result.a = c.a; + return result; +} + void process_pixel_using_pipeline(enum transfer_fn pre_curve, const struct lcmsMAT3 *mat, @@ -239,18 +262,9 @@ process_pixel_using_pipeline(enum transfer_fn pre_curve, const struct color_float *in, struct color_float *out) { - int i, j; struct color_float cf; - float tmp; cf = color_float_apply_curve(pre_curve, *in); - - for (i = 0; i < 3; i++) { - tmp = 0.0f; - for (j = 0; j < 3; j++) - tmp += cf.rgb[j] * mat->v[j].n[i]; - out->rgb[i] = tmp; - } - - *out = color_float_apply_curve(post_curve, *out); + cf = color_float_apply_matrix(mat, cf); + *out = color_float_apply_curve(post_curve, cf); } diff --git a/tests/color_util.h b/tests/color_util.h index 3e8e2abd..3fc21aa4 100644 --- a/tests/color_util.h +++ b/tests/color_util.h @@ -36,6 +36,7 @@ enum color_chan_index { COLOR_CHAN_NUM }; +/* column vector when used in linear algebra */ struct color_float { union { float rgb[COLOR_CHAN_NUM]; @@ -46,11 +47,13 @@ struct color_float { float a; }; +/* column vector */ struct lcmsVEC3 { float n[3]; }; struct lcmsMAT3 { + /* array of columns */ struct lcmsVEC3 v[3]; }; @@ -99,3 +102,6 @@ process_pixel_using_pipeline(enum transfer_fn pre_curve, enum transfer_fn post_curve, const struct color_float *in, struct color_float *out); + +struct color_float +color_float_apply_matrix(const struct lcmsMAT3 *mat, struct color_float c);