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>
This commit is contained in:
parent
722d7f8c3f
commit
8c9dd4febb
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
BIN
tests/reference/output-icc-decorations-03.png
Normal file
BIN
tests/reference/output-icc-decorations-03.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 689 B |
BIN
tests/reference/output-icc-decorations-04.png
Normal file
BIN
tests/reference/output-icc-decorations-04.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 689 B |
BIN
tests/reference/output_icc_alpha_blend-03.png
Normal file
BIN
tests/reference/output_icc_alpha_blend-03.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 394 B |
BIN
tests/reference/output_icc_alpha_blend-04.png
Normal file
BIN
tests/reference/output_icc_alpha_blend-04.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 390 B |
BIN
tests/reference/shaper_matrix-03.png
Normal file
BIN
tests/reference/shaper_matrix-03.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 433 B |
BIN
tests/reference/shaper_matrix-04.png
Normal file
BIN
tests/reference/shaper_matrix-04.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 530 B |
Loading…
Reference in New Issue
Block a user