⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yuvtorgb.cpp

📁 symbian下的FLV播放视频源码 可以快速便捷的播放FLV格式的视频
💻 CPP
字号:
#include "YUVtoRGB.h"
#include <stdio.h>

static double* crv_tab;
static double* cbu_tab;
static double* cgu_tab;
static double* cgv_tab;

static unsigned char* ryv_tab;
static unsigned char* rbu_tab;

static unsigned char *clp;

static int* g_TransformTableX;
static int* g_TransformTableXUV;
static int* g_TransformTableY;
static int* g_TransformTableFillY;

extern int g_RectWidth;
extern int g_RectHeight;

static struct TNeoColorRGB {
	unsigned char r, g, b, a;
} *neoColorRGB;

void InitConvertTable()
{
	int i, j, ind;
	clp = (unsigned char*)malloc(1024);
	for (i=0; i<384; i++)
		clp[i] =0;
	ind=384;
	for (i=0;i<256; i++)
		clp[ind++]=i;
	ind=640;
	for (i=0;i<384;i++)
		clp[ind++]=255;
	   
	
	// Generate crv
	crv_tab = (double*)malloc(256*sizeof(double));
	for (i = 0; i < 256; i++)
		crv_tab[i] = 1.370705 * (i-128) + 384;
	
	// Generate cgv
	cgv_tab = (double*)malloc(256*sizeof(double));
	for (i = 0; i < 256; i++)
		cgv_tab[i] = 0.698001 * (i-128) - 384;
	
	// Generate cgu
	cgu_tab = (double*)malloc(256*sizeof(double));
	for (i = 0; i < 256; i++)
		cgu_tab[i] = 0.337633 * (i-128);
	
	// Generate cbu
	cbu_tab = (double*)malloc(256*sizeof(double));
	for (i = 0; i < 256; i++)
		cbu_tab[i] = 1.732446 * (i-128) + 384;
		
	// Generate ryv
	ryv_tab = (unsigned char*)malloc(256*256);
	for (j = 0; j < 256; j++)
		for (i = 0; i < 256; i++)
			ryv_tab[i*256 + j] = clp[(int)(j + crv_tab[i])];
	
	// Generate rbu
	rbu_tab = (unsigned char*)malloc(256*256);
	for (j = 0; j < 256; j++)
		for (i = 0; i < 256; i++)
			rbu_tab[i*256 + j] = clp[(int)(j + cbu_tab[i])];

	neoColorRGB = (TNeoColorRGB*)malloc(64*64*64*4);
	TNeoColorRGB* tNeoColorRGB = neoColorRGB;

	unsigned char y1, u1, v1;
	for (int v = 0; v < 64; v++)
   		for (int u = 0; u < 64; u++)
		   for (int y = 0; y < 64; y++)
		   {
		   		y1 = y << 2;
		   		u1 = u << 2;
		   		v1 = v << 2;
				tNeoColorRGB->r = rbu_tab[y1 + (u1 << 8)];
				tNeoColorRGB->g = clp[(int)(y1 - cgv_tab[v1] - cgu_tab[u1])];
				tNeoColorRGB->b = ryv_tab[y1 + (v1 << 8)];
				tNeoColorRGB->a = 0xFF;
				tNeoColorRGB++;
		   }

	if (crv_tab)
	{
		free(crv_tab);
		crv_tab = NULL;
	}
	if (cbu_tab)
	{
		free(cbu_tab);
		cbu_tab = NULL;
	}
/*
	if (cgu_tab)
	{
		free(cgu_tab);
		cgu_tab = NULL;
	}
	if (cgv_tab)
	{
		free(cgv_tab);
		cgv_tab = NULL;
	}
*/
}

void DestroyConvertTable()
{
	if (clp)
	{
		free(clp);
		clp = NULL;
	}
	if (ryv_tab)
	{
		free(ryv_tab);
		ryv_tab = NULL;
	}
	if (rbu_tab)
	{
		free(rbu_tab);
		rbu_tab = NULL;
	}
	if (crv_tab)
	{
		free(crv_tab);
		crv_tab = NULL;
	}
	if (cbu_tab)
	{
		free(cbu_tab);
		cbu_tab = NULL;
	}
	if (cgu_tab)
	{
		free(cgu_tab);
		cgu_tab = NULL;
	}
	if (cgv_tab)
	{
		free(cgv_tab);
		cgv_tab = NULL;
	}
	if (neoColorRGB)
	{
		free(neoColorRGB);
		neoColorRGB = NULL;
	}
}

