📄 dxhelper.h
字号:
/*******************************************************************************
* DXHelper.h *
*------------*
* Description:
* This is the header file for core helper functions implementation.
*-------------------------------------------------------------------------------
* Created By: Edward W. Connell Date: 07/11/95
* Copyright (C) 1995 Microsoft Corporation
* All Rights Reserved
*
*-------------------------------------------------------------------------------
* Revisions:
*
*******************************************************************************/
#ifndef DXHelper_h
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
#define DXHelper_h
#ifndef DXTError_h
#include <DXTError.h>
#endif
#ifndef DXBounds_h
#include <DXBounds.h>
#endif
#ifndef __DXTrans_h__
#include <DXTrans.h>
#endif
#ifndef _INC_LIMITS
#include <limits.h>
#endif
#ifndef _INC_CRTDBG
#include <crtdbg.h>
#endif
#ifndef _INC_MALLOC
#include <malloc.h>
#endif
//=== Constants ==============================================================
#define DX_MMX_COUNT_CUTOFF 16
//=== Class, Enum, Struct and Union Declarations =============================
/*** DXLIMAPINFO
* This structure is used by the array linear interpolation and image
* filtering routines.
*/
typedef struct DXLIMAPINFO
{
float IndexFrac;
USHORT Index;
BYTE Weight;
} DXLIMAPINFO;
//
// Declare this class as a global to use for determining when to call MMX optimized
// code. You can use MinMMXOverCount to determine if MMX instructions are present.
// Typically, you would only want to use MMX instructions when you have a reasonably
// large number of pixels to work on. In this case your code can always be coded like
// this:
//
// if (CountOfPixelsToDo >= g_MMXInfo.MinMMXOverCount())
// {
// Do MMX Stuff
// } else {
// Do integer / float based stuff
// }
//
// If you code your MMX sequences like this, you will not have to use a special test
// for the presence of MMX since the MinMMXOverCount will be set to 0xFFFFFFFF if there
// is no MMX present on the processor.
//
// You do not need to use this unless your module needs to conditionally execute MMX vs
// non-MMX code. If you only call the helper functions provided by DXTrans.Dll, such as
// DXOverArrayMMX, you do NOT need this test. You can always call these functions and they
// will use the MMX code path only when MMX instructions are present.
//
class CDXMMXInfo
{
ULONG m_MinMMXOver;
public:
CDXMMXInfo()
{
#ifndef _X86_
m_MinMMXOver = 0xFFFFFFFF;
#else
m_MinMMXOver = DX_MMX_COUNT_CUTOFF;
__try
{
__asm
{
//--- Try the MMX exit multi-media state instruction
EMMS;
}
}
__except( GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION )
{
//--- MMX instructions not available
m_MinMMXOver = 0xFFFFFFFF;
}
#endif
}
inline ULONG MinMMXOverCount() { return m_MinMMXOver; }
};
//=== Function Prototypes ==========================================
_DXTRANS_IMPL_EXT void WINAPI
DXLinearInterpolateArray( const DXBASESAMPLE* pSamps, DXLIMAPINFO* pMapInfo,
DXBASESAMPLE* pResults, DWORD dwResultCount );
_DXTRANS_IMPL_EXT void WINAPI
DXLinearInterpolateArray( const DXBASESAMPLE* pSamps, PUSHORT pIndexes,
PBYTE pWeights, DXBASESAMPLE* pResults,
DWORD dwResultCount );
//
// DXOverArray
//
// Composits an array of source samples over the samples in the pDest buffer.
//
// pDest - Pointer to the samples that will be modified by compositing the pSrc
// samples over the pDest samples.
// pSrc - The samples to composit over the pDest samples
// nCount - The number of samples to process
//
_DXTRANS_IMPL_EXT void WINAPI
DXOverArray(DXPMSAMPLE* pDest, const DXPMSAMPLE* pSrc, ULONG nCount);
//
// DXOverArrayMMX
//
// Identical to DXOverArray except that the MMX instruction set will be used for
// large arrays of samples. If the CPU does not support MMX, you may still call
// this function, which will perform the same operation without the use of the MMX
// unit.
//
// Note that it is LESS EFFICIENT to use this function if the majority of the pixels
// in the pSrc buffer are either clear (alpha 0) or opaque (alpha 0xFF). This is
// because the MMX code must process every pixel and can not special case clear or
// opaque pixels. If there are a large number of translucent pixels then this function
// is much more efficent than DXOverArray.
//
// pDest - Pointer to the samples that will be modified by compositing the pSrc
// samples over the pDest samples.
// pSrc - The samples to composit over the pDest samples
// nCount - The number of samples to process
//
_DXTRANS_IMPL_EXT void WINAPI
DXOverArrayMMX(DXPMSAMPLE* pDest, const DXPMSAMPLE* pSrc, ULONG nCount);
//
// DXConstOverArray
//
// Composits a single color over an array of samples.
//
// pDest - Pointer to the samples that will be modified by compositing the color (val)
// over the pDest samples.
// val - The premultiplied color value to composit over the pDest array.
// nCount - The number of samples to process
//
_DXTRANS_IMPL_EXT void WINAPI
DXConstOverArray(DXPMSAMPLE* pDest, const DXPMSAMPLE & val, ULONG nCount);
//
// DXConstOverArray
//
// Composits a single color over an array of samples.
//
// pDest - Pointer to the samples that will be modified by compositing the samples
// in the buffer over the color (val).
// val - The premultiplied color value to composit under the pDest array.
// nCount - The number of samples to process
//
_DXTRANS_IMPL_EXT void WINAPI
DXConstUnderArray(DXPMSAMPLE* pDest, const DXPMSAMPLE & val, ULONG nCount);
//===================================================================================
//
// Dithering Helpers
//
// Image transforms are sometimes asked to dither their output. This helper function
// should be used by all image transforms to enusure a consistant dither pattern.
//
// DXDitherArray is used to dither pixels prior to writing them to a DXSurface.
// The caller must fill in the DXDITHERDESC structure, setting X and Y to the
// output surface X,Y coordinates that the pixels will be placed in. The samples
// will be modified in place.
//
// Once the samples have been dithered, they should be written to or composited with
// the destination surface.
//
#define DX_DITHER_HEIGHT 4 // The dither pattern is 4x4 pixels
#define DX_DITHER_WIDTH 4
typedef struct DXDITHERDESC
{
DXBASESAMPLE * pSamples; // Pointer to the 32-bit samples to dither
ULONG cSamples; // Count of number of samples in pSamples buffer
ULONG x; // X coordinate of the output surface
ULONG y; // Y coordinate of the output surface
DXSAMPLEFORMATENUM DestSurfaceFmt; // Pixel format of the output surface
} DXDITHERDESC;
_DXTRANS_IMPL_EXT void WINAPI
DXDitherArray(const DXDITHERDESC *pDitherDesc);
//=== Enumerated Set Definitions =============================================
//=== Function Type Definitions ==============================================
//=== Class, Struct and Union Definitions ====================================
//=== Inline Functions =======================================================
//===================================================================================
//
// Memory allocation helpers.
//
// These macros are used to allocate arrays of samples from the stack (using _alloca)
// and cast them to the appropriate type. The ulNumSamples parameter is the count
// of samples required.
//
#define DXBASESAMPLE_Alloca( ulNumSamples ) \
(DXBASESAMPLE *)_alloca( (ulNumSamples) * sizeof( DXBASESAMPLE ) )
#define DXSAMPLE_Alloca( ulNumSamples ) \
(DXSAMPLE *)_alloca( (ulNumSamples) * sizeof( DXSAMPLE ) )
#define DXPMSAMPLE_Alloca( ulNumSamples ) \
(DXPMSAMPLE *)_alloca( (ulNumSamples) * sizeof( DXPMSAMPLE ) )
//===================================================================================
//
// Critical section helpers.
//
// These C++ classes, CDXAutoObjectLock and CDXAutoCritSecLock are used within functions
// to automatically claim critical sections upon constuction, and the critical section
// will be released when the object is destroyed (goes out of scope).
//
// The macros DXAUTO_OBJ_LOCK and DX_AUTO_SEC_LOCK(s) are normally used at the beginning
// of a function that requires a critical section. Any exit from the scope in which the
// auto-lock was taken will automatically release the lock.
//
#ifdef __ATLCOM_H__ //--- Only enable these if ATL is being used
class CDXAutoObjectLock
{
protected:
CComObjectRootEx<CComMultiThreadModel>* m_pObject;
public:
CDXAutoObjectLock(CComObjectRootEx<CComMultiThreadModel> * const pobject)
{
m_pObject = pobject;
m_pObject->Lock();
};
~CDXAutoObjectLock() {
m_pObject->Unlock();
};
};
#define DXAUTO_OBJ_LOCK CDXAutoObjectLock lck(this);
#define DXAUTO_OBJ_LOCK_( t ) CDXAutoObjectLock lck(t);
class CDXAutoCritSecLock
{
protected:
CComAutoCriticalSection* m_pSec;
public:
CDXAutoCritSecLock(CComAutoCriticalSection* pSec)
{
m_pSec = pSec;
m_pSec->Lock();
};
~CDXAutoCritSecLock()
{
m_pSec->Unlock();
};
};
#define DXAUTO_SEC_LOCK( s ) CDXAutoCritSecLock lck(s);
#endif // __ATLCOM_H__
//--- This function is used to compute the coefficient for a gaussian filter coordinate
inline float DXGaussCoeff( double x, double y, double Sigma )
{
double TwoSigmaSq = 2 * ( Sigma * Sigma );
return (float)(exp( ( -(x*x + y*y) / TwoSigmaSq ) ) /
( 3.1415927 * TwoSigmaSq ));
}
//--- This function is used to initialize a gaussian convolution filter
inline void DXInitGaussianFilter( float* pFilter, ULONG Width, ULONG Height, double Sigma )
{
int i, NumCoeff = Width * Height;
float val, CoeffAdjust, FilterSum = 0.;
double x, y;
double LeftX = -(double)(Width / 2);
double RightX = Width - LeftX;
double TopY = -(double)(Height / 2);
double BottomY = Height - TopY;
for( y = -TopY; y <= BottomY; y += 1. )
{
for( x = -LeftX; x <= RightX; x += 1. )
{
val = DXGaussCoeff( x, y, Sigma );
pFilter[i++] = val;
}
}
//--- Normalize filter (make it sum to 1.0)
for( i = 0; i < NumCoeff; ++i ) FilterSum += pFilter[i];
if( FilterSum < 1. )
{
CoeffAdjust = 1.f / FilterSum;
for( i = 0; i < NumCoeff; ++i )
{
pFilter[i] *= CoeffAdjust;
}
}
} /* DXInitGaussianFilter*/
//
// DXConvertToGray
//
// Translates a color sample to a gray scale sample
//
// Sample - The sample to convert to gray scale.
// Return value is the gray scale sample.
//
inline DXBASESAMPLE DXConvertToGray( DXBASESAMPLE Sample )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -