Added Get/SetWICFactory

This commit is contained in:
Chuck Walbourn 2015-08-18 16:14:09 -07:00
parent 4a223dd8ad
commit 7093178481
8 changed files with 167 additions and 109 deletions

View File

@ -59,6 +59,9 @@
#define DIRECTX_TEX_VERSION 133
struct IWICImagingFactory;
namespace DirectX
{
@ -374,19 +377,6 @@ namespace DirectX
_In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV(IPropertyBag2*)> setCustomProps = nullptr );
enum WICCodecs
{
WIC_CODEC_BMP =1, // Windows Bitmap (.bmp)
WIC_CODEC_JPEG, // Joint Photographic Experts Group (.jpg, .jpeg)
WIC_CODEC_PNG, // Portable Network Graphics (.png)
WIC_CODEC_TIFF, // Tagged Image File Format (.tif, .tiff)
WIC_CODEC_GIF, // Graphics Interchange Format (.gif)
WIC_CODEC_WMP, // Windows Media Photo / HD Photo / JPEG XR (.hdp, .jxr, .wdp)
WIC_CODEC_ICO, // Windows Icon (.ico)
};
REFGUID __cdecl GetWICCodec( _In_ WICCodecs codec );
//---------------------------------------------------------------------------------
// Texture conversion, resizing, mipmap generation, and block compression
@ -584,6 +574,7 @@ namespace DirectX
//---------------------------------------------------------------------------------
// Misc image operations
struct Rect
{
size_t x;
@ -619,6 +610,25 @@ namespace DirectX
HRESULT __cdecl ComputeMSE( _In_ const Image& image1, _In_ const Image& image2, _Out_ float& mse, _Out_writes_opt_(4) float* mseV, _In_ DWORD flags = 0 );
//---------------------------------------------------------------------------------
// WIC utility code
enum WICCodecs
{
WIC_CODEC_BMP = 1, // Windows Bitmap (.bmp)
WIC_CODEC_JPEG, // Joint Photographic Experts Group (.jpg, .jpeg)
WIC_CODEC_PNG, // Portable Network Graphics (.png)
WIC_CODEC_TIFF, // Tagged Image File Format (.tif, .tiff)
WIC_CODEC_GIF, // Graphics Interchange Format (.gif)
WIC_CODEC_WMP, // Windows Media Photo / HD Photo / JPEG XR (.hdp, .jxr, .wdp)
WIC_CODEC_ICO, // Windows Icon (.ico)
};
REFGUID __cdecl GetWICCodec(_In_ WICCodecs codec);
IWICImagingFactory* __cdecl GetWICFactory( bool& iswic2 );
void __cdecl SetWICFactory( _In_opt_ IWICImagingFactory* pWIC);
//---------------------------------------------------------------------------------
// Direct3D 11 functions
bool __cdecl IsSupportedTexture( _In_ ID3D11Device* pDevice, _In_ const TexMetadata& metadata );

View File

@ -4374,7 +4374,8 @@ static HRESULT _ConvertUsingWIC( _In_ const Image& srcImage, _In_ const WICPixel
assert( srcImage.width == destImage.width );
assert( srcImage.height == destImage.height );
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;

View File

@ -31,7 +31,8 @@ static HRESULT _PerformFlipRotateUsingWIC( _In_ const Image& srcImage, _In_ DWOR
assert( srcImage.format == destImage.format );
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;

View File

@ -166,7 +166,7 @@ static HRESULT _EnsureWicBitmapPixelFormat( _In_ IWICImagingFactory* pWIC, _In_
//--- Resizing color and alpha channels separately using WIC ---
HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ IWICBitmap* original,
HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original,
_In_ size_t newWidth, _In_ size_t newHeight, _In_ DWORD filter, _Inout_ const Image* img )
{
if ( !pWIC || !original || !img )
@ -213,7 +213,7 @@ HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ IWICBi
else
{
#if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
if ( _IsWIC2() )
if ( iswic2 )
{
colorBytesInPixel = colorBytesPerPixel = 12;
colorPixelFormat = GUID_WICPixelFormat96bppRGBFloat;
@ -451,7 +451,8 @@ static HRESULT _GenerateMipMapsUsingWIC( _In_ const Image& baseImage, _In_ DWORD
if ( !baseImage.pixels || !mipChain.GetPixels() )
return E_POINTER;
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -515,7 +516,7 @@ static HRESULT _GenerateMipMapsUsingWIC( _In_ const Image& baseImage, _In_ DWORD
if ( (filter & TEX_FILTER_SEPARATE_ALPHA) && supportsTransparency )
{
hr = _ResizeSeparateColorAndAlpha( pWIC, source.Get(), width, height, filter, img );
hr = _ResizeSeparateColorAndAlpha( pWIC, iswic2, source.Get(), width, height, filter, img );
if ( FAILED(hr) )
return hr;
}

View File

@ -55,8 +55,6 @@
#include "scoped.h"
struct IWICImagingFactory;
#define TEX_FILTER_MASK 0xF00000
#define XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT DXGI_FORMAT(116)
@ -85,10 +83,6 @@ namespace DirectX
DWORD __cdecl _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetGUID );
IWICImagingFactory* __cdecl _GetWIC();
bool __cdecl _IsWIC2();
inline WICBitmapDitherType __cdecl _GetWICDither( _In_ DWORD flags )
{
static_assert( TEX_FILTER_DITHER == 0x10000, "TEX_FILTER_DITHER* flag values don't match mask" );

View File

@ -26,7 +26,7 @@ namespace DirectX
// WIC related helper functions
//-------------------------------------------------------------------------------------
extern HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ IWICBitmap* original,
extern HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original,
_In_ size_t newWidth, _In_ size_t newHeight, _In_ DWORD filter, _Inout_ const Image* img );
//--- Do image resize using WIC ---
@ -38,7 +38,8 @@ static HRESULT _PerformResizeUsingWIC( _In_ const Image& srcImage, _In_ DWORD fi
assert( srcImage.format == destImage.format );
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -66,7 +67,7 @@ static HRESULT _PerformResizeUsingWIC( _In_ const Image& srcImage, _In_ DWORD fi
if ( (filter & TEX_FILTER_SEPARATE_ALPHA) && supportsTransparency )
{
hr = _ResizeSeparateColorAndAlpha( pWIC, source.Get(), destImage.width, destImage.height, filter, &destImage );
hr = _ResizeSeparateColorAndAlpha( pWIC, iswic2, source.Get(), destImage.width, destImage.height, filter, &destImage );
if ( FAILED(hr) )
return hr;
}

View File

@ -15,6 +15,8 @@
#include "directxtexp.h"
using Microsoft::WRL::ComPtr;
#if defined(_XBOX_ONE) && defined(_TITLE)
static_assert(XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT == DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT, "Xbox One XDK mismatch detected");
static_assert(XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT == DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT, "Xbox One XDK mismatch detected");
@ -70,6 +72,8 @@ static WICTranslate g_WICFormats[] =
};
static bool g_WIC2 = false;
static IWICImagingFactory* g_Factory = nullptr;
namespace DirectX
{
@ -186,67 +190,6 @@ DWORD _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetG
return srgb;
}
bool _IsWIC2()
{
return g_WIC2;
}
IWICImagingFactory* _GetWIC()
{
static IWICImagingFactory* s_Factory = nullptr;
if ( s_Factory )
return s_Factory;
#if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory2,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory2),
(LPVOID*)&s_Factory
);
if ( SUCCEEDED(hr) )
{
// WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed
g_WIC2 = true;
}
else
{
hr = CoCreateInstance(
CLSID_WICImagingFactory1,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
(LPVOID*)&s_Factory
);
if ( FAILED(hr) )
{
s_Factory = nullptr;
return nullptr;
}
}
#else
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
(LPVOID*)&s_Factory
);
if ( FAILED(hr) )
{
s_Factory = nullptr;
return nullptr;
}
#endif
return s_Factory;
}
//-------------------------------------------------------------------------------------
// Public helper function to get common WIC codec GUIDs
@ -283,6 +226,102 @@ REFGUID GetWICCodec( WICCodecs codec )
}
//-------------------------------------------------------------------------------------
// Singleton function for WIC factory
//-------------------------------------------------------------------------------------
IWICImagingFactory* GetWICFactory(bool& iswic2)
{
if (g_Factory)
{
iswic2 = g_WIC2;
return g_Factory;
}
#if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory2,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory2),
(LPVOID*)&g_Factory
);
if (SUCCEEDED(hr))
{
// WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed
g_WIC2 = true;
}
else
{
g_WIC2 = false;
hr = CoCreateInstance(
CLSID_WICImagingFactory1,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
(LPVOID*)&g_Factory
);
if (FAILED(hr))
{
g_Factory = nullptr;
return nullptr;
}
}
#else
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
(LPVOID*)&s_Factory
);
g_WIC2 = false;
if (FAILED(hr))
{
g_Factory = nullptr;
return nullptr;
}
#endif
iswic2 = g_WIC2;
return g_Factory;
}
//-------------------------------------------------------------------------------------
// Optional initializer for WIC factory
//-------------------------------------------------------------------------------------
void SetWICFactory(_In_opt_ IWICImagingFactory* pWIC)
{
if (pWIC == g_Factory)
return;
bool iswic2 = false;
if (pWIC)
{
#if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
ComPtr<IWICImagingFactory2> wic2;
HRESULT hr = pWIC->QueryInterface(_uuidof(IWICImagingFactory2), reinterpret_cast<void**>(wic2.GetAddressOf()));
if (SUCCEEDED(hr))
{
iswic2 = true;
}
#endif
pWIC->AddRef();
}
g_WIC2 = iswic2;
std::swap(pWIC, g_Factory);
if ( pWIC )
pWIC->Release();
}
//=====================================================================================
// DXGI Format Utilities
//=====================================================================================

View File

@ -141,7 +141,7 @@ namespace DirectX
//-------------------------------------------------------------------------------------
// Returns the DXGI format and optionally the WIC pixel GUID to convert to
//-------------------------------------------------------------------------------------
static DXGI_FORMAT _DetermineFormat( _In_ const WICPixelFormatGUID& pixelFormat, _In_ DWORD flags,
static DXGI_FORMAT _DetermineFormat( _In_ const WICPixelFormatGUID& pixelFormat, _In_ DWORD flags, _In_ bool iswic2,
_Out_opt_ WICPixelFormatGUID* pConvert )
{
if ( pConvert )
@ -154,7 +154,7 @@ static DXGI_FORMAT _DetermineFormat( _In_ const WICPixelFormatGUID& pixelFormat,
if ( memcmp( &GUID_WICPixelFormat96bppRGBFixedPoint, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 )
{
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
if ( _IsWIC2() )
if ( iswic2 )
{
if ( pConvert )
memcpy( pConvert, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID) );
@ -234,7 +234,7 @@ static DXGI_FORMAT _DetermineFormat( _In_ const WICPixelFormatGUID& pixelFormat,
//-------------------------------------------------------------------------------------
// Determines metadata for image
//-------------------------------------------------------------------------------------
static HRESULT _DecodeMetadata( _In_ DWORD flags,
static HRESULT _DecodeMetadata( _In_ DWORD flags, _In_ bool iswic2,
_In_ IWICBitmapDecoder *decoder, _In_ IWICBitmapFrameDecode *frame,
_Out_ TexMetadata& metadata, _Out_opt_ WICPixelFormatGUID* pConvert )
{
@ -271,7 +271,7 @@ static HRESULT _DecodeMetadata( _In_ DWORD flags,
if ( FAILED(hr) )
return hr;
metadata.format = _DetermineFormat( pixelFormat, flags, pConvert );
metadata.format = _DetermineFormat( pixelFormat, flags, iswic2, pConvert );
if ( metadata.format == DXGI_FORMAT_UNKNOWN )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
@ -355,7 +355,8 @@ static HRESULT _DecodeSingleFrame( _In_ DWORD flags, _In_ const TexMetadata& met
if ( !img )
return E_POINTER;
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -410,7 +411,8 @@ static HRESULT _DecodeMultiframe( _In_ DWORD flags, _In_ const TexMetadata& meta
if ( FAILED(hr) )
return hr;
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -662,7 +664,8 @@ static HRESULT _EncodeImage( _In_ const Image& image, _In_ DWORD flags, _In_ REF
if ( memcmp( &targetGuid, &pfGuid, sizeof(WICPixelFormatGUID) ) != 0 )
{
// Conversion required to write
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -718,7 +721,8 @@ static HRESULT _EncodeSingleFrame( _In_ const Image& image, _In_ DWORD flags,
return E_INVALIDARG;
// Initialize WIC
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -737,7 +741,7 @@ static HRESULT _EncodeSingleFrame( _In_ const Image& image, _In_ DWORD flags,
if ( FAILED(hr) )
return hr;
if ( memcmp( &containerFormat, &GUID_ContainerFormatBmp, sizeof(WICPixelFormatGUID) ) == 0 && _IsWIC2() )
if ( memcmp( &containerFormat, &GUID_ContainerFormatBmp, sizeof(WICPixelFormatGUID) ) == 0 && iswic2 )
{
// Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel
PROPBAG2 option = { 0 };
@ -780,7 +784,8 @@ static HRESULT _EncodeMultiframe( _In_reads_(nimages) const Image* images, _In_
return E_POINTER;
// Initialize WIC
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -850,7 +855,8 @@ HRESULT GetMetadataFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, Tex
return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE );
#endif
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -877,7 +883,7 @@ HRESULT GetMetadataFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, Tex
return hr;
// Get metadata
hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), metadata, 0 );
hr = _DecodeMetadata( flags, iswic2, decoder.Get(), frame.Get(), metadata, 0 );
if ( FAILED(hr) )
return hr;
@ -894,7 +900,8 @@ HRESULT GetMetadataFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata& metada
if ( !szFile )
return E_INVALIDARG;
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -910,7 +917,7 @@ HRESULT GetMetadataFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata& metada
return hr;
// Get metadata
hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), metadata, 0 );
hr = _DecodeMetadata( flags, iswic2, decoder.Get(), frame.Get(), metadata, 0 );
if ( FAILED(hr) )
return hr;
@ -932,7 +939,8 @@ HRESULT LoadFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadat
return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE );
#endif
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -962,7 +970,7 @@ HRESULT LoadFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadat
// Get metadata
TexMetadata mdata;
WICPixelFormatGUID convertGUID = {0};
hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), mdata, &convertGUID );
hr = _DecodeMetadata( flags, iswic2, decoder.Get(), frame.Get(), mdata, &convertGUID );
if ( FAILED(hr) )
return hr;
@ -997,7 +1005,8 @@ HRESULT LoadFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
if ( !szFile )
return E_INVALIDARG;
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -1017,7 +1026,7 @@ HRESULT LoadFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
// Get metadata
TexMetadata mdata;
WICPixelFormatGUID convertGUID = {0};
hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), mdata, &convertGUID );
hr = _DecodeMetadata( flags, iswic2, decoder.Get(), frame.Get(), mdata, &convertGUID );
if ( FAILED(hr) )
return hr;
@ -1158,7 +1167,8 @@ HRESULT SaveToWICFile( const Image& image, DWORD flags, REFGUID containerFormat,
if ( !image.pixels )
return E_POINTER;
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;
@ -1185,7 +1195,8 @@ HRESULT SaveToWICFile( const Image* images, size_t nimages, DWORD flags, REFGUID
if ( !szFile || !images || nimages == 0 )
return E_INVALIDARG;
IWICImagingFactory* pWIC = _GetWIC();
bool iswic2 = false;
IWICImagingFactory* pWIC = GetWICFactory(iswic2);
if ( !pWIC )
return E_NOINTERFACE;