YUV422 <-> RGB Conversion

YUV422 <-> RGB Conversion

Post by anonymou » Sun, 14 Jan 2001 12:43:37



Hi,

I'm trying to decode a data source, which in the YUV422 format. (this is the
only format
it specify, no more details), Searching through many reference, I manage to
get the idea of YUV
color format, and found some source for YUV <-> RGB Conversion. However,
application
of these formula doesn't work, except for the Y component, which is exactly
match as documented,

So I'm now only able to get quite well B&W ( 8 bit grey scale actually)
result.

I think the color decoding may not as straight forward as to just apply the
single
formula as R = Y + V for eg.

Below is the attached code,  hopefully your can point me to the correct
direction,
Thank in advance.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ This code is on microsoft windows using visual C++, and o Intel platform ]

    // Prototype.
    void iYUV422toRGB(byte *U, byte *Y, byte *V, byte *R, byte *G, byte *B);

    while(1)
    {
            for (row = 0; row < CAP_HEIGHT; row++)
            {
                // same as the fread(), read CAP_WIDTH*2 bytes, into buffer.
                if (!ReadFile(hBitmapFile,buffer, CAP_WIDTH*2,&lrc,NULL))
                {
                    MessageBox(ghwnd,TEXT("Cannot read file"),TEXT("
"),MB_OK);
                    break;
                }

                if (lrc == 0)
                    break;

                index = 0;

                // UYVY
                for (col = 0; col < CAP_WIDTH; col+=2)
                {

                    // Lowest byte  | U0 | Y0 | V0 | Y1 |    | U2 | Y2 | V2
| Y3 |
                    U0 = buffer[index] ;
                    Y0 = buffer[index+1];
                    V0 = buffer[index+2];
                    Y1 = buffer[index+3];

                    // Pass-in address for faster processing.
                    iYUV422toRGB(&U0, &Y0, &V0, &Red, &Green, &Blue);

                    SetPixel(memdc, col, row+30, RGB(Red,Green,Blue));
                    iYUV422toRGB(&U0, &Y1, &V0, &Red, &Green, &Blue);
                    SetPixel(memdc, col+1, row+30, RGB(Red,Green,Blue));
                    index += 4;
                }
            }

    }

/*
    -179 < R < +433
    -135 < G < +390
    -227 < B < +365
    -179, -135 & -227 = c in y=mx+c
*/
void iYUV422toRGB(byte *U, byte *Y, byte *V, byte *R, byte *G, byte *B)
{

    int temp;
    int iR, iG, iB;

    iR = (1.164 * (*Y-16)) + (1.596 *(*V - 128));
    iG = (1.164 * (*Y-16)) - (0.391 *(*U))  - (0.813*(*V - 128));
    iB = (1.164 * (*Y-16)) + (2.018 *(*U - 128));

    // using y = mx + c, where m = (range of max Y to y-intersection,c ) /
255.

    // RED
    temp = ((255 * iR) + 45645) / 612;
    *R = temp;

    // GREEN
    temp = ((255 * iG) + 34425) / 525;
    *G = temp;

    // BLUE
    temp = ((255 * iB) + 57885) / 642;
    *B = temp;

Quote:}

Below is debug info with the real data of a row, which contains blue color
for your reference.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

row 120 col  49 : U0 223 Y0  58 V0  31 Y1  67 iR 89 iG 6 iB 281 - R 115 G 72
B 205
row 120 col  50 : U0 223 Y0  66 V0 191 Y1  66 iR 257 iG -66 iB 289 - R 181 G
33 B 204
row 120 col  51 : U0 223 Y0  66 V0 191 Y1  66 iR 257 iG -66 iB 289 - R 181 G
33 B 204
row 120 col  52 : U0 255 Y0  74 V0  31 Y1  75 iR 105 iG 17 iB 329 - R 118 G
73 B 220
row 120 col  53 : U0 255 Y0  74 V0  31 Y1  75 iR 105 iG 17 iB 329 - R 118 G
74 B 221
row 120 col  54 : U0  63 Y0  51 V0  63 Y1  51 iR 114 iG 10 iB 114 - R 122 G
70 B 135
row 120 col  55 : U0  63 Y0  51 V0  63 Y1  51 iR 114 iG 10 iB 114 - R 122 G
70 B 135
row 120 col  56 : U0  95 Y0  51 V0  95 Y1  51 iR 146 iG -11 iB 146 - R 135 G
60 B 148
row 120 col  57 : U0  95 Y0  51 V0  95 Y1  51 iR 146 iG -11 iB 146 - R 135 G
60 B 148
row 120 col  58 : U0  63 Y0  59 V0  63 Y1  59 iR 122 iG 18 iB 122 - R 125 G
74 B 138
row 120 col  59 : U0  63 Y0  59 V0  63 Y1  59 iR 122 iG 18 iB 122 - R 125 G
74 B 138
row 120 col  60 : U0  31 Y0  75 V0  31 Y1  75 iR 106 iG 55 iB 106 - R 118 G
92 B 132
row 120 col  61 : U0  31 Y0  75 V0  31 Y1  75 iR 106 iG 55 iB 106 - R 118 G
92 B 132
row 120 col  62 : U0 255 Y0  74 V0 255 Y1  74 iR 329 iG -95 iB 329 - R 211 G
19 B 220
row 120 col  63 : U0 255 Y0  74 V0 255 Y1  74 iR 329 iG -95 iB 329 - R 211 G
19 B 220
row 120 col  64 : U0 255 Y0  66 V0 255 Y1  66 iR 321 iG -103 iB 321 - R 208
G 15 B 217
row 120 col  65 : U0 255 Y0  66 V0 255 Y1  66 iR 321 iG -103 iB 321 - R 208
G 15 B 217
row 120 col  66 : U0  31 Y0  67 V0 255 Y1  66 iR 322 iG -65 iB 98 - R 208 G
34 B 129
row 120 col  67 : U0  31 Y0  67 V0 255 Y1  66 iR 322 iG -65 iB 98 - R 208 G
33 B 128
row 120 col  68 : U0  63 Y0  59 V0  63 Y1  59 iR 122 iG 18 iB 122 - R 125 G
74 B 138
row 120 col  69 : U0  63 Y0  59 V0  63 Y1  59 iR 122 iG 18 iB 122 - R 125 G
74 B 138
row 120 col  70 : U0  95 Y0  51 V0  95 Y1  51 iR 146 iG -11 iB 146 - R 135 G
60 B 148
row 120 col  71 : U0  95 Y0  51 V0  95 Y1  51 iR 146 iG -11 iB 146 - R 135 G
60 B 148
row 120 col  72 : U0  63 Y0  51 V0  63 Y1  51 iR 114 iG 10 iB 114 - R 122 G
70 B 135
row 120 col  73 : U0  63 Y0  51 V0  63 Y1  51 iR 114 iG 10 iB 114 - R 122 G
70 B 135
row 120 col  74 : U0  63 Y0  51 V0  63 Y1  51 iR 114 iG 10 iB 114 - R 122 G
70 B 135
row 120 col  75 : U0  63 Y0  51 V0  63 Y1  51 iR 114 iG 10 iB 114 - R 122 G
70 B 135
row 120 col  76 : U0  63 Y0  59 V0  31 Y1  59 iR 90 iG 34 iB 122 - R 112 G
82 B 138
row 120 col  77 : U0  63 Y0  59 V0  31 Y1  59 iR 90 iG 34 iB 122 - R 112 G
82 B 138
row 120 col  78 : U0  31 Y0  75 V0  31 Y1  75 iR 106 iG 55 iB 106 - R 118 G
92 B 132
row 120 col  79 : U0  31 Y0  75 V0  31 Y1  75 iR 106 iG 55 iB 106 - R 118 G
92 B 132
row 120 col  80 : U0 223 Y0  74 V0 223 Y1  74 iR 297 iG -74 iB 297 - R 198 G
29 B 208
row 120 col  81 : U0 223 Y0  74 V0 223 Y1  74 iR 297 iG -74 iB 297 - R 198 G
29 B 208

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 
 
 

YUV422 <-> RGB Conversion

Post by Mike Tull » Thu, 18 Jan 2001 09:29:27


On Sat, 13 Jan 2001 11:43:37 +0800, "anonymous"


>I'm trying to decode a data source, which in the YUV422 format. (this is the
>only format it specify, no more details), Searching through many reference, I manage to
>get the idea of YUV color format, and found some source for YUV <-> RGB Conversion. However,
>application of these formula doesn't work, except for the Y component, which is exactly
>match as documented,
>So I'm now only able to get quite well B&W ( 8 bit grey scale actually)
>result.
>I think the color decoding may not as straight forward as to just apply the
>single formula as R = Y + V for eg.
>Below is the attached code,  hopefully your can point me to the correct
>direction,

The basic equations to convert between YUV and gamma-corrected RGB
are:

R = Y + 1.140V
G = Y - 0.395U - 0.581V
B = Y + 2.032U

For digital RGB values with a range of 0 to 255, Y has a range of 0 to
255, U a range of 0 to +/- 112, and V a range of 0 to +/- 157. These
equations are usually scaled to simplify the implementation in an
actual NTSC or PAL digital encoder or decoder.
I didn't actually read your code,

Make sure you're sorting out the 4:2:2 part, which implies the format
of the byte stream representing the pixels.

Two adjacent pixels require 4 bytes, with 2 bytes of luma and 2 bytes
of chroma (hence 4:2:2 format). The colour information in these pixels
is not for every pixel, but for every 2-pixel group. In other words,
the chroma information (but not the luma) has been compressed 2:1 as
compared to 24-bit RGB.

Byte 0: Y0 luma for pixel 0
Byte 1: U for pixels 0 & 1
Byte 2: Y1 luma for pixel 1
Byte 3: V for pixels 0 & 1

Byte for: Y2 luma for pixel 2
etc.

Good luck!
Mike Tulley ("net") = f("ofu")
(my real e-mail address) = f("nlutztAufmvtqmbofu/ofu")

 
 
 

YUV422 <-> RGB Conversion

Post by Michael Morriso » Fri, 19 Jan 2001 12:09:23


Code always works.....
You'll need to hack on this stuff a bit to get it to compile.
This code uses integer math instead of floating point.

Mike

Mike Tulley wrote:
> On Sat, 13 Jan 2001 11:43:37 +0800, "anonymous"
> <nwxyznospamp...@pc.jaring.my> wrote:

> >I'm trying to decode a data source, which in the YUV422 format. (this is the
> >only format it specify, no more details), Searching through many reference, I manage to
> >get the idea of YUV color format, and found some source for YUV <-> RGB Conversion. However,
> >application of these formula doesn't work, except for the Y component, which is exactly
> >match as documented,
> >So I'm now only able to get quite well B&W ( 8 bit grey scale actually)
> >result.
> >I think the color decoding may not as straight forward as to just apply the
> >single formula as R = Y + V for eg.
> >Below is the attached code,  hopefully your can point me to the correct
> >direction,

> The basic equations to convert between YUV and gamma-corrected RGB
> are:

> R = Y + 1.140V
> G = Y - 0.395U - 0.581V
> B = Y + 2.032U

> For digital RGB values with a range of 0 to 255, Y has a range of 0 to
> 255, U a range of 0 to +/- 112, and V a range of 0 to +/- 157. These
> equations are usually scaled to simplify the implementation in an
> actual NTSC or PAL digital encoder or decoder.
> I didn't actually read your code,

> Make sure you're sorting out the 4:2:2 part, which implies the format
> of the byte stream representing the pixels.

> Two adjacent pixels require 4 bytes, with 2 bytes of luma and 2 bytes
> of chroma (hence 4:2:2 format). The colour information in these pixels
> is not for every pixel, but for every 2-pixel group. In other words,
> the chroma information (but not the luma) has been compressed 2:1 as
> compared to 24-bit RGB.

> Byte 0: Y0 luma for pixel 0
> Byte 1: U for pixels 0 & 1
> Byte 2: Y1 luma for pixel 1
> Byte 3: V for pixels 0 & 1

> Byte for: Y2 luma for pixel 2
> etc.

> Good luck!
> Mike Tulley ("net") = f("ofu")
> (my real e-mail address) = f("nlutztAufmvtqmbofu/ofu")

[ yuvrgb.c 3K ]

typedef struct
    {
    int magic;
    int xsize, ysize;
    int depth;
    int colors;
    uint8 *r, *g, *b;
    } RawRGB;

#define limit(x)         \
    {                    \
    if( (x) > 0xffffff) \
        (x) = 0xffffff; \
    if( (x) <= 0xffff )  \
        (x) = 0;         \
    x &= 0xff0000;      \
    }

/** \fn int rgb2yuv( uint8 *buffer, RawRGB *rgbP )
 * Converts image data to yuv.  Image data is on rgbP and ends up
 * in buffer
 *
 * \param buffer place to write YUV data
 * \param rgbP holds rgb data for the image to be converted
 *
 * \return Always returns 0.
 */
int rgb2yuv( uint8 *buffer, RawRGB *rgbP )
    {
    register int i,j;

    int r, g, b;
    long y1, y2, u, v, u0, u1, u2, v0, v1, v2;

    uint8 *rP;
    uint8 *gP;
    uint8 *bP;

    uint8 *yuvP;

    yuvP = buffer;

    rP = rgbP->r;
    gP = rgbP->g;
    bP = rgbP->b;

    for( i = 0; i < rgbP->ysize; i++ )
        {
        u = v = y2 = u0 = v0 = 0;

        for( j = 0; j < rgbP->xsize / 2; j++ )
            {
            /* first pixel gives Y and 0.5 of chroma */
            r = *rP++;
            g = *gP++;
            b = *bP++;

            y1  =    16829*r +  33039*g +  6416*b + (0xFFFF & y2);
            u1  =    -4857*r +  -9535*g + 14393*b;
            v1  =    14392*r + -12052*g + -2340*b;

            /* second pixel just yields a Y and 0.25 U, 0.25 V */
            r = *rP++;
            g = *gP++;
            b = *bP++;

            y2  =    16829*r +  33039*g +  6416*b + (0xFFFF & y1);
            u2  =    -2429*r +  -4767*g +  7192*b;
            v2  =     7196*r +  -6026*g + -1170*b;

            /* Filter the chroma */
            u = u0 + u1 + u2 + (0xFFFF & u);
            v = v0 + v1 + v2 + (0xFFFF & v);
            u0 = u2;
            v0 = v2;

            *yuvP++ = (u  >> 16) +  0x80;
            *yuvP++ = (y1 >> 16) +  0x10;
            *yuvP++ = (v  >> 16) +  0x80;
            *yuvP++ = (y2 >> 16) +  0x10;
            }
        }
    return 0;
    }

/** \fn int yuv2rgb( uint8 *buffer, RawRGB *rgbP )
 * Converts yuv data to raw RGB.  Image data is in buffer and ends up
 * in rgbP
 *
 * \param buffer full of YUV data
 * \param rgbP place to put result
 *
 * \return Always returns 0.
 */
int yuv2rgb( uint8 *buffer, RawRGB *rgbP )
    {
    register int i,j;

    int32 y,u,v,y1,r,g,b;

    uint8 *yuvP;
    uint8 *rP;
    uint8 *gP;
    uint8 *bP;

    if( rgbP->r == (uint8 *)NULL )
        rgbP->r = (uint8 *)malloc(rgbP->xsize*rgbP->ysize*(rgbP->depth/8));

    if( rgbP->g == (uint8 *)NULL )
        rgbP->g = (uint8 *)malloc(rgbP->xsize*rgbP->ysize*(rgbP->depth/8));

    if( rgbP->b == (uint8 *)NULL )
        rgbP->b = (uint8 *)malloc(rgbP->xsize*rgbP->ysize*(rgbP->depth/8));

    rP = rgbP->r;
    gP = rgbP->g;
    bP = rgbP->b;

    yuvP = buffer;

    for( i=0; i < rgbP->ysize; i++ )
        {
        for( j=0;  j < rgbP->xsize / 2; j++ )
            {
            u = *yuvP++;
            u -= 0x80;
            y = *yuvP++;
            y -= 0x10;

            if( y < 0 )
                y = 0;

            v = *yuvP++;
            v -= 0x80;
            y1 = *yuvP++;
            y1 -= 0x10;
            if( y1 < 0 )
                y1 = 0;

            y *= 76310;
            r  =    y +            104635*v;
            g  =    y + -25690*u + -53294*v;
            b  =    y + 132278*u;

            limit(r);
            limit(g);
            limit(b);

            *rP++ = r >> 16;
            *gP++ = g >> 16;
            *bP++ = b >> 16;

            y1 *= 76310;
            r  =    y1 +            104635*v;
            g  =    y1 + -25690*u + -53294*v;
            b  =    y1 + 132278*u;

            limit(r);
            limit(g);
            limit(b);

            *rP++ = r>>16;
            *gP++ = g>>16;
            *bP++ = b>>16;
            }
        }
    return 0;
    }

 
 
 

YUV422 <-> RGB Conversion

Post by Pavel Tkatchou » Sat, 20 Jan 2001 01:57:02



 
 
 

1. >>>> Free classified ad posting and track visitors <<<<<

The all new Infomak classifieds.
Free posting of your classified ad
with over 40 different categories including :

Computer Accessories
Computer Boards & Drives
Computer CPU & Memory
Computer Desktop & Laptops
Computer Monitor & Printers
Computer Software

Cool features
-------------
Track how many visitor has seen your ad ( a counter on your ad ).
E-mail address are hidden.
Place your ad.
Edit your ad.
Delete your ad.

http://www.infomak.com

2. Info wanted on Phonex/RCA/GE Intelejak Wireless Extension

3. <<>> COMPUTER SOFTWARE / HARDWARE <<>>

4. MV167 boot

5. <<<<<< HD Benchmark! Help me! >>>>>>

6. No posts on Hayes modems. Why?

7. <<<<help.>>>secondary scsi wont show up>>>>>>

8. PDFmark in latex

9. >>> 9 0 % O F F <<<

10. >>> F R E E <<<

11. >>> 9 0 % O F F <<<