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 <pekka.paalanen@collabora.com>
dev
Pekka Paalanen 3 years ago committed by Pekka Paalanen
parent c8195289a7
commit 53b1268018
  1. 36
      tests/color_util.c
  2. 6
      tests/color_util.h

@ -232,6 +232,29 @@ color_float_apply_curve(enum transfer_fn fn, struct color_float c)
return 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 void
process_pixel_using_pipeline(enum transfer_fn pre_curve, process_pixel_using_pipeline(enum transfer_fn pre_curve,
const struct lcmsMAT3 *mat, const struct lcmsMAT3 *mat,
@ -239,18 +262,9 @@ process_pixel_using_pipeline(enum transfer_fn pre_curve,
const struct color_float *in, const struct color_float *in,
struct color_float *out) struct color_float *out)
{ {
int i, j;
struct color_float cf; struct color_float cf;
float tmp;
cf = color_float_apply_curve(pre_curve, *in); cf = color_float_apply_curve(pre_curve, *in);
cf = color_float_apply_matrix(mat, cf);
for (i = 0; i < 3; i++) { *out = color_float_apply_curve(post_curve, cf);
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);
} }

@ -36,6 +36,7 @@ enum color_chan_index {
COLOR_CHAN_NUM COLOR_CHAN_NUM
}; };
/* column vector when used in linear algebra */
struct color_float { struct color_float {
union { union {
float rgb[COLOR_CHAN_NUM]; float rgb[COLOR_CHAN_NUM];
@ -46,11 +47,13 @@ struct color_float {
float a; float a;
}; };
/* column vector */
struct lcmsVEC3 { struct lcmsVEC3 {
float n[3]; float n[3];
}; };
struct lcmsMAT3 { struct lcmsMAT3 {
/* array of columns */
struct lcmsVEC3 v[3]; struct lcmsVEC3 v[3];
}; };
@ -99,3 +102,6 @@ process_pixel_using_pipeline(enum transfer_fn pre_curve,
enum transfer_fn post_curve, enum transfer_fn post_curve,
const struct color_float *in, const struct color_float *in,
struct color_float *out); struct color_float *out);
struct color_float
color_float_apply_matrix(const struct lcmsMAT3 *mat, struct color_float c);

Loading…
Cancel
Save