2 #include <util/u_math.h>
3 #include <util/u_debug.h>
6 * Color space conversion formulas
8 * To convert YCbCr to RGB,
13 * To calculate the color space conversion matrix csc with ProcAmp adjustments,
14 * mat44 csc, cstd, procamp, bias
15 * csc = cstd * (procamp * bias)
17 * Where cstd is a matrix corresponding to one of the color standards (BT.601, BT.709, etc)
18 * adjusted for the kind of YCbCr -> RGB mapping wanted (1:1, full),
19 * bias is a matrix corresponding to the kind of YCbCr -> RGB mapping wanted (1:1, full)
21 * To calculate procamp,
22 * mat44 procamp, hue, saturation, brightness, contrast
23 * procamp = brightness * (saturation * (contrast * hue))
25 * procamp = saturation * (brightness * (contrast * hue))
47 * [ 0, cos(h), sin(h), 0]
48 * [ 0, -sin(h), cos(h), 0]
53 * [ 0, c*s*cos(h), c*s*sin(h), 0]
54 * [ 0, -c*s*sin(h), c*s*cos(h), 0]
64 * [ c*cstd[ 0], c*cstd[ 1]*s*cos(h) - c*cstd[ 2]*s*sin(h), c*cstd[ 2]*s*cos(h) + c*cstd[ 1]*s*sin(h), cstd[ 3] + cstd[ 0]*(b + c*ybias) + cstd[ 1]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[ 2]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
65 * [ c*cstd[ 4], c*cstd[ 5]*s*cos(h) - c*cstd[ 6]*s*sin(h), c*cstd[ 6]*s*cos(h) + c*cstd[ 5]*s*sin(h), cstd[ 7] + cstd[ 4]*(b + c*ybias) + cstd[ 5]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[ 6]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
66 * [ c*cstd[ 8], c*cstd[ 9]*s*cos(h) - c*cstd[10]*s*sin(h), c*cstd[10]*s*cos(h) + c*cstd[ 9]*s*sin(h), cstd[11] + cstd[ 8]*(b + c*ybias) + cstd[ 9]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[10]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
67 * [ c*cstd[12], c*cstd[13]*s*cos(h) - c*cstd[14]*s*sin(h), c*cstd[14]*s*cos(h) + c*cstd[13]*s*sin(h), cstd[15] + cstd[12]*(b + c*ybias) + cstd[13]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[14]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
71 * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
72 * Y is in [16,235], Cb and Cr are in [16,240]
73 * R, G, and B are in [16,235]
75 static const float bt_601
[16] =
77 1.0f
, 0.0f
, 1.371f
, 0.0f
,
78 1.0f
, -0.336f
, -0.698f
, 0.0f
,
79 1.0f
, 1.732f
, 0.0f
, 0.0f
,
80 0.0f
, 0.0f
, 0.0f
, 1.0f
84 * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
85 * Y is in [16,235], Cb and Cr are in [16,240]
86 * R, G, and B are in [0,255]
88 static const float bt_601_full
[16] =
90 1.164f
, 0.0f
, 1.596f
, 0.0f
,
91 1.164f
, -0.391f
, -0.813f
, 0.0f
,
92 1.164f
, 2.018f
, 0.0f
, 0.0f
,
93 0.0f
, 0.0f
, 0.0f
, 1.0f
97 * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
98 * Y is in [16,235], Cb and Cr are in [16,240]
99 * R, G, and B are in [16,235]
101 static const float bt_709
[16] =
103 1.0f
, 0.0f
, 1.540f
, 0.0f
,
104 1.0f
, -0.183f
, -0.459f
, 0.0f
,
105 1.0f
, 1.816f
, 0.0f
, 0.0f
,
106 0.0f
, 0.0f
, 0.0f
, 1.0f
110 * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
111 * Y is in [16,235], Cb and Cr are in [16,240]
112 * R, G, and B are in [0,255]
114 static const float bt_709_full
[16] =
116 1.164f
, 0.0f
, 1.793f
, 0.0f
,
117 1.164f
, -0.213f
, -0.534f
, 0.0f
,
118 1.164f
, 2.115f
, 0.0f
, 0.0f
,
119 0.0f
, 0.0f
, 0.0f
, 1.0f
122 static const float identity
[16] =
124 1.0f
, 0.0f
, 0.0f
, 0.0f
,
125 0.0f
, 1.0f
, 0.0f
, 0.0f
,
126 0.0f
, 0.0f
, 1.0f
, 0.0f
,
127 0.0f
, 0.0f
, 0.0f
, 1.0f
130 void vl_csc_get_matrix(enum VL_CSC_COLOR_STANDARD cs
,
131 struct vl_procamp
*procamp
,
135 float ybias
= full_range
? -16.0f
/255.0f
: 0.0f
;
136 float cbbias
= -128.0f
/255.0f
;
137 float crbias
= -128.0f
/255.0f
;
138 float c
= procamp
? procamp
->contrast
: 1.0f
;
139 float s
= procamp
? procamp
->saturation
: 1.0f
;
140 float b
= procamp
? procamp
->brightness
: 0.0f
;
141 float h
= procamp
? procamp
->hue
: 0.0f
;
147 case VL_CSC_COLOR_STANDARD_BT_601
:
148 cstd
= full_range
? &bt_601_full
[0] : &bt_601
[0];
150 case VL_CSC_COLOR_STANDARD_BT_709
:
151 cstd
= full_range
? &bt_709_full
[0] : &bt_709
[0];
153 case VL_CSC_COLOR_STANDARD_IDENTITY
:
155 assert(cs
== VL_CSC_COLOR_STANDARD_IDENTITY
);
156 memcpy(matrix
, &identity
[0], sizeof(float) * 16);
160 matrix
[ 0] = c
*cstd
[ 0];
161 matrix
[ 1] = c
*cstd
[ 1]*s
*cosf(h
) - c
*cstd
[ 2]*s
*sinf(h
);
162 matrix
[ 2] = c
*cstd
[ 2]*s
*cosf(h
) + c
*cstd
[ 1]*s
*sinf(h
);
163 matrix
[ 3] = cstd
[ 3] + cstd
[ 0]*(b
+ c
*ybias
) + cstd
[ 1]*(c
*cbbias
*s
*cosf(h
) + c
*crbias
*s
*sinf(h
)) + cstd
[ 2]*(c
*crbias
*s
*cosf(h
) - c
*cbbias
*s
*sinf(h
));
165 matrix
[ 4] = c
*cstd
[ 4];
166 matrix
[ 5] = c
*cstd
[ 5]*s
*cosf(h
) - c
*cstd
[ 6]*s
*sinf(h
);
167 matrix
[ 6] = c
*cstd
[ 6]*s
*cosf(h
) + c
*cstd
[ 5]*s
*sinf(h
);
168 matrix
[ 7] = cstd
[ 7] + cstd
[ 4]*(b
+ c
*ybias
) + cstd
[ 5]*(c
*cbbias
*s
*cosf(h
) + c
*crbias
*s
*sinf(h
)) + cstd
[ 6]*(c
*crbias
*s
*cosf(h
) - c
*cbbias
*s
*sinf(h
));
170 matrix
[ 8] = c
*cstd
[ 8];
171 matrix
[ 9] = c
*cstd
[ 9]*s
*cosf(h
) - c
*cstd
[10]*s
*sinf(h
);
172 matrix
[10] = c
*cstd
[10]*s
*cosf(h
) + c
*cstd
[ 9]*s
*sinf(h
);
173 matrix
[11] = cstd
[11] + cstd
[ 8]*(b
+ c
*ybias
) + cstd
[ 9]*(c
*cbbias
*s
*cosf(h
) + c
*crbias
*s
*sinf(h
)) + cstd
[10]*(c
*crbias
*s
*cosf(h
) - c
*cbbias
*s
*sinf(h
));
175 matrix
[12] = c
*cstd
[12];
176 matrix
[13] = c
*cstd
[13]*s
*cos(h
) - c
*cstd
[14]*s
*sin(h
);
177 matrix
[14] = c
*cstd
[14]*s
*cos(h
) + c
*cstd
[13]*s
*sin(h
);
178 matrix
[15] = cstd
[15] + cstd
[12]*(b
+ c
*ybias
) + cstd
[13]*(c
*cbbias
*s
*cos(h
) + c
*crbias
*s
*sin(h
)) + cstd
[14]*(c
*crbias
*s
*cos(h
) - c
*cbbias
*s
*sin(h
));