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

📄 blit_soft.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
📖 第 1 页 / 共 5 页
字号:
		DstRect->x += ShrinkX;
		DstRect->Width = SrcAdjWidth;
	}
	else //adjust source position
	{
		ShrinkX = 0;
		SrcRect->x += ((SrcAdjWidth - DstRect->Width) << 15) / ScaleX;
		SrcRect->Width = -1;
	}
	
	ShrinkY = DstRect->Height - SrcAdjHeight;
	if (ShrinkY>0) //shrink Dst?
	{
		ShrinkY >>= 1;
		DstRect->y += ShrinkY;
		DstRect->Height = SrcAdjHeight;
	}
	else //adjust source position
	{
		ShrinkY = 0;
		SrcRect->y += ((SrcAdjHeight - DstRect->Height) << 15) / ScaleY;
		SrcRect->Height = -1;
	}

	// final alignment

	i = DstRect->Width & (DstAlignSize-1); 
	DstRect->Width -= i; 
	i >>= 1;
	ShrinkX += i;
	DstRect->x += i;

	i = DstRect->Height & (DstAlignSize-1);
	DstRect->Height -= i;
	i >>= 1;
	ShrinkY += i;
	DstRect->y += i;

	i = DstRect->x & (DstAlignPos-1);
	if (i && ShrinkX < i)
	{
		DstRect->Width -= DstAlignPos - i;
		DstRect->Width &= ~(DstAlignSize-1); 
		DstRect->x += DstAlignPos - i;
	}
	else
		DstRect->x -= i;

	i = DstRect->y & (DstAlignPos-1);
	if (i && ShrinkY < i)
	{
		DstRect->Height -= DstAlignPos - i;
		DstRect->Height &= ~(DstAlignSize-1);
		DstRect->y += DstAlignPos - i;
	}
	else
		DstRect->y -= i;

	SrcRect->x &= ~1;
	SrcRect->y &= ~1;

	if (SrcRect->Width < 0)
		SrcRect->Width = ((DstRect->Width << 16) / ScaleX +1) & ~1;
	if (SrcRect->Height < 0)
		SrcRect->Height = ((DstRect->Height << 16) / ScaleY +1) & ~1;

	if (FX->Direction & DIR_SWAPXY)
		SwapRect(SrcRect);

	if (SrcRect->x + SrcRect->Width > SrcRight)
		SrcRect->Width = SrcRight - SrcRect->x;

	if (SrcRect->y + SrcRect->Height > SrcBottom)
		SrcRect->Height = SrcBottom - SrcRect->y;

	return ERR_NONE;
}

static INLINE void SurfacePtr(uint8_t** Ptr, const planes Planes, const video* Format, int BPP, int x, int y, int Pitch)
{
	int Adj = (x & 1) << 1;
   	Ptr[0] = (uint8_t*)Planes[0] + ((x * BPP) >> 3) + y * Pitch;

	if (Format->Pixel.Flags & (PF_YUV420|PF_YUV422|PF_YUV444|PF_YUV410))
	{
		if (Format->Pixel.Flags & PF_YUV420)
		{
			Ptr[1] = (uint8_t*)Planes[1] + (x >> 1) + (y >> 1) * (Pitch >> 1);
			Ptr[2] = (uint8_t*)Planes[2] + (x >> 1) + (y >> 1) * (Pitch >> 1);
		}
		else
		if (Format->Pixel.Flags & PF_YUV422)
		{
			Ptr[1] = (uint8_t*)Planes[1] + (x >> 1) + y * (Pitch >> 1);
			Ptr[2] = (uint8_t*)Planes[2] + (x >> 1) + y * (Pitch >> 1);
		}
		else
		if (Format->Pixel.Flags & PF_YUV444)
		{
			Ptr[1] = (uint8_t*)Planes[1] + x + y * Pitch;
			Ptr[2] = (uint8_t*)Planes[2] + x + y * Pitch;
		}
		else
		if (Format->Pixel.Flags & PF_YUV410)
		{
			Ptr[1] = (uint8_t*)Planes[1] + (x >> 2) + (y >> 2) * (Pitch >> 2);
			Ptr[2] = (uint8_t*)Planes[2] + (x >> 2) + (y >> 2) * (Pitch >> 2);
		}
	}
	else
	if (Format->Pixel.Flags & PF_FOURCC)
		switch (Format->Pixel.FourCC)
		{
		case FOURCC_IMC2:
			Ptr[2] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + (y >> 1) * Pitch;
			Ptr[1] = Ptr[1] + (Pitch >> 1);
			break;
		case FOURCC_IMC4:
			Ptr[1] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + (y >> 1) * Pitch;
			Ptr[2] = Ptr[1] + (Pitch >> 1);
			break;
		case FOURCC_I420:
		case FOURCC_IYUV:
			Ptr[1] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + (y >> 1) * (Pitch >> 1);
			Ptr[2] = Ptr[1] + ((Format->Height * Pitch) >> 2);
			break;
		case FOURCC_YV16: 
			Ptr[2] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + y * (Pitch >> 1);
			Ptr[1] = Ptr[2] + ((Format->Height * Pitch) >> 1);
			break;
		case FOURCC_YVU9: 
			Ptr[2] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 2) + (y >> 2) * (Pitch >> 2);
			Ptr[1] = Ptr[2] + ((Format->Height * Pitch) >> 4);
			break;
		case FOURCC_YUV9: 
			Ptr[1] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 2) + (y >> 2) * (Pitch >> 2);
			Ptr[2] = Ptr[1] + ((Format->Height * Pitch) >> 4);
			break;
		case FOURCC_YV12: 
			Ptr[2] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + (y >> 1) * (Pitch >> 1);
			Ptr[1] = Ptr[2] + ((Format->Height * Pitch) >> 2);
			break;
		case FOURCC_YUY2:
		case FOURCC_YUNV:
		case FOURCC_V422:
		case FOURCC_YUYV:
			Ptr[1] = Ptr[0]+1-Adj;
			Ptr[2] = Ptr[0]+3-Adj;
			break;
		case FOURCC_YVYU:
			Ptr[1] = Ptr[0]+3-Adj;
			Ptr[2] = Ptr[0]+1-Adj;
			break;
		case FOURCC_UYVY:
		case FOURCC_Y422:
		case FOURCC_UYNV:
			Ptr[1] = Ptr[0]-Adj;
			Ptr[2] = Ptr[0]+2-Adj;
			Ptr[0]++;
			break;
		case FOURCC_VYUY:
			Ptr[2] = Ptr[0]-Adj;
			Ptr[1] = Ptr[0]+2-Adj;
			Ptr[0]++;
			break;
		}
}

