顏色空間轉換:libjpg中從RGB到YCbCr的轉換過程

轉換公式:

Y   = Kr * R + (1 - Kr - Kb) * G + Kb * B
Cb = 0.5 * (B - Y) / (1 - Kb)
Cr = 0.5 * (R - Y) / (1 - Kr)

其中:

Kr=0.299 , Kb=0.114

Y  =  0.299 * R + 0.587 * G + 0.114 * B
Cb = -0.168735892 * R - 0.331264108 * G + 0.5 * B + 128
Cr =  0.5 * R - 0.418687589 * G - 0.081312411 * B + 128

#define SCALEBITS    16    /* speediest right-shift on some machines */
#define CBCR_OFFSET    ((INT32) CENTERJSAMPLE << SCALEBITS)
#define ONE_HALF    ((INT32) 1 << (SCALEBITS-1))
#define FIX(x)        ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))

#define R_Y_OFF        0            /* offset to R => Y section */
#define G_Y_OFF        (1*(MAXJSAMPLE+1))    /* offset to G => Y section */
#define B_Y_OFF        (2*(MAXJSAMPLE+1))    /* etc. */
#define R_CB_OFF    (3*(MAXJSAMPLE+1))
#define G_CB_OFF    (4*(MAXJSAMPLE+1))
#define B_CB_OFF    (5*(MAXJSAMPLE+1))
#define R_CR_OFF    B_CB_OFF        /* B=>Cb, R=>Cr are the same */
#define G_CR_OFF    (6*(MAXJSAMPLE+1))
#define B_CR_OFF    (7*(MAXJSAMPLE+1))
#define TABLE_SIZE    (8*(MAXJSAMPLE+1))

#define RGB_RED        0    /* Offset of Red in an RGB scanline element */
#define RGB_GREEN    1    /* Offset of Green */
#define RGB_BLUE    2    /* Offset of Blue */
#define RGB_PIXELSIZE    3    /* JSAMPLEs per RGB scanline element */


初始化查找表:

for (i = 0; i <= MAXJSAMPLE; i++) {
    rgb2ycc_tab[i+R_Y_OFF] = FIX(0.299) * i;
    rgb2ycc_tab[i+G_Y_OFF] = FIX(0.587) * i;
    rgb2ycc_tab[i+B_Y_OFF] = FIX(0.114) * i   + ONE_HALF;
    rgb2ycc_tab[i+R_CB_OFF] = (-FIX(0.168735892)) * i;
    rgb2ycc_tab[i+G_CB_OFF] = (-FIX(0.331264108)) * i;
    /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
     * This ensures that the maximum output will round to MAXJSAMPLE
     * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
     */
    rgb2ycc_tab[i+B_CB_OFF] = FIX(0.5) * i    + CBCR_OFFSET + ONE_HALF-1;
/*  B=>Cb and R=>Cr tables are the same
    rgb2ycc_tab[i+R_CR_OFF] = FIX(0.5) * i    + CBCR_OFFSET + ONE_HALF-1;
*/
    rgb2ycc_tab[i+G_CR_OFF] = (-FIX(0.418687589)) * i;
    rgb2ycc_tab[i+B_CR_OFF] = (-FIX(0.081312411)) * i;
  }
  
  轉換一行數據
    inptr = *input_buf++;
    outptr0 = output_buf[0][output_row];
    outptr1 = output_buf[1][output_row];
    outptr2 = output_buf[2][output_row];
    output_row++;
    for (col = 0; col < num_cols; col++) {
      r = GETJSAMPLE(inptr[RGB_RED]);
      g = GETJSAMPLE(inptr[RGB_GREEN]);
      b = GETJSAMPLE(inptr[RGB_BLUE]);
      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
       * must be too; we do not need an explicit range-limiting operation.
       * Hence the value being shifted is never negative, and we don't
       * need the general RIGHT_SHIFT macro.
       */
      /* Y */
      outptr0[col] = (JSAMPLE)
        ((rgb2ycc_tab[r+R_Y_OFF] + rgb2ycc_tab[g+G_Y_OFF] + rgb2ycc_tab[b+B_Y_OFF])
         >> SCALEBITS);
      /* Cb */
      outptr1[col] = (JSAMPLE)
        ((rgb2ycc_tab[r+R_CB_OFF] + rgb2ycc_tab[g+G_CB_OFF] + rgb2ycc_tab[b+B_CB_OFF])
         >> SCALEBITS);
      /* Cr */
      outptr2[col] = (JSAMPLE)
        ((rgb2ycc_tab[r+R_CR_OFF] + rgb2ycc_tab[g+G_CR_OFF] + rgb2ycc_tab[b+B_CR_OFF])
         >> SCALEBITS);
      inptr += RGB_PIXELSIZE;
    }
  

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章