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

📄 blit_arm_rgb16.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
字号:
/*****************************************************************************
 *
 * This program is free software ; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * $Id: blit_arm_rgb16.c 339 2005-11-15 11:22:45Z picard $
 *
 * The Core Pocket Media Player
 * Copyright (c) 2004-2005 Gabor Kovacs
 *
 ****************************************************************************/

#include "../common.h"
#include "../dyncode/dyncode.h"
#include "blit_soft.h"

#if defined(ARM) 

// R0..R6 temporary
// R7 Pos(when Stretch)
// R8 Src2SrcLast (when Diff)
// R8 Src0 (when Stretch)
// R9 Src
// R10 EndOfLine 
// R11 Dst
// R12 DstPitch
// R14 SrcPitch 
// R14 Src1 (when Stretch)

typedef struct stack
{
	int EndOfRect; 
	int DstNext; 
	int SrcNext;
	void* Palette;

	int StackFrame[STACKFRAME];

	//void* this   R0
	//char* Dst    R1
	//char* Src    R2
	//int DstPitch R3 can be signed
	int SrcPitch;
	int Width; 
	int Height;
	int Src2SrcLast;
} stack;

void RGB_4X2(blit_soft* p)
{
	if (p->RealOnlyDiff)
	{
		p->Skip = Label(0);

		I3(LDR,R4,R9,R8);
		I3(LDR_POST,R0,R9,R14);

		I3(LDR,R6,R9,R8);
		I2C(LDR_POST,R2,R9,4);

		I3(LDR,R5,R9,R8);
		I3(LDR_POSTSUB,R3,R9,R14);

		I3(CMP,NONE,R0,R4);
		C(EQ); I3(CMP,NONE,R2,R6);

		I3(LDR,R6,R9,R8);
		I2C(LDR_POST,R1,R9,4);

		C(EQ); I3(CMP,NONE,R3,R5);
		C(EQ); I3(CMP,NONE,R1,R6);

		C(EQ);
		if (p->SwapXY)
			I3S(ADD,R11,R11,R12,LSL,2+p->DstDoubleY);
		else
			I2C(ADD,R11,R11,(2*4*p->DirX)<<p->DstDoubleX);

		I0P(B,EQ,p->Skip);
	}

	if (p->DstDoubleX && p->DstDoubleY)
	{
		//todo...
	}
	else
	{
		if (p->SwapXY)
		{
			if (p->RealOnlyDiff)
				I2C(SUB,R9,R9,8);

			Half(); I3(LDR_POST,R0,R9,R14);
			Half(); I2C(LDR_POST,R1,R9,2);

			Half(); I3(LDR_POSTSUB,R3,R9,R14);
			Half(); I2C(LDR_POST,R2,R9,2);

			if (p->DirX>0)
			{
				I3S(ORR,R4,R0,R1,LSL,16);
				I3S(ORR,R5,R2,R3,LSL,16);
			}
			else
			{
				I3S(ORR,R4,R1,R0,LSL,16);
				I3S(ORR,R5,R3,R2,LSL,16);
			}

			MB(); Half(); I3(LDR_POST,R0,R9,R14);
			MB(); Half(); I2C(LDR_POST,R1,R9,2);

			MB(); Half(); I3(LDR_POSTSUB,R3,R9,R14);
			MB(); Half(); I2C(LDR_POST,R2,R9,2);

			if (p->DirX>0)
			{
				I3S(ORR,R1,R0,R1,LSL,16);
				I3S(ORR,R3,R2,R3,LSL,16);
			}
			else
			{
				I3S(ORR,R1,R1,R0,LSL,16);
				I3S(ORR,R3,R3,R2,LSL,16);
			}

			I3(STR_POST,R4,R11,R12);
			I3(STR_POST,R5,R11,R12);
			I3(STR_POST,R1,R11,R12);
			I3(STR_POST,R3,R11,R12);
		}
		else
		{
			if (!p->RealOnlyDiff)
			{
				I3(LDR_POST,R0,R9,R14);
				I2C(LDR_POST,R2,R9,4);
				I3(LDR_POSTSUB,R3,R9,R14);
				I2C(LDR_POST,R1,R9,4);
			}
			if (p->DirX<0)
			{
				I3S(MOV,R0,NONE,R0,ROR,16);
				I3S(MOV,R1,NONE,R1,ROR,16);
				I3S(MOV,R2,NONE,R2,ROR,16);
				I3S(MOV,R3,NONE,R3,ROR,16);
			}

			I3(STR_POST,R0,R11,R12);
			I2C(STR_POST,R2,R11,4*p->DirX);
			I3(STR_POSTSUB,R3,R11,R12);
			I2C(STR_POST,R1,R11,4*p->DirX);
		}
	}

	if (p->RealOnlyDiff)
		InstPost(p->Skip);
}