void ConvertYUV2BGRFast(unsigned char *src0, register unsigned char *src1, register unsigned char *src2,unsigned char *dst_ori,
								 const int width, int height, const int realwidth)
{
	register unsigned char *py1,*py2;
	register int *tNeoColorRGB;
	register int *d1, *d2;
	register int *_neoColorRGB = (int*)neoColorRGB;
	int j;

//	if (realwidth > 320)
//		realwidth = 320;
	
	const int bytetonextrow_src0 = width+width-realwidth;
	const int bytetonextrow_src1 = (width-realwidth) >> 1;
	const int bytetonextrow_dst  = 640-realwidth;
	
	if (width == 0)
		return;

	py1=src0;
	py2=py1+width;
	d1=(int*)dst_ori + (320 * ((240-height) >> 1)) + ((320-realwidth) >> 1);
	d2=d1+320;
	
	if (height > 240)
		height = 240;
		
 	for (j = height; j > 0; j -= 2) { 
		for (register int i = realwidth; i > 0; i -= 2) {

			tNeoColorRGB = _neoColorRGB + (((*src1) >> 2) << 6) + (((*src2) >> 2) << 12);
			src1++;
			src2++;

			*d1 = *(tNeoColorRGB + (*py1 >> 2));
			*d2 = *(tNeoColorRGB + (*py2 >> 2));
			d1[1] = *(tNeoColorRGB + (py1[1] >> 2));
			d2[1] = *(tNeoColorRGB + (py2[1] >> 2));
			
			py1 += 2;
			py2 += 2;
			d1  += 2;
			d2  += 2;
		}
		d1  += bytetonextrow_dst;
		d2  += bytetonextrow_dst;
		py1 += bytetonextrow_src0;
		py2 += bytetonextrow_src0;
		src1+= bytetonextrow_src1;
		src2+= bytetonextrow_src1;
	}       

}

void CreateTransformTable(const int /*width*/, int height, int realwidth, int newrealwidth, int newheight)
{
	int tnewheight = newheight;
	int tnewrealwidth = newrealwidth;
	if (newrealwidth * height / newheight < realwidth)
		newheight = height * newrealwidth / realwidth;
	else
		newrealwidth = realwidth * newheight / height;

	const double incy_x = (realwidth + 0.0) / newrealwidth;
	const double incy_y = (newheight + 0.0) / height;
	const double incuv_x = incy_x / 2;

	DestroyTransformTable();

	g_TransformTableX = (int*)malloc(newrealwidth*sizeof(int));
	for (int i = 0; i < newrealwidth; i++)
	{
		g_TransformTableX[newrealwidth-i-1] = (int)(incy_x*i);
	}

	g_TransformTableXUV = (int*)malloc(newrealwidth*sizeof(int));
	for (int i = 0; i < newrealwidth; i++)
	{
		g_TransformTableXUV[(newrealwidth)-i-1] = (int)(incuv_x*i);
	}

	if (newrealwidth > realwidth)
	{
		g_TransformTableFillY = (int*)malloc(newheight*sizeof(int));
		for (int i = 0; i < newheight; i++)
			g_TransformTableFillY[i] = 0;

		g_TransformTableY = (int*)malloc(height*sizeof(int));
		for (int i = 0; i < height; i++)
		{
			g_TransformTableY[height-i-1] = tnewrealwidth*(int)(incy_y*i);
			g_TransformTableFillY[(int)(incy_y*i)] = 1;
		}
	}
	else
	{
		g_TransformTableFillY = (int*)malloc(height*sizeof(int));
		for (int i = 0; i < height; i++)
			g_TransformTableFillY[i] = 0;

		g_TransformTableY = (int*)malloc(height*sizeof(int));
		for (int i = 0; i < height; i++)
		{
			g_TransformTableY[height-i-1] = tnewrealwidth*(int)(incy_y*i);
		}

		g_TransformTableFillY[height-1] = 1;
		for (int i = 1; i < height; i++)
		{
			if (g_TransformTableY[height-i-1] != g_TransformTableY[height-i-2])
				g_TransformTableFillY[height-i-1] = 1;
		}
	}
}

