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

📄 blit_soft.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
📖 第 1 页 / 共 5 页
字号:
				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)
				{
					cR -= wp[1];
					cG -= wp[2];
					cB -= wp[3];
				}
				else
					cR=cG=cB=0;
				break;
			case 3: //RGB->Pal4
				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 &= ~(15 << ((~dx)&4));
				*q |=  (w  << ((~dx)&4));

				if (PalDither)
				{
					cR -= wp[1];
					cG -= wp[2];
					cB -= wp[3];
				}
				else
					cR=cG=cB=0;
				break;
			case 14: //YUV->Pal8
				w = ((Y << DstPos[0]) & DstMask[0]) |
					((U << DstPos[1]) & DstMask[1]) |
					((V << DstPos[2]) & DstMask[2]);

				wp = PalLookUp + (w >> 8)*4;
				w = wp[0];
				w ^= DstInvert;
				*q = (uint8_t)w;

				if (PalDither)
				{
					Y -= wp[1];
					U -= wp[2];
					V -= wp[3];
				}
				else
					Y=U=V=0;
				break;

			case 4: //RGB->Pal8
				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 = (uint8_t)w;
				if (PalDither)
				{
					cR -= wp[1];
					cG -= wp[2];
					cB -= wp[3];
				}
				else
					cR=cG=cB=0;
				break;
			case 5: //RGB->RGB8
				w = ((cR << DstPos[0]) & DstMask[0]) |
					((cG << DstPos[1]) & DstMask[1]) |
					((cB << DstPos[2]) & DstMask[2]);
				*q = (uint8_t)((w >> 8) ^ DstInvert);
				cR &= DitherMask[0];
				cG &= DitherMask[1];
				cB &= DitherMask[2];
				break;
			case 6: //RGB->RGB16
				w = ((cR << DstPos[0]) & DstMask[0]) |
					((cG << DstPos[1]) & DstMask[1]) |
					((cB << DstPos[2]) & DstMask[2]);
				*(uint16_t*)q = (uint16_t)((w >> 8) ^ DstInvert);
				cR &= DitherMask[0];
				cG &= DitherMask[1];
				cB &= DitherMask[2];
				break;
			case 7: //RGB->RGB24
				w = ((cR << DstPos[0]) & DstMask[0]) |
					((cG << DstPos[1]) & DstMask[1]) |
					((cB << DstPos[2]) & DstMask[2]);
				w >>= 8;
				w ^= DstInvert;
				q[0] = (uint8_t)(w);
				q[1] = (uint8_t)(w >> 8);
				q[2] = (uint8_t)(w >> 16);
				cR &= DitherMask[0];
				cG &= DitherMask[1];
				cB &= DitherMask[2];
				break;
			default: //RGB->RGB32
				w = ((cR << DstPos[0]) & DstMask[0]) |
					((cG << DstPos[1]) & DstMask[1]) |
					((cB << DstPos[2]) & DstMask[2]);
				*(uint32_t*)q = (w >> 8) ^ DstInvert;
				cR &= DitherMask[0];
				cG &= DitherMask[1];
				cB &= DitherMask[2];
				break;
			}
		}

		dy += DstStepY;
		if ((y & 1) || DstUVY2==0)
			dy2 += DstStepY2;

		sy0 = sy;
		sy += SrcStepY[y&15];
		Src[0] += SrcPitch * (sy - sy0);
		Src[1] += (SrcPitch >> SrcUVPitch2) * ((sy >> SrcUVY2) - (sy0 >> SrcUVY2));
		Src[2] += (SrcPitch >> SrcUVPitch2) * ((sy >> SrcUVY2) - (sy0 >> SrcUVY2));
	}
}

#endif

static bool_t BlitCompile(blit_soft* p,
				   const pixel* NewDst,const pixel* NewSrc,
		  		   const blitfx* NewFX,bool_t NewOnlyDiff)
{
	int i;
	bool_t Gray,SrcPlanarYUV,DstPlanarYUV;

	if (EqPixel(&p->Dst,NewDst) && 
		EqPixel(&p->Src,NewSrc) && 
		EqBlitFX(&p->FX,NewFX) &&
		NewOnlyDiff == p->OnlyDiff)
		return p->Entry != NULL;

	CodeStart(&p->Code);

	// defaults
	p->Caps = VC_BRIGHTNESS|VC_DITHER|VC_SATURATION|VC_CONTRAST|VC_RGBADJUST;
	p->SrcAlignPos = 2;
	p->DstAlignPos = 2;
	p->DstAlignSize = 2;

	p->Dst = *NewDst;
	p->Src = *NewSrc;
	p->FX = *NewFX;
	p->OnlyDiff = (boolmem_t)NewOnlyDiff;
	p->SwapXY = (boolmem_t)((p->FX.Direction & DIR_SWAPXY) != 0);
	p->DstLeftRight = (boolmem_t)((p->FX.Direction & DIR_MIRRORLEFTRIGHT) != 0);
	p->DstUpDown = (boolmem_t)((p->FX.Direction & DIR_MIRRORUPDOWN) != 0);
	p->SrcUpDown = (boolmem_t)((p->FX.Flags & BLITFX_AVOIDTEARING) && !p->SwapXY && p->DstUpDown != ((p->FX.Flags & BLITFX_VMEMUPDOWN) != 0));
	if (p->SrcUpDown)
		p->DstUpDown = (boolmem_t)!p->DstUpDown;

	// it's faster using slices with rotation (not just with AVOIDTEARING)
	// probably because of ram page trashing (during vertical writing)
	p->Slices = (boolmem_t)(p->SwapXY != ((p->FX.Flags & BLITFX_VMEMROTATED) != 0));
	p->SlicesReverse = (boolmem_t)((p->SwapXY ? p->DstUpDown : p->DstLeftRight) == ((p->FX.Flags & BLITFX_VMEMUPDOWN) != 0));

	Gray = (p->Dst.Flags & PF_PALETTE) && (p->Dst.BitCount == 4 || p->Dst.BitCount == 2);
	p->RScaleX = CalcRScale(p->FX.ScaleX,Gray);
	p->RScaleY = CalcRScale(p->FX.ScaleY,Gray);

	// important these integeres should be 1 or 0
	p->DstHalfX = p->SrcHalfX = p->RScaleX == 32;
	p->DstHalfY = p->SrcHalfY = p->RScaleY == 32;
	p->DstDoubleX = p->SrcDoubleX = p->RScaleX == 8;
	p->DstDoubleY = p->SrcDoubleY = p->RScaleY == 8;
	if (p->SwapXY)
	{
		SwapInt(&p->DstHalfX,&p->DstHalfY);
		SwapInt(&p->DstDoubleX,&p->DstDoubleY);
	}

	p->SrcBPP = GetBPP(&p->Src);
	p->SrcBPP2 = -3;
	for (i=p->SrcBPP;i>1;i>>=1)
		++p->SrcBPP2;

	p->DstBPP = GetBPP(&p->Dst);
	p->DstBPP2 = -3;
	for (i=p->DstBPP;i>1;i>>=1)
		++p->DstBPP2;

	p->SrcYUV = (boolmem_t)AnyYUV(&p->Src);
	p->SrcPalette = DefaultPal(&p->Src);
	p->DstPalette = DefaultPal(&p->Dst);

	free(p->LookUp_Data);
	p->LookUp_Data = NULL;

	p->ColorLookup = (boolmem_t)((p->FX.Flags & BLITFX_COLOR_LOOKUP) != 0);
#ifdef ARM
	p->ARM5 = (boolmem_t)((QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_5E)!=0);
	p->WMMX = (boolmem_t)((QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_WMMX)!=0 && 
	          !QueryAdvanced(ADVANCED_NOWMMX) && (p->Dst.Flags & PF_16ALIGNED) && (p->Src.Flags & PF_16ALIGNED));
	p->QAdd = (boolmem_t)((QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_5E)!=0 && 
		      !p->DstPalette && !p->WMMX && !(p->FX.Flags & BLITFX_DITHER) && !p->ColorLookup);
#endif
	CalcColor(p);
	if (p->DstPalette)
		BuildPalLookUp(p,p->SrcYUV);

	p->ArithStretch = (boolmem_t)((p->FX.Flags & BLITFX_ARITHSTRETCHALWAYS) != 0);
	if ((p->FX.Flags & BLITFX_ARITHSTRETCH50) && p->RScaleX==32 && p->RScaleY==32)
		p->ArithStretch = 1;
	if (p->DstPalette)
		p->ArithStretch = 0;

	SrcPlanarYUV = PlanarYUV(&p->Src,&p->SrcUVX2,&p->SrcUVY2,&p->SrcUVPitch2);
	DstPlanarYUV = PlanarYUV(&p->Dst,&p->DstUVX2,&p->DstUVY2,&p->DstUVPitch2);

	p->DirX = p->DstLeftRight ? -1:1;
	for (i=0;i<3;++i)
	{
		p->DstSize[i] = BitMaskSize(p->Dst.BitMask[i]);
		p->DstPos[i] = BitMaskPos(p->Dst.BitMask[i]);
		p->SrcSize[i] = BitMaskSize(p->Src.BitMask[i]);
		p->SrcPos[i] = BitMaskPos(p->Src.BitMask[i]);
	}

#if defined(ARM)
	if ((p->Dst.Flags & PF_RGB) && p->Dst.BitCount==16 && !p->SrcYUV)
		Any_RGB_RGB(p);
	if (!p->SrcYUV && DstPlanarYUV && p->RScaleX==16 && p->RScaleY==16)
		Fix_Any_YUV(p);
#endif

#if (defined(ARM) || defined(SH3) || defined(MIPS)) && defined(CONFIG_DYNCODE)
	if (SrcPlanarYUV)
	{
#if defined(ARM)
		if (DstPlanarYUV && p->RScaleX==16 && p->RScaleY==16 && 
			((p->SrcUVX2==p->DstUVX2 && p->SrcUVY2==p->DstUVY2 && !(p->SwapXY && p->SrcUVX2 != p->SrcUVY2)) || 
			(p->DstUVX2==1 && p->DstUVY2==1)))
			Fix_Any_YUV(p);

		if (PackedYUV(&p->Dst) && p->RScaleX==16 && p->RScaleY==16 && p->SrcUVY2<2 && p->SrcUVX2<2)
			Fix_PackedYUV_YUV(p);
#endif
		if ((p->Dst.Flags & (PF_RGB|PF_PALETTE)) && (p->Dst.BitCount == 8 || p->Dst.BitCount == 16 || p->Dst.BitCount == 32))
		{
#if defined(ARM)
			if (p->Dst.BitCount == 16 && p->WMMX && PlanarYUV420(&p->Src) && 
				(p->RScaleX==16 || p->RScaleX==8 || p->RScaleX==32) && (p->RScaleY==16 || p->RScaleY==8 || p->RScaleY==32))
				WMMXFix_RGB_UV(p);
			else
			if ((p->Dst.BitCount == 16 || p->Dst.BitCount==32) && p->SrcUVX2==1 && p->SrcUVY2==1 && p->RScaleX == 16 && p->RScaleY == 16)
				Fix_RGB_UV(p);
			else
			if (p->Dst.BitCount == 16 && p->SrcUVX2==1 && p->SrcUVY2==1 &&
				(p->RScaleX == 8 || p->RScaleX == 16) && 
				(p->RScaleY == 8 || p->RScaleY == 16) && !p->ArithStretch)
				Fix_RGB_UV(p);
			else
			if (p->Dst.BitCount == 16 && p->SrcUVX2==1 && p->SrcUVY2==1 && p->RScaleX == 32 && p->RScaleY == 32)
				Half_RGB_UV(p);
			else
				Stretch_RGB_UV(p);
#else
#if !defined(MIPS)
			if (p->SrcUVX2==1 && p->SrcUVY2==1 && 
				(p->RScaleX == 8 || p->RScaleX == 16) &&
				(p->RScaleY == 8 || p->RScaleY == 16))
#endif
				Fix_RGB_UV(p);
#endif
		}
		else
		if (Gray)
			Fix_Gray_UV(p);
	}
#endif

	CodeBuild(&p->Code);
	if (p->Code.Size)
		p->Entry = (blitsoftentry)p->Code.Code;
	else
		p->Entry = NULL;

#if defined(_M_IX86) && !defined(TARGET_SYMBIAN)

	if (p->FX.Direction==0 && p->RScaleX==16 && p->RScaleY==16)
	{
		uint32_t In = DefFourCC(&p->Src);
		uint32_t Out = DefFourCC(&p->Dst);
#ifdef CONFIG_CONTEXT
		int Caps = QueryPlatform(PLATFORM_CAPS);
#else
		int Caps = CPUCaps();
#endif
		const blitmmx* i;
		for (i=BlitMMX;i->In;++i)
			if (i->In==In && i->Out==Out)
			{
				p->Caps &= ~VC_DITHER;
				if (AnyYUV(&p->Src))
					CalcYUVMMX(p);
				if (Caps & CAPS_X86_MMX2)
					p->Entry = i->Func[1];
				else if (Caps & CAPS_X86_3DNOW)
					p->Entry = i->Func[2];
				else
					p->Entry = i->Func[0];
				break;
			}
	}

#endif

	if (!p->Entry)
	{
		// use YUV internal calulaction?
		bool_t YUV = (AnyYUV(&p->Dst) || 
			(p->Dst.BitCount==8 && p->Dst.Flags & PF_PALETTE)) && p->SrcYUV;

		p->DstType = UniversalType(&p->Dst,YUV);
		p->SrcType = UniversalType(&p->Src,YUV);

#if defined(_M_IX86) || !defined(CONFIG_DYNCODE) || defined(BLITTEST)

		if (p->SrcType>=0 && p->DstType>=0)
		{
			// universal
			if (AnyYUV(&p->Dst)) 
				p->Caps &= ~VC_DITHER;
			else
				p->Caps = VC_BRIGHTNESS | VC_DITHER;
			p->Entry = BlitUniversal; 
		}

		if (p->SrcUVX2 == 1 && !p->SwapXY && !p->DstLeftRight && p->SrcType == 10)
		{
			if (p->DstType == 8 && 
				p->Dst.BitMask[0] == 0xFF0000 &&
				p->Dst.BitMask[1] == 0x00FF00 &&
				p->Dst.BitMask[2] == 0x0000FF)
			{
				p->Caps = VC_BRIGHTNESS;
				p->Entry = Blit_PYUV_RGB32;
			}

			if (p->DstType == 6 && 
				p->Dst.BitMask[0] == 0xF800 &&
				p->Dst.BitMask[1] == 0x07E0 &&
				p->Dst.BitMask[2] == 0x001F)
			{
				p->Caps = VC_BRIGHTNESS;
				p->Entry = Blit_PYUV_RGB16;
			}
		}

		if (p->SrcUVX2 == p->DstUVX2 &&	!p->SwapXY && !p->DstLeftRight &&
			p->RScaleX == 16 && p->RScaleY==16 &&
			p->SrcType == 12 &&	p->DstType == 12)
		{
			CalcYUVLookUp(p);
			p->Caps &= ~VC_DITHER;
			p->Entry = Blit_PYUV_PYUV;
		}
#endif
		if (p->SrcUVX2 == p->DstUVX2 &&	
			p->SrcUVY2 == p->DstUVY2 &&	!p->SwapXY && !p->DstLeftRight &&
			(p->RScaleX != 16 || p->RScaleY != 16) &&
			(p->RScaleX == 16 || p->RScaleX == 8 || p->RScaleX == 32 || p->RScaleX == 4 || p->RScaleX == 64) && 
			(p->RScaleY == 16 || p->RScaleY == 8 || p->RScaleY == 32 || p->RScaleX == 4 || p->RScaleX == 64) && 
			p->SrcType == 12 &&	p->DstType == 12 &&
			!p->FX.Saturation && !p->FX.Contrast && !p->FX.RGBAdjust[0] && 
			!p->FX.RGBAdjust[1] && !p->FX.RGBAdjust[2] && !p->FX.Brightness)
		{
			p->Caps = 0;
			p->Entry = Blit_PYUV_PYUV_2;
		}
	}

	return p->Entry != NULL;
}

