mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-15 23:00:08 +00:00
Merge branch 'matthiasc/for-main' into 'main'
colorstate: Don't leak names See merge request GNOME/gtk!7611
This commit is contained in:
commit
5e3240a32f
@ -30,7 +30,7 @@ static inline float
|
||||
srgb_oetf (float v)
|
||||
{
|
||||
if (fabsf (v) > 0.0031308f)
|
||||
return 1.055f * sign (v) * powf (fabsf (v), 1.f / 2.4f) - 0.055f;
|
||||
return sign (v) * (1.055f * powf (fabsf (v), 1.f / 2.4f) - 0.055f);
|
||||
else
|
||||
return 12.92f * v;
|
||||
}
|
||||
@ -118,7 +118,7 @@ bt709_oetf (float v)
|
||||
if (fabsf (v) < b)
|
||||
return v * 4.5f;
|
||||
else
|
||||
return a * sign (v) * powf (fabsf (v), 0.45f) - (a - 1);
|
||||
return sign (v) * (a * powf (fabsf (v), 0.45f) - (a - 1));
|
||||
}
|
||||
|
||||
static inline float
|
||||
@ -128,10 +128,10 @@ hlg_eotf (float v)
|
||||
const float b = 0.28466892;
|
||||
const float c = 0.55991073;
|
||||
|
||||
if (v <= 0.5)
|
||||
return (v * v) / 3;
|
||||
if (fabsf (v) <= 0.5)
|
||||
return sign (v) * (v * v) / 3;
|
||||
else
|
||||
return (expf ((v - c) / a) + b) / 12.0;
|
||||
return sign (v) * (expf ((fabsf (v) - c) / a) + b) / 12.0;
|
||||
}
|
||||
|
||||
static inline float
|
||||
@ -141,10 +141,10 @@ hlg_oetf (float v)
|
||||
const float b = 0.28466892;
|
||||
const float c = 0.55991073;
|
||||
|
||||
if (v <= 1/12.0)
|
||||
return sqrtf (3 * v);
|
||||
if (fabsf (v) <= 1/12.0)
|
||||
return sign (v) * sqrtf (3 * fabsf (v));
|
||||
else
|
||||
return a * logf (12 * v - b) + c;
|
||||
return sign (v) * (a * logf (12 * fabsf (v) - b) + c);
|
||||
}
|
||||
|
||||
/* See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
||||
|
@ -425,15 +425,15 @@ struct _GdkCicpColorState
|
||||
|
||||
GdkColorState *no_srgb;
|
||||
|
||||
const char *name;
|
||||
char *name;
|
||||
|
||||
GdkTransferFunc eotf;
|
||||
GdkTransferFunc oetf;
|
||||
|
||||
float *to_srgb;
|
||||
float *to_rec2020;
|
||||
float *from_srgb;
|
||||
float *from_rec2020;
|
||||
float to_srgb[9];
|
||||
float to_rec2020[9];
|
||||
float from_srgb[9];
|
||||
float from_rec2020[9];
|
||||
|
||||
GdkCicp cicp;
|
||||
};
|
||||
@ -461,14 +461,11 @@ gdk_cicp_color_state_free (GdkColorState *cs)
|
||||
{
|
||||
GdkCicpColorState *self = (GdkCicpColorState *) cs;
|
||||
|
||||
g_free (self->name);
|
||||
|
||||
if (self->no_srgb)
|
||||
gdk_color_state_unref (self->no_srgb);
|
||||
|
||||
g_free (self->to_srgb);
|
||||
g_free (self->to_rec2020);
|
||||
g_free (self->from_srgb);
|
||||
g_free (self->from_rec2020);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
@ -558,7 +555,7 @@ gdk_cicp_color_state_get_cicp (GdkColorState *color_state)
|
||||
return &self->cicp;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
|
||||
static const
|
||||
GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
|
||||
@ -707,10 +704,10 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
self->eotf = eotf;
|
||||
self->oetf = oetf;
|
||||
|
||||
self->to_srgb = multiply (g_new (float, 9), xyz_to_srgb, to_xyz);
|
||||
self->to_rec2020 = multiply (g_new (float, 9), xyz_to_rec2020, to_xyz);
|
||||
self->from_srgb = multiply (g_new (float, 9), from_xyz, srgb_to_xyz);
|
||||
self->from_rec2020 = multiply (g_new (float, 9), from_xyz, rec2020_to_xyz);
|
||||
multiply (self->to_srgb, xyz_to_srgb, to_xyz);
|
||||
multiply (self->to_rec2020, xyz_to_rec2020, to_xyz);
|
||||
multiply (self->from_srgb, from_xyz, srgb_to_xyz);
|
||||
multiply (self->from_rec2020, from_xyz, rec2020_to_xyz);
|
||||
|
||||
self->name = g_strdup_printf ("cicp-%u/%u/%u/%u",
|
||||
cicp->color_primaries,
|
||||
@ -720,12 +717,12 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
|
||||
if (cicp->transfer_function == 13)
|
||||
{
|
||||
GdkCicp no_srgb;
|
||||
|
||||
memcpy (&no_srgb, cicp, sizeof (GdkCicp));
|
||||
no_srgb.transfer_function = 8;
|
||||
|
||||
self->no_srgb = gdk_color_state_new_for_cicp (&no_srgb, NULL);
|
||||
self->no_srgb = gdk_color_state_new_for_cicp (&(GdkCicp) {
|
||||
cicp->color_primaries,
|
||||
8,
|
||||
cicp->matrix_coefficients,
|
||||
cicp->range },
|
||||
NULL);
|
||||
}
|
||||
|
||||
return (GdkColorState *) self;
|
||||
|
@ -63,7 +63,7 @@ float
|
||||
srgb_oetf (float v)
|
||||
{
|
||||
if (abs (v) > 0.0031308)
|
||||
return 1.055 * sign (v) * pow (abs (v), 1.0 / 2.4) - 0.055;
|
||||
return sign (v) * (1.055 * pow (abs (v), 1.0 / 2.4) - 0.055);
|
||||
else
|
||||
return 12.92 * v;
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ bt709_oetf (float v)
|
||||
if (abs (v) < 0.081)
|
||||
return v * 4.5;
|
||||
else
|
||||
return 1.099 * sign (v) * pow (abs (v), 0.45) - 0.099;
|
||||
return 1.099 * sign (v) * (pow (abs (v), 0.45) - 0.099);
|
||||
}
|
||||
|
||||
float
|
||||
@ -207,10 +207,10 @@ hlg_eotf (float v)
|
||||
const float b = 0.28466892;
|
||||
const float c = 0.55991073;
|
||||
|
||||
if (v <= 0.5)
|
||||
return (v * v) / 3.0;
|
||||
if (abs (v) <= 0.5)
|
||||
return sign (v) * ((v * v) / 3.0);
|
||||
else
|
||||
return exp (((v - c) / a) + b) / 12.0;
|
||||
return sign (v) * (exp (((abs (v) - c) / a) + b) / 12.0);
|
||||
}
|
||||
|
||||
float
|
||||
@ -220,10 +220,10 @@ hlg_oetf (float v)
|
||||
const float b = 0.28466892;
|
||||
const float c = 0.55991073;
|
||||
|
||||
if (v <= 1.0 / 12.0)
|
||||
return sqrt (3.0 * v);
|
||||
if (abs (v) <= 1.0 / 12.0)
|
||||
return sign (v) * sqrt (3.0 * abs (v));
|
||||
else
|
||||
return a * log (12.0 * v - b) + c;
|
||||
return sign (v) * (a * log (12.0 * abs (v) - b) + c);
|
||||
}
|
||||
|
||||
vec3
|
||||
|
@ -12,30 +12,84 @@ typedef struct
|
||||
const char *name;
|
||||
TransferFunc oetf;
|
||||
TransferFunc eotf;
|
||||
float o_range[2];
|
||||
float e_range[2];
|
||||
} TransferTest;
|
||||
|
||||
TransferTest transfers[] = {
|
||||
{ "srgb", srgb_oetf, srgb_eotf },
|
||||
{ "pq", pq_oetf, pq_eotf },
|
||||
{ "bt709", bt709_oetf, bt709_eotf },
|
||||
{ "hlg", hlg_oetf, hlg_eotf },
|
||||
{ "gamma22", gamma22_oetf, gamma22_eotf },
|
||||
{ "gamma28", gamma28_oetf, gamma28_eotf },
|
||||
{ "srgb", srgb_oetf, srgb_eotf, { 0, 1 }, { 0, 1} },
|
||||
{ "pq", pq_oetf, pq_eotf, { 0, 49.2610855 }, { 0, 1 } },
|
||||
{ "bt709", bt709_oetf, bt709_eotf, { 0, 1 }, { 0, 1 } },
|
||||
{ "hlg", hlg_oetf, hlg_eotf, { 0, 1}, { 0, 1} },
|
||||
{ "gamma22", gamma22_oetf, gamma22_eotf, { 0, 1 }, { 0, 1 } },
|
||||
{ "gamma28", gamma28_oetf, gamma28_eotf, { 0, 1 }, { 0, 1 } },
|
||||
};
|
||||
|
||||
#define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
|
||||
|
||||
#define ASSERT_IN_RANGE(v, a, b, epsilon) \
|
||||
g_assert_cmpfloat_with_epsilon (MIN(v,a), a, epsilon); \
|
||||
g_assert_cmpfloat_with_epsilon (MAX(v,b), b, epsilon); \
|
||||
|
||||
static void
|
||||
test_transfer (gconstpointer data)
|
||||
{
|
||||
TransferTest *transfer = (TransferTest *) data;
|
||||
float v, v1, v2;
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
for (int i = 0; i < 1001; i++)
|
||||
{
|
||||
float v = i / 1000.0;
|
||||
float v2 = transfer->oetf (transfer->eotf (v));
|
||||
v = LERP (i/1000.0, transfer->e_range[0], transfer->e_range[1]);
|
||||
|
||||
v1 = transfer->eotf (v);
|
||||
|
||||
ASSERT_IN_RANGE (v1, transfer->o_range[0], transfer->o_range[1], 0.0001);
|
||||
|
||||
v2 = transfer->oetf (v1);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (v, v2, 0.05);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1001; i++)
|
||||
{
|
||||
v = LERP (i/1000.0, transfer->o_range[0], transfer->o_range[1]);
|
||||
|
||||
v1 = transfer->oetf (v);
|
||||
|
||||
ASSERT_IN_RANGE (v1, transfer->e_range[0], transfer->e_range[1], 0.0001);
|
||||
|
||||
v2 = transfer->eotf (v1);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (v, v2, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_transfer_symmetry (gconstpointer data)
|
||||
{
|
||||
TransferTest *transfer = (TransferTest *) data;
|
||||
float v, v1, v2;
|
||||
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
v = LERP (i/10.0, transfer->e_range[0], transfer->e_range[1]);
|
||||
|
||||
v1 = transfer->eotf (v);
|
||||
v2 = -transfer->eotf (-v);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (v1, v2, 0.05);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
v = LERP (i/10.0, transfer->o_range[0], transfer->o_range[1]);
|
||||
|
||||
v1 = transfer->oetf (v);
|
||||
v2 = -transfer->oetf (-v);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (v1, v2, 0.05);
|
||||
}
|
||||
}
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
@ -171,6 +225,14 @@ main (int argc, char *argv[])
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (transfers); i++)
|
||||
{
|
||||
TransferTest *test = &transfers[i];
|
||||
char *path = g_strdup_printf ("/colorstate/transfer-symmetry/%s", test->name);
|
||||
g_test_add_data_func (path, test, test_transfer_symmetry);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (matrices); i++)
|
||||
{
|
||||
MatrixTest *test = &matrices[i];
|
||||
|
Loading…
Reference in New Issue
Block a user