for(j=filter2Size-2; j>=0; j--) { int right= MIN(j + shift, filter2Size-1); filter2[i*filter2Size +right] += filter2[i*filter2Size +j]; filter2[i*filter2Size +j]=0; } (*filterPos)[i]= srcW - filter2Size; } }   *outFilterSize= (filter2Size +(filterAlign-1)) & (~(filterAlign-1)); *outFilter= (int16_t*)memalign(8, *outFilterSize*dstW*sizeof(int16_t)); memset(*outFilter, 0, *outFilterSize*dstW*sizeof(int16_t));
for(j=filterSize-2; j>=0; j--) { int right= MIN(j + shift, filterSize-1); filter[i*filterSize +right] += filter[i*filterSize +j]; filter[i*filterSize +j]=0; } (*filterPos)[i]= srcW - filterSize; } }   *outFilter= (int16_t*)memalign(8, *outFilterSize*(dstW+1)*sizeof(int16_t)); memset(*outFilter, 0, *outFilterSize*(dstW+1)*sizeof(int16_t));
static inline void initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc,			      int srcW, int dstW, int filterAlign, int one, int flags,			      SwsVector *srcFilter, SwsVector *dstFilter){	int i;	int filterSize;	int filter2Size;	int minFilterSize;	double *filter=NULL;	double *filter2=NULL;#ifdef ARCH_X86	if(gCpuCaps.hasMMX)		asm volatile("emms\n\t"::: "memory"); //FIXME this shouldnt be required but it IS (even for non mmx versions)#endif	*filterPos = (int16_t*)memalign(8, dstW*sizeof(int16_t));	if(ABS(xInc - 0x10000) <10) // unscaled	{		int i;		filterSize= 1;		filter= (double*)memalign(8, dstW*sizeof(double)*filterSize);		for(i=0; i<dstW*filterSize; i++) filter[i]=0;		for(i=0; i<dstW; i++)		{			filter[i*filterSize]=1;			(*filterPos)[i]=i;		}	}	else if(flags&SWS_POINT) // lame looking point sampling mode	{		int i;		int xDstInSrc;		filterSize= 1;		filter= (double*)memalign(8, dstW*sizeof(double)*filterSize);				xDstInSrc= xInc/2 - 0x8000;		for(i=0; i<dstW; i++)		{			int xx= (xDstInSrc>>16) - (filterSize>>1) + 1;			(*filterPos)[i]= xx;			filter[i]= 1.0;			xDstInSrc+= xInc;		}	}	else if(xInc <= (1<<16) || (flags&SWS_FAST_BILINEAR)) // upscale	{		int i;		int xDstInSrc;		if     (flags&SWS_BICUBIC) filterSize= 4;		else if(flags&SWS_X      ) filterSize= 4;		else			   filterSize= 2; // SWS_BILINEAR / SWS_AREA //		printf("%d %d %d\n", filterSize, srcW, dstW);		filter= (double*)memalign(8, dstW*sizeof(double)*filterSize);		xDstInSrc= xInc/2 - 0x8000;		for(i=0; i<dstW; i++)		{			int xx= (xDstInSrc>>16) - (filterSize>>1) + 1;			int j;			(*filterPos)[i]= xx;			if((flags & SWS_BICUBIC) || (flags & SWS_X))			{				double d= ABS(((xx+1)<<16) - xDstInSrc)/(double)(1<<16);				double y1,y2,y3,y4;				double A= -0.6;				if(flags & SWS_BICUBIC){						// Equation is from VirtualDub					y1 = (        +     A*d -       2.0*A*d*d +       A*d*d*d);					y2 = (+ 1.0             -     (A+3.0)*d*d + (A+2.0)*d*d*d);					y3 = (        -     A*d + (2.0*A+3.0)*d*d - (A+2.0)*d*d*d);					y4 = (                  +           A*d*d -       A*d*d*d);				}else{						// cubic interpolation (derived it myself)					y1 = (    -2.0*d + 3.0*d*d - 1.0*d*d*d)/6.0;					y2 = (6.0 -3.0*d - 6.0*d*d + 3.0*d*d*d)/6.0;					y3 = (    +6.0*d + 3.0*d*d - 3.0*d*d*d)/6.0;					y4 = (    -1.0*d           + 1.0*d*d*d)/6.0;				}//				printf("%d %d %d \n", coeff, (int)d, xDstInSrc);				filter[i*filterSize + 0]= y1;				filter[i*filterSize + 1]= y2;				filter[i*filterSize + 2]= y3;				filter[i*filterSize + 3]= y4;//				printf("%1.3f %1.3f %1.3f %1.3f %1.3f\n",d , y1, y2, y3, y4);			}			else			{				//Bilinear upscale / linear interpolate / Area averaging				for(j=0; j<filterSize; j++)				{					double d= ABS((xx<<16) - xDstInSrc)/(double)(1<<16);					double coeff= 1.0 - d;					if(coeff<0) coeff=0;	//				printf("%d %d %d \n", coeff, (int)d, xDstInSrc);					filter[i*filterSize + j]= coeff;					xx++;				}			}			xDstInSrc+= xInc;		}	}	else // downscale	{		int xDstInSrc;		if(flags&SWS_BICUBIC)	filterSize= (int)ceil(1 + 4.0*srcW / (double)dstW);		else if(flags&SWS_X)	filterSize= (int)ceil(1 + 4.0*srcW / (double)dstW);		else if(flags&SWS_AREA)	filterSize= (int)ceil(1 + 1.0*srcW / (double)dstW);		else /* BILINEAR */	filterSize= (int)ceil(1 + 2.0*srcW / (double)dstW);//		printf("%d %d %d\n", *filterSize, srcW, dstW);		filter= (double*)memalign(8, dstW*sizeof(double)*filterSize);		xDstInSrc= xInc/2 - 0x8000;		for(i=0; i<dstW; i++)		{			int xx= (int)((double)xDstInSrc/(double)(1<<16) - (filterSize-1)*0.5 + 0.5);			int j;			(*filterPos)[i]= xx;			for(j=0; j<filterSize; j++)			{				double d= ABS((xx<<16) - xDstInSrc)/(double)xInc;				double coeff;				if((flags & SWS_BICUBIC) || (flags & SWS_X))				{					double A= -0.75;//					d*=2;					// Equation is from VirtualDub					if(d<1.0)						coeff = (1.0 - (A+3.0)*d*d + (A+2.0)*d*d*d);					else if(d<2.0)						coeff = (-4.0*A + 8.0*A*d - 5.0*A*d*d + A*d*d*d);					else						coeff=0.0;				}				else if(flags & SWS_AREA)				{					double srcPixelSize= (1<<16)/(double)xInc;					if(d + srcPixelSize/2 < 0.5) coeff= 1.0;					else if(d - srcPixelSize/2 < 0.5) coeff= (0.5-d)/srcPixelSize + 0.5;					else coeff=0.0;				}				else				{					coeff= 1.0 - d;					if(coeff<0) coeff=0;				}//				printf("%1.3f %2.3f %d \n", coeff, d, xDstInSrc);				filter[i*filterSize + j]= coeff;				xx++;			}			xDstInSrc+= xInc;		}	}	/* apply src & dst Filter to filter -> filter2	   free(filter);	*/	filter2Size= filterSize;	if(srcFilter) filter2Size+= srcFilter->length - 1;	if(dstFilter) filter2Size+= dstFilter->length - 1;	filter2= (double*)memalign(8, filter2Size*dstW*sizeof(double));	for(i=0; i<dstW; i++)	{		int j;		SwsVector scaleFilter;		SwsVector *outVec;		scaleFilter.coeff= filter + i*filterSize;		scaleFilter.length= filterSize;		if(srcFilter) outVec= getConvVec(srcFilter, &scaleFilter);		else	      outVec= &scaleFilter;		ASSERT(outVec->length == filter2Size)		//FIXME dstFilter		for(j=0; j<outVec->length; j++)		{			filter2[i*filter2Size + j]= outVec->coeff[j];		}		(*filterPos)[i]+= (filterSize-1)/2 - (filter2Size-1)/2;		if(outVec != &scaleFilter) freeVec(outVec);	}	free(filter); filter=NULL;	/* try to reduce the filter-size (step1 find size and shift left) */	// Assume its near normalized (*0.5 or *2.0 is ok but * 0.001 is not)	minFilterSize= 0;	for(i=dstW-1; i>=0; i--)	{		int min= filter2Size;		int j;		double cutOff=0.0;		/* get rid off near zero elements on the left by shifting left */		for(j=0; j<filter2Size; j++)		{			int k;			cutOff += ABS(filter2[i*filter2Size]);			if(cutOff > SWS_MAX_REDUCE_CUTOFF) break;			/* preserve Monotonicity because the core cant handle the filter otherwise */			if(i<dstW-1 && (*filterPos)[i] >= (*filterPos)[i+1]) break;			// Move filter coeffs left			for(k=1; k<filter2Size; k++)				filter2[i*filter2Size + k - 1]= filter2[i*filter2Size + k];			filter2[i*filter2Size + k - 1]= 0.0;			(*filterPos)[i]++;		}		cutOff=0.0;		/* count near zeros on the right */		for(j=filter2Size-1; j>0; j--)		{			cutOff += ABS(filter2[i*filter2Size + j]);			if(cutOff > SWS_MAX_REDUCE_CUTOFF) break;			min--;		}		if(min>minFilterSize) minFilterSize= min;	}	/* try to reduce the filter-size (step2 reduce it) */	for(i=0; i<dstW; i++)	{		int j;		for(j=0; j<minFilterSize; j++)			filter2[i*minFilterSize + j]= filter2[i*filter2Size + j];	}	if((flags&SWS_PRINT_INFO) && verbose)		printf("SwScaler: reducing filtersize %d -> %d\n", filter2Size, minFilterSize);	filter2Size= minFilterSize;	ASSERT(filter2Size > 0)	//FIXME try to align filterpos if possible	//fix borders	for(i=0; i<dstW; i++)	{		int j;		if((*filterPos)[i] < 0)		{			// Move filter coeffs left to compensate for filterPos			for(j=1; j<filter2Size; j++)			{				int left= MAX(j + (*filterPos)[i], 0);				filter2[i*filter2Size + left] += filter2[i*filter2Size + j];				filter2[i*filter2Size + j]=0;			}			(*filterPos)[i]= 0;		}		if((*filterPos)[i] + filter2Size > srcW)		{			int shift= (*filterPos)[i] + filter2Size - srcW;			// Move filter coeffs right to compensate for filterPos			for(j=filter2Size-2; j>=0; j--)			{				int right= MIN(j + shift, filter2Size-1);				filter2[i*filter2Size +right] += filter2[i*filter2Size +j];				filter2[i*filter2Size +j]=0;			}			(*filterPos)[i]= srcW - filter2Size;		}	}	*outFilterSize= (filter2Size +(filterAlign-1)) & (~(filterAlign-1));	*outFilter= (int16_t*)memalign(8, *outFilterSize*dstW*sizeof(int16_t));	memset(*outFilter, 0, *outFilterSize*dstW*sizeof(int16_t));	/* Normalize & Store in outFilter */	for(i=0; i<dstW; i++)	{		int j;		double sum=0;		double scale= one;		for(j=0; j<filter2Size; j++)		{			sum+= filter2[i*filter2Size + j];		}		scale/= sum;		for(j=0; j<filter2Size; j++)		{			(*outFilter)[i*(*outFilterSize) + j]= (int)(filter2[i*filter2Size + j]*scale);		}	}	free(filter2);}