void DestroyTransformTable()
{
	if (g_TransformTableX)
	{
		free(g_TransformTableX);
		g_TransformTableX = NULL;
	}
	if (g_TransformTableXUV)
	{
		free(g_TransformTableXUV);
		g_TransformTableXUV = NULL;
	}
	if (g_TransformTableY)
	{
		free(g_TransformTableY);
		g_TransformTableY = NULL;
	}
	if (g_TransformTableFillY)
	{
		free(g_TransformTableFillY);
		g_TransformTableFillY = NULL;
	}
}

void ConvertYUV2BGRNeoFast(unsigned char *src0, register unsigned char *src1, register unsigned char *src2,unsigned char *dst_ori,
								 const int width, int height, int realwidth, int newrealwidth, int newheight)
{
	if (realwidth % 2 == 1)
		realwidth--;
	
	if (width == 0)
		return;

	int tnewrealwidth = newrealwidth;
	int tnewheight = newheight;
	if (newrealwidth * height / newheight < realwidth)
		tnewheight = height * newrealwidth / realwidth;
	else
		tnewrealwidth = realwidth * newheight / height;

	if (!g_TransformTableX)
		CreateTransformTable(width, height, realwidth, newrealwidth, newheight);

	if (tnewrealwidth > realwidth)
		ConvertYUV2BGRNeoFastScaleUp(src0, src1, src2, dst_ori, width, height, realwidth, newrealwidth, newheight);
	else
		ConvertYUV2BGRNeoFastScaleDown(src0, src1, src2, dst_ori, width, height, realwidth, newrealwidth, newheight);
}

void ConvertYUV2BGRNeoFastScaleUp(unsigned char *src0, register unsigned char *src1, register unsigned char *src2,unsigned char *dst_ori,
								 const int width, int height, int realwidth, const int newrealwidth, int newheight)
{
	register unsigned char *py1,*py2;
	register int *tNeoColorRGB;
	register int *d1, *d2;
	register int *_neoColorRGB = (int*)neoColorRGB;
	int j;
	register unsigned char* src1i = src1;
	register unsigned char* src2i = src2;
	unsigned char* dst_ori_i = dst_ori;

	int tnewrealwidth = newrealwidth;
	if (newrealwidth * height / newheight < realwidth)
	{
		dst_ori += (((((newheight-(height * newrealwidth / realwidth)) >> 1) * newrealwidth)) << 2);
		newheight = height * newrealwidth / realwidth;
		dst_ori_i = dst_ori;
	}
	else
	{
		dst_ori += ((newrealwidth - (realwidth * newheight / height)) >> 1) << 2;
		tnewrealwidth = realwidth * newheight / height;
	}

	if (tnewrealwidth % 2 == 1)
		tnewrealwidth--;
	if (tnewrealwidth % 4 != 0)
		tnewrealwidth -= 2;
	if (tnewrealwidth < 0)
		tnewrealwidth = 0;
	
	if (width == 0)
		return;

 	for (j = height-1; j >= 0; j -= 2) { 
		d1    = (int*)dst_ori + g_TransformTableY[j];
		d2    = (int*)dst_ori + g_TransformTableY[j-1];
		py1   = src0 + (height-j-1) * width;
		py2   = src0 + (height-j  ) * width;
		register int diff = ((height-j-1) * width) >> 2;
		src1i = src1 + diff;
		src2i = src2 + diff;
		for (register int i = tnewrealwidth-1; i >= 0; i -= 4) {

			tNeoColorRGB = _neoColorRGB + (((src1i[g_TransformTableXUV[i]]) >> 2) << 6) + (((src2i[g_TransformTableXUV[i]]) >> 2) << 12);

			*d1 = *(tNeoColorRGB + (py1[g_TransformTableX[i]] >> 2));
			*d2 = *(tNeoColorRGB + (py2[g_TransformTableX[i]] >> 2));
			d1[1] = *(tNeoColorRGB + (py1[g_TransformTableX[i-1]] >> 2));
			d2[1] = *(tNeoColorRGB + (py2[g_TransformTableX[i-1]] >> 2));

			d1[2] = *(tNeoColorRGB + (py1[g_TransformTableX[i-2]] >> 2));
			d2[2] = *(tNeoColorRGB + (py2[g_TransformTableX[i-2]] >> 2));
			d1[3] = *(tNeoColorRGB + (py1[g_TransformTableX[i-3]] >> 2));
			d2[3] = *(tNeoColorRGB + (py2[g_TransformTableX[i-3]] >> 2));
			
			d1  += 4;
			d2  += 4;
		}
	}
 	for (register int i = 0; i < newheight; i++)
	{
		if (g_TransformTableFillY[i] == 0)
			memcpy((int*)dst_ori_i + (i)*newrealwidth, (int*)dst_ori_i + (i-1)*newrealwidth, newrealwidth << 2);
	}

}

