⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxhelper.h

📁 希望我上传的这些东西可以对搞编程的程序员有点小小的帮助!谢谢!
💻 H
📖 第 1 页 / 共 3 页
字号:
{
    DWORD v = Sample;
    DWORD r = (BYTE)(v >> 16);
    DWORD g = (BYTE)(v >> 8);
    DWORD b = (BYTE)(v);
    DWORD sat = (r*306 + g*601 + b*117) / 1024;
    v &= 0xFF000000;
    v |= (sat << 16) | (sat << 8) | sat;
    return v;
} /* DXConvertToGray */

//--- This returns into the destination the value of the source
//  sample scaled by its own alpha (producing a premultiplied alpha sample)
//
inline DXPMSAMPLE DXPreMultSample(const DXSAMPLE & Src)
{
    if(Src.Alpha == 255 )
    {
        return (DWORD)Src;
    }
    else if(Src.Alpha == 0 )
    {
        return 0;
    }
    else
    {
        unsigned t1, t2;
        t1 = (Src & 0x00ff00ff) * Src.Alpha + 0x00800080;
        t1 = ((t1 + ((t1 >> 8) & 0x00ff00ff)) >> 8) & 0x00ff00ff;

        t2 = (((Src >> 8) & 0x000000ff) | 0x01000000) * Src.Alpha + 0x00800080;
        t2 = (t2 + ((t2 >> 8) & 0x00ff00ff)) & 0xff00ff00;
        return (t1 | t2);
    }
} /* DXPreMultSample */

inline DXPMSAMPLE * DXPreMultArray(DXSAMPLE *pBuffer, ULONG cSamples)
{
    for (ULONG i = 0; i < cSamples; i++)
    {
        BYTE SrcAlpha = pBuffer[i].Alpha;
        if (SrcAlpha != 0xFF)
        {
            if (SrcAlpha == 0)
            {
                pBuffer[i] = 0;
            }
            else
            {
                DWORD S = pBuffer[i];
                DWORD t1 = (S & 0x00ff00ff) * SrcAlpha + 0x00800080;
                t1 = ((t1 + ((t1 >> 8) & 0x00ff00ff)) >> 8) & 0x00ff00ff;

                DWORD t2 = (((S >> 8) & 0x000000ff) | 0x01000000) * SrcAlpha + 0x00800080;
                t2 = (t2 + ((t2 >> 8) & 0x00ff00ff)) & 0xff00ff00;

                pBuffer[i] = (t1 | t2);
            }
        }
    }
    return (DXPMSAMPLE *)pBuffer;
}


inline DXSAMPLE DXUnPreMultSample(const DXPMSAMPLE & Src)
{
    if(Src.Alpha == 255 || Src.Alpha == 0)
    {
        return (DWORD)Src;
    }
    else
    {
        DXSAMPLE Dst;
        Dst.Blue  = (BYTE)((Src.Blue  * 255) / Src.Alpha);
        Dst.Green = (BYTE)((Src.Green * 255) / Src.Alpha);
        Dst.Red   = (BYTE)((Src.Red   * 255) / Src.Alpha);
        Dst.Alpha = Src.Alpha;
        return Dst;
    }
} /* DXUnPreMultSample */

inline DXSAMPLE * DXUnPreMultArray(DXPMSAMPLE *pBuffer, ULONG cSamples)
{
    for (ULONG i = 0; i < cSamples; i++)
    {
        BYTE SrcAlpha = pBuffer[i].Alpha;
        if (SrcAlpha != 0xFF && SrcAlpha != 0)
        {
            pBuffer[i].Blue  = (BYTE)((pBuffer[i].Blue  * 255) / SrcAlpha);
            pBuffer[i].Green = (BYTE)((pBuffer[i].Green * 255) / SrcAlpha);
            pBuffer[i].Red   = (BYTE)((pBuffer[i].Red   * 255) / SrcAlpha);
        }
    }
    return (DXSAMPLE *)pBuffer;
}


//
//  This returns the result of 255-Alpha which is computed by doing a NOT
//
inline BYTE DXInvertAlpha( BYTE Alpha ) { return (BYTE)~Alpha; }

