colorstate: Add yuv support
Add support for some of the yuv-related cicp tuples. Concretely, this adds bt601, bt709 and bt2020, both in their narrow and full-range variants.
This commit is contained in:
@@ -208,7 +208,10 @@ gdk_cicp_params_class_init (GdkCicpParamsClass *klass)
|
||||
* Supported values:
|
||||
*
|
||||
* - 0: RGB
|
||||
* - 1: BT.709
|
||||
* - 2: unspecified
|
||||
* - 5,6: BT.601
|
||||
* - 9: BT.2020
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
|
||||
@@ -222,3 +222,39 @@ static const float srgb_to_rec2020[9] = {
|
||||
0.069108, 0.919519, 0.011360,
|
||||
0.016394, 0.088011, 0.895380,
|
||||
};
|
||||
|
||||
static const float rgb_to_bt601[9] = {
|
||||
0.299000, 0.587000, 0.114000,
|
||||
-0.168736, -0.331264, 0.500000,
|
||||
0.500000, -0.418688, -0.081312,
|
||||
};
|
||||
|
||||
static const float bt601_to_rgb[9] = {
|
||||
1.000000, 0.000000, 1.402000,
|
||||
1.000000, -0.344136, -0.714136,
|
||||
1.000000, 1.772000, 0.000000,
|
||||
};
|
||||
|
||||
static const float rgb_to_bt709[9] = {
|
||||
0.212600, 0.715200, 0.072200,
|
||||
-0.114572, -0.385428, 0.500000,
|
||||
0.500000, -0.454153, -0.045847,
|
||||
};
|
||||
|
||||
static const float bt709_to_rgb[9] = {
|
||||
1.000000, 0.000000, 1.574800,
|
||||
1.000000, -0.187324, -0.468124,
|
||||
1.000000, 1.855600, -0.000000,
|
||||
};
|
||||
|
||||
static const float rgb_to_bt2020[9] = {
|
||||
0.262700, 0.678000, 0.059300,
|
||||
-0.139630, -0.360370, 0.500000,
|
||||
0.500000, -0.459786, -0.040214,
|
||||
};
|
||||
|
||||
static const float bt2020_to_rgb[9] = {
|
||||
1.000000, -0.000000, 1.474600,
|
||||
1.000000, -0.164553, -0.571353,
|
||||
1.000000, 1.881400, -0.000000,
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define GDK_COLOR_STATE_IMPL
|
||||
#include "gdkcolorstateprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
@@ -411,7 +412,7 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
},
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
/* {{{ Cicp implementation */
|
||||
|
||||
typedef struct _GdkCicpColorState GdkCicpColorState;
|
||||
@@ -431,25 +432,128 @@ struct _GdkCicpColorState
|
||||
float *from_srgb;
|
||||
float *from_rec2020;
|
||||
|
||||
const float *from_yuv;
|
||||
const float *to_yuv;
|
||||
|
||||
GdkCicp cicp;
|
||||
};
|
||||
|
||||
/* {{{ Conversion functions */
|
||||
|
||||
#define cicp ((GdkCicpColorState *)self)
|
||||
#define TRANSFORM_FROM_CICP(name, matrix, oetf) \
|
||||
static void \
|
||||
name (GdkColorState *color_state, \
|
||||
float (*values)[4], \
|
||||
gsize n_values) \
|
||||
{ \
|
||||
GdkCicpColorState *self = (GdkCicpColorState *) color_state; \
|
||||
\
|
||||
for (gsize i = 0; i < n_values; i++) \
|
||||
{ \
|
||||
if (self->cicp.range == GDK_CICP_RANGE_NARROW) \
|
||||
{ \
|
||||
values[i][0] = CLAMP ((values[i][0] - 16.0/255.0) * 255.0 / 219.0, -10, 10); \
|
||||
values[i][1] = CLAMP ((values[i][1] - 16.0/255.0) * 255.0 / 224.0, -10, 10); \
|
||||
values[i][2] = CLAMP ((values[i][2] - 16.0/255.0) * 255.0 / 224.0, -10, 10); \
|
||||
} \
|
||||
if (self->from_yuv) \
|
||||
{ \
|
||||
float res[3]; \
|
||||
values[i][1] -= 0.5; \
|
||||
values[i][2] -= 0.5; \
|
||||
res[0] = self->from_yuv[0] * values[i][0] + self->from_yuv[1] * values[i][1] + self->from_yuv[2] * values[i][2]; \
|
||||
res[1] = self->from_yuv[3] * values[i][0] + self->from_yuv[4] * values[i][1] + self->from_yuv[5] * values[i][2]; \
|
||||
res[2] = self->from_yuv[6] * values[i][0] + self->from_yuv[7] * values[i][1] + self->from_yuv[8] * values[i][2]; \
|
||||
values[i][0] = res[0]; \
|
||||
values[i][1] = res[1]; \
|
||||
values[i][2] = res[2]; \
|
||||
} \
|
||||
if (self->eotf != NONE) \
|
||||
{ \
|
||||
values[i][0] = self->eotf (values[i][0]); \
|
||||
values[i][1] = self->eotf (values[i][1]); \
|
||||
values[i][2] = self->eotf (values[i][2]); \
|
||||
} \
|
||||
if (self->matrix != IDENTITY) \
|
||||
{ \
|
||||
float res[3]; \
|
||||
res[0] = self->matrix[0] * values[i][0] + self->matrix[1] * values[i][1] + self->matrix[2] * values[i][2]; \
|
||||
res[1] = self->matrix[3] * values[i][0] + self->matrix[4] * values[i][1] + self->matrix[5] * values[i][2]; \
|
||||
res[2] = self->matrix[6] * values[i][0] + self->matrix[7] * values[i][1] + self->matrix[8] * values[i][2]; \
|
||||
values[i][0] = res[0]; \
|
||||
values[i][1] = res[1]; \
|
||||
values[i][2] = res[2]; \
|
||||
} \
|
||||
if (oetf != NONE) \
|
||||
{ \
|
||||
values[i][0] = oetf (values[i][0]); \
|
||||
values[i][1] = oetf (values[i][1]); \
|
||||
values[i][2] = oetf (values[i][2]); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
TRANSFORM(gdk_cicp_to_srgb, cicp->eotf, cicp->to_srgb, srgb_oetf)
|
||||
TRANSFORM(gdk_cicp_to_srgb_linear, cicp->eotf, cicp->to_srgb, NONE)
|
||||
TRANSFORM(gdk_cicp_to_rec2100_pq, cicp->eotf, cicp->to_rec2020, pq_oetf)
|
||||
TRANSFORM(gdk_cicp_to_rec2100_linear, cicp->eotf, cicp->to_rec2020, NONE)
|
||||
TRANSFORM(gdk_cicp_from_srgb, srgb_eotf, cicp->from_srgb, cicp->oetf)
|
||||
TRANSFORM(gdk_cicp_from_srgb_linear, NONE, cicp->from_srgb, cicp->oetf)
|
||||
TRANSFORM(gdk_cicp_from_rec2100_pq, pq_eotf, cicp->from_rec2020, cicp->oetf)
|
||||
TRANSFORM(gdk_cicp_from_rec2100_linear, NONE, cicp->from_rec2020, cicp->oetf)
|
||||
#define TRANSFORM_TO_CICP(name, eotf, matrix) \
|
||||
static void \
|
||||
name (GdkColorState *color_state, \
|
||||
float (*values)[4], \
|
||||
gsize n_values) \
|
||||
{ \
|
||||
GdkCicpColorState *self = (GdkCicpColorState *) color_state; \
|
||||
\
|
||||
for (gsize i = 0; i < n_values; i++) \
|
||||
{ \
|
||||
if (eotf != NONE) \
|
||||
{ \
|
||||
values[i][0] = eotf (values[i][0]); \
|
||||
values[i][1] = eotf (values[i][1]); \
|
||||
values[i][2] = eotf (values[i][2]); \
|
||||
} \
|
||||
if (self->matrix != IDENTITY) \
|
||||
{ \
|
||||
float res[3]; \
|
||||
res[0] = self->matrix[0] * values[i][0] + self->matrix[1] * values[i][1] + self->matrix[2] * values[i][2]; \
|
||||
res[1] = self->matrix[3] * values[i][0] + self->matrix[4] * values[i][1] + self->matrix[5] * values[i][2]; \
|
||||
res[2] = self->matrix[6] * values[i][0] + self->matrix[7] * values[i][1] + self->matrix[8] * values[i][2]; \
|
||||
values[i][0] = res[0]; \
|
||||
values[i][1] = res[1]; \
|
||||
values[i][2] = res[2]; \
|
||||
} \
|
||||
if (self->oetf != NONE) \
|
||||
{ \
|
||||
values[i][0] = self->oetf (values[i][0]); \
|
||||
values[i][1] = self->oetf (values[i][1]); \
|
||||
values[i][2] = self->oetf (values[i][2]); \
|
||||
} \
|
||||
if (self->to_yuv) \
|
||||
{ \
|
||||
float res[3]; \
|
||||
res[0] = self->to_yuv[0] * values[i][0] + self->to_yuv[1] * values[i][1] + self->to_yuv[2] * values[i][2]; \
|
||||
res[1] = self->to_yuv[3] * values[i][0] + self->to_yuv[4] * values[i][1] + self->to_yuv[5] * values[i][2]; \
|
||||
res[2] = self->to_yuv[6] * values[i][0] + self->to_yuv[7] * values[i][1] + self->to_yuv[8] * values[i][2]; \
|
||||
values[i][0] = res[0]; \
|
||||
values[i][1] = res[1] + 0.5; \
|
||||
values[i][2] = res[2] + 0.5; \
|
||||
} \
|
||||
if (self->cicp.range == GDK_CICP_RANGE_NARROW) \
|
||||
{ \
|
||||
values[i][0] = values[i][0] * 219.0 / 255.0 + 16.0 / 255.0; \
|
||||
values[i][1] = values[i][1] * 224.0 / 255.0 + 16.0 / 255.0; \
|
||||
values[i][2] = values[i][2] * 224.0 / 255.0 + 16.0 / 255.0; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#undef cicp
|
||||
TRANSFORM_FROM_CICP(gdk_cicp_to_srgb, to_srgb, srgb_oetf)
|
||||
TRANSFORM_FROM_CICP(gdk_cicp_to_srgb_linear, to_srgb, NONE)
|
||||
TRANSFORM_FROM_CICP(gdk_cicp_to_rec2100_pq, to_rec2020, pq_oetf)
|
||||
TRANSFORM_FROM_CICP(gdk_cicp_to_rec2100_linear, to_rec2020, NONE)
|
||||
|
||||
TRANSFORM_TO_CICP(gdk_cicp_from_srgb, srgb_eotf, from_srgb)
|
||||
TRANSFORM_TO_CICP(gdk_cicp_from_srgb_linear, NONE, from_srgb)
|
||||
TRANSFORM_TO_CICP(gdk_cicp_from_rec2100_pq, pq_eotf, from_rec2020)
|
||||
TRANSFORM_TO_CICP(gdk_cicp_from_rec2100_linear, NONE, from_rec2020)
|
||||
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
/* {{{ Vfuncs */
|
||||
|
||||
@@ -555,7 +659,7 @@ gdk_cicp_color_state_get_cicp (GdkColorState *color_state)
|
||||
return &self->cicp;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
|
||||
static const
|
||||
GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
|
||||
@@ -568,6 +672,46 @@ GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
|
||||
.get_cicp = gdk_cicp_color_state_get_cicp,
|
||||
};
|
||||
|
||||
GdkCicpColorState gdk_color_state_bt601_narrow = {
|
||||
.parent = {
|
||||
.klass = &GDK_CICP_COLOR_STATE_CLASS,
|
||||
.ref_count = 1,
|
||||
.depth = GDK_MEMORY_FLOAT16,
|
||||
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
|
||||
},
|
||||
.name = "cicp-1/13/6/0",
|
||||
.no_srgb = NULL,
|
||||
.cicp = { 1, 13, 6, 0 },
|
||||
.eotf = srgb_eotf,
|
||||
.oetf = srgb_oetf,
|
||||
.to_yuv = rgb_to_bt601,
|
||||
.from_yuv = bt601_to_rgb,
|
||||
.to_srgb = IDENTITY,
|
||||
.to_rec2020 = (float *) srgb_to_rec2020,
|
||||
.from_srgb = IDENTITY,
|
||||
.from_rec2020 = (float *) rec2020_to_srgb,
|
||||
};
|
||||
|
||||
GdkCicpColorState gdk_color_state_bt601_full = {
|
||||
.parent = {
|
||||
.klass = &GDK_CICP_COLOR_STATE_CLASS,
|
||||
.ref_count = 1,
|
||||
.depth = GDK_MEMORY_FLOAT16,
|
||||
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
|
||||
},
|
||||
.name = "cicp-1/13/6/1",
|
||||
.no_srgb = NULL,
|
||||
.cicp = { 1, 13, 6, 1 },
|
||||
.eotf = srgb_eotf,
|
||||
.oetf = srgb_oetf,
|
||||
.to_yuv = rgb_to_bt601,
|
||||
.from_yuv = bt601_to_rgb,
|
||||
.to_srgb = IDENTITY,
|
||||
.to_rec2020 = (float *) srgb_to_rec2020,
|
||||
.from_srgb = IDENTITY,
|
||||
.from_rec2020 = (float *) rec2020_to_srgb,
|
||||
};
|
||||
|
||||
static inline float *
|
||||
multiply (float res[9],
|
||||
const float m1[9],
|
||||
@@ -592,14 +736,8 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
GdkTransferFunc oetf;
|
||||
gconstpointer to_xyz;
|
||||
gconstpointer from_xyz;
|
||||
|
||||
if (cicp->range == GDK_CICP_RANGE_NARROW || cicp->matrix_coefficients != 0)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
_("cicp: Narrow range or YUV not supported"));
|
||||
return NULL;
|
||||
}
|
||||
gconstpointer to_yuv = NULL;
|
||||
gconstpointer from_yuv = NULL;
|
||||
|
||||
if (cicp->color_primaries == 2 ||
|
||||
cicp->transfer_function == 2 ||
|
||||
@@ -613,10 +751,16 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
|
||||
for (guint i = 0; i < GDK_COLOR_STATE_N_IDS; i++)
|
||||
{
|
||||
if (gdk_cicp_equivalent (cicp, &gdk_default_color_states[i].cicp))
|
||||
if (gdk_cicp_equal (cicp, &gdk_default_color_states[i].cicp))
|
||||
return (GdkColorState *) &gdk_default_color_states[i];
|
||||
}
|
||||
|
||||
if (gdk_cicp_equal (cicp, &gdk_color_state_bt601_narrow.cicp))
|
||||
return gdk_color_state_ref ((GdkColorState *) &gdk_color_state_bt601_narrow);
|
||||
|
||||
if (gdk_cicp_equal (cicp, &gdk_color_state_bt601_full.cicp))
|
||||
return gdk_color_state_ref ((GdkColorState *) &gdk_color_state_bt601_full);
|
||||
|
||||
switch (cicp->transfer_function)
|
||||
{
|
||||
case 1:
|
||||
@@ -669,6 +813,7 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
from_xyz = xyz_to_pal;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
to_xyz = ntsc_to_xyz;
|
||||
from_xyz = xyz_to_ntsc;
|
||||
break;
|
||||
@@ -688,6 +833,34 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (cicp->matrix_coefficients)
|
||||
{
|
||||
case 0:
|
||||
to_yuv = IDENTITY;
|
||||
from_yuv = IDENTITY;
|
||||
break;
|
||||
case 1:
|
||||
to_yuv = rgb_to_bt709;
|
||||
from_yuv = bt709_to_rgb;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
to_yuv = rgb_to_bt601;
|
||||
from_yuv = bt601_to_rgb;
|
||||
break;
|
||||
case 9:
|
||||
to_yuv = rgb_to_bt2020;
|
||||
from_yuv = bt2020_to_rgb;
|
||||
break;
|
||||
default:
|
||||
g_set_error (error,
|
||||
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
_("cicp: Matrix coefficients %u, %s not supported"),
|
||||
cicp->matrix_coefficients,
|
||||
cicp->range == GDK_CICP_RANGE_NARROW ? "narrow" : "full");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = g_new0 (GdkCicpColorState, 1);
|
||||
|
||||
self->parent.klass = &GDK_CICP_COLOR_STATE_CLASS;
|
||||
@@ -700,6 +873,9 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
|
||||
memcpy (&self->cicp, cicp, sizeof (GdkCicp));
|
||||
|
||||
self->to_yuv = to_yuv;
|
||||
self->from_yuv = from_yuv;
|
||||
|
||||
self->eotf = eotf;
|
||||
self->oetf = oetf;
|
||||
|
||||
|
||||
@@ -211,3 +211,10 @@ gdk_color_state_from_rgba (GdkColorState *self,
|
||||
out_color);
|
||||
}
|
||||
|
||||
#ifndef GDK_COLOR_STATE_IMPL
|
||||
extern GdkColorState gdk_color_state_bt601_narrow;
|
||||
extern GdkColorState gdk_color_state_bt601_full;
|
||||
#endif
|
||||
|
||||
#define GDK_COLOR_STATE_YUV ((GdkColorState *) &gdk_color_state_bt601_narrow)
|
||||
#define GDK_COLOR_STATE_JPEG ((GdkColorState *) &gdk_color_state_bt601_full)
|
||||
|
||||
@@ -36,7 +36,8 @@ gsk_gpu_convert_cicp_op_print_instance (GskGpuShaderOp *shader,
|
||||
g_string_append_printf (string, "cicp %u/%u/%u/%u",
|
||||
instance->color_primaries,
|
||||
instance->transfer_function,
|
||||
0, 1);
|
||||
instance->matrix_coefficients,
|
||||
instance->range);
|
||||
}
|
||||
|
||||
static const GskGpuShaderOpClass GSK_GPU_CONVERT_OP_CLASS = {
|
||||
@@ -88,6 +89,8 @@ gsk_gpu_convert_from_cicp_op (GskGpuFrame *frame,
|
||||
instance->opacity = opacity;
|
||||
instance->color_primaries = cicp->color_primaries;
|
||||
instance->transfer_function = cicp->transfer_function;
|
||||
instance->matrix_coefficients = cicp->matrix_coefficients;
|
||||
instance->range = cicp->range == GDK_CICP_RANGE_NARROW ? 0 : 1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -118,4 +121,6 @@ gsk_gpu_convert_to_cicp_op (GskGpuFrame *frame,
|
||||
instance->opacity = opacity;
|
||||
instance->color_primaries = cicp->color_primaries;
|
||||
instance->transfer_function = cicp->transfer_function;
|
||||
instance->matrix_coefficients = cicp->matrix_coefficients;
|
||||
instance->range = cicp->range == GDK_CICP_RANGE_NARROW ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ PASS(2) vec2 _tex_coord;
|
||||
PASS_FLAT(3) float _opacity;
|
||||
PASS_FLAT(4) uint _transfer_function;
|
||||
PASS_FLAT(5) mat3 _mat;
|
||||
PASS_FLAT(8) mat3 _yuv;
|
||||
PASS_FLAT(11) uint _range;
|
||||
|
||||
#ifdef GSK_VERTEX_SHADER
|
||||
|
||||
@@ -22,6 +24,8 @@ IN(1) vec4 in_tex_rect;
|
||||
IN(2) float in_opacity;
|
||||
IN(3) uint in_color_primaries;
|
||||
IN(4) uint in_transfer_function;
|
||||
IN(5) uint in_matrix_coefficients;
|
||||
IN(6) uint in_range;
|
||||
|
||||
|
||||
const mat3 identity = mat3(
|
||||
@@ -90,6 +94,42 @@ const mat3 xyz_to_p3 = mat3(
|
||||
-0.4027108, 0.0236247, 0.9568845
|
||||
);
|
||||
|
||||
const mat3 rgb_to_bt601 = mat3(
|
||||
0.299000, -0.168736, 0.500000,
|
||||
0.587000, -0.331264, -0.418688,
|
||||
0.114000, 0.500000, -0.081312
|
||||
);
|
||||
|
||||
const mat3 bt601_to_rgb = mat3(
|
||||
1.000000, 1.000000, 1.000000,
|
||||
0.000000, -0.344136, 1.772000,
|
||||
1.402000, -0.714136, 0.000000
|
||||
);
|
||||
|
||||
const mat3 rgb_to_bt709 = mat3(
|
||||
0.212600, -0.114572, 0.500000,
|
||||
0.715200, -0.385428, -0.454153,
|
||||
0.072200, 0.500000, -0.045847
|
||||
);
|
||||
|
||||
const mat3 bt709_to_rgb = mat3(
|
||||
1.000000, 1.000000, 1.000000,
|
||||
0.000000, -0.187324, 1.855600,
|
||||
1.574800, -0.468124, -0.000000
|
||||
);
|
||||
|
||||
const mat3 rgb_to_bt2020 = mat3(
|
||||
0.262700, -0.139630, 0.500000,
|
||||
0.678000, -0.360370, -0.459786,
|
||||
0.059300, 0.500000, -0.040214
|
||||
);
|
||||
|
||||
const mat3 bt2020_to_rgb = mat3(
|
||||
1.000000, 1.000000, 1.000000,
|
||||
-0.000000, -0.164553, 1.881400,
|
||||
1.474600, -0.571353, -0.000000
|
||||
);
|
||||
|
||||
mat3
|
||||
cicp_to_xyz (uint cp)
|
||||
{
|
||||
@@ -121,6 +161,34 @@ cicp_from_xyz (uint cp)
|
||||
}
|
||||
|
||||
|
||||
mat3
|
||||
yuv_to_rgb (uint mc)
|
||||
{
|
||||
switch (mc)
|
||||
{
|
||||
case 0u: return identity;
|
||||
case 1u: return bt709_to_rgb;
|
||||
case 5u:
|
||||
case 6u: return bt601_to_rgb;
|
||||
case 9u: return bt2020_to_rgb;
|
||||
}
|
||||
return mat3(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
|
||||
}
|
||||
|
||||
mat3
|
||||
rgb_to_yuv (uint mc)
|
||||
{
|
||||
switch (mc)
|
||||
{
|
||||
case 0u: return identity;
|
||||
case 1u: return rgb_to_bt709;
|
||||
case 5u:
|
||||
case 6u: return rgb_to_bt601;
|
||||
case 9u: return rgb_to_bt2020;
|
||||
}
|
||||
return mat3(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
|
||||
}
|
||||
|
||||
void
|
||||
run (out vec2 pos)
|
||||
{
|
||||
@@ -133,6 +201,7 @@ run (out vec2 pos)
|
||||
_tex_coord = rect_get_coord (rect_from_gsk (in_tex_rect), pos);
|
||||
_opacity = in_opacity;
|
||||
_transfer_function = in_transfer_function;
|
||||
_range = in_range;
|
||||
|
||||
if (HAS_VARIATION (VARIATION_REVERSE))
|
||||
{
|
||||
@@ -141,6 +210,8 @@ run (out vec2 pos)
|
||||
_mat = cicp_from_xyz (in_color_primaries) * srgb_to_xyz;
|
||||
else
|
||||
_mat = cicp_from_xyz (in_color_primaries) * rec2020_to_xyz;
|
||||
|
||||
_yuv = rgb_to_yuv (in_matrix_coefficients);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -149,6 +220,8 @@ run (out vec2 pos)
|
||||
_mat = xyz_to_srgb * cicp_to_xyz (in_color_primaries);
|
||||
else
|
||||
_mat = xyz_to_rec2020 * cicp_to_xyz (in_color_primaries);
|
||||
|
||||
_yuv = yuv_to_rgb (in_matrix_coefficients);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,6 +402,18 @@ convert_color_from_cicp (vec4 color,
|
||||
if (from_premul)
|
||||
color = color_unpremultiply (color);
|
||||
|
||||
if (_range == 0u)
|
||||
{
|
||||
color.r = (color.r - 16.0/255.0) * 255.0/219.0;
|
||||
color.g = (color.g - 16.0/255.0) * 255.0/224.0;
|
||||
color.b = (color.b - 16.0/255.0) * 255.0/224.0;
|
||||
}
|
||||
|
||||
color.g -= 0.5;
|
||||
color.b -= 0.5;
|
||||
|
||||
color.rgb = _yuv * color.rgb;
|
||||
|
||||
color.rgb = apply_cicp_eotf (color.rgb, _transfer_function);
|
||||
color.rgb = _mat * color.rgb;
|
||||
color.rgb = apply_oetf (color.rgb, to);
|
||||
@@ -352,6 +437,18 @@ convert_color_to_cicp (vec4 color,
|
||||
color.rgb = _mat * color.rgb;
|
||||
color.rgb = apply_cicp_oetf (color.rgb, _transfer_function);
|
||||
|
||||
color.rgb = _yuv * color.rgb;
|
||||
|
||||
color.g += 0.5;
|
||||
color.b += 0.5;
|
||||
|
||||
if (_range == 0u)
|
||||
{
|
||||
color.r = color.r * 219.0/255.0 + 16.0/255.0;
|
||||
color.g = color.g * 224.0/255.0 + 16.0/255.0;
|
||||
color.b = color.b * 224.0/255.0 + 16.0/255.0;
|
||||
}
|
||||
|
||||
if (to_premul)
|
||||
color = color_premultiply (color);
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ static MatrixTest matrices[] = {
|
||||
{ "ntsc", ntsc_to_xyz, xyz_to_ntsc },
|
||||
{ "p3", p3_to_xyz, xyz_to_p3 },
|
||||
{ "srgb<>rec2020", rec2020_to_srgb, srgb_to_rec2020 },
|
||||
{ "bt601", bt601_to_rgb, rgb_to_bt601 },
|
||||
{ "bt709", bt709_to_rgb, rgb_to_bt709 },
|
||||
{ "bt2020", bt2020_to_rgb, rgb_to_bt2020 },
|
||||
};
|
||||
|
||||
#define IDX(i,j) 3*i+j
|
||||
|
||||
Reference in New Issue
Block a user