blitpack* BlitCreate(const video* Dst, 
			         const video* Src, const blitfx* FX, int* OutCaps)
{
	blitfx CopyFX;
	bool_t Gray;

	blitpack* p = BlitAlloc();
	if (!p)	return NULL;

	if (!FX)
	{
		memset(&CopyFX,0,sizeof(CopyFX));
		CopyFX.ScaleX = SCALE_ONE;
		CopyFX.ScaleY = SCALE_ONE;
		FX = &CopyFX;
	}

	if (!BlitCompile(&p->Code[0],&Dst->Pixel,&Src->Pixel,FX,0) ||
		((FX->Flags & BLITFX_ONLYDIFF) && !BlitCompile(&p->Code[1],&Dst->Pixel,&Src->Pixel,FX,1)))
	{
		BlitRelease(p);
		return NULL;
	}

	p->FX = *FX;
	p->Dst = *Dst;
	p->Src = *Src;

	Gray = (Dst->Pixel.Flags & PF_PALETTE) && 
		   (Dst->Pixel.BitCount == 4 || Dst->Pixel.BitCount == 2);

	p->RScaleX = CalcRScale(FX->ScaleX,Gray);
	p->RScaleY = CalcRScale(FX->ScaleY,Gray);

	if (OutCaps)
		*OutCaps = p->Code[0].Caps;

	return p;
}

static NOINLINE int CMul(blit_soft* p, int64_t* r, int64_t v, bool_t UV)
{
	int m;

	if (UV)
	{
		m = p->FX.Saturation;
		if (m<0) m >>= 1; // adjust negtive interval: -128..0 -> -64..0
		m = 4*m+256;
		v *= m;
		if (v<0) 
			v -= 128; 
		else 
			v += 128;
		v >>= 8;
	}

	m = p->FX.Contrast;

⌨️ 快捷键说明

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