void RGB_Read(blit_soft* p,reg RGB,reg Src,int Inc)
{
	int Type[4];
	int IncByte[4];
	reg Tmp = R6;
	int i,j;
	bool_t First;

	if (p->Src.BitCount==p->Dst.BitCount && (p->Src.BitCount!=8 || !p->LookUp) &&
		p->Src.BitMask[0] == p->Dst.BitMask[0] &&
		p->Src.BitMask[1] == p->Dst.BitMask[1] &&
		p->Src.BitMask[2] == p->Dst.BitMask[2])
	{
		switch (p->Src.BitCount)
		{
		case 8:
			Byte(); I2C(LDR_POST,RGB,Src,Inc); 
			break;
		case 16:
			Half(); I2C(LDR_POST,RGB,Src,Inc*2); 
			break;
		case 32:
			I2C(LDR_POST,RGB,Src,Inc*4); 
			break;
		}
	}
	else
	{
		switch (p->Src.BitCount)
		{
		case 8:
			if (p->LookUp)
			{
				I1P(MOV,Tmp,p->LookUp,0);
				Byte(); I2C(LDR_POST,RGB,Src,Inc);
				switch (p->Dst.BitCount)
				{
				case 8:
					Byte(); I3(LDR,RGB,Tmp,RGB); 
					break;
				case 16:
					I3(ADD,RGB,RGB,RGB);
					Half(); I3(LDR,RGB,Tmp,RGB);
					break;
				case 32:
					I3S(LDR,RGB,Tmp,RGB,LSL,2);
					break;
				}
			}
			break;

		case 16:
			Half(); I2C(LDR_POST,RGB,Src,Inc*2);

			for (i=0;i<3;++i)
			{
				j = min(p->DstSize[i],p->SrcSize[i]);
				I2C(AND,Tmp,RGB,((1<<j)-1) << (p->SrcSize[i]+p->SrcPos[i]-j));
				I3S(ORR,RGB,RGB,Tmp,LSL,16-p->SrcSize[i]-p->SrcPos[i]+p->DstSize[i]+p->DstPos[i]);
			}

			I3S(MOV,RGB,NONE,RGB,LSR,16);
			break;

		case 32:
		case 24:

			for (j=0;j<3;++j)
				IncByte[j] = 1;
			IncByte[3] = (Inc-1) * (p->SrcBPP/8) + (p->Src.BitCount==32);

			for (j=0;j<4;++j)
			{
				Type[j] = -1;
				for (i=0;i<3;++i)
					if (p->SrcPos[i]==j*8)
						Type[j] = i;

				if (Type[j]<0)
				{
					// merge IncByte to previous
					for (i=j-1;i>=0;--i)
						if (Type[i]>=0 || IncByte[i])
						{
							IncByte[i] += IncByte[j];
							IncByte[j] = 0;
							break;
						}
				}
			}

			First = 1;
			for (j=0;j<4;++j)
			{
				i = Type[j];
				if (i>=0)
				{
					Byte(); I2C(LDR_POST,Tmp,Src,IncByte[j]);
					I2C(AND,Tmp,Tmp,((1 << p->DstSize[i])-1) << (8-p->DstSize[i]));
					if (First)
					{
						I3S(MOV,RGB,NONE,Tmp,LSR,8-p->DstPos[i]-p->DstSize[i]);
						First = 0;
					}
					else
						I3S(ORR,RGB,RGB,Tmp,LSR,8-p->DstPos[i]-p->DstSize[i]);
				}
				else if (IncByte[j]>0)
					I2C(ADD,Src,Src,IncByte[j]);
			}

			break;
		}
	}
}

