shithub: treason

ref: b6f90701508babfab5fec9c71f6f43a72c933737
dir: treason/yuv.c

View raw version
#include <u.h>
#include "misc.h"

uvlong yuv→rgb;

void yuv420_xrgb32(
	int width, int height,
	u8int *y, u8int *u, u8int *v,
	u32int ystride, u32int uvstride,
	u8int *rgb, u32int rgbstride)
{
	u32int w, h;
	int r, g, b;
	int yy, cb, cr, go;
	uvlong start;

	start = nanosec();
	for(h = 0; h < height-1; h += 2){
		for(w = 0; w < width-1; w += 2){
			cb = *u - 0x80;
			cr = *v - 0x80;
			go = 22554*cb + 46802*cr;

			cb *= 116130;
			cr *= 91881;

#define ONE do{ \
			yy = *y * 0x10101; \
			b = yy + cb; \
			rgb[0] = (b >> 24) ? ~(b >> 31) : (b>>16); \
			g = yy - go; \
			rgb[1] = (g >> 24) ? ~(g >> 31) : (g>>16); \
			r = yy + cr; \
			rgb[2] = (r >> 24) ? ~(r >> 31) : (r>>16); \
}while(0)
			ONE; y += 1;       rgb += 4;
			ONE; y += ystride; rgb += rgbstride;
			ONE; y -= 1;       rgb -= 4;
			ONE; y -= ystride; rgb -= rgbstride - 8;
#undef ONE

			y += 2;
			u += 1;
			v += 1;
		}

		y += ystride*2 - w;
		u += uvstride - w/2;
		v += uvstride - w/2;
		rgb += rgbstride*2 - 4*w;
	}
	yuv→rgb = nanosec() - start;
}