- // Matrix to convert RGB to YCbCr. See e.g. Rec. 601.
- Matrix3d rgb_to_ycbcr;
- rgb_to_ycbcr(0,0) = coeff[0];
- rgb_to_ycbcr(0,1) = coeff[1];
- rgb_to_ycbcr(0,2) = coeff[2];
-
- float cb_fac = (224.0 / 219.0) / (coeff[0] + coeff[1] + 1.0f - coeff[2]);
- rgb_to_ycbcr(1,0) = -coeff[0] * cb_fac;
- rgb_to_ycbcr(1,1) = -coeff[1] * cb_fac;
- rgb_to_ycbcr(1,2) = (1.0f - coeff[2]) * cb_fac;
-
- float cr_fac = (224.0 / 219.0) / (1.0f - coeff[0] + coeff[1] + coeff[2]);
- rgb_to_ycbcr(2,0) = (1.0f - coeff[0]) * cr_fac;
- rgb_to_ycbcr(2,1) = -coeff[1] * cr_fac;
- rgb_to_ycbcr(2,2) = -coeff[2] * cr_fac;
-
- // Inverting the matrix gives us what we need to go from YCbCr back to RGB.
- Matrix3d ycbcr_to_rgb = rgb_to_ycbcr.inverse();
-
- // Fold in the scaling.
- ycbcr_to_rgb *= Map<const Vector3d>(scale).asDiagonal();
-
- string frag_shader;
-
- frag_shader = output_glsl_mat3("PREFIX(inv_ycbcr_matrix)", ycbcr_to_rgb);
- frag_shader += output_glsl_vec3("PREFIX(offset)", offset[0], offset[1], offset[2]);
-
- float cb_offset_x = compute_chroma_offset(
- ycbcr_format.cb_x_position, ycbcr_format.chroma_subsampling_x, widths[1]);
- float cb_offset_y = compute_chroma_offset(
- ycbcr_format.cb_y_position, ycbcr_format.chroma_subsampling_y, heights[1]);
- frag_shader += output_glsl_vec2("PREFIX(cb_offset)", cb_offset_x, cb_offset_y);
-
- float cr_offset_x = compute_chroma_offset(
- ycbcr_format.cr_x_position, ycbcr_format.chroma_subsampling_x, widths[2]);
- float cr_offset_y = compute_chroma_offset(
- ycbcr_format.cr_y_position, ycbcr_format.chroma_subsampling_y, heights[2]);
- frag_shader += output_glsl_vec2("PREFIX(cr_offset)", cr_offset_x, cr_offset_y);
-