void BlitImage(blitpack* Pack, const planes Dst, const constplanes Src, const constplanes SrcLast, int DstPitch, int SrcPitch)
{
	uint8_t* DstPtr[MAXPLANES];
	uint8_t* SrcPtr[MAXPLANES];
	bool_t OnlyDiff;
	int Width,Height;
	blit_soft* p;
	uintptr_t Src2SrcLast;
	int DstStepX;
	int DstStepY;
	int DstX;
	int DstY;
	int SrcY;

	// nothing to do?
	if (!Pack || Pack->DstRect.Width<=0 || Pack->DstRect.Height<=0)
		return;

	OnlyDiff = (Pack->FX.Flags & BLITFX_ONLYDIFF) && SrcLast && SrcLast[0] != NULL;

	p = &Pack->Code[OnlyDiff];

	// calculate the Src and Dst pointers
	//   Src: always upperleft corner
	//   Dst: according to swapxy and mirroring

	Width = Pack->DstRect.Width;
	Height = Pack->DstRect.Height;

	if (p->SwapXY)
		SwapInt(&Width,&Height);

	if (DstPitch < 0)
		DstPitch = Pack->Dst.Pitch;
	if (SrcPitch < 0)
		SrcPitch = Pack->Src.Pitch;

	SrcY = Pack->SrcRect.y;
	if (p->SrcUpDown)
		SrcY += Pack->SrcRect.Height-1;

	SurfacePtr(SrcPtr,*(const planes*)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 = malloc(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->c.r-v[0])*(q->c.r-v[0])+
								   (q->c.g-v[1])*(q->c.g-v[1])+
								   (q->c.b-v[2])*(q->c.b-v[2]);

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

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

						v[0]=SAT(v[0]);
						v[1]=SAT(v[1]);
						v[2]=SAT(v[2]);
					}
					else
					{
						v[0] = q->c.r;
						v[1] = q->c.g;
						v[2] = q->c.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;
				}
	}
}

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 == 32/16/8
// RScaleY == 32/16/8 
// SrcUVX2 == DstUVX2
// SrcUVY2 == DstUVY2

static void Blit_PYUV_PYUV_2Plane(const uint8_t* Src,uint8_t* Dst,int Width,int Height,int SrcPitch,int DstPitch,int ScaleX,int ScaleY)
{
	int y;
	for (y=0;y<Height;++y)
	{
		const uint8_t* s = Src;
		uint8_t* d = Dst;
		uint8_t* de = Dst + Width;

		switch (ScaleX)
		{
		case 4:
			while (d<de)
			{
				d[0] = d[1] = d[2] = d[3] = *s;
				++s;
				d+=4;
			}
			break;
		case 8:
			while (d<de)
			{
				d[0] = *s;
				d[1] = *s;
				++s;
				d+=2;
			}
			break;
		case 16:
			memcpy(d,s,Width);
			break;
		case 32:
			while (d<de)
			{
				*d = *s;
				++d;
				s+=2;
			}
			break;
		case 64:
			while (d<de)
			{
				*d = *s;
				++d;
				s+=4;
			}
			break;
		}

		Dst += DstPitch;

		switch (ScaleY)
		{
		case 4:
			if ((y&3)==3) Src += SrcPitch;
			break;
		case 8:
			if (y&1) Src += SrcPitch;
			break;
		case 16:
			Src += SrcPitch;
			break;
		case 32:
			Src += SrcPitch*2;
			break;
		case 64:
			Src += SrcPitch*4;
			break;
		}
	}
}

// needed for half/quarter software idct mode changes
static void STDCALL Blit_PYUV_PYUV_2(blit_soft* This, uint8_t** DstPtr,uint8_t** SrcPtr,int DstPitch,int SrcPitch,
	                  int Width,int Height,uintptr_t Src2SrcLast) 
{
	Blit_PYUV_PYUV_2Plane(SrcPtr[0],DstPtr[0],Width,Height,SrcPitch,DstPitch,This->RScaleX,This->RScaleY);

	Width >>= This->SrcUVX2;

⌨️ 快捷键说明

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