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

📄 sccoef.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
字号:
/*********************************************************************************
 *********************************************************************************
 **
 ** Name        : sccoef.c
 ** Title       : Video scaler coefficient generation module
 ** Author      : P. Buxton
 ** Created     : June 2001
 ** 
 ** Copyright   : 2001 by Imagination Technologies Limited. All rights reserved
 **             : No part of this software, either material or conceptual
 **             : may be copied or distributed, transmitted, transcribed,
 **             : stored in a retrieval system or translated into any
 **             : human or computer language in any form by any means,
 **             : electronic, mechanical, manual or other-wise, or
 **             : disclosed to third parties without the express written
 **             : permission of Imagination Technologies Limited, Unit 8,
 **             : HomePark Industrial Estate, King's Langley, Hertfordshire,
 **             : WD4 8LZ, U.K.
 **
 ** Description : This module contains the algorithms necessary to generate
 **               the coefficients for a multitap video scaler.
 **
 ** Platform    : Platform independent	(modify 'types.h' accordingly)
 ** $Log: sccoef.c $
 **
 **  --- Revision Logs Removed --- 
 **
 *********************************************************************************
 *********************************************************************************/

#include "dp_types.h"
#include <math.h>
#include "sccoef.h"

/* This file abstracts the maths required to generate the coefficients
for scaling


The formula basically creates a discret weighted Sinc function.

table[t][i] = A - (1-A)*Cos(PI*Scale*(t+i/I))/(T/2))
x = PI*Scale*(T/2 -t -i/I + 0.000001)
sincfunc = sin(x)/x
table[t][i] *= sincfunc

where:

table[t][i] is the coeff for current tap and interpolation point. t is the current tap.
i is the current interpolation point.
I is the total interpolation points per tap. T is the total number of taps in the filter
Scale is the scaling factor clamped to [0.0, 1.0] A is a mystical number

Simulations show that the following setting are best:

A = 0.54
I = 8
T = 8 for horizontal scale, T = 4 for vertical scale

Note that the above function has reflective symmetry.


*/

#define Index(X,Y) ((X)+((Y)*T))


/***********************************************************************************************
 *
 * Function Name  : DP_CalcCoefs
 * Inputs         : dwSrc						-	The length of the dimension which is being
 *													scaled FROM (i.e.: the source dimension),
 *													measured in pixels.
 *					
 *					dwDest						-	The length of the dimension which is being
 *													scaled TO (i.e.: the destination dimension),
 *													measured in pixels.
 *					
 *					Table						-	A pointer to an array of 'DP_UINT_8'
 *													variables, which the function will populate
 *													with the appropriate scaler tap
 *													co-efficients.
 *
 *					I							-	The number of interpolation points to be
 *													calculated for each tap.
 *
 *					T							-	The number of taps to be calculated.
 *
 * Outputs        : Table						-	See above.
 * Returns        : Nothing.
 * Globals Used   :	None.
 *
 * Description    : This function calculates all filter taps for one dimensions (i.e.: height
 *					or width) of a video scaler.
 *
 ***********************************************************************************************/

void DP_CalcCoefs	 (	DP_UINT_32	dwSrc,
						DP_UINT_32	dwDest,
						DP_UINT_8	Table		[MAXTAP][MAXINTPT],
						DP_UINT_32	I, 
						DP_UINT_32	T		)
{

/* Due to the nature of the function we will only ever want to calculate the first half of the	*/
/* taps and the middle one (is this really a tap ?) as the seconda half are dervied from the	*/ 
/* first half as the function is symetrical.													*/

	DP_FLOAT	fScale;
	DP_UINT_32	i,t;
	DP_FLOAT	flTable[MAXTAP][MAXINTPT]={0.0};
	DP_INT_32	nTotal;
	DP_FLOAT	ftotal;
	DP_INT_32	val;
	DP_FLOAT	fI, fT;	
	DP_INT_32	mT,mI;		/* mirrored / middle Values for I and T								*/
	DP_INT_32	startoffset=0;

	fI = (DP_FLOAT) I;
	fT = (DP_FLOAT) T;
	fScale=((DP_FLOAT) dwDest/(DP_FLOAT) dwSrc);
	if (fScale>1.0f)   
	{
		fScale=1.0f;
	}
	for(i=0;i<I;i++)
	{
		for(t=0;t<T;t++)
		{
			flTable[t][i]=0.0;
		}
	}

	for(i=0;i<I;i++)
	{
		for(t=0;t<T;t++)
		{
			flTable[t][i]= DP_SyncFunc((DP_FLOAT) i,(DP_FLOAT) t,fI,fT,fScale);
		} 
	}
										    
	if(T>2)
	{
		for(t=0;t<((T/2)+(T%2));t++)
		{
			for(i=0;i<I;i++)
			{
				/* copy the table around the centrepoint									*/
				mT=((T-1)-t)+(I-i)/I;
				mI=(I-i)%I;
				if(((DP_UINT_32)mI<I) && ((DP_UINT_32)mT<T) && ((t<((T/2)+(T%2)-1)) || ((I-i)>((T%2)*(I/2)))))
				{
					flTable[mT][mI]=flTable[t][i];
				}
			}
		}

		/* the middle value																	*/
		mT = T/2;
		if ((T%2) != 0) {
			mI = I/2;
		} else {
			mI = 0;
		}
		flTable[mT][mI]= DP_SyncFunc((DP_FLOAT) mI,(DP_FLOAT) mT,fI,fT,fScale);
	}
	
	/* normalize this interpolation point, and convert to 2.6 format trucating the result	*/
	for(i=0;i<I;i++)
	{
		nTotal=0;
		for(ftotal=0,t=0;t<T;t++) 
		{
			ftotal+=flTable[t][i];
		}
		for(t=0;t<T;t++) 
		{
			val=(DP_INT_32) ((flTable[t][i]*64.0f)/ftotal);
			Table[t][i]=(DP_UINT_8) val;
			nTotal+=val;
		}
		if((i<=(I/2)) || (T<=2)) /* normalize any floating point errors						*/
		{
			nTotal-=64;
			if((i==(I/2)) && (T > 2))
			{
				nTotal/=2;
			}

			/* subtract the error from the I Point in the first tap ( this will not get		*/
			/* mirrored, as it would go off the end).										*/
			Table[0][i]=(DP_UINT_8) (Table[0][i]-(DP_UINT_8) nTotal); 
			
		}
	}

	/* copy the normalised table around the centrepoint										*/
	if(T>2)
	{
		for(t=0;t<((T/2)+(T%2));t++)
		{
			for(i=0;i<I;i++)
			{
				mT=((T-1)-t)+(I-i)/I;
				mI=(I-i)%I;
				if(((DP_UINT_32)mI<I) && ((DP_UINT_32)mT<T) && ((t<((T/2)+(T%2)-1)) || ((I-i)>((T%2)*(I/2)))))
				{
					Table[mT][mI]=Table[t][i];
				}
			}
		}
	}

}


/***********************************************************************************************
 *
 * Function Name  : DP_SyncFunc
 * Inputs         : fi							-	The number of interpolation points being
 *													used.
 *					
 *					ft							-	The number of taps being used.
 *					
 *					fI							-	The current interpolation point being
 *													considered.
 *					
 *					fT							-	The current tap being considered.
 *
 *					fScale						-	The scaling factor being used.
 *
 * Outputs        : None.
 * Returns        : The result of the sync. function for the current point.
 * Globals Used   :	None.
 *
 * Description    : Calculates a single point on a discrete weighted sync. function.
 *
 ***********************************************************************************************/

__inline DP_FLOAT DP_SyncFunc	(	DP_FLOAT	fi,
									DP_FLOAT	ft, 
									DP_FLOAT	fI, 
									DP_FLOAT	fT, 
									DP_FLOAT	fScale	)
{
	DP_FLOAT fSincfunc,fX;
	DP_FLOAT fTempval;
	DP_FLOAT fPI;
	DP_FLOAT fA;

	fPI=3.1415926535897f;
	fA=0.54f;

	fTempval= (DP_FLOAT) (fA - (1-fA)*DP_COS(2*fPI*fScale*(ft + fi/fI)/fT));

	if ((fT/2 - ft - fi/fI) == 0) {
		fSincfunc=1;
	} else {
		fX=fPI*fScale*(fT/2 - (ft + fi/fI));
		fSincfunc = (DP_FLOAT) (DP_SIN(fX)/fX);
	}

	return ( fSincfunc * fTempval );
}


/*--------------------------- End of File --------------------------------*/

⌨️ 快捷键说明

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