• 2004-12-03

    YUV2RGB565(16位色)

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://ffmpeg.blogbus.com/logs/525422.html

    lcd显示器是多少位色的啊?俺不知道,人家说都用16位色(rgb565),那俺就学学这个怎么转换来着。如果用公式的话,又是乘法,又是饱和,又是移位,又是或的,会把人累死的:(.不过SDL里有个查表的算法不错,分析一下。

    下面是一个表的初始化。

    swdata->pixels = (Uint8 *) malloc(width*height*2);
     swdata->colortab = (int *)malloc(4*256*sizeof(int));
     Cr_r_tab = &swdata->colortab[0*256];
     Cr_g_tab = &swdata->colortab[1*256];
     Cb_g_tab = &swdata->colortab[2*256];
     Cb_b_tab = &swdata->colortab[3*256];
     swdata->rgb_2_pix = (Uint32 *)malloc(3*768*sizeof(Uint32));
     r_2_pix_alloc = &swdata->rgb_2_pix[0*768];
     g_2_pix_alloc = &swdata->rgb_2_pix[1*768];
     b_2_pix_alloc = &swdata->rgb_2_pix[2*768];

     for (i=0; i<256; i++) {
      /* 这里的一个表是为乘法做的一个表*/
      CB = CR = (i-128);
      Cr_r_tab[i] = (int) ( (0.419/0.299) * CR);
      Cr_g_tab[i] = (int) (-(0.299/0.419) * CR);
      Cb_g_tab[i] = (int) (-(0.114/0.331) * CB);
      Cb_b_tab[i] = (int) ( (0.587/0.331) * CB);
     }

     Rmask = display->format->Rmask;
     Gmask = display->format->Gmask;
     Bmask = display->format->Bmask;
     for ( i=0; i<256; ++i ) {

    /*这个表是为饱和做的,并且已经做好了移位,到查表的时候只要将这几个rgb的值或起来即可,r被饱和到0~0xf800之间(高5位有值),g被饱和到0~0x07e0之间(中间6位有值),b被饱和到0~0x001f之间(低5位有值)*/
      r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask));
      r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask);
      g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask));
      g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask);
      b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask));
      b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask);
     }

    下面是使用部分代码,也就是查表过程

    /*前面那个768的系数其实是算在第二个表的偏移上的,因为y部分数据要使用四次,所以提前到cb,cr里面*/
    cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
    crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
                       + colortab[ *cb + 2*256 ];
    cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
                ++cr; ++cb;

    L = *lum++;/*将3个值或起来,构成rgb565,没什么好说的。*/
    *row1++ = (rgb_2_pix[ L + cr_r ] |
              rgb_2_pix[ L + crb_g ] |
               rgb_2_pix[ L + cb_b ]);

     


    收藏到:Del.icio.us