inline DWORD DXScaleSample( DWORD Src, ULONG beta )
{
    ULONG t1, t2;

    t1 = (Src & 0x00ff00ff) * beta + 0x00800080;
    t1 = ((t1 + ((t1 >> 8) & 0x00ff00ff)) >> 8) & 0x00ff00ff;

    t2 = ((Src >> 8) & 0x00ff00ff) * beta + 0x00800080;
    t2 = (t2 + ((t2 >> 8) & 0x00ff00ff)) & 0xff00ff00;

    return (DWORD)(t1 | t2);
}


inline DWORD DXScaleSamplePercent( DWORD Src, float Percent )
{
    if (Percent > (254.0f / 255.0f)) {
        return Src;
    }
    else
    {
        return DXScaleSample(Src, (BYTE)(Percent * 255));
    }
}

inline void DXCompositeOver(DXPMSAMPLE & Dst, const DXPMSAMPLE & Src)
{
    if (Src.Alpha)
    {
        ULONG Beta = DXInvertAlpha(Src.Alpha);
        if (Beta)
        {
            Dst = Src + DXScaleSample(Dst, Beta);
        }
        else
        {
            Dst = Src;
        }
    }
}


inline DXPMSAMPLE DXCompositeUnder(DXPMSAMPLE Dst, DXPMSAMPLE Src )
{
    return Dst + DXScaleSample(Src, DXInvertAlpha(Dst.Alpha));
}


inline DXBASESAMPLE DXApplyLookupTable(const DXBASESAMPLE Src, const BYTE * pTable)
{
    DXBASESAMPLE Dest;
    Dest.Blue   = pTable[Src.Blue];
    Dest.Green  = pTable[Src.Green];
    Dest.Red    = pTable[Src.Red];
    Dest.Alpha  = pTable[Src.Alpha];
    return Dest;
}

inline DXBASESAMPLE * DXApplyLookupTableArray(DXBASESAMPLE *pBuffer, ULONG cSamples, const BYTE * pTable)
{
    for (ULONG i = 0; i < cSamples; i++)
    {
        DWORD v = pBuffer[i];
        DWORD a = pTable[v >> 24];
        DWORD r = pTable[(BYTE)(v >> 16)];
        DWORD g = pTable[(BYTE)(v >> 8)];
        DWORD b = pTable[(BYTE)v];
        pBuffer[i] = (a << 24) | (r << 16) | (g << 8) | b;
    }
    return pBuffer;
}

inline DXBASESAMPLE * DXApplyColorChannelLookupArray(DXBASESAMPLE *pBuffer,
                                                     ULONG cSamples,
                                                     const BYTE * pAlphaTable,
                                                     const BYTE * pRedTable,
                                                     const BYTE * pGreenTable,
                                                     const BYTE * pBlueTable)
{
    for (ULONG i = 0; i < cSamples; i++)
    {
        pBuffer[i].Blue   = pBlueTable[pBuffer[i].Blue];
        pBuffer[i].Green  = pGreenTable[pBuffer[i].Green];
        pBuffer[i].Red    = pRedTable[pBuffer[i].Red];
        pBuffer[i].Alpha  = pAlphaTable[pBuffer[i].Alpha];
    }
    return pBuffer;
}