void RGB_4X2S(blit_soft* p,int* Inc)
{
	if (p->SwapXY)
	{
		RGB_Read(p,R0,R8,Inc[0]);
		RGB_Read(p,R1,R14,Inc[0]);
		RGB_Read(p,R2,R8,Inc[1]);
		RGB_Read(p,R3,R14,Inc[1]);

		if (p->DirX>0)
		{
			I3S(ORR,R4,R0,R1,LSL,16);
			I3S(ORR,R5,R2,R3,LSL,16);
		}
		else
		{
			I3S(ORR,R4,R1,R0,LSL,16);
			I3S(ORR,R5,R3,R2,LSL,16);
		}

		RGB_Read(p,R0,R8,Inc[2]);
		RGB_Read(p,R1,R14,Inc[2]);
		RGB_Read(p,R2,R8,Inc[3]);
		RGB_Read(p,R3,R14,Inc[3]);

		if (p->DirX>0)
		{
			I3S(ORR,R1,R0,R1,LSL,16);
			I3S(ORR,R3,R2,R3,LSL,16);
		}
		else
		{
			I3S(ORR,R1,R1,R0,LSL,16);
			I3S(ORR,R3,R3,R2,LSL,16);
		}

		I3(STR_POST,R4,R11,R12);
		I3(STR_POST,R5,R11,R12);
		I3(STR_POST,R1,R11,R12);
		I3(STR_POST,R3,R11,R12);
	}
	else
	{
		RGB_Read(p,R0,R8,Inc[0]);
		RGB_Read(p,R1,R8,Inc[1]);
		RGB_Read(p,R2,R8,Inc[2]);
		RGB_Read(p,R3,R8,Inc[3]);

		if (p->DirX>0)
		{
			I3S(ORR,R4,R0,R1,LSL,16);
			I3S(ORR,R5,R2,R3,LSL,16);
		}
		else
		{
			I3S(ORR,R4,R1,R0,LSL,16);
			I3S(ORR,R5,R3,R2,LSL,16);
		}

		RGB_Read(p,R0,R14,Inc[0]);
		RGB_Read(p,R1,R14,Inc[1]);
		RGB_Read(p,R2,R14,Inc[2]);
		RGB_Read(p,R3,R14,Inc[3]);

		if (p->DirX>0)
		{
			I3S(ORR,R1,R0,R1,LSL,16);
			I3S(ORR,R3,R2,R3,LSL,16);
		}
		else
		{
			I3S(ORR,R1,R1,R0,LSL,16);
			I3S(ORR,R3,R3,R2,LSL,16);
		}

		I3(STR_POST,R4,R11,R12);
		I2C(STR_POST,R1,R11,4*p->DirX);
		I3(STR_POSTSUB,R3,R11,R12);
		I2C(STR_POST,R5,R11,4*p->DirX);
	}
}

void Any_RGB_RGB(blit_soft* p)
{
	dyninst* LoopX;
	dyninst* LoopY;
	dyninst* EndOfLine;
	bool_t Stretch;
	bool_t Same = 
		p->Src.BitCount==p->Dst.BitCount && 
		p->Src.BitMask[0] == p->Dst.BitMask[0] &&
		p->Src.BitMask[1] == p->Dst.BitMask[1] &&
		p->Src.BitMask[2] == p->Dst.BitMask[2];

	Stretch = p->RScaleX!=16 || p->RScaleY!=16 || !Same;

	p->RealOnlyDiff = (boolmem_t)(p->OnlyDiff && !Stretch);
	p->Caps = 0;
	p->DstAlignSize = 4;

	if (p->SrcDoubleX && !Stretch)
		p->DstAlignSize = 8;

	p->LookUp = NULL;
	if (p->Src.Palette)
		CalcPalRGBLookUp(p);

	if (p->LookUp_Data)
	{
		p->LookUp = InstCreate(p->LookUp_Data,p->LookUp_Size,NONE,NONE,NONE,0,0);
		free(p->LookUp_Data);
		p->LookUp_Data = NULL;
	}

	CodeBegin();
	I2C(SUB,SP,SP,OFS(stack,StackFrame));

	I2C(LDR,R11,R1,0);//Dst[0]
	I2C(LDR,R9,R2,0); //Src[0]

	if (p->DirX<0)
	{
		//adjust reversed destination for block size
		I2C(SUB,R11,R11,2);
	}

	I3(MOV,R12,NONE,R3); //DstPitch

	I2C(LDR,R2,SP,OFS(stack,Height));
	I2C(LDR,R1,SP,OFS(stack,Width));

	if (!Stretch)
	{
		//SrcNext = 2*Src->Pitch - SrcWidth << (SrcBPP2+SrcDoubleX)
		I2C(LDR,R14,SP,OFS(stack,SrcPitch));
		I3S(MOV,R3,NONE,R1,LSL,p->SrcDoubleX+p->SrcBPP2);
		I3S(RSB,R0,R3,R14,LSL,1); 
		I2C(STR,R0,SP,OFS(stack,SrcNext));
	}

	if (p->SwapXY)
	{
		//EndOfRect = Dst + Height*2*DirX
		I3S(p->DirX<0?SUB:ADD,R0,R11,R2,LSL,p->DstBPP2);
		I2C(STR,R0,SP,OFS(stack,EndOfRect));

		//DstNext = 2*(DstBPP/8)*DirX - Width*Dst->Pitch
		I3(MUL,R3,R1,R12);
		I2C(MOV,R0,NONE,2*p->DirX*(p->DstBPP/8));
		I3(SUB,R0,R0,R3);
		I2C(STR,R0,SP,OFS(stack,DstNext));
	}
	else
	{
		I3(MUL,R0,R12,R2); //DstPitch * Height
		I3(ADD,R0,R11,R0);
		I2C(STR,R0,SP,OFS(stack,EndOfRect));

		//DstNext = 2*Dst->Pitch - DirX*Width*(DstBPP/8)
		I3(ADD,R3,R1,R1);
		I3S(p->DirX<0?ADD:RSB,R0,R3,R12,LSL,p->DstBPP2); 
		I2C(STR,R0,SP,OFS(stack,DstNext));
	}

	if (p->RealOnlyDiff)
		I2C(LDR,R8,SP,OFS(stack,Src2SrcLast));

	if (Stretch)
		I2C(MOV,R7,NONE,0); //Pos

	I2C(LDR,R0,SP,OFS(stack,Width));
	LoopY = Label(1);

	//R0 width
	if (p->SwapXY)
	{
		I3(MUL,R10,R12,R0); //R12=DstPitch
		I3(ADD,R10,R11,R10);
	}
	else
		I3S(p->DirX>0?ADD:SUB,R10,R11,R0,LSL,1);

	if (Stretch)
	{
		int Col,i,ColCount;

		I3(MOV,R8,NONE,R9); //Src0

		I2C(LDR,R6,SP,OFS(stack,SrcPitch));
		I3S(MOV,R4,NONE,R7,LSR,4);
		I2C(ADD,R0,R7,p->RScaleY);
		I3S(RSB,R4,R4,R0,LSR,4);
		I3(MUL,R4,R6,R4);
		I3(ADD,R14,R9,R4); //Src1

		EndOfLine = Label(0);
		LoopX = Label(1);

		ColCount = 16;
		for (i=1;i<4 && !(p->RScaleX & i);i<<=1)
			ColCount >>= 1;

		for (Col=0;Col<ColCount;Col+=4)
		{
			int Inc[4];
			for (i=0;i<4;++i)
				Inc[i] = (((Col+i+1) * p->RScaleX) >> 4) - (((Col+i) * p->RScaleX) >> 4);

			RGB_4X2S(p,Inc);
			
			I3(CMP,NONE,R10,R11);
			if (Col+4 >= ColCount) 
				I0P(B,NE,LoopX);
			else
				I0P(B,EQ,EndOfLine);
		}

		InstPost(EndOfLine);

		I2C(LDR,R6,SP,OFS(stack,SrcPitch));
		I3S(MOV,R4,NONE,R7,LSR,4);
		I2C(ADD,R7,R7,2*p->RScaleY);
		I3S(RSB,R4,R4,R7,LSR,4);
		I3(MUL,R4,R6,R4);
		I3(ADD,R9,R9,R4); //add 2 lines
	}
	else
	{
		LoopX = Label(1);
		RGB_4X2(p);
		I3(CMP,NONE,R10,R11);
		I0P(B,NE,LoopX);
		I2C(LDR,R0,SP,OFS(stack,SrcNext));
		I3(ADD,R9,R9,R0);
	}

	I2C(LDR,R1,SP,OFS(stack,DstNext));
	I2C(LDR,R2,SP,OFS(stack,EndOfRect));
	I2C(LDR,R0,SP,OFS(stack,Width)); // needed for next EndOfLine
	I3(ADD,R11,R11,R1);
	I3(CMP,NONE,R2,R11);
	I0P(B,NE,LoopY);

	I2C(ADD,SP,SP,OFS(stack,StackFrame));
	CodeEnd();

	if (p->LookUp)
	{
		Align(16);
		InstPost(p->LookUp);
	}
}

#endif

⌨️ 快捷键说明

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