implement basic C yuv422toRGB function
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29306 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -268,3 +268,64 @@ void gfx_conv_YCbCr420p_RGB32_c(AVFrame *in, AVFrame *out, int width, int height
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define CLIP(a) if (0xffffff00 & (uint32)a) { if (a < 0) a = 0; else a = 255; }
|
||||
|
||||
// http://en.wikipedia.org/wiki/YUV
|
||||
uint32 YUV444TORGBA8888(uint8 y, uint8 u, uint8 v)
|
||||
{
|
||||
uint32 pixel = 0;
|
||||
int32 c, d, e;
|
||||
int32 r,g,b;
|
||||
|
||||
c = y - 16;
|
||||
d = u - 128;
|
||||
e = v - 128;
|
||||
|
||||
r = (298 * c + 409 * e + 128) >> 8;
|
||||
g = (298 * c - 100 * d - 208 * e + 128) >> 8;
|
||||
b = (298 * c + 516 * d + 128) >> 8;
|
||||
|
||||
CLIP(r);
|
||||
CLIP(g);
|
||||
CLIP(b);
|
||||
|
||||
pixel = (r << 16) | (g << 8) | b;
|
||||
|
||||
return pixel;
|
||||
}
|
||||
|
||||
void gfx_conv_YCbCr422_RGB32_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||
{
|
||||
uint8 *ybase = (uint8 *)in->data[0];
|
||||
uint8 *ubase = (uint8 *)in->data[1];
|
||||
uint8 *vbase = (uint8 *)in->data[2];
|
||||
|
||||
uint32 *rgbbase = (uint32 *)out->data[0];
|
||||
|
||||
int uv_index;
|
||||
|
||||
for (uint32 i = 0; i < height; i++) {
|
||||
|
||||
uv_index = 0;
|
||||
|
||||
for (uint32 j=0; j < width; j+=2) {
|
||||
rgbbase[j] = YUV444TORGBA8888(ybase[j] ,ubase[uv_index],vbase[uv_index]);
|
||||
rgbbase[j+1] = YUV444TORGBA8888(ybase[j+1],ubase[uv_index],vbase[uv_index]);
|
||||
|
||||
uv_index++;
|
||||
}
|
||||
|
||||
ybase += in->linesize[0];
|
||||
ubase += in->linesize[1];
|
||||
vbase += in->linesize[2];
|
||||
|
||||
rgbbase += out->linesize[0] / 4;
|
||||
}
|
||||
|
||||
if (height & 1) {
|
||||
// XXX special case for last line if height not multiple of 2 goes here
|
||||
memset((height - 1) * out->linesize[0] + (uint8 *)out->data[0], 0, width * 4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,5 +14,6 @@ void gfx_conv_yuv420p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int heigh
|
||||
void gfx_conv_yuv410p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||
void gfx_conv_yuv411p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||
void gfx_conv_YCbCr420p_RGB32_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||
void gfx_conv_YCbCr422_RGB32_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -68,6 +68,10 @@ gfx_convert_func resolve_colorspace(color_space colorSpace, PixelFormat pixelFor
|
||||
}
|
||||
}
|
||||
|
||||
if (pixelFormat == PIX_FMT_YUV422P || pixelFormat == PIX_FMT_YUVJ422P) {
|
||||
return gfx_conv_YCbCr422_RGB32_c;
|
||||
}
|
||||
|
||||
TRACE("resolve_colorspace: %s => B_RGB32: NULL\n", pixfmt_to_string(pixelFormat));
|
||||
return NULL;
|
||||
|
||||
@@ -120,7 +124,7 @@ gfx_convert_func resolve_colorspace(color_space colorSpace, PixelFormat pixelFor
|
||||
}
|
||||
}
|
||||
|
||||
if (pixelFormat == PIX_FMT_YUV422) {
|
||||
if (pixelFormat == PIX_FMT_YUV422 || PIX_FMT_YUVJ422P) {
|
||||
#if INCLUDE_MMX
|
||||
if (mmx) {
|
||||
TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: gfx_conv_null_mmx\n");
|
||||
@@ -134,7 +138,7 @@ gfx_convert_func resolve_colorspace(color_space colorSpace, PixelFormat pixelFor
|
||||
}
|
||||
|
||||
TRACE("resolve_colorspace: %s => B_YCbCr422: NULL\n", pixfmt_to_string(pixelFormat));
|
||||
return NULL;
|
||||
return gfx_conv_null_c;
|
||||
|
||||
default:
|
||||
TRACE("resolve_colorspace: default: NULL !!!\n");
|
||||
@@ -159,6 +163,8 @@ const char *pixfmt_to_string(int p)
|
||||
return "PIX_FMT_BGR24";
|
||||
case PIX_FMT_YUV422P:
|
||||
return "PIX_FMT_YUV422P";
|
||||
case PIX_FMT_YUVJ422P:
|
||||
return "PIX_FMT_YUVJ422P - YUV422P (Jpeg)";
|
||||
case PIX_FMT_YUV444P:
|
||||
return "PIX_FMT_YUV444P";
|
||||
case PIX_FMT_RGBA32:
|
||||
|
||||
Reference in New Issue
Block a user