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

📄 yuv.c

📁 傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。
💻 C
字号:

#include "yuv.h"
#include "mathutil.h"

// do NOT put +0.5 's in the ftoi's !

/**************************************************************/

static void RGB_to_YUVf(float Red,float Green,float Blue,float *Y,float *U,float *V)
{
    *Y =  0.2989f*Red + 0.5867f*Green + 0.1144f*Blue;
    *U = -0.1687f*Red - 0.3312f*Green + 0.5000f*Blue;
    *V =  0.5000f*Red - 0.4183f*Green - 0.0816f*Blue;
}

static void YUV_to_RGBf(float Y,float U,float V,float *R,float *G,float *B)
{
	*R = Y             + 1.4022f*V;
	*G = Y - 0.3456f*U - 0.7145f*V;
	*B = Y + 1.7710f*U            ;
}

void BGRb_to_YUVf(ubyte *BGRptr,float *Y,float *U,float *V)
{
int R,G,B;
	B = BGRptr[0];
	G = BGRptr[1];
	R = BGRptr[2];
	
	RGB_to_YUVf(R,G,B,Y,U,V);
}

static void Yf_to_BGRb(float y,float ruv,float guv,float buv,ubyte * bgr)
{
int z;
	z = ftoi(y+buv);	bgr[0] = clamp255(z);
	z = ftoi(y+guv);	bgr[1] = clamp255(z);
	z = ftoi(y+ruv);	bgr[2] = clamp255(z);
}

void YUV_122toBGRbytes(float *Yptr0,float *Yptr1,float *Uptr,float *Vptr,ubyte *BGRptr,int width)
{
ubyte *BGRptr2;
int x;
	BGRptr2 = BGRptr + (width*3);
	for(x=(width>>1);x--;)
	{
	float u,v;
	float ruv,guv,buv;
		u = *Uptr++; v = *Vptr++;
		ruv =             + 1.4022f*v;
		guv = - 0.3456f*u - 0.7145f*v;
		buv = + 1.7710f*u;
	
		Yf_to_BGRb(*Yptr0++,ruv,guv,buv,BGRptr ); BGRptr  += 3;
		Yf_to_BGRb(*Yptr0++,ruv,guv,buv,BGRptr ); BGRptr  += 3;
		Yf_to_BGRb(*Yptr1++,ruv,guv,buv,BGRptr2); BGRptr2 += 3;
		Yf_to_BGRb(*Yptr1++,ruv,guv,buv,BGRptr2); BGRptr2 += 3;
	}
}

static uword rtablebase[512],gtablebase[512],btablebase[512];
static uword *rtable = rtablebase+128,*gtable=gtablebase+128,*btable=btablebase+128;

uword INLINE packyrgb(int y,int r,int g,int b)
{
return rtable[y+r] | gtable[y+g] | btable[y+b];
}

static bool havetables = false;
static void maketables(int Mode)
{
int p,q,r,g,b;
	for(p=0;p<512;p++)
	{
		q = clamp255(p-128);
		r = b = q>>3;

		switch(Mode)
		{
		case DRIVER_MODE_565:
			g = q>>2;
			r<<=11;
			break;
		case DRIVER_MODE_555:
			g = q>>3;
			r<<=10;
			break;
		}
		g<<=5;
		rtablebase[p] = r;
		gtablebase[p] = g;
		btablebase[p] = b;
	}
	havetables = true;
}

void YUV_122toDriver(float *Yptr0,float *Yptr1,float *Uptr,float *Vptr,Driver_Window * Driver,int width)
{
uword *p0,*p1;
int x;

	if ( Driver->UserY >= Driver->Height )
		return;

	if ( ! havetables )
		maketables(Driver->Mode);

	assert( (int)Driver->Width >= width );
	p0 = (uword *)(Driver->Buffer + Driver->Stride * Driver->UserY);
	p1 = p0 + (Driver->Stride>>1);
	Driver->UserY += 2;

	/**
		should do this all in assembly
		the biggest hurt is in the ftoi's

	----
	@@

	one method would be to do the YUV in 755 in which case we
	could do a direct lookup to get the 555 RGB result.  Doing 755
	does hurt psnr a bit (26.9 instead of 27.2).

	The path then is like :
		u = clamp31[ftoi(*Uptr++)];
		v = clamp31[ftoi(*Vptr++)];
		uv = (u<<5) | v;
		y = ftoi(*Yptr0++); *p0++ = maintable[ clamp128[y] | uv ]
		y = ftoi(*Yptr0++); *p0++ = maintable[ clamp128[y] | uv ]
		y = ftoi(*Yptr1++); *p1++ = maintable[ clamp128[y] | uv ]
		y = ftoi(*Yptr1++); *p1++ = maintable[ clamp128[y] | uv ]

	we would do:
		6 ftoi's
		6 small table lookups
		4 big table lookups

	as opposed to the current:
		7 ftoi's
		12 small table lookups
		4 fmuls

	actually that's very tasty, and doesn't cost any visual
	quality, since 755 YUV is way better than 555 RGB

	In the end, the ftoi's are by far the biggest problem, 
	at about 100 clocks each (on my K6)
	**/

	for(x=(width>>1);x--;)
	{
	float u,v;
	int y,r,g,b;
	uword *rptr,*gptr,*bptr;
		u = *Uptr++;
		v = *Vptr++;
		r = ftoi(1.4022f*v);
		g =-ftoi(0.3456f*u + 0.7145f*v);
		b = ftoi(1.7710f*u);
		rptr = rtable + r;
		gptr = gtable + g;
		bptr = btable + b;
		y = ftoi(*Yptr0++); *p0++ = rptr[y] | gptr[y] | bptr[y];
		y = ftoi(*Yptr0++); *p0++ = rptr[y] | gptr[y] | bptr[y];
		y = ftoi(*Yptr1++); *p1++ = rptr[y] | gptr[y] | bptr[y];
		y = ftoi(*Yptr1++); *p1++ = rptr[y] | gptr[y] | bptr[y];
	}
}

⌨️ 快捷键说明

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