[M4IF Technotes] question on YUV2RGB conversion
Robert Bleidt
rbleidt hdtv.com
Wed Jan 29 12:15:18 EST 2003
Here is a code fragment that shows how to do this in C integer arithmetic.
RGB255 mode uses the full dynamic range of the RGB signal for video. (The
most common display mode) RGB235 makes full white equal 235 decimal and
full black equal 16 decimal in each RGB component. (very obscure)
Although I used to know what I was doing, that was a long time ago, and
this work has not been thoroughly checked. Details of clipping errors,
roundoff noise, overflow, transcoding matrix could be wrong; though it
seems to work.
You can find a discussion of the theory behind this at
http://www.inforamp.net/~poynton/ , though it looks like his site is down
today.
======================================
void convertFrameYUV2RGB(byte *outFrameBuf, byte *inFrameBuf,int pixLine,
int linesFrm, AviFormatCode aviFormat)
{
long r,g,b; short y,cr,cb;
byte *tempp = outFrameBuf;
/*( //RGB235 mode
r = (256 * y + 351 * cr) >> 8 + 16;
g = (256 * y - 86 * cb - 179 * cr) >> 8 + 16;
b = (256 * y + 444 * cb ) >> 8 + 16;
*/
const int bytesPixYUV = 2;
int lineLength = pixLine * bytesPixYUV;
if (aviFormat == RGB255)
{
for (int yy = linesFrm-1; yy >= 0; yy--)
{
for (int xx = 0; xx <pixLine; xx += 2)
{
cb = inFrameBuf[(xx * 2) + (yy *
lineLength)] - 128;
y = inFrameBuf[(xx * 2) + 1 + (yy *
lineLength)] - 16;
cr = inFrameBuf[(xx * 2) + 2 + (yy *
lineLength)] - 128;
//RGB255 mode
r = (298 * y + 409 * cr) >> 8;
g = (298 * y - 100 * cb - 208 * cr) >> 8;
b = (298 * y + 516 * cb ) >> 8;
if (r > 255) r = 255;
if (r < 0) r = 0;
if (g > 255) g = 255;
if (g < 0) g = 0;
if (b > 255) b = 255;
if (b < 0) b = 0;
*outFrameBuf++ = (byte) b;
*outFrameBuf++ = (byte) g;
*outFrameBuf++ = (byte) r;
y = inFrameBuf[(xx * 2) + 3 + (yy *
lineLength)] - 16;
if (xx < pixLine -2)
{ // average chroma for now
cb = ( cb + (inFrameBuf[(xx * 2) +
4 + (yy * lineLength)] - 128) ) / 2;
cr = ( cr + (inFrameBuf[(xx * 2) +
6 + (yy * lineLength)] - 128) ) / 2;
}
//RGB255 mode
r = (298 * y + 409 * cr) >> 8;
g = (298 * y - 100 * cb - 208 * cr) >> 8;
b = (298 * y + 516 * cb ) >> 8;
if (r > 255) r = 255;
if (r < 0) r = 0;
if (g > 255) g = 255;
if (g < 0) g = 0;
if (b > 255) b = 255;
if (b < 0) b = 0;
*outFrameBuf++ = (byte) b;
*outFrameBuf++ = (byte) g;
*outFrameBuf++ = (byte) r;
}
}
}
else
{
for (int yy = linesFrm-1; yy >= 0; yy--)
{
for (int xx = 0; xx <pixLine; xx += 2)
{
cb = inFrameBuf[(xx * 2) + (yy *
lineLength)] - 128;
y = inFrameBuf[(xx * 2) + 1 + (yy *
lineLength)] - 16;
cr = inFrameBuf[(xx * 2) + 2 + (yy *
lineLength)] - 128;
//RGB235 mode
r = ((256 * y + 351 * cr) >> 8)
+ 16;
g = ((256 * y - 86 * cb - 179 * cr) >> 8)
+ 16;
b = ((256 * y + 444 * cb ) >> 8)
+ 16;
if (r > 255) r = 255;
if (r < 0) r = 0;
if (g > 255) g = 255;
if (g < 0) g = 0;
if (b > 255) b = 255;
if (b < 0) b = 0;
*outFrameBuf++ = (byte) b ;
*outFrameBuf++ = (byte) g;
*outFrameBuf++ = (byte) r;
y = inFrameBuf[(xx * 2) + 3 + (yy *
lineLength)] - 16;
if (xx < pixLine -2)
{ // average chroma for now
cb = ( cb + (inFrameBuf[(xx * 2) +
4 + (yy * lineLength)] - 128) ) / 2;
cr = ( cr + (inFrameBuf[(xx * 2) +
6 + (yy * lineLength)] - 128) ) / 2;
}
//RGB235 mode
r = ((256 * y + 351 * cr) >> 8)
+ 16;
g = ((256 * y - 86 * cb - 179 * cr) >> 8)
+ 16;
b = ((256 * y + 444 * cb ) >> 8)
+ 16;
if (r > 255) r = 255;
if (r < 0) r = 0;
if (g > 255) g = 255;
if (g < 0) g = 0;
if (b > 255) b = 255;
if (b < 0) b = 0;
*outFrameBuf++ = (byte) b;
*outFrameBuf++ = (byte) g;
*outFrameBuf++ = (byte) r;
}
}
}
}
======================================
The following link shows how to do this using an Intel processor's MMX
instructions:
http://cedar.intel.com/cgi-bin/ids.dll/content/content.jsp?cntKey=Legacy::irtm_AP548_9996&cntType=IDS_EDITORIAL&catCode=0
At 12:56 PM 1/28/2003 -0800, you wrote:
>Hi,
>
>Is there an efficient library or function that I can
>use for YUV2RGB conversion? It seems the
>float-operation for every pixel is a very high cost
>for the rendering.
>
>Thanks in advance,
>
>Liang
>
>__________________________________________________
>Do you Yahoo!?
>Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
>http://mailplus.yahoo.com
>_______________________________________________
>Technotes mailing list
>Technotes lists.m4if.org
>http://lists.m4if.org/mailman/listinfo/technotes
Robert Bleidt - rbleidt hdtv.com
More information about the Mp4-tech
mailing list