wrong colors with Xv extension and image format id: 0x59565955 (UYVY) from an rgb mapping

Amos Tibaldi amos.tibaldi at gmail.com
Thu Jan 22 10:35:37 PST 2009


2009/1/22 Simon Farnsworth <simon.farnsworth at onelan.co.uk>

> Amos Tibaldi wrote:
> >     unsigned short int thecolor =  u << 12 | y << 8 | v << 4 | y;
> >
> This is completely wrong. In a UYVY image, you have two different 8-bit
> Y components, sharing an 8-bit U component, and an 8-bit V component. In
> pseudocode, creating a 32-bit UYVY pixel pair from two RGB pixels:
>
> (y, u, v) RGBtoYUV( r, g, b )
> {
>        y =  0.299 * r +
>             0.587 * g +
>             0.114 * b;
>
>        u = -0.147 * r +
>            -0.289 * g +
>             0.436 * b;
>
>        v =  0.615 * r +
>            -0.515 * g +
>            -0.100 * b;
> }
>
> uyvy RGBtoUYUV( r1, g1, b1, r2, g2, b2 )
> {
>        (y1,u1,v1) = RGBtoYUV( r1, g1, b1 )
>        (y2,u2,v2) = RGBtoYUV( r2, g2, b2 )
>
>        u = (u1 + u2) / 2; // Or other decimation strategy
>        v = (v1 + v2) / 2; // Or other decimation strategy
>
>        uyvy  = 8bits(u) << 24;
>        uyvy |= 8bits(y1) << 16;
>        uyvy |= 8bits(v) << 8;
>        uyvy |= 8bits(y2);
> }
> --
> Simon Farnsworth
>
>
You both are right, but for now I obtain only solid color that doesn't
correspond to the desired one; here is the code:

void RGBToUV(unsigned short int r,
                           unsigned short int g,
                           unsigned short int b,
                           unsigned short int * u,
                           unsigned short int * v)
{
        *u = -0.147 * r +
           -0.289 * g +
            0.436 * b; // min(abs(r * -1214 + g * -2384 + b * 3598 + 4096 +
1048576) >> 13, 240);
    //(unsigned short
int)(-0.147f*(float)r-0.289f*(float)g+0.436f*(float)b);
        *v = 0.615 * r +
           -0.515 * g +
           -0.100 * b;
    //min(abs(r * 3598 + g * -3013 + b * -585 + 4096 + 1048576) >> 13, 240);
    //(unsigned short int)(0.615f*(float)r-0.515f*(float)g-0.100f*(float)b);
}
void RGBToY(unsigned short int r,
                           unsigned short int g,
                           unsigned short int b,
                           unsigned short int * y
           )
{
   *y = 0.299 * r +
            0.587 * g +
            0.114 * b; // min(abs(r * 2104 + g * 4130 + b * 802 + 4096 +
131072) >> 13, 235);
//(unsigned short int)(0.299f*(float)r+0.587f*(float)g+0.114f*(float)b);
}

void XVWindow::Redraw()
{
    unsigned short int u, y1, y2, v;
    /*RGBToY(255,0,0,&y1);
    RGBToY(255,0,0,&y2);
    RGBToUV(255,0,0,&u,&v);*/
/*    RGBToY(0,255,0,&y1);
    RGBToY(0,255,0,&y2);
    RGBToUV(0,255,0,&u,&v); */
    RGBToY(0,0,255,&y1);
    RGBToY(0,0,255,&y2);
    RGBToUV(0,0,255,&u,&v);

    unsigned char * p = (unsigned char *) BGimage->data;
  for ( int y=0; y<ImageHeight; y++ , p += BGimage->pitches[0] )
   for ( int x=0; x<ImageWidth; x++ )
    {
      p [ (x << 1) + 3 ] = y2;
      p [ (x << 1) + 2 ] = v;
      p [ (x << 1) + 1 ] = y1;
      p [ (x << 1)     ] = u;
    }

    counter++;
            XvPutImage( xvc.display, xvc.port, window, gc,
                    BGimage, 0, 0, ImageWidth, ImageHeight,
                       0, 0, WindowWidth, WindowHeight );
}

I cannot understand but it works only if I use (x<<1). What can I do to
associate the colours correctly?


Thanks,

-- 
Amos Tibaldi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.x.org/archives/xorg/attachments/20090122/e910ea50/attachment.html>


More information about the xorg mailing list