www.pudn.com > mmxswarm.zip > MMXSurface32.cpp, change:2005-09-21,size:3047b


// MMXSurface32.cpp : implementation of the CMMXSurface32Intrinsic 
// class 
// 
// This is a part of the Microsoft Foundation Classes C++ library. 
// Copyright (c) Microsoft Corporation.  All rights reserved. 
// 
// This source code is only intended as a supplement to the 
// Microsoft Foundation Classes Reference and related 
// electronic documentation provided with the library. 
// See these sources for detailed information regarding the 
// Microsoft Foundation Classes product. 
// 
#include "stdafx.h" 
#include "MMXSurface.h" 
#include "MMXWrapper.h" 
 
typedef CMMXUnsigned16Saturated CMMX; 
 
// Optimized for a 2-pixel processing 32 bit buffer 
void CMMXSurface32Intrinsic::AdjustWidth(int *pWidth) 
{ 
	ASSERT(pWidth != NULL); 
	ASSERT(m_kDeltaX == 1); 
	// increment if odd.  If we are even, we stop 
	// dead on correctly, reading the single black buffer 
	// column. If we are odd, we need an extra column so 
	// we don't need to special case the tail of the loop. 
 
	// Because we know there is always a DeltaX black stripe 
	// at least 1 pixel wide, we can subtract instead of adding. 
	// this allows us to get rid of adding a delta per horizontal 
	// loop. while in theory this could cause the left side to bleed 
	// to the right, in reality this won't happen. 
	if (*pWidth & 0x01) 
		*pWidth -= 1; 
} 
 
void CMMXSurface32Intrinsic::OnCreated() 
{ 
	ASSERT(GetBitDepth() == 32); 
	ASSERT((GetPitch() & 0x7) == 0); 
	ASSERT(GetVisibleWidth() && GetVisibleHeight()); 
 
	int width = GetVisibleWidth(); 
    m_dwpl = GetPitch()/4; // dwords Per Line 
    m_width = (width+1)/2; // 2 pixels at a time 
} 
 
void CMMXSurface32Intrinsic::BlurBits() 
{ 
    int height = GetVisibleHeight(); 
    DWORD *pCur  = (DWORD *)GetPixelAddress(0,0); 
 
	CMMX cFader; 
	CMMX cRight, cRightRight; 
	CMMX cDownRight; 
	CMMX cLeft; 
	CMMX cUpRight; 
	CMMX cUp, cDown, cCur; 
 
	cFader.UnpackBytesLo( 0x01010101 ); 
	cLeft.Clear(); 
	cCur.UnpackBytesLo( *pCur ); 
 
	do { 
		int width = m_width; 
		do { 
			// Load pixels and do the mmx unpack 
			cRight.UnpackBytesLo( pCur[1] ); 
			cRightRight.UnpackBytesLo( pCur[2] ); 
			cUp.UnpackBytesLo( pCur[-m_dwpl] ); 
			cUpRight.UnpackBytesLo( pCur[-m_dwpl+1] ); 
			cDown.UnpackBytesLo( pCur[m_dwpl] ); 
			cDownRight.UnpackBytesLo( pCur[m_dwpl+1] ); 
 
			// Actual math. Don't step on current, or right. 
			// Sum the 4 around and double the middle 
			 
			// Do current pixel in this line 
			cUp = (cDown+cUp+cLeft+cRight+(cCur<<2))>>3; 
 
			// Do next pixel 
			cDown = (cDownRight+cUpRight+cCur+cRightRight+(cRight<<2))>>3; 
 
#if defined(TRIPPY) 
			cUp += cFader; // increase the fade to white 
			cDown += cFader; // increase the fade to white 
#elif defined (FAST_FADE) 
    	    cUp -= cFader; // increase the fade to black 
    	    cDown -= cFader; // increase the fade to black 
#endif 
			cLeft = cRight; 		// Slide left! 
			cCur = cRightRight; 
	 
			*(ULONGLONG *)pCur = cUp.PackBytes(cDown); 
			pCur += 2; 
		} while (--width > 0); 
	} while (--height > 0); 
}