I encountered a probem when I was using the WIC lib. And I found that I can't scale R32G32B32 images using IWICBitmapScaler... The code example shows below:
{
IWICImagingFactory* m_pWICFactory;
HRESULT hr = S_OK;
// Initialize COM
hr = CoInitialize(nullptr);
assert(SUCCEEDED(hr));
// Initialize Factory
hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory), (void**)&m_pWICFactory);
assert(SUCCEEDED(hr));
// 4x4 R32G32B32 image
XMFLOAT3 srcImg[] = { XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1),
XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1),
XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1),
XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), };
// 2x2 R32G32B32 image
XMFLOAT3 dstImg[4];
CComPtr<IWICBitmap> pSrcBitmap;
hr = m_pWICFactory->CreateBitmapFromMemory(4, 4, GUID_WICPixelFormat96bppRGBFloat, 4 * sizeof(XMFLOAT3),
4 * sizeof(XMFLOAT3)* 4, (BYTE*)srcImg, &pSrcBitmap);
IWICBitmapSource *pSrcBitmapSource = pSrcBitmap.p;
// scale to 2x2
CComPtr<IWICBitmapScaler> pScaler;
hr = m_pWICFactory->CreateBitmapScaler(&pScaler);
hr = pScaler->Initialize(pSrcBitmapSource, 2, 2, WICBitmapInterpolationModeFant);
pSrcBitmapSource = pScaler.p;
// copy back
WICRect rect = { 0, 0, 2, 2 };
hr = pSrcBitmapSource->CopyPixels(&rect, 2 * sizeof(XMFLOAT3), 2 * sizeof(XMFLOAT3)* 2, (BYTE*)dstImg);
}
And I just get -1.#QNAN000 in the dstImg buffer :( I'm not sure whether I did something wrong, or the IWICBitmapScaler just don't support such format?
Another ploblem is that when I use IWICFormatConverter to convert R32G32B32A32 (i.e. 128bppRGBFloat) images to R32Gray (i.e.32bppGrayFloat)format, it always clamp the value to [0, 1], is this a desired behavior? (Why???)
(My platform: Win 8.1 64bit + VS2013)
You are incorrectly assuming that the IWICBitmapScaler
always returns the data in the same pixel format as it's input. It does not. You have to call GetPixelFormat
to find out how the result is going to be formatted. Also, when working with a COM API you must be checking the HRESULT for every call that returns one to catch problems.
CComPtr<IWICBitmapScaler> pScaler;
hr = m_pWICFactory->CreateBitmapScaler(&pScaler);
if ( FAILED(hr) )
...
hr = pScaler->Initialize(pSrcBitmapSource, 2, 2, ICBitmapInterpolationModeFant);
if ( FAILED(hr) )
...
pSrcBitmapSource = pScaler.p;
WICPixelFormatGUID pfScaler;
hr = scaler->GetPixelFormat( &pfScaler );
if ( FAILED(hr) )
...
// In many cases, pfScaler will not be the same GUID as your pSrcBItmapSource.
You should take a look at DirctXTex for extensive examples of using WIC.