Compare commits

...

3 Commits

Author SHA1 Message Date
Matthias Clasen
e432fa50d4 gsk: Make shader matrices match
We were using slightly different numbers here, which isn't good.

The matrices in gdkcolordefs.h are tested in the colorstate-internal
tests, so they are at least properly inverse, and the products match.

It would be better to generate the glsl definitions, somehow.
2024-07-24 18:07:08 -06:00
Matthias Clasen
74d7130684 Add tests
Add some more texture conversion roundtrips. They are currently
ifdefed out, since they need cicp api.

Also add another test binary for internal tests.
2024-07-24 18:07:08 -06:00
Matthias Clasen
1a58101604 Move transfer functions and matrices to a header
This way, we can write tests against them without static linking.
2024-07-24 18:07:08 -06:00
7 changed files with 492 additions and 187 deletions

194
gdk/gdkcolordefs.h Normal file
View File

@@ -0,0 +1,194 @@
/* gdkcolordefs.h
*
* Copyright 2024 Matthias Clasen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/* Note that this header is shared between the color state implementation
* and tests, and must not include other headers.
*/
static inline float
srgb_oetf (float v)
{
if (v > 0.0031308f)
return 1.055f * powf (v, 1.f / 2.4f) - 0.055f;
else
return 12.92f * v;
}
static inline float
srgb_eotf (float v)
{
if (v >= 0.04045f)
return powf (((v + 0.055f) / (1.f + 0.055f)), 2.4f);
else
return v / 12.92f;
}
static inline float
pq_eotf (float v)
{
float ninv = (1 << 14) / 2610.0;
float minv = (1 << 5) / 2523.0;
float c1 = 3424.0 / (1 << 12);
float c2 = 2413.0 / (1 << 7);
float c3 = 2392.0 / (1 << 7);
float x = powf (MAX ((powf (v, minv) - c1), 0) / (c2 - (c3 * (powf (v, minv)))), ninv);
return x * 10000 / 203.0;
}
static inline float
pq_oetf (float v)
{
float x = v * 203.0 / 10000.0;
float n = 2610.0 / (1 << 14);
float m = 2523.0 / (1 << 5);
float c1 = 3424.0 / (1 << 12);
float c2 = 2413.0 / (1 << 7);
float c3 = 2392.0 / (1 << 7);
return powf (((c1 + (c2 * powf (x, n))) / (1 + (c3 * powf (x, n)))), m);
}
static inline float
bt709_eotf (float v)
{
const float a = 1.099;
const float d = 0.0812;
if (v < d)
return v / 4.5f;
else
return powf ((v + (a - 1)) / a, 1 / 0.45f);
}
static inline float
bt709_oetf (float v)
{
const float a = 1.099;
const float b = 0.018;
if (v < b)
return v * 4.5f;
else
return a * powf (v, 0.45f) - (a - 1);
}
static inline float
hlg_eotf (float v)
{
const float a = 0.17883277;
const float b = 0.28466892;
const float c = 0.55991073;
if (v <= 0.5)
return (v * v) / 3;
else
return (expf ((v - c) / a) + b) / 12.0;
}
static inline float
hlg_oetf (float v)
{
const float a = 0.17883277;
const float b = 0.28466892;
const float c = 0.55991073;
if (v <= 1/12.0)
return sqrtf (3 * v);
else
return a * logf (12 * v - b) + c;
}
/* See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
* for how to derive the abc_to_xyz matrices from chromaticity coordinates.
*/
static const float srgb_to_xyz[3][3] = {
{ 0.4124564, 0.3575761, 0.1804375 },
{ 0.2126729, 0.7151522, 0.0721750 },
{ 0.0193339, 0.1191920, 0.9503041 }
};
static const float xyz_to_srgb[3][3] = {
{ 3.2404542, -1.5371385, -0.4985314 },
{ -0.9692660, 1.8760108, 0.0415560 },
{ 0.0556434, -0.2040259, 1.0572252 },
};
static const float rec2020_to_xyz[3][3] = {
{ 0.6369580, 0.1446169, 0.1688810 },
{ 0.2627002, 0.6779981, 0.0593017 },
{ 0.0000000, 0.0280727, 1.0609851 }
};
static const float xyz_to_rec2020[3][3] = {
{ 1.7166512, -0.3556708, -0.2533663 },
{ -0.6666844, 1.6164812, 0.0157685 },
{ 0.0176399, -0.0427706, 0.9421031 },
};
static const float pal_to_xyz[3][3] = {
{ 0.4305538, 0.3415498, 0.1783523 },
{ 0.2220043, 0.7066548, 0.0713409 },
{ 0.0201822, 0.1295534, 0.9393222 },
};
static const float xyz_to_pal[3][3] = {
{ 3.0633611, -1.3933902, -0.4758237 },
{ -0.9692436, 1.8759675, 0.0415551 },
{ 0.0678610, -0.2287993, 1.0690896 },
};
static const float ntsc_to_xyz[3][3] = {
{ 0.3935209, 0.3652581, 0.1916769 },
{ 0.2123764, 0.7010599, 0.0865638 },
{ 0.0187391, 0.1119339, 0.9583847 },
};
static const float xyz_to_ntsc[3][3] = {
{ 3.5060033, -1.7397907, -0.5440583 },
{ -1.0690476, 1.9777789, 0.0351714 },
{ 0.0563066, -0.1969757, 1.0499523 },
};
static const float p3_to_xyz[3][3] = {
{ 0.4865709, 0.2656677, 0.1982173 },
{ 0.2289746, 0.6917385, 0.0792869 },
{ 0.0000000, 0.0451134, 1.0439444 },
};
static const float xyz_to_p3[3][3] = {
{ 2.4934969, -0.9313836, -0.4027108 },
{ -0.8294890, 1.7626641, 0.0236247 },
{ 0.0358458, -0.0761724, 0.9568845 },
};
/* premultiplied matrices for default conversions */
static const float rec2020_to_srgb[3][3] = {
{ 1.660227, -0.587548, -0.072838 },
{ -0.124553, 1.132926, -0.008350 },
{ -0.018155, -0.100603, 1.118998 },
};
static const float srgb_to_rec2020[3][3] = {
{ 0.627504, 0.329275, 0.043303 },
{ 0.069108, 0.919519, 0.011360 },
{ 0.016394, 0.088011, 0.895380 },
};

