Files
core/ASCImageStudio3/AVSImageView5/Common.h

808 lines
24 KiB
C++
Raw Blame History

#pragma once
#include <comdef.h>
#include <gdiplus.h>
/*
#include <MediaFormatDefine.h>
#include <MediaDataDefine.h>
#include <emmintrin.h> // MMX, SSE, SSE2 intrinsic support
const DWORD _MMX_FEATURE_BIT = 0x00800000;
const DWORD _SSE_FEATURE_BIT = 0x02000000;
const DWORD _SSE2_FEATURE_BIT = 0x04000000;
*/
namespace Core
{
/*
class CheckFeatures
{
public:
CheckFeatures ()
{
m_FeatureMMX = false;
m_FeatureSSE = false;
m_FeatureSSE2 = false;
}
void Analyze ()
{
m_FeatureMMX = IsMMX ();
m_FeatureSSE = IsSSE ();
m_FeatureSSE2 = IsSSE2 ();
#ifdef _DEBUG
ATLTRACE("MMX : %s SSE : %s SSE2 : %s\n", m_FeatureMMX == true ? _T("available") : _T("disable"),
m_FeatureSSE == true ? _T("available") : _T("disable"),
m_FeatureSSE2 == true ? _T("available") : _T("disable") );
#endif
}
//void SetAlphaChanelValue ( byte Value, long PixelsCount, unsigned long* pSrc )
//{
// if ( m_FeatureSSE2 )
// {
// if ( PixelsCount < 4 )
// return;
// unsigned mask = ( Value << 24 | 0x00FFFFFF );
// __m128i nmask = _mm_set_epi32 ( mask, mask, mask, mask );
// __m128i* source = (__m128i*)pSrc;
// long count = PixelsCount / 4;
// for ( long i = 0; i < count; ++i )
// {
// __m128i xmm1 = _mm_loadu_si128 ( source );
// __m128i xmm2 = _mm_min_epu8 ( nmask, xmm1 );
// __m128i xmm3 = _mm_and_si128 ( xmm1, xmm2 );
// _mm_store_si128 ( source, xmm3 );
// ++source;
// }
// }
// else
// {
// unsigned long AlphaMask = (unsigned long)(Value<<24);
// for ( long i = 0; i < PixelsCount; ++i )
// {
// if ( pSrc[i] > AlphaMask )
// pSrc[i] = ( pSrc[i] & 0x00FFFFFF ) | AlphaMask;
// }
// }
//}
bool FeatureMMX ()
{
return m_FeatureMMX;
}
bool FeatureSSE ()
{
return m_FeatureSSE;
}
bool FeatureSSE2 ()
{
return m_FeatureSSE2;
}
private:
static bool IsMMX()
{
static bool bMMX = _IsFeature(_MMX_FEATURE_BIT);
return(bMMX);
}
static bool IsSSE()
{
static bool bSSE = _IsFeature(_SSE_FEATURE_BIT);
return(bSSE);
}
static bool IsSSE2()
{
static bool bSSE2 = _IsFeature(_SSE2_FEATURE_BIT);
return(bSSE2);
}
static bool _IsFeature(DWORD dwRequestFeature)
{
// This bit flag can get set on calling cpuid
// with register eax set to 1
DWORD dwFeature = 0;
__try {
_asm {
mov eax,1
cpuid
mov dwFeature,edx
}
} __except ( EXCEPTION_EXECUTE_HANDLER) {
return false;
}
if ((dwRequestFeature == _MMX_FEATURE_BIT) &&
(dwFeature & _MMX_FEATURE_BIT)) {
__try {
__asm {
pxor mm0, mm0 // executing MMX instruction
emms
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
return (0);
}
return(true);
}
else if ((dwRequestFeature == _SSE2_FEATURE_BIT) &&
(dwFeature & _SSE2_FEATURE_BIT)) {
__try {
__asm {
xorpd xmm0, xmm0 // executing SSE2 instruction
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
return (0);
}
return(true);
}
else if ((dwRequestFeature == _SSE_FEATURE_BIT) &&
(dwFeature & _SSE_FEATURE_BIT)) {
__try {
__asm {
xorps xmm0, xmm0 // executing SSE instruction
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
return (0);
}
return(true);
}
return false;
}
private:
bool m_FeatureMMX;
bool m_FeatureSSE;
bool m_FeatureSSE2;
};
*/
class MediaTransform
{
public:
MediaTransform()
{
m_pFormat = NULL;
m_pTransform = NULL;
m_bInterfacesValid = TRUE;
}
virtual ~MediaTransform()
{
Destroy();
}
bool ConvertToBGRA ( IUnknown* pSource, IUnknown*& pResult )
{
pResult = NULL;
if ( NULL == pSource )
return false;
if ( false == Create() )
return false;
MediaCore::IAVSUncompressedVideoFrame* pSourceFrame = NULL;
pSource->QueryInterface ( &pSourceFrame );
if ( NULL == pSourceFrame )
return false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
long lWidth = 0; pSourceFrame->get_Width ( &lWidth );
long lHeight = 0; pSourceFrame->get_Height ( &lHeight );
long lAspectX = 0; pSourceFrame->get_AspectRatioX ( &lAspectX );
long lAspectY = 0; pSourceFrame->get_AspectRatioY ( &lAspectY );
long lColorSpace = 0; pSourceFrame->get_ColorSpace ( &lColorSpace );
m_pFormat->put_Width ( lWidth );
m_pFormat->put_Height ( lHeight );
m_pFormat->put_AspectRatioX ( lAspectX );
m_pFormat->put_AspectRatioY ( lAspectY );
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> BGRA32 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!)
m_pTransform->SetVideoFormat ( m_pFormat );
m_pTransform->raw_TransformFrame ( pSourceFrame, &pResult );
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( pSourceFrame == pResult ) // <20><><EFBFBD><EFBFBD><EFBFBD> (pResult != NULL)
{
pResult->Release();
pResult = NULL;
pSourceFrame->raw_CreateDuplicate(DUBLICATE_TYPE_COPY, (MediaCore::IAVSMediaData**)(&pResult));
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> BGRA (<28>.<2E>. <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> alpha <20><><EFBFBD><EFBFBD><EFBFBD>), <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 255
if ( ( lColorSpace != CSP_BGRA ) && ( lColorSpace != ( CSP_BGRA | CSP_VFLIP ) ) && ( NULL != pResult ) )
{
BYTE* pResultBuffer = NULL; ((MediaCore::IAVSMediaData*)pResult)->get_Buffer(&pResultBuffer);
if (NULL != pResultBuffer)
{
BYTE* pResultAlpha = pResultBuffer + 3;
for ( long index = 4 * lWidth * lHeight - 1; index >= 0; index -= 4, pResultAlpha += 4 )
*pResultAlpha = 255;
}
}
pSourceFrame->Release();
return ( NULL != pResult );
}
bool ConvertToI420 ( IUnknown* pSource, IUnknown*& pResult )
{
pResult = NULL;
if ( NULL == pSource )
return false;
if ( false == CreateToI420() )
return false;
MediaCore::IAVSUncompressedVideoFrame* pSourceFrame = NULL;
pSource->QueryInterface ( &pSourceFrame );
if ( NULL == pSourceFrame )
return false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
long lWidth = 0; pSourceFrame->get_Width ( &lWidth );
long lHeight = 0; pSourceFrame->get_Height ( &lHeight );
long lAspectX = 0; pSourceFrame->get_AspectRatioX ( &lAspectX );
long lAspectY = 0; pSourceFrame->get_AspectRatioY ( &lAspectY );
long lColorSpace = 0; pSourceFrame->get_ColorSpace ( &lColorSpace );
m_pFormat->put_Width ( lWidth );
m_pFormat->put_Height ( lHeight );
m_pFormat->put_AspectRatioX ( lAspectX );
m_pFormat->put_AspectRatioY ( lAspectY );
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> I420 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!)
m_pTransform->SetVideoFormat ( m_pFormat );
m_pTransform->raw_TransformFrame ( pSourceFrame, &pResult );
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( pSourceFrame == pResult ) // <20><><EFBFBD><EFBFBD><EFBFBD> (pResult != NULL)
{
pResult->Release();
pResult = NULL;
pSourceFrame->raw_CreateDuplicate ( DUBLICATE_TYPE_COPY, (MediaCore::IAVSMediaData**)(&pResult) );
}
pSourceFrame->Release ();
return (NULL != pResult);
}
bool ConvertToBitmap ( IUnknown* pSource, Bitmap*& pBitmap )
{
pBitmap = NULL;
if ( NULL == pSource )
return false;
MediaCore::IAVSUncompressedVideoFrame* pMediaData = NULL;
pSource->QueryInterface ( &pMediaData );
pSource->Release ();
if ( NULL == pMediaData )
return false;
LONG ColorSpace = 0; pMediaData->get_ColorSpace(&ColorSpace);
/*
const long CONST_CSP_VFLIP = CSP_VFLIP;
const long CONST_CSP_BGRA = CSP_BGRA;
const long CONST_CSP_BGRA_CSP_VFLIP = CSP_BGRA | CSP_VFLIP;
*/
if ( ( ColorSpace != CSP_BGRA ) && ( ColorSpace != ( CSP_BGRA | CSP_VFLIP ) ) )
{
IUnknown* pInterface = NULL; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MediaTransform::ConvertToBGRA ( pSource, *&pInterface );
MediaCore::IAVSUncompressedVideoFrame* pUncompressed = NULL;
pInterface->QueryInterface ( &pUncompressed );
pInterface->Release ();
if ( NULL == pUncompressed )
{
pInterface->Release();
return false;
}
LONG lWidth = 0; pUncompressed->get_Width ( &lWidth );
LONG lHeight = 0; pUncompressed->get_Height ( &lHeight );
LONG lStride = 0; pUncompressed->get_Stride ( 0, &lStride );
BYTE* pSourceBuffer = 0; pUncompressed->get_Buffer ( &pSourceBuffer );
LONG nSize = 0; pUncompressed->get_BufferSize ( &nSize );
pBitmap = new Bitmap ( lWidth, lHeight, PixelFormat32bppARGB );
Rect rectLock ( 0, 0, lWidth, lHeight );
if ( pBitmap )
{
BitmapData data;
if ( Gdiplus::Ok == pBitmap->LockBits ( &rectLock, ImageLockModeWrite, PixelFormat32bppARGB, &data ) )
{
memcpy ( data.Scan0, pSourceBuffer, nSize );
pBitmap->UnlockBits ( &data );
if ( ColorSpace & CSP_VFLIP )
pBitmap->RotateFlip ( RotateNoneFlipY );
}
}
/*
ImageFile::IImageFile3Ptr ptrImageFile;
ptrImageFile.CreateInstance ( ImageFile::CLSID_ImageFile3 );
ptrImageFile->SaveImage2 ( (IUnknown**)&pInterface, 4, L"c:\\DebugTestImage.png" );
*/
pInterface->Release();
return true;
}
else
{
LONG lWidth = 0; pMediaData->get_Width ( &lWidth );
LONG lHeight = 0; pMediaData->get_Height ( &lHeight );
LONG lStride = 0; pMediaData->get_Stride ( 0, &lStride );
BYTE* pSourceBuffer = 0; pMediaData->get_Buffer ( &pSourceBuffer );
LONG nSize = 0; pMediaData->get_BufferSize ( &nSize );
//BYTE* pPlane0 = NULL; pMediaData->get_Plane ( 0, &pPlane0 );
pBitmap = new Bitmap ( lWidth, lHeight, PixelFormat32bppARGB );
Rect rectLock ( 0, 0, lWidth, lHeight );
if ( pBitmap )
{
BitmapData data;
if ( Gdiplus::Ok == pBitmap->LockBits ( &rectLock, ImageLockModeWrite, PixelFormat32bppARGB, &data ) )
{
memcpy ( data.Scan0, pSourceBuffer, nSize );
pBitmap->UnlockBits ( &data );
if ( ColorSpace & CSP_VFLIP )
pBitmap->RotateFlip ( RotateNoneFlipY );
return true;
}
}
}
return false;
}
protected:
bool IsValid()
{
if ( NULL == m_pFormat || NULL == m_pTransform )
return false;
return true;
}
void Destroy ()
{
RELEASEINTERFACE ( m_pFormat );
RELEASEINTERFACE ( m_pTransform );
}
bool Create()
{
if ( NULL != m_pTransform && NULL != m_pFormat )
return false;
if ( false == m_bInterfacesValid )
return false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (NULL == m_pTransform)
{
if ( FAILED ( CoCreateInstance ( MediaCore::CLSID_CAVSVideoFrameTransform, NULL, CLSCTX_ALL,
MediaCore::IID_IAVSVideoFrameTransform, (void**)(&m_pTransform) ) ) )
{
m_pTransform = NULL;
m_bInterfacesValid = FALSE;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( NULL == m_pFormat )
{
if ( FAILED ( CoCreateInstance ( MediaFormat::CLSID_CAVSVideoFormat, NULL, CLSCTX_ALL,
MediaFormat::IID_IAVSVideoFormat, (void**)(&m_pFormat) ) ) )
{
m_pFormat = NULL;
m_bInterfacesValid = FALSE;
}
else
{
m_pFormat->SetDefaultProperties ();
m_pFormat->put_ColorSpace ( CSP_BGRA /* | CSP_VFLIP*/ );
}
}
return IsValid ();
}
bool CreateToI420()
{
if ( NULL != m_pTransform && NULL != m_pFormat )
return true;
if ( false == m_bInterfacesValid )
return false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( NULL == m_pTransform )
{
if ( FAILED ( CoCreateInstance ( MediaCore::CLSID_CAVSVideoFrameTransform, NULL, CLSCTX_ALL,
MediaCore::IID_IAVSVideoFrameTransform, (void**)(&m_pTransform) ) ) )
{
m_pTransform = NULL;
m_bInterfacesValid = FALSE;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( NULL == m_pFormat )
{
if ( FAILED ( CoCreateInstance ( MediaFormat::CLSID_CAVSVideoFormat, NULL, CLSCTX_ALL,
MediaFormat::IID_IAVSVideoFormat, (void**)(&m_pFormat) ) ) )
{
m_pFormat = NULL;
m_bInterfacesValid = FALSE;
}
else
{
m_pFormat->SetDefaultProperties();
m_pFormat->put_ColorSpace ( CSP_I420 | CSP_VFLIP );
}
}
return IsValid();
}
protected:
MediaFormat::IAVSVideoFormat* m_pFormat; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BGR32
MediaCore::IAVSVideoFrameTransform* m_pTransform; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> media data <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BGR32
bool m_bInterfacesValid; // <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
};
// TODO : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
class PixelsOperations
{
public:
static const long sc_nInterpolationModeNearestNeighbor = 0;
static const long sc_nInterpolationModeBilinear = 1;
static const long sc_nInterpolationModeBicubic = 2;
public:
static void MemsetDW ( DWORD* pSrc, long Count, DWORD Color /* nChannels = 4 */ )
{
DWORD* pPixelsRGBA = (DWORD*) pSrc;
for ( long i = 0; i < Count; ++i )
pSrc[i] = Color;
}
static void BilinearResizeImageBT ( BYTE* pSrc, BYTE* pPixels,
long SourceWidth, long SourceHeight, long nWidth, long nHeight,
double SourceOffsetWidth, double SourceOffsetHeight,
double DestOffsetWidth, double DestOffsetHeight,
double SrcStepWidth, double SrcStepHeight,
long StartWriteW, long EndWriteW, long StartWriteH, long EndWriteH /* nChannels = 4 */ )
{
for ( long j = StartWriteH; j < EndWriteH-1; ++j )
{
for ( long i = StartWriteW; i < EndWriteW-1; ++i )
{
long nWriteInd = ( i + j * nWidth ) << 2; // * nChannels; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
double SourceIndX = ( SrcStepWidth * ( i + DestOffsetWidth ) + SourceOffsetWidth );
double SourceIndY = ( SrcStepHeight * ( j + DestOffsetHeight ) + SourceOffsetHeight );
// long FloorIndX = floor ( SourceIndX );
// long FloorIndY = floor ( SourceIndY );
// double FractionX = SourceIndX - FloorIndX;
// double FractionY = SourceIndY - FloorIndY;
long FloorIndX = (long) ( SourceIndX );
long FloorIndY = (long) ( SourceIndY );
double FractionX = /*abs*/ ( SourceIndX - FloorIndX );
double FractionY = /*abs*/ ( SourceIndY - FloorIndY );
long SelectColor03 = ( FloorIndX + SourceWidth * FloorIndY + SourceWidth ) << 2; // * nChannels;
long SelectColor01 = ( FloorIndX + SourceWidth * FloorIndY ) << 2; // * nChannels;
BYTE* pColor03 = &pSrc [ SelectColor03 ];
BYTE* pColor01 = &pSrc [ SelectColor01 ];
BYTE Blue01 = (BYTE) ( pColor01[0] + ( pColor01[4] - pColor01[0] ) * FractionX );
BYTE Blue02 = (BYTE) ( pColor03[0] + ( pColor03[4] - pColor03[0] ) * FractionX );
BYTE Green01 = (BYTE) ( pColor01[1] + ( pColor01[5] - pColor01[1] ) * FractionX );
//00
BYTE Green02 = (BYTE) ( pColor03[1] + ( pColor03[5] - pColor03[1] ) * FractionX );
BYTE Red01 = (BYTE) ( pColor01[2] + ( pColor01[6] - pColor01[2] ) * FractionX );
BYTE Red02 = (BYTE) ( pColor03[2] + ( pColor03[6] - pColor03[2] ) * FractionX );
//00
pPixels [ nWriteInd + 0 ] = (BYTE) ( Blue01 + FractionY * ( Blue02 - Blue01 ) );
pPixels [ nWriteInd + 1 ] = (BYTE) ( Green01 + FractionY * ( Green02 - Green01 ) );
pPixels [ nWriteInd + 2 ] = (BYTE) ( Red01 + FractionY * ( Red02 - Red01 ) );
pPixels [ nWriteInd + 3 ] = 0xFF;
}
}
}
static void BilinearResizeImageDW ( DWORD* pSrc, DWORD* pPixels,
long SourceWidth, long SourceHeight, long nWidth, long nHeight,
double SourceOffsetWidth, double SourceOffsetHeight,
double DestOffsetWidth, double DestOffsetHeight,
double SrcStepWidth, double SrcStepHeight,
long StartWriteW, long EndWriteW, long StartWriteH, long EndWriteH /* nChannels = 4 */ )
{
for ( long j = StartWriteH; j < EndWriteH-1; ++j )
{
for ( long i = StartWriteW; i < EndWriteW-1; ++i )
{
long nWriteInd = ( i + j * nWidth ); //* nChannels; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
double SourceIndX = ( SrcStepWidth * ( i + DestOffsetWidth ) + SourceOffsetWidth );
double SourceIndY = ( SrcStepHeight * ( j + DestOffsetHeight ) + SourceOffsetHeight );
// long FloorIndX = floor ( SourceIndX );
// long FloorIndY = floor ( SourceIndY );
// double FractionX = SourceIndX - FloorIndX;
// double FractionY = SourceIndY - FloorIndY;
long FloorIndX = (long) ( SourceIndX );
long FloorIndY = (long) ( SourceIndY );
double FractionX = /*abs*/ ( SourceIndX - FloorIndX );
double FractionY = /*abs*/ ( SourceIndY - FloorIndY );
long SelectColor01 = ( FloorIndX + SourceWidth * FloorIndY ); //* nChannels;
long SelectColor03 = ( FloorIndX + SourceWidth * FloorIndY + SourceWidth ); // * nChannels;
DWORD pColor01 = pSrc [ SelectColor01 ];
DWORD pColor02 = pSrc [ SelectColor01 + 1 ];
DWORD pColor03 = pSrc [ SelectColor03 ];
DWORD pColor04 = pSrc [ SelectColor03 + 1 ];
//__int64 Color00 = pColor01 + ( pColor03 - pColor01 ) * FractionX;
//__int64 Color11 = pColor02 + ( pColor04 - pColor02 ) * FractionX;
//__int64 ColorResult = Color00 + ( Color11 - Color00 ) * FractionY;
//pPixels [ nWriteInd ] = ColorResult;
//BYTE* pColor01 = (BYTE*)pSrc [ SelectColor01 ];
//BYTE* pColor03 = (BYTE*)pSrc [ SelectColor03 ];
//BYTE Blue01 = (BYTE) ( pColor01[0] + ( pColor01[4] - pColor01[0] ) * FractionX );
//BYTE Blue02 = (BYTE) ( pColor03[0] + ( pColor03[4] - pColor03[0] ) * FractionX );
//BYTE Green01 = (BYTE) ( pColor01[1] + ( pColor01[5] - pColor01[1] ) * FractionX );
////00
//BYTE Green02 = (BYTE) ( pColor03[1] + ( pColor03[5] - pColor03[1] ) * FractionX );
//BYTE Red01 = (BYTE) ( pColor01[2] + ( pColor01[6] - pColor01[2] ) * FractionX );
//BYTE Red02 = (BYTE) ( pColor03[2] + ( pColor03[6] - pColor03[2] ) * FractionX );
////00
//BYTE Blue = (BYTE) ( Blue01 + FractionY * ( Blue02 - Blue01 ) );
//BYTE Green = (BYTE) ( Green01 + FractionY * ( Green02 - Green01 ) );
//BYTE Red = (BYTE) ( Red01 + FractionY * ( Red02 - Red01 ) );
//((BYTE*)pPixels) [ nWriteInd + 0 ] = Blue;
//((BYTE*)pPixels) [ nWriteInd + 1 ] = Green;
//((BYTE*)pPixels) [ nWriteInd + 2 ] = Red;
//((BYTE*)pPixels) [ nWriteInd + 3 ] = 0xFF;
}
}
}
static void NearestResizeImageBT ( BYTE* pSrc, BYTE* pPixels,
long SourceWidth, long SourceHeight, long nWidth, long nHeight,
double SourceOffsetWidth, double SourceOffsetHeight,
double DestOffsetWidth, double DestOffsetHeight,
double SrcStepWidth, double SrcStepHeight,
long StartWriteW, long EndWriteW, long StartWriteH, long EndWriteH /* nChannels = 4 */ )
{
for ( double j = StartWriteH; j < EndWriteH; ++j )
{
for ( double i = StartWriteW; i < EndWriteW; ++i )
{
double SourceIndX = ( SrcStepWidth * ( i + DestOffsetWidth ) + SourceOffsetWidth );
double SourceIndY = ( SrcStepHeight * ( j + DestOffsetHeight ) + SourceOffsetHeight );
double nSourceIndD = SourceIndX + (long) SourceIndY * SourceWidth;
long SourceInd = ((long) nSourceIndD );
long nWriteInd = ((long)( i + j * nWidth )) << 2; // * nChannels;
pPixels [ nWriteInd ] = pSrc [ SourceInd ];
pPixels [ nWriteInd + 1 ] = pSrc [ SourceInd + 1 ];
pPixels [ nWriteInd + 2 ] = pSrc [ SourceInd + 2 ];
pPixels [ nWriteInd + 3 ] = 0xFF;
}
}
}
static void NearestResizeImageDW ( DWORD* pSrc, DWORD* pPixels,
long SourceWidth, long SourceHeight, long nWidth, long nHeight,
double SourceOffsetWidth, double SourceOffsetHeight,
double DestOffsetWidth, double DestOffsetHeight,
double SrcStepWidth, double SrcStepHeight,
long StartWriteW, long EndWriteW, long StartWriteH, long EndWriteH /* nChannels = 4 */ )
{
double PreMulX = SrcStepWidth * DestOffsetWidth + SourceOffsetWidth;
double PreMulY = SrcStepHeight * DestOffsetHeight + SourceOffsetHeight;
double PreSourceIndX = ( SrcStepWidth * StartWriteW + PreMulX );
long PreSourceIndY = (long)( SrcStepHeight * ( StartWriteH - 1 ) + PreMulY );
long SourceSize = SourceWidth * SourceHeight;
double SourceIndY2 = ( SrcStepHeight * ( EndWriteH - 1 ) + PreMulY );
double SourceIndX2 = ( SrcStepWidth * ( EndWriteW - 1 ) + PreMulX );
double nSourceIndD2 = SourceIndX2 + (long) SourceIndY2 * SourceWidth;
long SourceInd2 = (long) nSourceIndD2;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD>
if ( SourceSize <= SourceInd2 )
{
EndWriteH--;
}
for ( long j = StartWriteH; j < EndWriteH; ++j )
{
long SourceIndY = (long)( SrcStepHeight * j + PreMulY );
double dSourceInd = PreSourceIndX + (long) SourceIndY * SourceWidth;
long WriteInd = j * nWidth + StartWriteW;
for ( long i = StartWriteW; i < EndWriteW; ++i )
{
pPixels[WriteInd] = pSrc [ (long) dSourceInd ];
++WriteInd;
dSourceInd += SrcStepWidth;
///*
// OLD STYLE
//double SourceIndY = ( SrcStepHeight * j + PreMulY );
//double SourceIndX = ( SrcStepWidth * i + PreMulX );
//double nSourceIndD = SourceIndX + (long) SourceIndY * SourceWidth;
//long SourceInd = (long) nSourceIndD;
//long nWriteInd = (long)( i + j * nWidth );
//
//pPixels [ nWriteInd ] = pSrc [ SourceInd ];
//*/
}
}
}
//static void NearestResizeImageDW (
// DWORD* pSrc,
// DWORD* pPixels,
// long SourceWidth, long SourceHeight,
// long nWidth, long nHeight,
// double SourceOffsetWidth, double SourceOffsetHeight,
// double DestOffsetWidth, double DestOffsetHeight,
// double SrcStepWidth, double SrcStepHeight,
// long StartWriteW, long EndWriteW,
// long StartWriteH, long EndWriteH )
//{
// double PreMulX = SrcStepWidth * DestOffsetWidth + SourceOffsetWidth;
// double PreMulY = SrcStepHeight * DestOffsetHeight + SourceOffsetHeight;
// double PreSourceIndX = SrcStepWidth * StartWriteW + PreMulX;
// long PreSourceIndY = static_cast<long> ( SrcStepHeight * ( StartWriteH - 1 ) + PreMulY );
// double nIndX = SrcStepWidth * ( StartWriteW ) + PreMulX;
// long Width = static_cast<long> ( ( EndWriteH - StartWriteH ) * 0.5 );
// for ( long j = StartWriteH; j < EndWriteH - Width; ++j )
// {
// long SourceIndY = static_cast<long> ( SrcStepHeight * j + PreMulY );
// long WriteInd = static_cast<long> ( j * nWidth + StartWriteW );
// double SourceIndX = nIndX;
// long SourceMoveY = SourceIndY * SourceWidth;
// for ( long i = StartWriteW; i < EndWriteW; ++i )
// {
// long nSourceInd = static_cast<long> ( SourceIndX + SourceMoveY );
// pPixels [ WriteInd ] = pSrc [ nSourceInd ];
// ++WriteInd;
// SourceIndX += SrcStepWidth;
// }
// }
// for ( long j = StartWriteH + Width; j < EndWriteH; ++j )
// {
// long SourceIndY = static_cast<long> ( SrcStepHeight * j + PreMulY );
// long WriteInd = static_cast<long> ( j * nWidth + StartWriteW );
// double SourceIndX = nIndX;
// long SourceMoveY = SourceIndY * SourceWidth;
// for ( long i = StartWriteW; i < EndWriteW; ++i )
// {
// long nSourceInd = static_cast<long> ( SourceIndX + SourceMoveY );
// pPixels [ WriteInd ] = pSrc [ nSourceInd ];
// ++WriteInd;
// SourceIndX += SrcStepWidth;
// }
// }
//}
/*
static void NearestResizeImageDW_SSE2 ( DWORD* pSrc, DWORD* pPixels,
long SourceWidth, long SourceHeight, long nWidth, long nHeight,
double SourceOffsetWidth, double SourceOffsetHeight,
double DestOffsetWidth, double DestOffsetHeight,
double SrcStepWidth, double SrcStepHeight,
long StartWriteW, long EndWriteW, long StartWriteH, long EndWriteH )
{
double PreMulX = SrcStepWidth * DestOffsetWidth + SourceOffsetWidth;
double PreMulY = SrcStepHeight * DestOffsetHeight + SourceOffsetHeight;
__m128d XMMMPreMul = _mm_set_pd ( PreMulX, PreMulY );
__m128d XMMMSrcStep = _mm_set_pd ( SrcStepWidth, SrcStepHeight );
__m128d XMMMSourceOffset = _mm_set_pd ( SourceOffsetWidth, SourceOffsetHeight );
for ( long j = StartWriteH; j < EndWriteH; ++j )
{
for ( long i = StartWriteW; i < EndWriteW; ++i )
{
__m128d XMMMInd = _mm_set_pd ( i, j );
__m128d XMMMSourceInd = _mm_mul_pd ( XMMMInd, XMMMSrcStep );
XMMMSourceInd = _mm_add_pd ( XMMMSourceInd, XMMMPreMul );
long SourceInd = (long) XMMMSourceInd.m128d_f64[1] +
(long) XMMMSourceInd.m128d_f64[0] * SourceWidth;
long nWriteInd = i + j * nWidth;
pPixels [ nWriteInd ] = pSrc [ SourceInd ];
}
}
}
*/
};
}