diff options
-rw-r--r-- | ext/hermes/rgb2yuv.c | 156 |
1 files changed, 43 insertions, 113 deletions
diff --git a/ext/hermes/rgb2yuv.c b/ext/hermes/rgb2yuv.c index 7495c71b..6aa1e805 100644 --- a/ext/hermes/rgb2yuv.c +++ b/ext/hermes/rgb2yuv.c @@ -12,139 +12,69 @@ #include <gst/gst.h> -#define RGB2YUV_SHIFT 8 -#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5)) -#define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5)) -#define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) -#define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5)) -#define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5)) -#define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5)) -#define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5)) -#define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) -#define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5)) - -/** - * - * height should be a multiple of 2 and width should be a multiple of 2 (if this is a - * problem for anyone then tell me, and ill fix it) - * chrominance data is only taken from every secound line others are ignored FIXME write HQ version - */ -void -gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest, guint width, guint height) +#define Y_FROM_RGB(r,g,b) ((9798 * (r) + 19235 * (g) + 3736 * (b)) >> 15) +#define U_FROM_BY(b,y) ((16122 * ((b) - (y))) >> 15) + 128; +#define V_FROM_RY(r,y) ((25203 * ((r) - (y))) >> 15) + 128; + +static void +gst_colorspace_rgb32_to_yuv (unsigned char *src, + unsigned char *ydst, + unsigned char *udst, + unsigned char *vdst, + guint width, guint height) { int y; const int chrom_width = width >> 1; - const int chrom_size = (width * height) >> 2; + int Y; + int b, g, r; - unsigned char *ydst = dest; - unsigned char *udst = ydst + (width * height); - unsigned char *vdst = udst + chrom_size; - - for (y = 0; y < height; y += 2) { + for (y = height; y; y -= 2) { int i; - for (i = 0; i < chrom_width; i++) { - unsigned int b = src[8 * i + 0]; - unsigned int g = src[8 * i + 1]; - unsigned int r = src[8 * i + 2]; + for (i = chrom_width; i; i--) { + b = *src++; + g = *src++; + r = *src++; + src++; - unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; - unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128; - unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128; + Y = Y_FROM_RGB (r,g,b); - udst[i] = U; - vdst[i] = V; - ydst[2 * i] = Y; + *ydst++ = Y; + *udst++ = U_FROM_BY (b,Y); + *vdst++ = V_FROM_RY (r,Y); - b = src[8 * i + 4]; - g = src[8 * i + 5]; - r = src[8 * i + 6]; + b = *src++; + g = *src++; + r = *src++; src++; - Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i + 1] = Y; + *ydst++ = Y_FROM_RGB (r,g,b); } - ydst += width; - src += (width * 4); - - for (i = 0; i < chrom_width; i++) { - unsigned int b = src[8 * i + 0]; - unsigned int g = src[8 * i + 1]; - unsigned int r = src[8 * i + 2]; - - unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i] = Y; - - b = src[8 * i + 4]; - g = src[8 * i + 5]; - r = src[8 * i + 6]; - - Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i + 1] = Y; + for (i = width; i; i--) { + b = *src++; + g = *src++; + r = *src++; src++; + *ydst++ = Y_FROM_RGB (r,g,b); } - udst += chrom_width; - vdst += chrom_width; - ydst += width; - src += (width * 4); } } void -gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height) +gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest, guint width, guint height) { - int y; - const int chrom_width = width >> 1; - const int chrom_size = (width * height) >> 2; - unsigned char *ydst = dest; - unsigned char *vdst = ydst + (width * height); - unsigned char *udst = vdst + chrom_size; - - for (y = 0; y < height; y += 2) { - int i; - - for (i = 0; i < chrom_width; i++) { - unsigned int b = src[8 * i + 0]; - unsigned int g = src[8 * i + 1]; - unsigned int r = src[8 * i + 2]; - - unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; - unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128; - unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128; - - udst[i] = U; - vdst[i] = V; - ydst[2 * i] = Y; - - b = src[8 * i + 4]; - g = src[8 * i + 5]; - r = src[8 * i + 6]; - - Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i + 1] = Y; - } - ydst += width; - src += (width * 4); - - for (i = 0; i < chrom_width; i++) { - unsigned int b = src[8 * i + 0]; - unsigned int g = src[8 * i + 1]; - unsigned int r = src[8 * i + 2]; - - unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + unsigned char *udst = ydst + (width * height); + unsigned char *vdst = udst + ((width * height) >> 2); - ydst[2 * i] = Y; + gst_colorspace_rgb32_to_yuv (src, ydst, udst, vdst, width, height); +} - b = src[8 * i + 4]; - g = src[8 * i + 5]; - r = src[8 * i + 6]; +void +gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height) +{ + unsigned char *ydst = dest; + unsigned char *vdst = ydst + (width * height); + unsigned char *udst = vdst + ((width * height) >> 2); - Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i + 1] = Y; - } - udst += chrom_width; - vdst += chrom_width; - ydst += width; - src += (width * 4); - } + gst_colorspace_rgb32_to_yuv (src, ydst, udst, vdst, width, height); } |