View File

@@ -22,6 +22,8 @@
#include <math.h>
#include "gdkcolordefs.h"
#include <glib/gi18n-lib.h>
/**
@@ -259,173 +261,6 @@ name (GdkColorState *self, \
} \
}
static inline float
srgb_oetf (float v)
{
if (v > 0.0031308f)
return 1.055f * powf (v, 1.f / 2.4f) - 0.055f;
else
return 12.92f * v;
}
static inline float
srgb_eotf (float v)
{
if (v >= 0.04045f)
return powf (((v + 0.055f) / (1.f + 0.055f)), 2.4f);
else
return v / 12.92f;
}
static inline float
pq_eotf (float v)
{
float ninv = (1 << 14) / 2610.0;
float minv = (1 << 5) / 2523.0;
float c1 = 3424.0 / (1 << 12);
float c2 = 2413.0 / (1 << 7);
float c3 = 2392.0 / (1 << 7);
float x = powf (MAX ((powf (v, minv) - c1), 0) / (c2 - (c3 * (powf (v, minv)))), ninv);
return x * 10000 / 203.0;
}
static inline float
pq_oetf (float v)
{
float x = v * 203.0 / 10000.0;
float n = 2610.0 / (1 << 14);
float m = 2523.0 / (1 << 5);
float c1 = 3424.0 / (1 << 12);
float c2 = 2413.0 / (1 << 7);
float c3 = 2392.0 / (1 << 7);
return powf (((c1 + (c2 * powf (x, n))) / (1 + (c3 * powf (x, n)))), m);
}
static inline float
bt709_eotf (float v)
{
if (v < 0.081)
return v / 4.5;
else
return powf ((v + 0.099) / 1.099, 1/0.45);
}
static inline float
bt709_oetf (float v)
{
if (v < 0.081)
return v * 4.5;
else
return 1.099 * powf (v, 0.45) - 0.099;
}
static inline float
hlg_eotf (float v)
{
const float a = 0.17883277;
const float b = 0.28466892;
const float c = 0.55991073;
if (v <= 0.5)
return (v * v) / 3;
else
return expf (((v - c) / a) + b) / 12.0;
}
static inline float
hlg_oetf (float v)
{
const float a = 0.17883277;
const float b = 0.28466892;
const float c = 0.55991073;
if (v <= 1/12.0)
return sqrtf (3 * v);
else
return a * logf (12 * v - b) + c;
}
/* See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
* for how to derive the abc_to_xyz matrices from chromaticity coordinates.
*/
static const float srgb_to_xyz[3][3] = {
{ 0.4125288, 0.3581642, 0.1774037 },
{ 0.2127102, 0.7163284, 0.0709615 },
{ 0.0193373, 0.1193881, 0.9343260 },
};
static const float xyz_to_srgb[3][3] = {
{ 3.2409699, -1.5373832, -0.4986108 },
{ -0.9692436, 1.8759675, 0.0415551 },
{ 0.0556301, -0.2039770, 1.0569715 },
};
static const float rec2020_to_xyz[3][3] = {
{ 0.6369615, 0.1448079, 0.1663273 },
{ 0.2627016, 0.6788934, 0.0584050 },
{ 0.0000000, 0.0281098, 1.0449416 },
};
static const float xyz_to_rec2020[3][3] = {
{ 1.7166512, -0.3556708, -0.2533663 },
{ -0.6666844, 1.6164812, 0.0157685 },
{ 0.0176399, -0.0427706, 0.9421031 },
};
static const float pal_to_xyz[3][3] = {
{ 0.4305538, 0.3415498, 0.1783523 },
{ 0.2220043, 0.7066548, 0.0713409 },
{ 0.0201822, 0.1295534, 0.9393222 },
};
static const float xyz_to_pal[3][3] = {
{ 3.0633611, -1.3933902, -0.4758237 },
{ -0.9692436, 1.8759675, 0.0415551 },
{ 0.0678610, -0.2287993, 1.0690896 },
};
static const float ntsc_to_xyz[3][3] = {
{ 0.3935209, 0.3652581, 0.1916769 },
{ 0.2123764, 0.7010599, 0.0865638 },
{ 0.0187391, 0.1119339, 0.9583847 },
};
static const float xyz_to_ntsc[3][3] = {
{ 3.5060033, -1.7397907, -0.5440583 },
{ -1.0690476, 1.9777789, 0.0351714 },
{ 0.0563066, -0.1969757, 1.0499523 },
};
static const float p3_to_xyz[3][3] = {
{ 0.4865709, 0.2656677, 0.1982173 },
{ 0.2289746, 0.6917385, 0.0792869 },
{ 0.0000000, 0.0451134, 1.0439444 },
};
static const float xyz_to_p3[3][3] = {
{ 2.4934969, -0.9313836, -0.4027108 },
{ -0.8294890, 1.7626641, 0.0236247 },
{ 0.0358458, -0.0761724, 0.9568845 },
};
/* premultiplied matrices for default conversions */
static const float rec2020_to_srgb[3][3] = {
{ 1.659944, -0.588220, -0.071724 },
{ -0.124350, 1.132559, -0.008210 },
{ -0.018466, -0.102459, 1.120924 },
};
static const float srgb_to_rec2020[3][3] = {
{ 0.627610, 0.329815, 0.042574 },
{ 0.069029, 0.919817, 0.011154 },
{ 0.016649, 0.089510, 0.893842 },
};
TRANSFORM(gdk_default_srgb_to_srgb_linear, srgb_eotf, IDENTITY, NONE);
TRANSFORM(gdk_default_srgb_linear_to_srgb, NONE, IDENTITY, srgb_oetf)
TRANSFORM(gdk_default_rec2100_pq_to_rec2100_linear, pq_eotf, IDENTITY, NONE)

