tests: change rgb_diff_stat printing

Seems it will be common to print all four min/max/avg sets of errors, so
move the printing code into a shared place.

While 0.0-1.0 is the natural range for color values, people are often
accustomed to working with 8-bit or even 10-bit pixel values. An error
of +/- 1 in 8-bit is more intuitive than +/- 0.004 in floating-point.
Hence 'scaling_bits' is added so the caller can determine the value
scaling. This will scale both the reported error numbers, and the
recorded error positions (rgb-tuples), so they are all comparable.

I'm happy to get rid of those two macros as well.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen 2022-06-13 17:31:18 +03:00 committed by Pekka Paalanen
parent 0d385ffacb
commit 9026293bff
3 changed files with 40 additions and 25 deletions

View File

@ -189,8 +189,6 @@ test_roundtrip(uint8_t r, uint8_t g, uint8_t b, cmsPipeline *pip,
static void
roundtrip_verification(cmsPipeline *DToB, cmsPipeline *BToD, float tolerance)
{
const char *const chan_name[COLOR_CHAN_NUM] = { "r", "g", "b" };
unsigned i;
unsigned r, g, b;
struct rgb_diff_stat stat = {};
cmsPipeline *pip;
@ -211,15 +209,7 @@ roundtrip_verification(cmsPipeline *DToB, cmsPipeline *BToD, float tolerance)
cmsPipelineFree(pip);
testlog("DToB->BToD roundtrip error statistics (%u samples):\n",
stat.two_norm.count);
for (i = 0; i < COLOR_CHAN_NUM; i++) {
testlog(" ch %s error:\n", chan_name[i]);
scalar_stat_print_rgb8bit(&stat.rgb[i]);
}
testlog(" Two-norm error:\n");
scalar_stat_print_rgb8bit(&stat.two_norm);
rgb_diff_stat_print(&stat, "DToB->BToD roundtrip", 8);
assert(stat.two_norm.max < tolerance);
}

View File

@ -396,17 +396,6 @@ scalar_stat_avg(const struct scalar_stat *stat)
return stat->sum / stat->count;
}
#define RGB888_FMT "(%3u, %3u, %3u)"
#define RGB888_VAL(cf) (unsigned)round((cf).r * 255.0), (unsigned)round((cf).g * 255.0), (unsigned)round((cf).b * 255.0)
void
scalar_stat_print_rgb8bit(const struct scalar_stat *stat)
{
testlog(" min %8.5f at " RGB888_FMT "\n", stat->min, RGB888_VAL(stat->min_pos));
testlog(" max %8.5f at " RGB888_FMT "\n", stat->max, RGB888_VAL(stat->max_pos));
testlog(" avg %8.5f\n", scalar_stat_avg(stat));
}
void
scalar_stat_print_float(const struct scalar_stat *stat)
{
@ -415,6 +404,41 @@ scalar_stat_print_float(const struct scalar_stat *stat)
testlog(" avg %11.5g\n", scalar_stat_avg(stat));
}
static void
print_stat_at_pos(const char *lim, double val, struct color_float pos, double scale)
{
testlog(" %s %8.5f at rgb(%7.2f, %7.2f, %7.2f)\n",
lim, val * scale, pos.r * scale, pos.g * scale, pos.b * scale);
}
static void
print_rgb_at_pos(const struct scalar_stat *stat, double scale)
{
print_stat_at_pos("min", stat->min, stat->min_pos, scale);
print_stat_at_pos("max", stat->max, stat->max_pos, scale);
testlog(" avg %8.5f\n", scalar_stat_avg(stat) * scale);
}
void
rgb_diff_stat_print(const struct rgb_diff_stat *stat,
const char *title, unsigned scaling_bits)
{
const char *const chan_name[COLOR_CHAN_NUM] = { "r", "g", "b" };
float scale = exp2f(scaling_bits) - 1.0f;
unsigned i;
assert(scaling_bits > 0);
testlog("%s error statistics, %u samples, value range 0.0 - %.1f:\n",
title, stat->two_norm.count, scale);
for (i = 0; i < COLOR_CHAN_NUM; i++) {
testlog(" ch %s (signed):\n", chan_name[i]);
print_rgb_at_pos(&stat->rgb[i], scale);
}
testlog(" rgb two-norm:\n");
print_rgb_at_pos(&stat->two_norm, scale);
}
void
rgb_diff_stat_update(struct rgb_diff_stat *stat,
struct color_float *ref, struct color_float *val)

View File

@ -144,12 +144,13 @@ scalar_stat_update(struct scalar_stat *stat, double val, struct color_float *pos
float
scalar_stat_avg(const struct scalar_stat *stat);
void
scalar_stat_print_rgb8bit(const struct scalar_stat *stat);
void
scalar_stat_print_float(const struct scalar_stat *stat);
void
rgb_diff_stat_update(struct rgb_diff_stat *stat,
struct color_float *ref, struct color_float *val);
void
rgb_diff_stat_print(const struct rgb_diff_stat *stat,
const char *title, unsigned scaling_bits);