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

📄 blit_soft.c

📁 betaplayer的源码 tcpmp的老版本
💻 C
📖 第 1 页 / 共 3 页
字号:
	SurfacePtr(SrcPtr,Src,&Pack->Src,p->SrcBPP,Pack->SrcRect.x,SrcY,SrcPitch);

	if (p->SrcUpDown)
		SrcPitch = -SrcPitch;

	Src2SrcLast = 0;
	if (OnlyDiff)
		Src2SrcLast = (uint8_t*)SrcLast[0] - (uint8_t*)Src[0];

	DstStepX = p->DstBPP;
	DstStepY = DstPitch*8;
	DstX = Pack->DstRect.x;
	DstY = Pack->DstRect.y;

	if (p->DstLeftRight)
	{
		DstX += Pack->DstRect.Width-1;
		DstStepX = -DstStepX;
	}		

	if (p->DstUpDown)
	{
		DstY += Pack->DstRect.Height-1;
		DstStepY = -DstStepY;
	}

	if (p->SwapXY)
		SwapInt(&DstStepX,&DstStepY);

	SurfacePtr(DstPtr,Dst,&Pack->Dst,p->DstBPP,DstX,DstY,DstPitch);

	if (p->DstUpDown)
		DstPitch = -DstPitch;

	if (p->Slices)
	{
		const int DstBlock2 = 5;
		const int DstBlock = 32;

		int SrcBlock = (DstBlock * p->RScaleX) >> 4; //SrcBlock has to be even because of YUV
		int DstNext = (DstBlock * DstStepX) >> 3;
		int DstNextUV = DstNext >> (p->SwapXY ? p->DstUVPitch2+p->DstUVY2 : p->DstUVX2);
		int SrcNext = (SrcBlock * p->SrcBPP) >> 3;
		int SrcNextUV = SrcNext >> p->SrcUVX2;

		if (Width > DstBlock && p->SlicesReverse) // reverse order?
		{
			int Quot = Width >> DstBlock2;
			int Rem = Width & (DstBlock-1);

			DstPtr[0] += Quot*DstNext;
			DstPtr[1] += Quot*DstNextUV;
			DstPtr[2] += Quot*DstNextUV;

			SrcPtr[0] += Quot*SrcNext;
			SrcPtr[1] += Quot*SrcNextUV;
			SrcPtr[2] += Quot*SrcNextUV;

			if (Rem)
			{
				p->Entry(p,DstPtr,SrcPtr,DstPitch,SrcPitch,Rem,Height,Src2SrcLast);

				Width -= Rem;
			}

			DstNext = -DstNext;
			DstNextUV = -DstNextUV;
			SrcNext = -SrcNext;
			SrcNextUV = -SrcNextUV;

			DstPtr[0] += DstNext;
			DstPtr[1] += DstNextUV;
			DstPtr[2] += DstNextUV;

			SrcPtr[0] += SrcNext;
			SrcPtr[1] += SrcNextUV;
			SrcPtr[2] += SrcNextUV;
		}

		for (;Width > DstBlock;Width -= DstBlock)
		{
			p->Entry(p,DstPtr,SrcPtr,DstPitch,SrcPitch,DstBlock,Height,Src2SrcLast);

			DstPtr[0] += DstNext;
			DstPtr[1] += DstNextUV;
			DstPtr[2] += DstNextUV;

			SrcPtr[0] += SrcNext;
			SrcPtr[1] += SrcNextUV;
			SrcPtr[2] += SrcNextUV;
		}
	}

	p->Entry(p,DstPtr,SrcPtr,DstPitch,SrcPitch,Width,Height,Src2SrcLast); 
}