View File

@@ -99,15 +99,15 @@ pq_oetf (float v)
/* Note that these matrices are transposed from the C version */
const mat3 srgb_from_rec2020 = mat3(
1.659944, -0.124350, -0.018466,
-0.588220, 1.132559, -0.102459,
-0.071724, -0.008210, 1.120924
1.660227, -0.124553, -0.018155,
-0.587548, 1.132926, -0.100603,
-0.072838, -0.008350, 1.118998
);
const mat3 rec2020_from_srgb = mat3(
0.627610, 0.069029, 0.016649,
0.329815, 0.919817, 0.089510,
0.042574, 0.011154, 0.893842
0.627504, 0.069108, 0.016394,
0.329275, 0.919519, 0.088011,
0.043303, 0.011360, 0.895380
);
vec3

View File

@@ -31,21 +31,21 @@ const mat3 identity = mat3(
);
const mat3 srgb_to_xyz = mat3(
0.4125288, 0.2127102, 0.0193373,
0.3581642, 0.7163284, 0.1193881,
0.1774037, 0.0709615, 0.9343260
0.4124564, 0.2126729, 0.0193339,
0.3575761, 0.7151522, 0.1191920,
0.1804375, 0.0721750, 0.9503041
);
const mat3 xyz_to_srgb = mat3(
3.2409699, -0.9692436, 0.0556301,
-1.5373832, 1.8759675, -0.2039770,
-0.4986108, 0.0415551, 1.0569715
3.2404542, -0.9692660, 0.0556434,
-1.5371385, 1.8760108, -0.2040259,
-0.4985314, 0.0415560, 1.0572252
);
const mat3 rec2020_to_xyz = mat3(
0.6369615, 0.2627016, 0.0000000,
0.1448079, 0.6788934, 0.0281098,
0.1663273, 0.0584050, 1.0449416
0.6369580, 0.2627002, 0.0000000,
0.1446169, 0.6779981, 0.0280727,
0.1688810, 0.0593017, 1.0609851
);
const mat3 xyz_to_rec2020 = mat3(

View File

@@ -0,0 +1,167 @@
#include <gdk/gdk.h>
#include "gdkcolorstateprivate.h"
#include <math.h>
#include "gdkcolordefs.h"
typedef float (* TransferFunc) (float v);
typedef struct
{
const char *name;
TransferFunc oetf;
TransferFunc eotf;
} TransferTest;
TransferTest transfers[] = {
{ "srgb", srgb_oetf, srgb_eotf },
{ "pq", pq_oetf, pq_eotf },
{ "bt709", bt709_oetf, bt709_eotf },
{ "hlg", hlg_oetf, hlg_eotf },
};
static void
test_transfer (gconstpointer data)
{
TransferTest *transfer = (TransferTest *) data;
for (int i = 0; i < 1000; i++)
{
float v = i / 1000.0;
float v2 = transfer->oetf (transfer->eotf (v));
g_assert_cmpfloat_with_epsilon (v, v2, 0.05);
}
}
typedef const float Matrix[3][3];
typedef struct
{
const char *name;
Matrix *to_xyz;
Matrix *from_xyz;
} MatrixTest;
static MatrixTest matrices[] = {
{ "srgb", &srgb_to_xyz, &xyz_to_srgb },
{ "rec2020", &rec2020_to_xyz, &xyz_to_rec2020 },
{ "pal", &pal_to_xyz, &xyz_to_pal },
{ "ntsc", &ntsc_to_xyz, &xyz_to_ntsc },
{ "p3", &p3_to_xyz, &xyz_to_p3 },
{ "srgb<>rec2020", &rec2020_to_srgb, &srgb_to_rec2020 },
};
static inline void
multiply (float res[3][3],
const float m1[3][3],
const float m2[3][3])
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
res[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] + m1[i][2] * m2[2][j];
}
static inline void
difference (float res[3][3],
const float m1[3][3],
const float m2[3][3])
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
res[i][j] = m1[i][j] - m2[i][j];
}
static float
norm (const float m[3][3])
{
float sum = 0;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
sum += m[i][j] * m[i][j];
return sqrtf (sum);
}
static const float identity[3][3] = {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 },
};
static void
print_matrix (const float m[3][3])
{
g_print ("%f %f %f\n%f %f %f\n%f %f %f\n",
m[0][0], m[0][1], m[0][2],
m[1][0], m[1][1], m[1][2],
m[2][0], m[2][1], m[2][2]);
}
static void
test_matrix (gconstpointer data)
{
MatrixTest *matrix = (MatrixTest *) data;
float res[3][3];
float res2[3][3];
multiply (res, *matrix->to_xyz, *matrix->from_xyz);
if (g_test_verbose ())
print_matrix (res);
difference (res2, res, identity);
if (g_test_verbose ())
g_print ("distance: %f\n", norm (res2));
g_assert_cmpfloat_with_epsilon (norm (res2), 0, 0.001);
}
static void
test_srgb_to_rec2020 (void)
{
float m[3][3], res[3][3];
multiply (m, xyz_to_rec2020, srgb_to_xyz);
difference (res, m, srgb_to_rec2020);
g_assert_cmpfloat_with_epsilon (norm (res), 0, 0.001);
}
static void
test_rec2020_to_srgb (void)
{
float m[3][3], res[3][3];
multiply (m, xyz_to_srgb, rec2020_to_xyz);
difference (res, m, rec2020_to_srgb);
g_assert_cmpfloat_with_epsilon (norm (res), 0, 0.001);
}
int
main (int argc, char *argv[])
{
(g_test_init) (&argc, &argv, NULL);
for (guint i = 0; i < G_N_ELEMENTS (transfers); i++)
{
TransferTest *test = &transfers[i];
char *path = g_strdup_printf ("/colorstate/transfer/%s", test->name);
g_test_add_data_func (path, test, test_transfer);
g_free (path);
}
for (guint i = 0; i < G_N_ELEMENTS (matrices); i++)
{
MatrixTest *test = &matrices[i];
char *path = g_strdup_printf ("/colorstate/matrix/%s", test->name);
g_test_add_data_func (path, test, test_matrix);
g_free (path);
}
g_test_add_func ("/colorstate/matrix/srgb_to_rec2020", test_srgb_to_rec2020);
g_test_add_func ("/colorstate/matrix/rec2020_to_srgb", test_rec2020_to_srgb);
return g_test_run ();
}