void ConvertYUV2BGRNeoFastScaleDown(unsigned char *src0, register unsigned char *src1, register unsigned char *src2,unsigned char *dst_ori,
								 const int width, int height, int realwidth, const int newrealwidth, int newheight)
{
	register unsigned char *py1,*py2;
	register int *tNeoColorRGB;
	register int *d1, *d2;
	register int *_neoColorRGB = (int*)neoColorRGB;
	int j;
	register unsigned char* src1i = src1;
	register unsigned char* src2i = src2;

	int tnewrealwidth = newrealwidth;
	//if (newrealwidth * height / newheight < realwidth)
	//	newheight = height * newrealwidth / realwidth;
	//else
	//	tnewrealwidth = realwidth * newheight / height;
	if (newrealwidth * height / newheight < realwidth)
	{
		dst_ori += (((((newheight-(height * newrealwidth / realwidth)) >> 1) * newrealwidth)) << 2);
		newheight = height * newrealwidth / realwidth;
	}
	else
	{
		dst_ori += ((newrealwidth - (realwidth * newheight / height)) >> 1) << 2;
		tnewrealwidth = realwidth * newheight / height;
	}

	if (tnewrealwidth % 2 == 1)
		tnewrealwidth--;
	
	if (width == 0)
		return;

 	for (j = height-1; j >= 0; j -= 2) { 
		register int diff = ((height-j-1) * width) >> 2;
		src1i = src1 + diff;
		src2i = src2 + diff;
		if (g_TransformTableFillY[j] && g_TransformTableFillY[j-1])
		{
			d1    = (int*)dst_ori + g_TransformTableY[j];
			d2    = (int*)dst_ori + g_TransformTableY[j-1];
			py1   = src0 + (height-j-1) * width;
			py2   = src0 + (height-j  ) * width;
			for (register int i = tnewrealwidth-1; i >= 0; i -= 2)
			{
				tNeoColorRGB = _neoColorRGB + (((src1i[g_TransformTableXUV[i]]) >> 2) << 6) + (((src2i[g_TransformTableXUV[i]]) >> 2) << 12);

				*d1 = *(tNeoColorRGB + (py1[g_TransformTableX[i]] >> 2));
				*d2 = *(tNeoColorRGB + (py2[g_TransformTableX[i]] >> 2));
				d1[1] = *(tNeoColorRGB + (py1[g_TransformTableX[i-1]] >> 2));
				d2[1] = *(tNeoColorRGB + (py2[g_TransformTableX[i-1]] >> 2));
				
				d1  += 2;
				d2  += 2;
			}
		}
		else if (g_TransformTableFillY[j])
		{
			d1    = (int*)dst_ori + g_TransformTableY[j];
			py1   = src0 + (height-j-1) * width;
			for (register int i = tnewrealwidth-1; i >= 0; i -= 2)
			{
				tNeoColorRGB = _neoColorRGB + (((src1i[g_TransformTableXUV[i]]) >> 2) << 6) + (((src2i[g_TransformTableXUV[i]]) >> 2) << 12);

				*d1 = *(tNeoColorRGB + (py1[g_TransformTableX[i]] >> 2));
				d1[1] = *(tNeoColorRGB + (py1[g_TransformTableX[i-1]] >> 2));
				
				d1  += 2;
			}
		}
		else if (g_TransformTableFillY[j-1])
		{
			d2    = (int*)dst_ori + g_TransformTableY[j-1];
			py2   = src0 + (height-j  ) * width;
			for (register int i = tnewrealwidth-1; i >= 0; i -= 2)
			{
				tNeoColorRGB = _neoColorRGB + (((src1i[g_TransformTableXUV[i]]) >> 2) << 6) + (((src2i[g_TransformTableXUV[i]]) >> 2) << 12);

				*d2 = *(tNeoColorRGB + (py2[g_TransformTableX[i]] >> 2));
				d2[1] = *(tNeoColorRGB + (py2[g_TransformTableX[i-1]] >> 2));
				
				d2  += 2;
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -