{
	int maskPitch=mask->bytePitch;

	PVideoFrame srcA;
	PVideoFrame srcB;

	int srcAPitch;
	int srcBPitch;

	const unsigned char* srcAPtr;
	const unsigned char* srcBPtr;

	int rowSize;

	unsigned char* maskPtr;

	srcA=GetField(n  ,env);
	srcB=GetField(n-2,env);

	srcAPitch=srcA->GetPitch();
	srcBPitch=srcB->GetPitch();

	srcAPtr=srcA->GetReadPtr();
	srcBPtr=srcB->GetReadPtr();

	rowSize=srcA->GetRowSize();

	bool oddPitch=(srcAPitch % PITCH_MOD) != 0;

	maskPtr=mask->buffer;

 	int bytesLeft;
 	unsigned short doubleThreshold=(unsigned short)(2*threshold);

	const unsigned char* curSrcAPtr;
	const unsigned char* curSrcBPtr;

	int height=srcA->GetHeight();
	int rowsLeft=height;

	if (oddPitch) rowsLeft--;

	while (rowsLeft > 0)
	{
		#define PREFIX1(x) P1_##x

		#define PART 1

		#include MOTIONMASK_STAGE1

		rowsLeft--;
	}

	if (oddPitch)
	{
		// copy bottom parts of fields to scratch buffer

		int safePitch=(scratchPitch >= srcAPitch ? srcAPitch : scratchPitch);

		memcpy(scratch,srcAPtr,safePitch);
		memcpy(scratch+scratchPitch,srcBPtr,safePitch);

		// change pointers to point to scratch buffer

		srcAPtr=scratch;
		srcBPtr=srcAPtr+scratchPitch;

		srcAPitch=srcBPitch=scratchPitch*2;

		#define PREFIX1(x) P1a_##x

		#define PART 1

		#include MOTIONMASK_STAGE1
	}

	srcA=GetField(n+1,env);
	srcB=GetField(n-1,env);

	srcAPtr=srcA->GetReadPtr()-(1-order)*srcAPitch;
	srcBPtr=srcB->GetReadPtr()-(1-order)*srcBPitch;;

	maskPtr=mask->buffer;

	#define PREFIX1(x) P2_##x

	#define PART 2

	#include MOTIONMASK_STAGE1

	rowsLeft=height-2;

	if (oddPitch) rowsLeft--;

	while (rowsLeft > 0)
	{
		#define PREFIX1(x) P3_##x

		#define PART 3

		#include MOTIONMASK_STAGE1

		rowsLeft--;
	}

	if (oddPitch)
	{
		// copy bottom parts of fields to scratch buffer

		int safePitch=(scratchPitch >= srcAPitch ? srcAPitch : scratchPitch);

		unsigned char* scratchPtr=scratch;

		for (rowsLeft=2; rowsLeft > 0; rowsLeft--)
		{
			memcpy(scratchPtr,srcAPtr,safePitch);
			scratchPtr+=scratchPitch;

			memcpy(scratchPtr,srcBPtr,safePitch);
			scratchPtr+=scratchPitch;

			srcAPtr+=srcAPitch; srcBPtr+=srcBPitch;
		}

		// change pointers to point to scratch buffer

		srcAPtr=scratch+2*scratchPitch;
		srcBPtr=srcAPtr+scratchPitch;

		srcAPitch=srcBPitch=scratchPitch*2;

		#define PREFIX1(x) P3a_##x

		#define PART 3

		#include MOTIONMASK_STAGE1
	}

	#define PREFIX1(x) P4_##x

	#define PART 4

	#include MOTIONMASK_STAGE1

	__asm emms

	#undef COLORSPACE
	#undef PITCH_MOD
	#undef MOTIONMASK_STAGE1
	#undef MOTIONMASK_STAGE2
}