View File

@@ -66,6 +66,9 @@ image_distance (const guchar *data,
gsize height)
{
float dist = 0;
gsize imax = 0, jmax = 0;
float r1 = 0, g1 = 0, b1 = 0, a1 = 0;
float r2 = 0, g2 = 0, b2 = 0, a2 = 0;
for (gsize i = 0; i < height; i++)
{
@@ -81,10 +84,31 @@ image_distance (const guchar *data,
db = p[4 * j + 2] - p2[4 * j + 2];
da = p[4 * j + 3] - p2[4 * j + 3];
dist = MAX (dist, dr * dr + dg * dg + db * db + da * da);
float d = dr * dr + dg * dg + db * db + da * da;
if (d > dist)
{
dist = d;
imax = i;
jmax = j;
r1 = p[4+j+0];
g1 = p[4+j+1];
b1 = p[4+j+2];
a1 = p[4+j+3];
r2 = p2[4+j+0];
g2 = p2[4+j+1];
b2 = p2[4+j+2];
a2 = p2[4+j+3];
}
}
}
if (g_test_verbose() &&
dist > 0)
{
g_print ("worst pixel %lu %lu: %f %f %f %f vs %f %f %f %f\n",
imax, jmax, r1, g1, b1, a1, r2, g2, b2, a2);
}
return sqrt (dist);
}
@@ -142,7 +166,8 @@ test_convert (gconstpointer testdata)
g_bytes_unref (bytes2);
/* Download the data of the new texture in the original texture's colorstate.
* This does the reverse conversion. */
* This does the reverse conversion.
*/
gdk_texture_downloader_set_texture (downloader, texture2);
gdk_texture_downloader_set_color_state (downloader, gdk_texture_get_color_state (texture));
bytes2 = gdk_texture_downloader_download_bytes (downloader, &stride2);
@@ -151,7 +176,8 @@ test_convert (gconstpointer testdata)
/* Check that the conversions produce pixels that are close enough */
g_assert_cmpfloat (image_distance (data, stride, data2, stride2, width, height), <, 0.001);
g_test_message ("%g\n", image_distance (data, stride, data2, stride2, width, height));
if (g_test_verbose ())
g_test_message ("%g\n", image_distance (data, stride, data2, stride2, width, height));
g_bytes_unref (bytes2);
g_bytes_unref (bytes);
@@ -199,6 +225,47 @@ test_png (gconstpointer testdata)
g_object_unref (loaded);
}
static void
test_cicp (void)
{
GdkCicpParams *params;
GdkColorState *cs;
GError *error = NULL;
GdkCicpParams *params2;
params = gdk_cicp_params_new ();
g_assert_true (gdk_cicp_params_get_color_primaries (params) == 2);
g_assert_true (gdk_cicp_params_get_transfer_function (params) == 2);
g_assert_true (gdk_cicp_params_get_matrix_coefficients (params) == 2);
g_assert_true (gdk_cicp_params_get_range (params) == GDK_CICP_RANGE_NARROW);
cs = gdk_cicp_params_build_color_state (params, &error);
g_assert_null (cs);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
g_clear_error (&error);
gdk_cicp_params_set_color_primaries (params, 5);
gdk_cicp_params_set_transfer_function (params, 1);
gdk_cicp_params_set_matrix_coefficients (params, 0);
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
cs = gdk_cicp_params_build_color_state (params, &error);
g_assert_nonnull (cs);
g_assert_no_error (error);
params2 = gdk_color_state_create_cicp_params (cs);
g_assert_true (gdk_cicp_params_get_color_primaries (params) == gdk_cicp_params_get_color_primaries (params2));
g_object_unref (params2);
gdk_color_state_unref (cs);
g_object_unref (params);
}
int
main (int argc, char *argv[])
{
@@ -207,6 +274,7 @@ main (int argc, char *argv[])
(g_test_init) (&argc, &argv, NULL);
g_test_add_func ("/colorstate/equal", test_equal);
g_test_add_func ("/colorstate/cicp", test_cicp);
for (i = 0; ; i++)
{
@@ -219,11 +287,51 @@ main (int argc, char *argv[])
break;
test_name = g_strdup_printf ("/colorstate/convert/srgb/%s", cs_name);
g_test_add_data_func_full (test_name, csi, test_convert, (GDestroyNotify) gdk_color_state_unref);
g_test_add_data_func_full (test_name, gdk_color_state_ref (csi), test_convert, (GDestroyNotify) gdk_color_state_unref);
g_free (test_name);
test_name = g_strdup_printf ("/colorstate/png/%s", cs_name);
g_test_add_data_func_full (test_name, csi, test_png, (GDestroyNotify) gdk_color_state_unref);
g_test_add_data_func_full (test_name, gdk_color_state_ref (csi), test_png, (GDestroyNotify) gdk_color_state_unref);
g_free (test_name);
gdk_color_state_unref (csi);
}
GdkCicpParams *params = gdk_cicp_params_new ();
for (guint primaries = 0; primaries < 32; primaries++)
{
gdk_cicp_params_set_color_primaries (params, primaries);
for (guint tf = 0; tf < 32; tf++)
{
gdk_cicp_params_set_transfer_function (params, tf);
for (guint matrix = 0; matrix < 32; matrix++)
{
GdkColorState *color_state;
gdk_cicp_params_set_matrix_coefficients (params, matrix);
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_NARROW);
color_state = gdk_cicp_params_build_color_state (params, NULL);
if (color_state)
{
char *test_name = g_strdup_printf ("/colorstate/convert/srgb/cicp/%u/%u/%u/0", primaries, tf, matrix);
g_test_add_data_func_full (test_name, gdk_color_state_ref (color_state), test_convert, (GDestroyNotify) gdk_color_state_unref);
g_free (test_name);
gdk_color_state_unref (color_state);
}
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
color_state = gdk_cicp_params_build_color_state (params, NULL);
if (color_state)
{
char *test_name = g_strdup_printf ("/colorstate/convert/srgb/cicp/%u/%u/%u/1", primaries, tf, matrix);
g_test_add_data_func_full (test_name, gdk_color_state_ref (color_state), test_convert, (GDestroyNotify) gdk_color_state_unref);
g_free (test_name);
gdk_color_state_unref (color_state);
}
}
}
}
return g_test_run ();

View File

@@ -58,6 +58,7 @@ foreach t : tests
endforeach
internal_tests = [
{ 'name': 'colorstate-internal' },
{ 'name': 'dihedral' },
{ 'name': 'image' },
{ 'name': 'texture' },