summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeandro Ribeiro <leandro.ribeiro@collabora.com>2023-04-21 15:27:30 -0300
committerPekka Paalanen <pq@iki.fi>2023-04-27 10:37:38 +0000
commit8c9dd4febbe129a29d045974a89eec8e28bd3418 (patch)
treea3dc3511e32d4eba45dcb4248d05843e5e90d8b6
parent722d7f8c3f278b74764a7da68284c5c1f059a601 (diff)
downloadweston-8c9dd4febbe129a29d045974a89eec8e28bd3418.tar.gz
tests/color-icc-output: add ICC VCGT tests
There are some ICC profiles that contain something named VCGT tag. These are usually power curves (y = x ^ exp) that were loaded in the video card when the ICC profile was created. So the compositor should mimic that in order to use the profile. Weston already has support for that, but our ICC profile tests were missing this case. This adds such tests. For testing purposes, we have added tests with different exponents per color channel. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
-rw-r--r--tests/color-icc-output-test.c61
-rw-r--r--tests/color_util.c22
-rw-r--r--tests/color_util.h4
-rw-r--r--tests/reference/output-icc-decorations-03.pngbin0 -> 689 bytes
-rw-r--r--tests/reference/output-icc-decorations-04.pngbin0 -> 689 bytes
-rw-r--r--tests/reference/output_icc_alpha_blend-03.pngbin0 -> 394 bytes
-rw-r--r--tests/reference/output_icc_alpha_blend-04.pngbin0 -> 390 bytes
-rw-r--r--tests/reference/shaper_matrix-03.pngbin0 -> 433 bytes
-rw-r--r--tests/reference/shaper_matrix-04.pngbin0 -> 530 bytes
9 files changed, 74 insertions, 13 deletions
diff --git a/tests/color-icc-output-test.c b/tests/color-icc-output-test.c
index 62103c4b..076a360d 100644
--- a/tests/color-icc-output-test.c
+++ b/tests/color-icc-output-test.c
@@ -161,15 +161,25 @@ struct setup_args {
/** Two-norm error limit for cLUT DToB->BToD roundtrip */
float clut_roundtrip_tolerance;
+
+ /**
+ * VCGT tag exponents for each channel. If any is zeroed, we ignore
+ * the VCGT tag.
+ */
+ double vcgt_exponents[COLOR_CHAN_NUM];
};
static const struct setup_args my_setup_args[] = {
- /* name, ref img, pipeline, tolerance, dim, profile type, clut tolerance */
- { { "sRGB->sRGB MAT" }, 0, &pipeline_sRGB, 0.0, 0, PTYPE_MATRIX_SHAPER },
- { { "sRGB->adobeRGB MAT" }, 1, &pipeline_adobeRGB, 1.4, 0, PTYPE_MATRIX_SHAPER },
- { { "sRGB->BT2020 MAT" }, 2, &pipeline_BT2020, 4.5, 0, PTYPE_MATRIX_SHAPER },
- { { "sRGB->sRGB CLUT" }, 0, &pipeline_sRGB, 0.0, 17, PTYPE_CLUT, 0.0005 },
- { { "sRGB->adobeRGB CLUT" }, 1, &pipeline_adobeRGB, 1.8, 17, PTYPE_CLUT, 0.0065 },
+ /* name, ref img, pipeline, tolerance, dim, profile type, clut tolerance, vcgt_exponents */
+ { { "sRGB->sRGB MAT" }, 0, &pipeline_sRGB, 0.0, 0, PTYPE_MATRIX_SHAPER },
+ { { "sRGB->sRGB MAT VCGT" }, 3, &pipeline_sRGB, 0.8, 0, PTYPE_MATRIX_SHAPER, 0.0000, {1.1, 1.2, 1.3} },
+ { { "sRGB->adobeRGB MAT" }, 1, &pipeline_adobeRGB, 1.4, 0, PTYPE_MATRIX_SHAPER },
+ { { "sRGB->adobeRGB MAT VCGT" }, 4, &pipeline_adobeRGB, 1.0, 0, PTYPE_MATRIX_SHAPER, 0.0000, {1.1, 1.2, 1.3} },
+ { { "sRGB->BT2020 MAT" }, 2, &pipeline_BT2020, 4.5, 0, PTYPE_MATRIX_SHAPER },
+ { { "sRGB->sRGB CLUT" }, 0, &pipeline_sRGB, 0.0, 17, PTYPE_CLUT, 0.0005 },
+ { { "sRGB->sRGB CLUT VCGT" }, 3, &pipeline_sRGB, 0.9, 17, PTYPE_CLUT, 0.0005, {1.1, 1.2, 1.3} },
+ { { "sRGB->adobeRGB CLUT" }, 1, &pipeline_adobeRGB, 1.8, 17, PTYPE_CLUT, 0.0065 },
+ { { "sRGB->adobeRGB CLUT VCGT" }, 4, &pipeline_adobeRGB, 1.1, 17, PTYPE_CLUT, 0.0065, {1.1, 1.2, 1.3} },
};
static void
@@ -247,6 +257,24 @@ create_cLUT_from_matrix(cmsContext context_id, const struct lcmsMAT3 *mat, int d
return cLUT_stage;
}
+static void
+vcgt_tag_add_to_profile(cmsContext context_id, cmsHPROFILE profile,
+ const double vcgt_exponents[COLOR_CHAN_NUM])
+{
+ cmsToneCurve *vcgt_tag_curves[COLOR_CHAN_NUM];
+ unsigned int i;
+
+ if (!should_include_vcgt(vcgt_exponents))
+ return;
+
+ for (i = 0; i < COLOR_CHAN_NUM; i++)
+ vcgt_tag_curves[i] = cmsBuildGamma(context_id, vcgt_exponents[i]);
+
+ assert(cmsWriteTag(profile, cmsSigVcgtTag, vcgt_tag_curves));
+
+ cmsFreeToneCurveTriple(vcgt_tag_curves);
+}
+
/*
* Originally the cLUT profile test attempted to use the AToB/BToA tags. Those
* come with serious limitations though: at most uint16 representation for
@@ -332,6 +360,8 @@ build_lcms_clut_profile_output(cmsContext context_id,
cmsLinkTag(hRGB, cmsSigDToB2Tag, cmsSigDToB0Tag);
cmsLinkTag(hRGB, cmsSigDToB3Tag, cmsSigDToB0Tag);
+ vcgt_tag_add_to_profile(context_id, hRGB, arg->vcgt_exponents);
+
roundtrip_verification(DToB0, BToD0, arg->clut_roundtrip_tolerance);
cmsPipelineFree(BToD0);
@@ -344,14 +374,14 @@ build_lcms_clut_profile_output(cmsContext context_id,
static cmsHPROFILE
build_lcms_matrix_shaper_profile_output(cmsContext context_id,
- const struct lcms_pipeline *pipeline)
+ const struct setup_args *arg)
{
cmsToneCurve *arr_curves[3];
cmsHPROFILE hRGB;
int type_inverse_tone_curve;
double inverse_tone_curve_param[5];
- assert(find_tone_curve_type(pipeline->post_fn, &type_inverse_tone_curve,
+ assert(find_tone_curve_type(arg->pipeline->post_fn, &type_inverse_tone_curve,
inverse_tone_curve_param));
/*
@@ -371,9 +401,11 @@ build_lcms_matrix_shaper_profile_output(cmsContext context_id,
assert(arr_curves[0]);
hRGB = cmsCreateRGBProfileTHR(context_id, &wp_d65,
- &pipeline->prim_output, arr_curves);
+ &arg->pipeline->prim_output, arr_curves);
assert(hRGB);
+ vcgt_tag_add_to_profile(context_id, hRGB, arg->vcgt_exponents);
+
cmsFreeToneCurve(arr_curves[0]);
return hRGB;
}
@@ -383,8 +415,7 @@ build_lcms_profile_output(cmsContext context_id, const struct setup_args *arg)
{
switch (arg->type) {
case PTYPE_MATRIX_SHAPER:
- return build_lcms_matrix_shaper_profile_output(context_id,
- arg->pipeline);
+ return build_lcms_matrix_shaper_profile_output(context_id, arg);
case PTYPE_CLUT:
return build_lcms_clut_profile_output(context_id, arg);
}
@@ -561,6 +592,7 @@ process_pipeline_comparison(const struct buffer *src_buf,
process_pixel_using_pipeline(arg->pipeline->pre_fn,
&arg->pipeline->mat,
arg->pipeline->post_fn,
+ arg->vcgt_exponents,
&pix_src, &pix_src_pipeline);
rgb_diff_stat_update(&diffstat,
@@ -646,6 +678,7 @@ convert_to_blending_space(const struct lcms_pipeline *pip,
static void
compare_blend(const struct lcms_pipeline *pip,
+ const double vcgt_exponents[COLOR_CHAN_NUM],
struct color_float bg,
struct color_float fg,
const struct color_float *shot,
@@ -668,6 +701,10 @@ compare_blend(const struct lcms_pipeline *pip,
/* non-linear encoding for output */
ref = color_float_apply_curve(pip->post_fn, ref);
+ if (should_include_vcgt(vcgt_exponents))
+ for (i = 0; i < COLOR_CHAN_NUM; i++)
+ ref.rgb[i] = pow(ref.rgb[i], vcgt_exponents[i]);
+
rgb_diff_stat_update(diffstat, &ref, shot, &fg);
}
@@ -714,7 +751,7 @@ check_blend_pattern(struct buffer *bg_buf,
struct color_float fg = a8r8g8b8_to_float(fg_row[x]);
struct color_float shot = a8r8g8b8_to_float(shot_row[x]);
- compare_blend(arg->pipeline, bg, fg, &shot, &diffstat);
+ compare_blend(arg->pipeline, arg->vcgt_exponents, bg, fg, &shot, &diffstat);
}
rgb_diff_stat_print(&diffstat, "Blending", 8);
diff --git a/tests/color_util.c b/tests/color_util.c
index fc406d87..5db692e5 100644
--- a/tests/color_util.c
+++ b/tests/color_util.c
@@ -321,18 +321,38 @@ color_float_apply_matrix(const struct lcmsMAT3 *mat, struct color_float c)
return result;
}
+bool
+should_include_vcgt(const double vcgt_exponents[COLOR_CHAN_NUM])
+{
+ unsigned int i;
+
+ for (i = 0; i < COLOR_CHAN_NUM; i++)
+ if (vcgt_exponents[i] == 0.0)
+ return false;
+
+ return true;
+}
+
void
process_pixel_using_pipeline(enum transfer_fn pre_curve,
const struct lcmsMAT3 *mat,
enum transfer_fn post_curve,
+ const double vcgt_exponents[COLOR_CHAN_NUM],
const struct color_float *in,
struct color_float *out)
{
struct color_float cf;
+ unsigned i;
cf = color_float_apply_curve(pre_curve, *in);
cf = color_float_apply_matrix(mat, cf);
- *out = color_float_apply_curve(post_curve, cf);
+ cf = color_float_apply_curve(post_curve, cf);
+
+ if (should_include_vcgt(vcgt_exponents))
+ for (i = 0; i < COLOR_CHAN_NUM; i++)
+ cf.rgb[i] = pow(cf.rgb[i], vcgt_exponents[i]);
+
+ *out = cf;
}
static void
diff --git a/tests/color_util.h b/tests/color_util.h
index a5003fa8..46817dfc 100644
--- a/tests/color_util.h
+++ b/tests/color_util.h
@@ -101,10 +101,14 @@ find_tone_curve_type(enum transfer_fn fn, int *type, double params[5]);
float
apply_tone_curve(enum transfer_fn fn, float r);
+bool
+should_include_vcgt(const double vcgt_exponents[COLOR_CHAN_NUM]);
+
void
process_pixel_using_pipeline(enum transfer_fn pre_curve,
const struct lcmsMAT3 *mat,
enum transfer_fn post_curve,
+ const double vcgt_exponents[COLOR_CHAN_NUM],
const struct color_float *in,
struct color_float *out);
diff --git a/tests/reference/output-icc-decorations-03.png b/tests/reference/output-icc-decorations-03.png
new file mode 100644
index 00000000..f10f000f
--- /dev/null
+++ b/tests/reference/output-icc-decorations-03.png
Binary files differ
diff --git a/tests/reference/output-icc-decorations-04.png b/tests/reference/output-icc-decorations-04.png
new file mode 100644
index 00000000..6b0c6222
--- /dev/null
+++ b/tests/reference/output-icc-decorations-04.png
Binary files differ
diff --git a/tests/reference/output_icc_alpha_blend-03.png b/tests/reference/output_icc_alpha_blend-03.png
new file mode 100644
index 00000000..9072beda
--- /dev/null
+++ b/tests/reference/output_icc_alpha_blend-03.png
Binary files differ
diff --git a/tests/reference/output_icc_alpha_blend-04.png b/tests/reference/output_icc_alpha_blend-04.png
new file mode 100644
index 00000000..0919087a
--- /dev/null
+++ b/tests/reference/output_icc_alpha_blend-04.png
Binary files differ
diff --git a/tests/reference/shaper_matrix-03.png b/tests/reference/shaper_matrix-03.png
new file mode 100644
index 00000000..693385c8
--- /dev/null
+++ b/tests/reference/shaper_matrix-03.png
Binary files differ
diff --git a/tests/reference/shaper_matrix-04.png b/tests/reference/shaper_matrix-04.png
new file mode 100644
index 00000000..68fc25bf
--- /dev/null
+++ b/tests/reference/shaper_matrix-04.png
Binary files differ