//
//  CDXScale helper class
//
//  This class uses a pre-computed lookup table to scale samples.  For scaling large
//  arrays of samples to a constant scale, this is much faster than using even MMX
//  instructions.  This class is usually declared as a member of another class and
//  is most often used to apply a global opacity to a set of samples.
//
//  When using this class, you must always check for the two special cases of clear
//  and opaque before calling any of the scaling member functions.  Do this by using
//  the ScaleType() inline function.  Your code should look somthing like this:
//
//  if (ScaleType() == DXRUNTYPE_CLEAR)
//      Do whatever you do for a 0 alpha set of samples -- usually just ignore them
//  else if (ScaleType() == DXRUNTYPE_OPAQUE)
//      Do whatever you would do for a non-scaled set of samples
//  else
//      Scale the samples by using ScaleSample or one of the ScaleArray members
//
//  If you call any of the scaling members when the ScaleType() is either clear or
//  opaque, you will GP fault becuase the lookup table will not be allocated.
//
//  The scale can be set using either a floating point number between 0 and 1 using:
//      CDXScale::SetScale / CDXScale::GetScale
//  or you can use a byte integer value by using:
//      CDXScale::SetScaleAlphaValue / CDXScale::GetScaleAlphaValue
//
class CDXScale
{
private:
    float       m_Scale;
    BYTE        m_AlphaScale;
    BYTE        *m_pTable;

HRESULT InternalSetScale(BYTE Scale)
{
    if (m_AlphaScale == Scale) return S_OK;
    if (Scale == 0 || Scale == 255) 
    {
        delete m_pTable;
        m_pTable = NULL;
    }
    else
    {
        if(!m_pTable)
        {
            m_pTable = new BYTE[256];
            if(!m_pTable )
            {
                return E_OUTOFMEMORY;
            }
        }
        for (int i = 0; i < 256; ++i )
        {
            m_pTable[i] = (BYTE)((i * Scale) / 255);
        }
    }
    m_AlphaScale = Scale;
    return S_OK;
}
public:
    CDXScale() : 
      m_Scale(1.0f),
      m_AlphaScale(0xFF),
      m_pTable(NULL)
      {}
    ~CDXScale()
    {
        delete m_pTable;
    }
    DXRUNTYPE ScaleType() 
    {
        if (m_AlphaScale == 0) return DXRUNTYPE_CLEAR;
        if (m_AlphaScale == 0xFF) return DXRUNTYPE_OPAQUE;
        return DXRUNTYPE_TRANS;
    }
    HRESULT SetScaleAlphaValue(BYTE Alpha)
    {
        HRESULT hr = InternalSetScale(Alpha);
        if (SUCCEEDED(hr))
        {
            m_Scale = ((float)Alpha) / 255.0f;
        }
        return hr;
    }
    BYTE GetScaleAlphaValue(void)
    {
        return m_AlphaScale;
    }
    HRESULT SetScale(float Scale)
    {
        HRESULT hr = S_OK;
        if(( Scale < 0.0f ) || ( Scale > 1.0f ) )
        {
            hr = E_INVALIDARG;
        }
        else
        {
            ULONG IntScale = (ULONG)(Scale * 256.0f);     // Round up alpha (.9999 = 255 = Solid)
            if (IntScale > 255) 
            {
                IntScale = 255;
            }
            hr = SetScaleAlphaValue((BYTE)IntScale);
            if (SUCCEEDED(hr))
            {
                m_Scale = Scale;
            }
        }
        return hr;
    }
    float GetScale() const
    {
        return m_Scale;
    }
    DXRUNTYPE ScaleType() const
    {
        return (m_pTable ? DXRUNTYPE_TRANS : (m_AlphaScale ? DXRUNTYPE_OPAQUE : DXRUNTYPE_CLEAR));
    }
    DWORD ScaleSample(const DWORD s) const
    {
        return DXApplyLookupTable((DXBASESAMPLE)s, m_pTable);
    }
    DXBASESAMPLE * ScaleBaseArray(DXBASESAMPLE * pBuffer, ULONG cSamples) const
    {
        return DXApplyLookupTableArray(pBuffer, cSamples, m_pTable);
    }
    DXPMSAMPLE * ScalePremultArray(DXPMSAMPLE * pBuffer, ULONG cSamples) const
    {
        return (DXPMSAMPLE *)DXApplyLookupTableArray(pBuffer, cSamples, m_pTable);
    }
    DXSAMPLE * ScaleArray(DXSAMPLE * pBuffer, ULONG cSamples) const
    {
        return (DXSAMPLE *)DXApplyLookupTableArray(pBuffer, cSamples, m_pTable);
    }
    DXSAMPLE * ScaleArrayAlphaOnly(DXSAMPLE *pBuffer, ULONG cSamples) const
    {
        const BYTE *pTable = m_pTable;
        for (ULONG i = 0; i < cSamples; i++)
        {
            pBuffer[i].Alpha  = pTable[pBuffer[i].Alpha];
        }
        return pBuffer;
    }
};

inline DWORD DXWeightedAverage( DXBASESAMPLE S1, DXBASESAMPLE S2, ULONG Wgt )
{
    _ASSERT( Wgt < 256 );
    ULONG t1, t2;
    ULONG InvWgt = Wgt ^ 0xFF;

    t1  = (((S1 & 0x00ff00ff) * Wgt) + ((S2 & 0x00ff00ff) * InvWgt )) + 0x00800080;
    t1  = ((t1 + ((t1 >> 8) & 0x00ff00ff)) >> 8) & 0x00ff00ff;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -