Inside IPU there are two block where color space conversion can be made: IC (Image Converter) and DP (Display processor).  On Linux, the CSC parameters are located at IPU (IC and DP) drivers, linux/drivers/mxc/ipu3 folder.    All negative coefficients are represented using two's complement.    Linux Image Converter driver:    The parameters are set on function _init_csc:    http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/mxc/ipu3/ipu_ic.c?h=imx_3.14.28_1.0.0_ga     static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
 ipu_color_space_t out_format, int csc_index)
{
 /*
 * Y = 0.257 * R + 0.504 * G + 0.098 * B + 16;
 * U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
 * V = 0.439 * R - 0.368 * G - 0.071 * B + 128;
 */
 static const uint32_t rgb2ycbcr_coeff[4][3] = {
 {0x0042, 0x0081, 0x0019},
 {0x01DA, 0x01B6, 0x0070},
 {0x0070, 0x01A2, 0x01EE},
 {0x0040, 0x0200, 0x0200}, /* A0, A1, A2 */
 };
 /* transparent RGB->RGB matrix for combining
 */
 static const uint32_t rgb2rgb_coeff[4][3] = {
 {0x0080, 0x0000, 0x0000},
 {0x0000, 0x0080, 0x0000},
 {0x0000, 0x0000, 0x0080},
 {0x0000, 0x0000, 0x0000}, /* A0, A1, A2 */
 };
/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
  G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
  B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
 static const uint32_t ycbcr2rgb_coeff[4][3] = {
 {149, 0, 204},
 {149, 462, 408},
 {149, 255, 0},
 {8192 - 446, 266, 8192 - 554}, /* A0, A1, A2 */
 };
       Linux Display Processor driver:    The parameters are set on constants (rgb2ycbcr_coeff and ycbcr2rgb_coeff):    http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/mxc/ipu3/ipu_disp.c?h=imx_3.14.28_1.0.0_ga     /* Y = R * 1.200 + G * 2.343 + B * .453 + 0.250;
  U = R * -.672 + G * -1.328 + B * 2.000 + 512.250.;
  V = R * 2.000 + G * -1.672 + B * -.328 + 512.250.;*/
static const int rgb2ycbcr_coeff[5][3] = {
 {0x4D, 0x96, 0x1D},
 {-0x2B, -0x55, 0x80},
 {0x80, -0x6B, -0x15},
 {0x0000, 0x0200, 0x0200}, /* B0, B1, B2 */
 {0x2, 0x2, 0x2}, /* S0, S1, S2 */
};
/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
  G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
  B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
static const int ycbcr2rgb_coeff[5][3] = {
 {0x095, 0x000, 0x0CC},
 {0x095, 0x3CE, 0x398},
 {0x095, 0x0FF, 0x000},
 {0x3E42, 0x010A, 0x3DD6}, /*B0,B1,B2 */
 {0x1, 0x1, 0x1}, /*S0,S1,S2 */
};    
        
        View full article