void BuildPalLookUp(blit_soft* p,bool_t YUV)
{
	//create a palette lookup with 3x3 bits RGB input
	int a,b,c;
	int Size = 1 << p->Dst.BitCount;
	uint8_t* LookUp;

	p->LookUp_Data = Alloc(16*16*16*4);
	if (p->LookUp_Data)
	{
		LookUp = (uint8_t*) p->LookUp_Data;

		for (a=16;a<512;a+=32)
			for (b=16;b<512;b+=32)
				for (c=16;c<512;c+=32)
				{
					const rgb* q = p->DstPalette;
					int BestMatch = 0;
					int BestDiff = 0x7FFFFFFF;
					int i,v[3];

					v[0] = a; 
					v[1] = b;
					v[2] = c;
					if (v[0] >= 384) v[0] -= 512;
					if (v[1] >= 384) v[1] -= 512;
					if (v[2] >= 384) v[2] -= 512;

					if (YUV)
					{
						int w[3];

						w[0] = (v[0]*p->_YMul +                  v[2]*p->_RVMul + p->_RAdd) >> 16;
						w[1] = (v[0]*p->_YMul + v[1]*p->_GUMul + v[2]*p->_GVMul + p->_GAdd) >> 16;
						w[2] = (v[0]*p->_YMul + v[1]*p->_BUMul +               p->_BAdd) >> 16;
						v[0]=w[0];
						v[1]=w[1];
						v[2]=w[2];
					}

					for (i=0;i<Size;++i,++q)
					{
						int Diff = (q->r-v[0])*(q->r-v[0])+
								   (q->g-v[1])*(q->g-v[1])+
								   (q->b-v[2])*(q->b-v[2]);

						if (Diff < BestDiff)
						{
							BestMatch = i;
							BestDiff = Diff;
						}
					}

					q = p->DstPalette + BestMatch;
					if (YUV)
					{
						v[0] = ( (2105 * q->r) + (4128 * q->g) + ( 802 * q->b))/0x2000 + 16;
						v[1] = (-(1212 * q->r) - (2384 * q->g) + (3596 * q->b))/0x2000 + 128;
						v[2] = ( (3596 * q->r) - (3015 * q->g) - ( 582 * q->b))/0x2000 + 128;

						v[0]=SAT(v[0]);
						v[1]=SAT(v[1]);
						v[2]=SAT(v[2]);
					}
					else
					{
						v[0] = q->r;
						v[1] = q->g;
						v[2] = q->b;
					}

					LookUp[0] = (uint8_t)BestMatch;
#if defined(SH3)
					LookUp[3] = (uint8_t)(v[0] >> 1);
					LookUp[1] = (uint8_t)(v[1] >> 1);
					LookUp[2] = (uint8_t)(v[2] >> 1);
#else
					LookUp[1] = (uint8_t)v[0];
					LookUp[2] = (uint8_t)v[1];
					LookUp[3] = (uint8_t)v[2];
#endif
					LookUp += 4;
				}
	}
}

#if defined(_M_IX86)

int UniversalType( const pixel* p, bool_t YUV )
{
	if (PlanarYUV(p,NULL,NULL,NULL)) return YUV ? 12:10;
	if (PackedYUV(p)) return YUV ? 13:11;

	if (p->Flags & PF_PALETTE)
	{
		if (p->BitCount==1) return 1;
		if (p->BitCount==2) return 2;
		if (p->BitCount==4) return 3;
		if (p->BitCount==8) return YUV ? 14:4;
	}

	if (p->Flags & PF_RGB)
	{
		if (p->BitCount==8)  return 5;
		if (p->BitCount==16) return 6;
		if (p->BitCount==24) return 7;
		if (p->BitCount==32) return 8;
	}

	return -1;
}

// !SwapXY
// !DstLeftRight
// SrcType == 12
// DstType == 12
// RScaleX == 16 && RScaleY == 16
// SrcUVX2 == DstUVX2

void Blit_PYUV_PYUV(blit_soft* This, uint8_t** DstPtr,uint8_t** SrcPtr,int DstPitch,int SrcPitch,
	               int Width,int Height,int Src2SrcLast) 
{
	uint8_t* Src[3];
	uint8_t* Dst[3];

	int UVY = 1 << This->DstUVY2;
	int UVDup = 1;
	int SrcPitchUV = SrcPitch >> This->SrcUVPitch2;
	int DstPitchUV = DstPitch >> This->DstUVPitch2;
	int WidthUV = Width >> This->SrcUVX2;
	int YAdd = This->FX.Brightness;
	int x,y,i;

	for (i=0;i<3;++i)
	{
		Src[i] = SrcPtr[i];
		Dst[i] = DstPtr[i];
	}

	// skip some UV lines?
	if (This->DstUVY2 > This->SrcUVY2)
		SrcPitchUV <<= This->DstUVY2 - This->SrcUVY2;
	else
		UVDup = 1 << (This->SrcUVY2 - This->DstUVY2);

	Height >>= This->DstUVY2;

	for (y=0;y<Height;++y)
	{
		for (i=0;i<UVY;++i)
		{
			if (YAdd)
			{
				uint8_t* s = Src[0];
				uint8_t* d = Dst[0];
				for (x=0;x<Width;++x,++s,++d)
				{
					int Y = *s + YAdd;
					Y = SAT(Y);
					*d = (uint8_t)Y;
				}
			}
			else
				memcpy(Dst[0],Src[0],Width);

			Src[0] += SrcPitch;
			Dst[0] += DstPitch;
		}

		for (i=0;i<UVDup;++i)
		{
			memcpy(Dst[1],Src[1],WidthUV);
			memcpy(Dst[2],Src[2],WidthUV);

			Dst[1] += DstPitchUV;
			Dst[2] += DstPitchUV;
		}

		Src[1] += SrcPitchUV;
		Src[2] += SrcPitchUV;
	}
}

