c->lumXInc= ((srcW<<16) + (1<<15))/dstW; c->lumYInc= ((srcH<<16) + (1<<15))/dstH;
c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW; c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH;
SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,                         SwsFilter *srcFilter, SwsFilter *dstFilter){	const int widthAlign= dstFormat==IMGFMT_YV12 ? 16 : 8;	SwsContext *c;	int i;	SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};#ifdef ARCH_X86	if(gCpuCaps.hasMMX)		asm volatile("emms\n\t"::: "memory");#endif	if(swScale==NULL) globalInit();	/* sanity check */	if(srcW<1 || srcH<1 || dstW<1 || dstH<1) return NULL;/* FIXME	if(dstStride[0]%widthAlign !=0 )	{		if(flags & SWS_PRINT_INFO)			fprintf(stderr, "SwScaler: Warning: dstStride is not a multiple of %d!\n"					"SwScaler:          ->cannot do aligned memory acesses anymore\n",					widthAlign);	}*/	if(!dstFilter) dstFilter= &dummyFilter;	if(!srcFilter) srcFilter= &dummyFilter;	c= memalign(64, sizeof(SwsContext));	memset(c, 0, sizeof(SwsContext));	c->srcW= srcW;	c->srcH= srcH;	c->dstW= dstW;	c->dstH= dstH;	c->lumXInc= ((srcW<<16) + (1<<15))/dstW;	c->lumYInc= ((srcH<<16) + (1<<15))/dstH;	c->flags= flags;	c->dstFormat= dstFormat;	c->srcFormat= srcFormat;	if(cpuCaps.hasMMX2)	{		c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;		if(!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR))		{			if(flags&SWS_PRINT_INFO)				fprintf(stderr, "SwScaler: output Width is not a multiple of 32 -> no MMX2 scaler\n");		}	}	else		c->canMMX2BeUsed=0;	// match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst	// but only for the FAST_BILINEAR mode otherwise do correct scaling	// n-2 is the last chrominance sample available	// this is not perfect, but noone shuld notice the difference, the more correct variant	// would be like the vertical one, but that would require some special code for the	// first and last pixel	if(flags&SWS_FAST_BILINEAR)	{		if(c->canMMX2BeUsed) 	c->lumXInc+= 20;		//we dont use the x86asm scaler if mmx is available		else if(cpuCaps.hasMMX)	c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;	}	/* set chrXInc & chrDstW */	if((flags&SWS_FULL_UV_IPOL) && dstFormat!=IMGFMT_YV12)		c->chrXInc= c->lumXInc>>1, c->chrDstW= dstW;	else		c->chrXInc= c->lumXInc,    c->chrDstW= (dstW+1)>>1;	/* set chrYInc & chrDstH */	if(dstFormat==IMGFMT_YV12)	c->chrYInc= c->lumYInc,    c->chrDstH= (dstH+1)>>1;	else				c->chrYInc= c->lumYInc>>1, c->chrDstH= dstH;	/* precalculate horizontal scaler filter coefficients */	{		const int filterAlign= cpuCaps.hasMMX ? 4 : 1;		initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc,				 srcW      ,       dstW, filterAlign, 1<<14, flags,				 srcFilter->lumH, dstFilter->lumH);		initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc,				(srcW+1)>>1, c->chrDstW, filterAlign, 1<<14, flags,				 srcFilter->chrH, dstFilter->chrH);#ifdef ARCH_X86// cant downscale !!!		if(c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR))		{			initMMX2HScaler(      dstW, c->lumXInc, c->funnyYCode);			initMMX2HScaler(c->chrDstW, c->chrXInc, c->funnyUVCode);		}#endif	} // Init Horizontal stuff	/* precalculate vertical scaler filter coefficients */	initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc,			srcH      ,        dstH, 1, (1<<12)-4, flags,			srcFilter->lumV, dstFilter->lumV);	initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc,			(srcH+1)>>1, c->chrDstH, 1, (1<<12)-4, flags,			 srcFilter->chrV, dstFilter->chrV);	// Calculate Buffer Sizes so that they wont run out while handling these damn slices	c->vLumBufSize= c->vLumFilterSize;	c->vChrBufSize= c->vChrFilterSize;	for(i=0; i<dstH; i++)	{		int chrI= i*c->chrDstH / dstH;		int nextSlice= MAX(c->vLumFilterPos[i   ] + c->vLumFilterSize - 1,				 ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<<1));		nextSlice&= ~1; // Slices start at even boundaries		if(c->vLumFilterPos[i   ] + c->vLumBufSize < nextSlice)			c->vLumBufSize= nextSlice - c->vLumFilterPos[i   ];		if(c->vChrFilterPos[chrI] + c->vChrBufSize < (nextSlice>>1))			c->vChrBufSize= (nextSlice>>1) - c->vChrFilterPos[chrI];	}	// allocate pixbufs (we use dynamic allocation because otherwise we would need to	// allocate several megabytes to handle all possible cases)	c->lumPixBuf= (int16_t**)memalign(4, c->vLumBufSize*2*sizeof(int16_t*));	c->chrPixBuf= (int16_t**)memalign(4, c->vChrBufSize*2*sizeof(int16_t*));	for(i=0; i<c->vLumBufSize; i++)		c->lumPixBuf[i]= c->lumPixBuf[i+c->vLumBufSize]= (uint16_t*)memalign(8, 4000);	for(i=0; i<c->vChrBufSize; i++)		c->chrPixBuf[i]= c->chrPixBuf[i+c->vChrBufSize]= (uint16_t*)memalign(8, 8000);	//try to avoid drawing green stuff between the right end and the stride end	for(i=0; i<c->vLumBufSize; i++) memset(c->lumPixBuf[i], 0, 4000);	for(i=0; i<c->vChrBufSize; i++) memset(c->chrPixBuf[i], 64, 8000);	ASSERT(c->chrDstH <= dstH)	// pack filter data for mmx code	if(cpuCaps.hasMMX)	{		c->lumMmxFilter= (int16_t*)memalign(8, c->vLumFilterSize*      dstH*4*sizeof(int16_t));		c->chrMmxFilter= (int16_t*)memalign(8, c->vChrFilterSize*c->chrDstH*4*sizeof(int16_t));		for(i=0; i<c->vLumFilterSize*dstH; i++)			c->lumMmxFilter[4*i]=c->lumMmxFilter[4*i+1]=c->lumMmxFilter[4*i+2]=c->lumMmxFilter[4*i+3]=				c->vLumFilter[i];		for(i=0; i<c->vChrFilterSize*c->chrDstH; i++)			c->chrMmxFilter[4*i]=c->chrMmxFilter[4*i+1]=c->chrMmxFilter[4*i+2]=c->chrMmxFilter[4*i+3]=				c->vChrFilter[i];	}	if(flags&SWS_PRINT_INFO)	{#ifdef DITHER1XBPP		char *dither= cpuCaps.hasMMX ? " dithered" : "";#endif		if(flags&SWS_FAST_BILINEAR)			fprintf(stderr, "\nSwScaler: FAST_BILINEAR scaler ");		else if(flags&SWS_BILINEAR)			fprintf(stderr, "\nSwScaler: BILINEAR scaler ");		else if(flags&SWS_BICUBIC)			fprintf(stderr, "\nSwScaler: BICUBIC scaler ");		else			fprintf(stderr, "\nSwScaler: ehh flags invalid?! ");		if(dstFormat==IMGFMT_BGR15)			fprintf(stderr, "with%s BGR15 output ", dither);		else if(dstFormat==IMGFMT_BGR16)			fprintf(stderr, "with%s BGR16 output ", dither);		else if(dstFormat==IMGFMT_BGR24)			fprintf(stderr, "with BGR24 output ");		else if(dstFormat==IMGFMT_BGR32)			fprintf(stderr, "with BGR32 output ");		else if(dstFormat==IMGFMT_YV12)			fprintf(stderr, "with YV12 output ");		else			fprintf(stderr, "without output ");		if(cpuCaps.hasMMX2)			fprintf(stderr, "using MMX2\n");		else if(cpuCaps.has3DNow)			fprintf(stderr, "using 3DNOW\n");		else if(cpuCaps.hasMMX)			fprintf(stderr, "using MMX\n");		else			fprintf(stderr, "using C\n");	}	if((flags & SWS_PRINT_INFO) && verbose)	{		if(cpuCaps.hasMMX)		{			if(c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR))				printf("SwScaler: using FAST_BILINEAR MMX2 scaler for horizontal scaling\n");			else			{				if(c->hLumFilterSize==4)					printf("SwScaler: using 4-tap MMX scaler for horizontal luminance scaling\n");				else if(c->hLumFilterSize==8)					printf("SwScaler: using 8-tap MMX scaler for horizontal luminance scaling\n");				else					printf("SwScaler: using n-tap MMX scaler for horizontal luminance scaling\n");				if(c->hChrFilterSize==4)					printf("SwScaler: using 4-tap MMX scaler for horizontal chrominance scaling\n");				else if(c->hChrFilterSize==8)					printf("SwScaler: using 8-tap MMX scaler for horizontal chrominance scaling\n");				else					printf("SwScaler: using n-tap MMX scaler for horizontal chrominance scaling\n");			}		}		else		{#ifdef ARCH_X86			printf("SwScaler: using X86-Asm scaler for horizontal scaling\n");#else			if(flags & SWS_FAST_BILINEAR)				printf("SwScaler: using FAST_BILINEAR C scaler for horizontal scaling\n");			else				printf("SwScaler: using C scaler for horizontal scaling\n");#endif		}		if(dstFormat==IMGFMT_YV12)		{			if(c->vLumFilterSize==1)				printf("SwScaler: using 1-tap %s \"scaler\" for vertical scaling (YV12)\n", cpuCaps.hasMMX ? "MMX" : "C");			else				printf("SwScaler: using n-tap %s scaler for vertical scaling (YV12)\n", cpuCaps.hasMMX ? "MMX" : "C");		}		else		{			if(c->vLumFilterSize==1 && c->vChrFilterSize==2)				printf("SwScaler: using 1-tap %s \"scaler\" for vertical luminance scaling (BGR)\n"				       "SwScaler:       2-tap scaler for vertical chrominance scaling (BGR)\n",cpuCaps.hasMMX ? "MMX" : "C");			else if(c->vLumFilterSize==2 && c->vChrFilterSize==2)				printf("SwScaler: using 2-tap linear %s scaler for vertical scaling (BGR)\n", cpuCaps.hasMMX ? "MMX" : "C");			else				printf("SwScaler: using n-tap %s scaler for vertical scaling (BGR)\n", cpuCaps.hasMMX ? "MMX" : "C");		}		if(dstFormat==IMGFMT_BGR24)			printf("SwScaler: using %s YV12->BGR24 Converter\n",				cpuCaps.hasMMX2 ? "MMX2" : (cpuCaps.hasMMX ? "MMX" : "C"));		else			printf("SwScaler: using %s YV12->BGR Converter\n", cpuCaps.hasMMX ? "MMX" : "C");//FIXME print format		printf("SwScaler: %dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);	}	return c;}