void BlitUniversal(blit_soft* This, uint8_t** DstPtr,uint8_t** SrcPtr,int DstPitch,int SrcPitch,
	               int Width,int Height,int Src2SrcLast) 
{
	//this will be very-very slow, only for compability and testing

	int i,j,x,y;

	uint8_t* Src[3];
	uint8_t* Dst[3];

	int SrcType = This->SrcType;
	int DstType = This->DstType;

	int DstMask[3],DstPos[3];
	int SrcMask[3],SrcPos[3];
	int DitherMask[3];

	uint8_t* PalLookUp = (uint8_t*)This->LookUp_Data;
	uint8_t* wp;
	int Flags = This->FX.Flags;
	bool_t Dither = (Flags & BLITFX_DITHER) != 0 && !(This->Dst.Flags & PF_FOURCC);
	bool_t PalDither = Dither && (This->Dst.Flags & PF_PALETTE);

	const rgb* SrcPalette = This->SrcPalette;

	int SrcStepX[16];
	int SrcStepY[16];
	int RScaleX = This->RScaleX;
	int RScaleY = This->RScaleY;

	int SrcUVPitch2 = This->SrcUVPitch2;
	int SrcUVX2 = This->SrcUVX2;
	int SrcUVY2 = This->SrcUVY2;
	int DstUVX2 = This->DstUVX2;
	int DstUVY2 = This->DstUVY2;
	int DstStepX = This->DstBPP;
	int DstStepX2 = This->DstBPP;
	int DstStepY = DstPitch << 3;
	int DstStepY2 = DstStepY >> This->DstUVPitch2;
	int dy = 0;
	int dy2 = 0;

	int cR,cG,cB;
	int Y,U,V;
	int sy0;
	int sy=0;
	int YAdd = This->FX.Brightness;

	uint32_t SrcInvert = 0;
	uint32_t DstInvert = 0;

	SrcMask[0] = This->Src.RBitMask;
	SrcMask[1] = This->Src.GBitMask;
	SrcMask[2] = This->Src.BBitMask;

	DstMask[0] = This->Dst.RBitMask;
	DstMask[1] = This->Dst.GBitMask;
	DstMask[2] = This->Dst.BBitMask;

	for (i=0;i<3;++i)
	{
		DitherMask[i] = Dither ? (1 << (8 - BitMaskSize(DstMask[i]))) - 1 : 0;
		SrcPos[i] = BitMaskPos(SrcMask[i]) + BitMaskSize(SrcMask[i]);
		DstPos[i] = BitMaskPos(DstMask[i]) + BitMaskSize(DstMask[i]);
		SrcMask[i] <<= 8;
		DstMask[i] <<= 8;
		Src[i] = SrcPtr[i];
		Dst[i] = DstPtr[i];
	}

	if (This->DstPalette)
	{
		DstPos[0] = 11;
		DstPos[1] = 7;
		DstPos[2] = 3; 
		DstMask[0] = 0xF0000;
		DstMask[1] = 0x0F000;
		DstMask[2] = 0x00F00;
	}

	for (j=0;j<16;++j)
	{
		SrcStepX[j] = ((RScaleX * (j+1)) >> 4) - ((RScaleX * j) >> 4);
		SrcStepY[j] = ((RScaleY * (j+1)) >> 4) - ((RScaleY * j) >> 4);
	}

	if (This->DstLeftRight)
	{	
		DstStepX = -DstStepX;
		DstStepX2 = -DstStepX2;
		if (This->DstBPP < 8)
			dy = 8 - This->DstBPP;
	}

	if (This->SwapXY)
	{
		SwapInt(&DstUVX2,&DstUVY2);
		SwapInt(&DstStepX,&DstStepY);
		SwapInt(&DstStepX2,&DstStepY2);
	}

	cR = (DitherMask[0] >> 1);
	cG = (DitherMask[1] >> 1);
	cB = (DitherMask[2] >> 1);
	Y=U=V=0;

	if (This->Src.Flags & PF_INVERTED)
		SrcInvert = (This->Src.BitCount>=32?0:(1 << This->Src.BitCount))-1;
	if (This->Dst.Flags & PF_INVERTED)
		DstInvert = (This->Dst.BitCount>=32?0:(1 << This->Dst.BitCount))-1;

	for (y=0;y<Height;++y)
	{
		int dx=dy;
		int dx2=dy2;
		int sx=0;

		for (x=0;x<Width;sx+=SrcStepX[x&15],++x,dx+=DstStepX)
		{
			uint8_t* q;
			const rgb* p;
			uint32_t v,w;

			switch (SrcType)
			{
			case 10: //Planar YUV->RGB
				cR += ((Src[0][sx]+YAdd-16)*0x2568						              + 0x3343*(Src[2][sx>>SrcUVX2]-128)) /0x2000;
				cG += ((Src[0][sx]+YAdd-16)*0x2568 - 0x0c92*(Src[1][sx>>SrcUVX2]-128)  - 0x1a1e*(Src[2][sx>>SrcUVX2]-128)) /0x2000;
				cB += ((Src[0][sx]+YAdd-16)*0x2568 + 0x40cf*(Src[1][sx>>SrcUVX2]-128))                                     /0x2000;

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			case 11: //Packed YUV->RGB
				cR += ((Src[0][sx*2]+YAdd-16)*0x2568									  + 0x3343*(Src[2][4*(sx>>1)]-128)) /0x2000;
				cG += ((Src[0][sx*2]+YAdd-16)*0x2568 - 0x0c92*(Src[1][4*(sx>>1)]-128)  - 0x1a1e*(Src[2][4*(sx>>1)]-128)) /0x2000;
				cB += ((Src[0][sx*2]+YAdd-16)*0x2568 + 0x40cf*(Src[1][4*(sx>>1)]-128))                                   /0x2000;

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			case 12: //Planar YUV->YUV
				Y += Src[0][sx];
				U += Src[1][sx>>SrcUVX2];
				V += Src[2][sx>>SrcUVX2];

				//Y=SAT(Y);
				//U=SAT(U);
				//V=SAT(V);
				break;
			case 13: //Packed YUV->YUV
				Y += Src[0][sx*2];
				U += Src[1][4*(sx>>1)];
				V += Src[2][4*(sx>>1)];

				//Y=SAT(Y);
				//U=SAT(U);
				//V=SAT(V);
				break;
			case 1: //Pal1->RGB
				p = &SrcPalette[ ((Src[0][sx>>3] >> ((~sx)&7)) & 1) ^ SrcInvert];
				cR += p->r; cG += p->g; cB += p->b;

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			case 2: //Pal2->RGB
				p = &SrcPalette[ ((Src[0][sx>>2] >> (((~sx)&3)*2)) & 3) ^ SrcInvert];
				cR += p->r; cG += p->g; cB += p->b;

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			case 3: //Pal4->RGB
				p = &SrcPalette[ ((Src[0][sx>>1] >> (((~sx)&1)*4)) & 15) ^ SrcInvert];
				cR += p->r; cG += p->g; cB += p->b;

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			case 4: //Pal8->RGB
				p = &SrcPalette[Src[0][sx] ^ SrcInvert];
				cR += p->r; cG += p->g; cB += p->b;

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			case 5: //RGB8->RGB
				v = Src[0][sx];
				v ^= SrcInvert;
				v <<= 8;
				cR += (v & SrcMask[0]) >> SrcPos[0];
				cG += (v & SrcMask[1]) >> SrcPos[1];
				cB += (v & SrcMask[2]) >> SrcPos[2];

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			case 6: //RGB16->RGB
				v = ((uint16_t*)Src[0])[sx];
				v ^= SrcInvert;
				v <<= 8;
				cR += (v & SrcMask[0]) >> SrcPos[0];
				cG += (v & SrcMask[1]) >> SrcPos[1];
				cB += (v & SrcMask[2]) >> SrcPos[2];

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			case 7: //RGB24->RGB
				v = Src[0][sx*3] | (Src[0][sx*3+1] << 8) | (Src[0][sx*3+2] << 16);
				v ^= SrcInvert;
				v <<= 8;
				cR += (v & SrcMask[0]) >> SrcPos[0];
				cG += (v & SrcMask[1]) >> SrcPos[1];
				cB += (v & SrcMask[2]) >> SrcPos[2];

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			default: //RGB32->RGB
				v = ((uint32_t*)Src[0])[sx];
				v ^= SrcInvert;
				v <<= 8;
				cR += (v & SrcMask[0]) >> SrcPos[0];
				cG += (v & SrcMask[1]) >> SrcPos[1];
				cB += (v & SrcMask[2]) >> SrcPos[2];

				cR=SAT(cR);
				cG=SAT(cG);
				cB=SAT(cB);
				break;
			}

			q = Dst[0]+(dx >> 3);
			switch (DstType)
			{
			case 10: //RGB->Planar YUV
				Y = ( (2105 * cR) + (4128 * cG) + ( 802 * cB))/0x2000 + 16;
				U = (-(1212 * cR) - (2384 * cG) + (3596 * cB))/0x2000 + 128;
				V = ( (3596 * cR) - (3015 * cG) - ( 582 * cB))/0x2000 + 128;

				*q = (uint8_t)Y;
				Dst[1][dx2 >> 3] = (uint8_t)U;
				Dst[2][dx2 >> 3] = (uint8_t)V;
				if ((x & 1) || DstUVX2==0)
					dx2+=DstStepX2;
				cR=cG=cB=0;
				break;
			case 11: //RGB->Packed YUV
				Y = ( (2105 * cR) + (4128 * cG) + ( 802 * cB))/0x2000 + 16;
				U = (-(1212 * cR) - (2384 * cG) + (3596 * cB))/0x2000 + 128;
				V = ( (3596 * cR) - (3015 * cG) - ( 582 * cB))/0x2000 + 128;
				Y=SAT(Y);
				U=SAT(U);
				V=SAT(V);
				*q = (uint8_t)Y;
				Dst[1][4*(dx >> 5)] = (uint8_t)U;
				Dst[2][4*(dx >> 5)] = (uint8_t)V;
				cR=cG=cB=0;
				break;
			case 12: //YUV->Planar YUV
				Y += YAdd;
				Y=SAT(Y);
				*q = (uint8_t)Y;
				Dst[1][dx2 >> 3] = (uint8_t)U;
				Dst[2][dx2 >> 3] = (uint8_t)V;
				if ((x & 1) || DstUVX2==0)
					dx2+=DstStepX2;
				Y=U=V=0;
				break;
			case 13: //YUV->Packed YUV
				Y += YAdd;
				Y=SAT(Y);
				*q = (uint8_t)Y;
				Dst[1][4*(dx >> 5)] = (uint8_t)U;
				Dst[2][4*(dx >> 5)] = (uint8_t)V;
				Y=U=V=0;
				break;
			case 1: //RGB->Pal1
				w = ((cR << DstPos[0]) & DstMask[0]) |
					((cG << DstPos[1]) & DstMask[1]) |
					((cB << DstPos[2]) & DstMask[2]);

				wp = PalLookUp + (w >> 8)*4;
				w = wp[0];
				w ^= DstInvert;
				*q &= ~(1 << ((~dx)&7));
				*q |=  (w << ((~dx)&7));

				if (PalDither)
				{
					cR -= wp[1];
					cG -= wp[2];
					cB -= wp[3];
				}
				else
					cR=cG=cB=0;
				break;
			case 2: //RGB->Pal2
				w = ((cR << DstPos[0]) & DstMask[0]) |
					((cG << DstPos[1]) & DstMask[1]) |
					((cB << DstPos[2]) & DstMask[2]);

				wp = PalLookUp + (w >> 8)*4;
				w = wp[0];
				w ^= DstInvert;
				*q &= ~(3 << ((~dx)&6));
				*q |=  (w << ((~dx)&6));

				if (PalDither)
				{

⌨️ 快捷键说明

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