bool WICImageLoader::processImage(IWICBitmapDecoder* pDecoder)
{
    HRESULT hr = E_FAIL;
	IWICBitmapFrameDecode* pFrame = NULL;

	if(NULL != pDecoder)
	{
		hr = pDecoder->GetFrame(0, &pFrame);
	}

	if(SUCCEEDED(hr))
	{
		hr = pFrame->GetPixelFormat(&_format);
	}

	IWICFormatConverter* pConv = NULL;

	if(SUCCEEDED(hr))
	{
		hr = convertFormatIfRequired(pFrame, &pConv);
	}

	if(SUCCEEDED(hr))
	{
		_bpp = getBitsPerPixel(_format); 

		if(NULL != pConv) 
		{
			hr = pConv->GetSize((UINT*)&_width, (UINT*)&_height);
		}
		else
		{
			hr = pFrame->GetSize((UINT*)&_width, (UINT*)&_height);
		}
	}

	assert(_bpp > 0);
	assert(_width > 0 && _height > 0);

	if(SUCCEEDED(hr))
	{
		size_t rowPitch = (_width * _bpp + 7) / 8;
		_dataLen = rowPitch * _height;
		_data = new (std::nothrow) BYTE[_dataLen];

		if(NULL != pConv)
		{
			hr = pConv->CopyPixels(NULL, static_cast<UINT>(rowPitch), static_cast<UINT>(_dataLen), _data);
		}
		else
		{
			hr = pFrame->CopyPixels(NULL, static_cast<UINT>(rowPitch), static_cast<UINT>(_dataLen), _data);
		}
	}

	SafeRelease(&pFrame);
	SafeRelease(&pConv);
	return SUCCEEDED(hr);
}
Exemple #2
0
void GL::Image::load(const unsigned char *buf, size_t bufSize)
{
    if (CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK) {
        // bad!
        return;
    }
    IStream *stream = SHCreateMemStream((const BYTE*)buf, (UINT)bufSize);
    if (stream != NULL) {
        IWICImagingFactory *pFactory;
        if (CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pFactory) == S_OK) {
            IWICBitmapDecoder *pDecoder;
            if (pFactory->CreateDecoderFromStream(stream, &CLSID_WICPngDecoder, WICDecodeMetadataCacheOnDemand, &pDecoder) == S_OK) {
                IWICBitmapFrameDecode *frame;
                if (pDecoder->GetFrame(0, &frame) == S_OK) {
                    UINT w, h;
                    if (frame->GetSize(&w, &h) == S_OK) {
                        width_ = w;
                        height_ = h;
                    }
                    IWICFormatConverter *formatConverter;
                    if (pFactory->CreateFormatConverter(&formatConverter) == S_OK) {
                        if (formatConverter->Initialize(frame, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0, WICBitmapPaletteTypeCustom) == S_OK) {
                            unsigned char *pixels = new unsigned char[w * h * 4];
                            if (formatConverter->CopyPixels(0, w * 4, w * h * 4, pixels) == S_OK) {
                                loadTextureData_(pixels);
                            }
                            delete[] pixels;
                        }
                        formatConverter->Release();
                    }
                }
                pDecoder->Release();
            }
            pFactory->Release();
        }
        stream->Release();
    }
    CoUninitialize();
}
Exemple #3
0
//  解码照片的基础位图文件的.
HRESULT VideoEncoder::DecodeFrame(Photo* pPhoto, BYTE** ppOutputBitmap, int* pBitmapSize)
{
	HRESULT hr = S_OK;

	IWICBitmapDecoder *pDecoder  = nullptr;
	IWICBitmapFrameDecode *pFrame  = nullptr;
	IWICBitmap* pSourceBitmap = nullptr;
	IWICBitmapLock* pLock = nullptr;
	BYTE* pSourceBuffer = nullptr;
	BYTE* pDestinationBuffer = nullptr;
	UINT pixelWidth;
	UINT pixelHeight;
	WICRect lockRect;

	*ppOutputBitmap = nullptr;
		hr = m_pIWICFactory->CreateDecoderFromFilename(
		pPhoto->GetFile().c_str(),
		nullptr,
		GENERIC_READ,
		WICDecodeMetadataCacheOnDemand,
		&pDecoder
		);
	CheckHR(hr);
	this->m_logFileStream << "WIC解码器创建成功." << endl;
	GUID containerFormat;
	CheckHR(pDecoder->GetContainerFormat(&containerFormat));

	// 我们仅支持jpg 文件.
	if (containerFormat != GUID_ContainerFormatJpeg)
	{
		this->m_logFileStream << "仅支持jpeg文件." << endl;
		return E_NOTSUPPORTEDFORMAT;
	}

	// 我们仅支持jpg 文件. 因此只有一桢.
	CheckHR(pDecoder->GetFrame(0, &pFrame));

	// TODO: 目前我们需要所有照片有相同的大小.
	// 如果需求在将来发生变化,修改代码.
	pFrame->GetSize(&pixelWidth, &pixelHeight);
	if (pixelWidth != this->m_frameWidth || pixelHeight != this->m_frameHeight)
	{
		this->m_logFileStream << "所有的照片必须使用固定的大小." << endl;
		return E_IMAGESIZEINCORRECT;
	}

	// 创建源位图对象.
	CheckHR(this->m_pIWICFactory->CreateBitmapFromSource(pFrame, WICBitmapCacheOnLoad, &pSourceBitmap));
	this->m_logFileStream << "位图资源创建成功." << endl;

	lockRect.X = 0;
	lockRect.Y = 0;
	lockRect.Width = pixelWidth;
	lockRect.Height = pixelHeight;
	CheckHR(pSourceBitmap->Lock(&lockRect, WICBitmapLockWrite, &pLock));
	UINT sourceBufferSize;
	CheckHR(pLock->GetDataPointer(&sourceBufferSize, &pSourceBuffer));

	// Jpg BGR 位图转换 RGBA 格式.
	UINT destinationBufferSize = sourceBufferSize / 3 * 4;
	pDestinationBuffer = new BYTE[destinationBufferSize];
	for (UINT i = 0, j = 0; i < sourceBufferSize; i+=3, j+=4)
	{
		pDestinationBuffer[j] = pSourceBuffer[i]; // R
		pDestinationBuffer[j + 1] = pSourceBuffer[i + 1]; // G
		pDestinationBuffer[j + 2] = pSourceBuffer[i + 2]; // B
		pDestinationBuffer[j + 3] = 255; // A
	}

	*ppOutputBitmap = pDestinationBuffer;
	*pBitmapSize = destinationBufferSize;

cleanup:
	if (!SUCCEEDED(hr))
	{
		DWORD error = GetLastError();
		this->m_logFileStream << "意外错误: " << error << endl;
		this->m_logFileStream << "HResult是: " << hr << endl;
	}
	if (pSourceBuffer != nullptr)
	{
		// 删除pSourceBuffer;
	}
	SafeRelease(&pDecoder);
	SafeRelease(&pFrame);
	SafeRelease(&pSourceBitmap);
	SafeRelease(&pLock);

	return hr;
}
Exemple #4
0
HRESULT App::LoadResourceBitmap(
    ID2D1RenderTarget *pRenderTarget,
    IWICImagingFactory *pIWICFactory,
    PCWSTR resourceName,
    PCWSTR resourceType,
    UINT destinationWidth,
    UINT destinationHeight,
    ID2D1Bitmap **ppBitmap
    )
{
    IWICBitmapDecoder *pDecoder = NULL;
    IWICBitmapFrameDecode *pSource = NULL;
    IWICStream *pStream = NULL;
    IWICFormatConverter *pConverter = NULL;
    IWICBitmapScaler *pScaler = NULL;

    HRSRC imageResHandle = NULL;
    HGLOBAL imageResDataHandle = NULL;
    void *pImageFile = NULL;
    DWORD imageFileSize = 0;

    // Locate the resource.
    imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName, resourceType);
    HRESULT hr = imageResHandle ? S_OK : E_FAIL;
    if (SUCCEEDED(hr))
    {
        // Load the resource.
        imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle);

        hr = imageResDataHandle ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(hr))
    {
        // Lock it to get a system memory pointer.
        pImageFile = LockResource(imageResDataHandle);

        hr = pImageFile ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(hr))
    {
        // Calculate the size.
        imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);

        hr = imageFileSize ? S_OK : E_FAIL;
        
    }
    if (SUCCEEDED(hr))
    {
          // Create a WIC stream to map onto the memory.
        hr = pIWICFactory->CreateStream(&pStream);
    }
    if (SUCCEEDED(hr))
    {
        // Initialize the stream with the memory pointer and size.
        hr = pStream->InitializeFromMemory(
            reinterpret_cast<BYTE*>(pImageFile),
            imageFileSize
            );
    }
    if (SUCCEEDED(hr))
    {
        // Create a decoder for the stream.
        hr = pIWICFactory->CreateDecoderFromStream(
            pStream,
            NULL,
            WICDecodeMetadataCacheOnLoad,
            &pDecoder
            );
    }
    if (SUCCEEDED(hr))
    {
        // Create the initial frame.
        hr = pDecoder->GetFrame(0, &pSource);
    }
    if (SUCCEEDED(hr))
    {
        // Convert the image format to 32bppPBGRA
        // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
        hr = pIWICFactory->CreateFormatConverter(&pConverter);
    }
    if (SUCCEEDED(hr))
    {
        // If a new width or height was specified, create an
        // IWICBitmapScaler and use it to resize the image.
        if (destinationWidth != 0 || destinationHeight != 0)
        {
            UINT originalWidth, originalHeight;
            hr = pSource->GetSize(&originalWidth, &originalHeight);
            if (SUCCEEDED(hr))
            {
                if (destinationWidth == 0)
                {
                    FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
                    destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
                }
                else if (destinationHeight == 0)
                {
                    FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
                    destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
                }

                hr = pIWICFactory->CreateBitmapScaler(&pScaler);
                if (SUCCEEDED(hr))
                {
                    hr = pScaler->Initialize(
                            pSource,
                            destinationWidth,
                            destinationHeight,
                            WICBitmapInterpolationModeCubic
                            );
                    if (SUCCEEDED(hr))
                    {
                        hr = pConverter->Initialize(
                            pScaler,
                            GUID_WICPixelFormat32bppPBGRA,
                            WICBitmapDitherTypeNone,
                            NULL,
                            0.f,
                            WICBitmapPaletteTypeMedianCut
                            );
                    }
                }
            }
        }
        else
        {
                    
            hr = pConverter->Initialize(
                pSource,
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                NULL,
                0.f,
                WICBitmapPaletteTypeMedianCut
                );
        }
    }
    if (SUCCEEDED(hr))
    {
        //create a Direct2D bitmap from the WIC bitmap.
        hr = pRenderTarget->CreateBitmapFromWicBitmap(
            pConverter,
            NULL,
            ppBitmap
            );
    
    }

    SafeRelease(&pDecoder);
    SafeRelease(&pSource);
    SafeRelease(&pStream);
    SafeRelease(&pConverter);
    SafeRelease(&pScaler);

    return hr;
}
Exemple #5
0
unsigned char *BBWin8Game::LoadImageData( String path,int *pwidth,int *pheight,int *pformat ){

	if( !_wicFactory ){
		DXASS( CoCreateInstance( CLSID_WICImagingFactory,0,CLSCTX_INPROC_SERVER,__uuidof(IWICImagingFactory),(LPVOID*)&_wicFactory ) );
	}
	
	path=PathToFilePath( path );

	IWICBitmapDecoder *decoder;
	if( !SUCCEEDED( _wicFactory->CreateDecoderFromFilename( path.ToCString<wchar_t>(),NULL,GENERIC_READ,WICDecodeMetadataCacheOnDemand,&decoder ) ) ){
		return 0;
	}
	
	unsigned char *data=0;

	IWICBitmapFrameDecode *bitmapFrame;
	DXASS( decoder->GetFrame( 0,&bitmapFrame ) );
	
	UINT width,height;
	WICPixelFormatGUID pixelFormat;
	DXASS( bitmapFrame->GetSize( &width,&height ) );
	DXASS( bitmapFrame->GetPixelFormat( &pixelFormat ) );
			
	if( pixelFormat==GUID_WICPixelFormat24bppBGR ){
		unsigned char *t=(unsigned char*)malloc( width*3*height );
		DXASS( bitmapFrame->CopyPixels( 0,width*3,width*3*height,t ) );
		data=(unsigned char*)malloc( width*4*height );
		unsigned char *s=t,*d=data;
		int n=width*height;
		while( n-- ){
			*d++=s[2];
			*d++=s[1];
			*d++=s[0];
			*d++=0xff;
			s+=3;
		}
		free( t );
	}else if( pixelFormat==GUID_WICPixelFormat32bppBGRA ){
		unsigned char *t=(unsigned char*)malloc( width*4*height );
		DXASS( bitmapFrame->CopyPixels( 0,width*4,width*4*height,t ) );
		data=t;
		int n=width*height;
		while( n-- ){	//premultiply alpha
			unsigned char r=t[0];
			t[0]=t[2]*t[3]/255;
			t[1]=t[1]*t[3]/255;
			t[2]=r*t[3]/255;
			t+=4;
		}
	}
	
	if( data ){
		*pwidth=width;
		*pheight=height;
		*pformat=4;
	}
	
	bitmapFrame->Release();
	decoder->Release();
	
	gc_force_sweep=true;

	return data;
}
Exemple #6
0
HRESULT LoadBitmapFromFile(
	PCWSTR uri,
	UINT dweight,
	UINT dheight,
	ID2D1Bitmap **bitmap
	)
{
	HRESULT hr = S_OK;
	IWICImagingFactory* pWICFactory = NULL;
	IWICBitmapDecoder* pDecoder = NULL;
	IWICBitmapScaler* pScaler = NULL;
	IWICBitmapFrameDecode* pSource = NULL;
	IWICFormatConverter* pConverter = NULL;
	hr = CoCreateInstance(
		CLSID_WICImagingFactory,
		NULL,
		CLSCTX_INPROC_SERVER,
		IID_IWICImagingFactory,
		(LPVOID*)&pWICFactory);
	if (SUCCEEDED(hr))
	{
		hr = pWICFactory->CreateDecoderFromFilename(
			uri,
			NULL,
			GENERIC_READ,
			WICDecodeMetadataCacheOnLoad,
			&pDecoder);
	}
	if (SUCCEEDED(hr))
	{
		hr = pDecoder->GetFrame(0, &pSource);
	}
	if (SUCCEEDED(hr))
	{
		hr = pWICFactory->CreateFormatConverter(&pConverter);
	}
	if (SUCCEEDED(hr))
	{
		UINT oWeight, oHeight;
		hr = pSource->GetSize(&oWeight, &oHeight);
		if (SUCCEEDED(hr))
		{
			hr = pWICFactory->CreateBitmapScaler(&pScaler);
			if (SUCCEEDED(hr))
			{
				hr = pScaler->Initialize(
					pSource,
					dweight,
					dheight,
					WICBitmapInterpolationModeCubic);
			}

			if (SUCCEEDED(hr))
			{
				hr = pConverter->Initialize(
					pScaler,
					GUID_WICPixelFormat32bppPBGRA,
					WICBitmapDitherTypeNone,
					NULL,
					0.f,
					WICBitmapPaletteTypeMedianCut
					);
			}

		}
	}
	if (SUCCEEDED(hr))
	{
		hr = pRT->CreateBitmapFromWicBitmap(pConverter, bitmap);
	}
	Safe_Release(pWICFactory);
	Safe_Release(pDecoder);
	Safe_Release(pScaler);
	Safe_Release(pSource);
	Safe_Release(pConverter);
	return hr;
}
// Create a Direct2D bitmap from the specified file name
HRESULT DemoApp::LoadBitmapFromFile(
	ID2D1RenderTarget *pRenderTarget,
	IWICImagingFactory *pIWICFactory,
	PCWSTR uri,
	UINT destinationWidth,
	UINT destinationHeight,
	ID2D1Bitmap **ppBitmap)
{
	HRESULT hr = S_OK;

	IWICBitmapDecoder *pDecoder = NULL;
	IWICBitmapFrameDecode *pSource = NULL;
	IWICStream *pStream = NULL;
	IWICFormatConverter *pConverter = NULL;
	IWICBitmapScaler *pScaler = NULL;

	hr = pIWICFactory->CreateDecoderFromFilename(
		uri, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder);
	if (SUCCEEDED(hr))
	{
		// Create the initial frame
		hr = pDecoder->GetFrame(0, &pSource);
	}

	if (SUCCEEDED(hr))
	{
		// Convert the image format to 32bppPBGRA
		// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
		hr = pIWICFactory->CreateFormatConverter(&pConverter);
	}
	if (SUCCEEDED(hr))
	{
		// If a new width or height was specified, create an
		// IWICBitmapScaler and use it to resize the image.
		if (destinationWidth != 0 || destinationHeight != 0)
		{
			UINT originalWidth, originalHeight;
			hr = pSource->GetSize(&originalWidth, &originalHeight);
			if (SUCCEEDED(hr))
			{
				if (destinationWidth == 0)
				{
					FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
					destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
				}
				else if (destinationHeight == 0)
				{
					FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
					destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
				}

				hr = pIWICFactory->CreateBitmapScaler(&pScaler);
				if (SUCCEEDED(hr))
				{
					hr = pScaler->Initialize(
						pSource,
						destinationWidth,
						destinationHeight,
						WICBitmapInterpolationModeCubic);
				}
				if (SUCCEEDED(hr))
				{
					hr = pConverter->Initialize(
						pScaler,
						GUID_WICPixelFormat32bppPBGRA,
						WICBitmapDitherTypeNone,
						NULL,
						0.f,
						WICBitmapPaletteTypeMedianCut);
				}
			}
		}
		else // Don't scale the image.
		{
			hr = pConverter->Initialize(
				pSource,
				GUID_WICPixelFormat32bppPBGRA,
				WICBitmapDitherTypeNone,
				NULL,
				0.f,
				WICBitmapPaletteTypeMedianCut);
		}
	}
	if (SUCCEEDED(hr))
	{
		// Create a Direct2D bitmap from the WIC bitmap.
		hr = pRenderTarget->CreateBitmapFromWicBitmap(
			pConverter,
			NULL,
			ppBitmap);
	}

	SafeRelease(&pDecoder);
	SafeRelease(&pSource);
	SafeRelease(&pStream);
	SafeRelease(&pConverter);
	SafeRelease(&pScaler);

	return hr;
}
ID2D1Bitmap * BaseButton::LoadBitmap(wchar_t* sz_path)
{
	ID2D1Bitmap *p_bmp=NULL;
	IWICBitmapDecoder *pDecoder = NULL;
	IWICBitmapFrameDecode *pSource = NULL;
	IWICStream *pStream = NULL;
	IWICFormatConverter *pConverter = NULL;
	IWICBitmapScaler *pScaler = NULL;
	HRESULT hr;
	hr = g_pIWICFactory->CreateDecoderFromFilename(sz_path,NULL,GENERIC_READ,WICDecodeMetadataCacheOnLoad,&pDecoder);
	if (SUCCEEDED(hr))
	{
		// Create the initial frame.
		hr = pDecoder->GetFrame(0, &pSource);
	}
	
	if (SUCCEEDED(hr))
	{
		// Convert the image format to 32bppPBGRA
		// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
		hr = g_pIWICFactory->CreateFormatConverter(&pConverter);
	}
	if (SUCCEEDED(hr))
	{
		// If a new width or height was specified, create an
		// IWICBitmapScaler and use it to resize the image.
		UINT originalWidth, originalHeight;
		hr = pSource->GetSize(&originalWidth, &originalHeight);
	}
	if (SUCCEEDED(hr))
	{

		hr =g_pIWICFactory->CreateBitmapScaler(&pScaler);
	}
	if (SUCCEEDED(hr))
	{
		hr = pScaler->Initialize(pSource,50,30,WICBitmapInterpolationModeCubic);
	}
	if (SUCCEEDED(hr))
	{
		hr = pConverter->Initialize(pScaler,GUID_WICPixelFormat32bppPBGRA,WICBitmapDitherTypeNone,NULL,0.f,WICBitmapPaletteTypeMedianCut);
	}
	
	if (SUCCEEDED(hr))
	{
		// Create a Direct2D bitmap from the WIC bitmap.
		hr =m_pRenderTarget->CreateBitmapFromWicBitmap(pConverter,NULL,&p_bmp);
	}
	
	
	SafeRelease(&pDecoder);
	SafeRelease(&pSource);
	SafeRelease(&pStream);
	SafeRelease(&pConverter);
	SafeRelease(&pScaler);
// 	if (SUCCEEDED(hr))
// 	{
// 		return TRUE;
// 	}
// 	else
// 		return FALSE;
	return p_bmp;
}
Exemple #9
0
	bool Image::Initialize(wchar_t *filename, Graphics *graphics)
	{
		std::ifstream file;
		IWICImagingFactory *pWIC;
		IWICStream *stream;
		IWICBitmapDecoder *decoder;
		IWICBitmapFrameDecode *frame;
		unsigned int width, height, twidth, theight, maxsize, bpp, i, support, rowPitch, imageSize;
		float ratio;
		WICPixelFormatGUID pixelFormat;
		DXGI_FORMAT format;
		IWICComponentInfo *cinfo;
		IWICPixelFormatInfo *pfinfo;
		IWICBitmapScaler *scaler;
		bool autogen = false;
		D3D11_TEXTURE2D_DESC desc;
		D3D11_SUBRESOURCE_DATA initData;
		D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;

		file.open(filename, std::ios::in | std::ios::binary | std::ios::ate);
		if(!file.is_open()) return false;

		m_size = file.tellg();
		file.seekg(0, std::ios::beg);

		m_bytes = new unsigned char [m_size];
		file.read((char *)m_bytes, m_size);

		file.close();

		RETURN_FAIL( CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&pWIC ) );
		RETURN_FAIL( pWIC->CreateStream( &stream ) );
		RETURN_FAIL( stream->InitializeFromMemory( m_bytes, m_size ) );
		RETURN_FAIL( pWIC->CreateDecoderFromStream( stream, 0, WICDecodeMetadataCacheOnDemand, &decoder ) );
		RETURN_FAIL( decoder->GetFrame( 0, &frame ) );
		RETURN_FAIL( frame->GetSize( &width, &height ) );

		SAFE_RELEASE( stream );
		SAFE_RELEASE( decoder );

		if( width <= 0 || height <= 0 ) return false;

		maxsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;

		if( width > maxsize || height > maxsize )
		{
			ratio = static_cast<float>(height) / static_cast<float>(width);
			if(width > height)
			{
				twidth = maxsize;
				theight = static_cast<unsigned int>( static_cast<float>(maxsize) * ratio );
			}
			else
			{
				theight = maxsize;
				twidth = static_cast<unsigned int>( static_cast<float>(maxsize) / ratio );
			}
		}
		else
		{
			twidth = width;
			theight = height;
		}

		RETURN_FAIL( frame->GetPixelFormat( &pixelFormat ) );

		format = DXGI_FORMAT_UNKNOWN;
		for( i = 0; i < _countof(g_WICFormats); ++i )
		{
			if( memcmp( &g_WICFormats[i].wic, &pixelFormat, sizeof(GUID) )  == 0 )
			{
				format = g_WICFormats[i].dxgi;
				break;
			}
		}

		RETURN_FAIL( pWIC->CreateComponentInfo( pixelFormat, &cinfo ) );
		RETURN_FAIL( cinfo->QueryInterface( __uuidof(IWICPixelFormatInfo), (LPVOID*)&pfinfo ) );
		RETURN_FAIL( pfinfo->GetBitsPerPixel( &bpp ) );

		SAFE_RELEASE( cinfo );
		SAFE_RELEASE( pfinfo );

		RETURN_FAIL( graphics->GetDevice()->CheckFormatSupport( format, &support ) );
		if( !(support & D3D11_FORMAT_SUPPORT_TEXTURE2D) ) return false;

		rowPitch = ( twidth * bpp + 7 ) / 8;
		imageSize = rowPitch * theight;

		std::unique_ptr<uint8_t[]> temp( new (std::nothrow) uint8_t[ imageSize ] );
		if( !temp ) return false;

		if( twidth == width && theight == height )
		{
			RETURN_FAIL( frame->CopyPixels( 0, rowPitch, imageSize, temp.get() ) );
		}
		else
		{
			RETURN_FAIL( pWIC->CreateBitmapScaler( &scaler ) );
			RETURN_FAIL( scaler->Initialize( frame, twidth, theight, WICBitmapInterpolationModeFant ) );
			RETURN_FAIL( scaler->CopyPixels( 0, rowPitch, imageSize, temp.get() ) );
			SAFE_RELEASE( scaler );
		}

		SAFE_RELEASE( frame );

		if( support & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN )
		{
			autogen = true;
		}

		desc.Width = twidth;
		desc.Height = theight;
		desc.MipLevels = (autogen) ? 0 : 1;
		desc.ArraySize = 1;
		desc.Format = format;
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
		desc.Usage = D3D11_USAGE_DEFAULT;
		desc.CPUAccessFlags = 0;
		desc.BindFlags = (autogen) ? D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET : D3D11_BIND_SHADER_RESOURCE;
		desc.MiscFlags = (autogen) ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;

		initData.pSysMem = temp.get();
		initData.SysMemPitch = rowPitch;
		initData.SysMemSlicePitch = imageSize;

		RETURN_FAIL( graphics->GetDevice()->CreateTexture2D( &desc, (autogen) ? nullptr : &initData, &m_texture2D ) );

		//ZeroMemory( &SRVDesc, sizeof( SRVDesc ) );
		memset( &SRVDesc, 0, sizeof( SRVDesc ) );
		SRVDesc.Format = desc.Format;
		SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1;

		RETURN_FAIL( graphics->GetDevice()->CreateShaderResourceView( m_texture2D, &SRVDesc, &m_shaderResourceView ) );
		
		if( autogen )
		{
			graphics->GetContext()->UpdateSubresource( m_texture2D, 0, nullptr, temp.get(), rowPitch, imageSize );
			graphics->GetContext()->GenerateMips( m_shaderResourceView );
		}

		SAFE_RELEASE(pWIC);
	}
Exemple #10
0
HRESULT touchmind::Context::LoadResourceBitmap(ID2D1RenderTarget *pRenderTarget, IWICImagingFactory *pIWICFactory,
                                               PCWSTR resourceName, PCWSTR resourceType, UINT destinationWidth,
                                               UINT destinationHeight, ID2D1Bitmap **ppBitmap) {
#ifdef TOUCHMIND_CONTEXT_DEBUG
  LOG_ENTER;
#endif
  HRESULT hr = S_OK;
  IWICBitmapDecoder *pDecoder = nullptr;
  IWICBitmapFrameDecode *pSource = nullptr;
  IWICStream *pStream = nullptr;
  IWICFormatConverter *pConverter = nullptr;
  IWICBitmapScaler *pScaler = nullptr;

  HRSRC imageResHandle = nullptr;
  HGLOBAL imageResDataHandle = nullptr;
  void *pImageFile = nullptr;
  DWORD imageFileSize = 0;

  imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName, resourceType);
  hr = imageResHandle ? S_OK : E_FAIL;
  if (SUCCEEDED(hr)) {
    imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle);
    hr = imageResDataHandle ? S_OK : E_FAIL;
  }
  if (SUCCEEDED(hr)) {
    pImageFile = LockResource(imageResDataHandle);
    hr = pImageFile ? S_OK : E_FAIL;
  }
  if (SUCCEEDED(hr)) {
    imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);
    hr = imageFileSize ? S_OK : E_FAIL;
  }
  if (SUCCEEDED(hr)) {
    hr = pIWICFactory->CreateStream(&pStream);
#ifdef DEBUG_GPU_RESOURCE
    LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IWICStream = [" << std::hex << pStream << L"]" << std::dec;
#endif
  }
  if (SUCCEEDED(hr)) {
    hr = pStream->InitializeFromMemory(reinterpret_cast<BYTE *>(pImageFile), imageFileSize);
  }
  if (SUCCEEDED(hr)) {
    hr = pIWICFactory->CreateDecoderFromStream(pStream, nullptr, WICDecodeMetadataCacheOnLoad, &pDecoder);
#ifdef DEBUG_GPU_RESOURCE
    LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IWICBitmapDecoder = [" << std::hex << pDecoder << L"]" << std::dec;
#endif
  }
  if (SUCCEEDED(hr)) {
    hr = pDecoder->GetFrame(0, &pSource);
  }
  if (SUCCEEDED(hr)) {
    hr = pIWICFactory->CreateFormatConverter(&pConverter);
#ifdef DEBUG_GPU_RESOURCE
    LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IWICFormatConverter = [" << std::hex << pConverter << L"]" << std::dec;
#endif
  }
  if (SUCCEEDED(hr)) {
    if (destinationWidth != 0 || destinationHeight != 0) {
      UINT originalWidth, originalHeight;
      hr = pSource->GetSize(&originalWidth, &originalHeight);
      if (SUCCEEDED(hr)) {
        if (destinationWidth == 0) {
          FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
          destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
        } else if (destinationHeight == 0) {
          FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
          destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
        }

        hr = pIWICFactory->CreateBitmapScaler(&pScaler);
#ifdef DEBUG_GPU_RESOURCE
        LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IWICBitmapScaler = [" << std::hex << pScaler << L"]" << std::dec;
#endif
        if (SUCCEEDED(hr)) {
          hr = pScaler->Initialize(pSource, destinationWidth, destinationHeight, WICBitmapInterpolationModeCubic);
          if (SUCCEEDED(hr)) {
            hr = pConverter->Initialize(pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.f,
                                        WICBitmapPaletteTypeMedianCut);
          }
        }
      }
    } else {
      hr = pConverter->Initialize(pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.f,
                                  WICBitmapPaletteTypeMedianCut);
    }
  }
  if (SUCCEEDED(hr)) {
    hr = pRenderTarget->CreateBitmapFromWicBitmap(pConverter, nullptr, ppBitmap);
#ifdef DEBUG_OUTPUT_GPU_RESOURCE
    LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] ID2D1Bitmap = [" << std::hex << *ppBitmap << L"]" << std::dec;
#endif
  }

  SafeRelease(&pDecoder);
  SafeRelease(&pSource);
  SafeRelease(&pStream);
  SafeRelease(&pConverter);
  SafeRelease(&pScaler);

#ifdef TOUCHMIND_CONTEXT_DEBUG
  LOG_LEAVE_HRESULT(hr);
#endif
  return hr;
}
Exemple #11
0
ID2D1Bitmap* d2d::CreateBitmapFromResource(int idPic, int destinationWidth, int destinationHeight)
{
    // Locate the resource.
    HRSRC imageResHandle = FindResource(NULL, MAKEINTRESOURCE(idPic), L"PNG");
    if (imageResHandle == nullptr)
    {
        return nullptr;
    }

    // Load the resource.
    HGLOBAL imageResDataHandle = LoadResource(NULL, imageResHandle);
    //If hModule is NULL, the system loads the resource from the module that was used to create the current process

    HRESULT hr = imageResDataHandle ? S_OK : E_FAIL;
    if (FAILED(hr))
    {
        return nullptr;
    }

    // Lock it to get a system memory pointer.
    void* pImageFile = LockResource(imageResDataHandle);
    if (pImageFile == nullptr)
    {
        return nullptr;
    }
        
    // Calculate the size.
    DWORD imageFileSize = SizeofResource(NULL, imageResHandle);
    if (imageFileSize == 0)
    {
        return nullptr;
    }
    
    // Create a WIC stream to map onto the memory.
    IWICStream *pStream = nullptr;

    hr = m_pWICFactory->CreateStream(&pStream);
    if (FAILED(hr))
    {
        return nullptr;
    }
        
    // Initialize the stream with the memory pointer and size.
    hr = pStream->InitializeFromMemory(reinterpret_cast<BYTE*>(pImageFile), imageFileSize);
    if (FAILED(hr))
    {
        return nullptr;
    }
    
    // Create a decoder for the stream.
    IWICBitmapDecoder *pDecoder = nullptr;

    hr = m_pWICFactory->CreateDecoderFromStream(pStream, NULL, WICDecodeMetadataCacheOnLoad, &pDecoder);
    if (FAILED(hr))
    {
        return nullptr;
    }
    
    // Create the initial frame.
    IWICBitmapFrameDecode *pSource = nullptr;

    hr = pDecoder->GetFrame(0, &pSource);
    if (FAILED(hr))
    {
        return nullptr;
    }

    // Convert the image format to 32bppPBGRA
    // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
    IWICFormatConverter *pConverter = NULL;

    hr = m_pWICFactory->CreateFormatConverter(&pConverter);
    if (FAILED(hr))
    {
        return nullptr;
    }

    // If a new width or height was specified, create an
    // IWICBitmapScaler and use it to resize the image.
    if (destinationWidth != 0 || destinationHeight != 0)
    {
        UINT originalWidth, originalHeight;
        hr = pSource->GetSize(&originalWidth, &originalHeight);
        if (SUCCEEDED(hr))
        {
            if (destinationWidth == 0)
            {
                FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
                destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
            }
            else if (destinationHeight == 0)
            {
                FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
                destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
            }

            IWICBitmapScaler *pScaler = nullptr;

            hr = m_pWICFactory->CreateBitmapScaler(&pScaler);
            if (SUCCEEDED(hr))
            {
                hr = pScaler->Initialize(pSource,destinationWidth,destinationHeight,WICBitmapInterpolationModeCubic);
                if (SUCCEEDED(hr))
                {
                    hr = pConverter->Initialize(pScaler,GUID_WICPixelFormat32bppPBGRA,WICBitmapDitherTypeNone,NULL,0.f,WICBitmapPaletteTypeMedianCut);
                }
            }
            SafeRelease(pScaler);
        }
    }
    else
    {
        hr = pConverter->Initialize(pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut);
    }
    if (FAILED(hr))
    {
        return nullptr;
    }

    //create a Direct2D bitmap from the WIC bitmap.
    ID2D1Bitmap* resBitmap = nullptr;

    hr = m_pRenderTarget->CreateBitmapFromWicBitmap(pConverter, NULL, &resBitmap);
    if (FAILED(hr) || resBitmap == nullptr)
    {
        return nullptr;
    }

    SafeRelease(pDecoder);
    SafeRelease(pSource);
    SafeRelease(pStream);
    SafeRelease(pConverter);

    pokerlog << "CreateBitmapFromResource " << idPic << " OK." << endl;
    return resBitmap;
}
Exemple #12
0
void LoadJPG(wchar_t *pwszJpg, HWND hwnd)
{
    IWICImagingFactory *pFactory = NULL;
    HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFactory));
    if (SUCCEEDED(hr)) {
        IWICBitmapDecoder *pDecoder = NULL;
        hr = pFactory->CreateDecoderFromFilename(pwszJpg, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder);
        if (SUCCEEDED(hr)) {
            IWICBitmapFrameDecode *pIDecoderFrame = NULL;
            hr = pDecoder->GetFrame(0, &pIDecoderFrame);
            if (SUCCEEDED(hr)) {
                IWICFormatConverter *pFC = NULL;
                hr = pFactory->CreateFormatConverter(&pFC);
                hr = pFC->Initialize(pIDecoderFrame, GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom);

                const int nBytesPixel = 3; // GUID_WICPixelFormat24bppBGR 每像素3字节(24bits)

                BITMAPINFO bmpInfo;
                ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
                bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                hr = pIDecoderFrame->GetSize((UINT*)&bmpInfo.bmiHeader.biWidth, (UINT*)&bmpInfo.bmiHeader.biHeight);
                bmpInfo.bmiHeader.biPlanes = 1;
                bmpInfo.bmiHeader.biBitCount = 8 * nBytesPixel;
                bmpInfo.bmiHeader.biCompression = BI_RGB;

                BYTE *pBuf = NULL;
                HDC hdc = GetDC(hwnd);
                bmpInfo.bmiHeader.biHeight *= -1; // BMP 方向调整
                HBITMAP hBmp = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, (void**)&pBuf, NULL, 0);
                bmpInfo.bmiHeader.biHeight *= -1;

                // 计算扫描线
                unsigned int cbStride = nBytesPixel * bmpInfo.bmiHeader.biWidth;
                unsigned int total = cbStride*bmpInfo.bmiHeader.biHeight;
                hr = pFC->CopyPixels(NULL, cbStride, total, pBuf);

                // HSL色彩空间变换
                DirectX::XMVECTORF32 colorTransofrom = { 1.0f, 1.0f, 1.0f, 1.0f };

                if (SUCCEEDED(hr)) {
                    for (int i = 0; i < bmpInfo.bmiHeader.biHeight; i++) {
                        for (int j = 0; j < bmpInfo.bmiHeader.biWidth; j++) {
                            BYTE *pColor = pBuf + cbStride*i + j * nBytesPixel;

                            DirectX::XMVECTOR colorM = DirectX::PackedVector::XMLoadUByteN4((DirectX::PackedVector::XMUBYTEN4*)pColor);
                            colorM = DirectX::XMColorRGBToHSL(colorM);
                            colorM = DirectX::XMColorModulate(colorM, colorTransofrom);
                            colorM = DirectX::XMColorHSLToRGB(colorM);
                            DirectX::PackedVector::XMStoreUByteN4((DirectX::PackedVector::XMUBYTEN4*)pColor, colorM);

                            SetPixel(hdc, j, i, RGB(pColor[2], pColor[1], pColor[0]));
                        }
                    }
                }

                ReleaseDC(hwnd, hdc);

                if (SUCCEEDED(hr)) {
                    MakeMemDC(hBmp, hwnd);
                    InvalidateRect(hwnd, NULL, TRUE);
                }

                hr = pFC->Release();
                pIDecoderFrame->Release();
            }
            pDecoder->Release();
        }

        pFactory->Release();
    }
}
Exemple #13
0
HRESULT LoadResourceBitmap(
	ID2D1RenderTarget* pRendertarget,
	IWICImagingFactory* pIWICFactory,
	PCWSTR resourceName,
	PCWSTR resourceType,
	UINT destinationWidth,
	UINT destinationHeight,
	ID2D1Bitmap** ppBitmap
	)
{
	HRESULT hr = S_OK;

	IWICBitmapDecoder* pDecoder = NULL;
	IWICBitmapFrameDecode* pSource = NULL;
	IWICStream* pStream = NULL;
	IWICFormatConverter* pConverter = NULL;
	IWICBitmapScaler* pScaler = NULL;

	HRSRC imageResHandle = NULL;
	HGLOBAL imageResDataHandle = NULL;
	void* pImageFile = NULL;
	DWORD imageFileSize = 0;

	// Find the resource then load it
	imageResHandle = FindResource(HINST_THISCOMPONENT, resourceName, resourceType);
	hr = imageResHandle ? S_OK : E_FAIL;
	if (SUCCEEDED(hr))
	{
		imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle);

		hr = imageResDataHandle ? S_OK : E_FAIL;
	}

	// Lock the resource and calculate the image's size
	if (SUCCEEDED(hr))
	{
		// Lock it to get the system memory pointer
		pImageFile = LockResource(imageResDataHandle);

		hr = pImageFile ? S_OK : E_FAIL;
	}
	if (SUCCEEDED(hr))
	{
		// Calculate the size
		imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);

		hr = imageFileSize ? S_OK : E_FAIL;
	}

	// Create an IWICStream object
	if (SUCCEEDED(hr))
	{
		// Create a WIC stream to map onto the memory
		hr = pIWICFactory->CreateStream(&pStream);
	}

	if (SUCCEEDED(hr))
	{
		// Initialize the stream with the memory pointer and size
		hr = pStream->InitializeFromMemory(
			reinterpret_cast<BYTE*>(pImageFile),
			imageFileSize
			);
	}

	// Create IWICBitmapDecoder
	if (SUCCEEDED(hr))
	{
		// Create a decoder for the stream
		hr = pIWICFactory->CreateDecoderFromStream(
			pStream,
			NULL,
			WICDecodeMetadataCacheOnLoad,
			&pDecoder
			);
	}

	// Retrieve a frame from the image and store it in an IWICBitmapFrameDecode object
	if (SUCCEEDED(hr))
	{
		// Create the initial frame
		hr = pDecoder->GetFrame(0, &pSource);
	}

	// Before Direct2D can use the image, it must be converted to the 32bppPBGRA pixel format.
	// To convert the image format, use the IWICImagingFactory::CreateFormatConverter method to create an IWICFormatConverter object, then use the IWICFormatConverter object's Initialize method to perform the conversion.
	if (SUCCEEDED(hr))
	{
		// Convert the image format to 32bppPBGRA
		// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
		hr = pIWICFactory->CreateFormatConverter(&pConverter);
	}

	if (SUCCEEDED(hr))
	{
		// If a new width or height was specified, create and
		// IWICBitmapScaler and use it to resize the image.
		if (destinationWidth != 0 || destinationHeight != 0)
		{
			UINT originalWidth;
			UINT originalHeight;
			hr = pSource->GetSize(&originalWidth, &originalHeight);
			if (SUCCEEDED(hr))
			{
				if (destinationWidth == 0)
				{
					FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
					destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
				}
				else if (destinationHeight == 0)
				{
					FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
					destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
				}

				hr = pIWICFactory->CreateBitmapScaler(&pScaler);
				if (SUCCEEDED(hr))
				{
					hr = pScaler->Initialize(
						pSource,
						destinationWidth,
						destinationHeight,
						WICBitmapInterpolationModeCubic
						);
					if (SUCCEEDED(hr))
					{
						hr = pConverter->Initialize(
							pScaler,
							GUID_WICPixelFormat32bppPBGRA,
							WICBitmapDitherTypeNone,
							NULL,
							0.f,
							WICBitmapPaletteTypeMedianCut
							);
					}
				}
			}
		}

		else // use default width and height
		{
			hr = pConverter->Initialize(
				pSource,
				GUID_WICPixelFormat32bppPBGRA,
				WICBitmapDitherTypeNone,
				NULL,
				0.f,
				WICBitmapPaletteTypeMedianCut
				);
		}
	}

	// Finally, Create an ID2D1Bitmap object, that can be drawn by a render target and used with other Direct2D objects
	if (SUCCEEDED(hr))
	{
		// Create a Direct2D bitmap from the WIC bitmap
		hr = pRendertarget->CreateBitmapFromWicBitmap(
			pConverter,
			NULL,
			ppBitmap
			);
	}

	SAFE_RELEASE(pDecoder);
	SAFE_RELEASE(pSource);
	SAFE_RELEASE(pStream);
	SAFE_RELEASE(pConverter);
	SAFE_RELEASE(pScaler);

	return hr;
}
Exemple #14
0
// 从文件读取位图
HRESULT ImageRenderer::LoadBitmapFromFile(
    ID2D1DeviceContext *pRenderTarget,
    IWICImagingFactory2 *pIWICFactory,
    PCWSTR uri,
    UINT width,
    UINT height,
    ID2D1Bitmap1 **ppBitmap
    ){
    IWICBitmapDecoder *pDecoder = nullptr;
    IWICBitmapFrameDecode *pSource = nullptr;
    IWICStream *pStream = nullptr;
    IWICFormatConverter *pConverter = nullptr;
    IWICBitmapScaler *pScaler = nullptr;

    HRESULT hr = pIWICFactory->CreateDecoderFromFilename(
        uri,
        nullptr,
        GENERIC_READ,
        WICDecodeMetadataCacheOnLoad,
        &pDecoder
        );

    if (SUCCEEDED(hr)) {
        hr = pDecoder->GetFrame(0, &pSource);
    }
    if (SUCCEEDED(hr)) {
        hr = pIWICFactory->CreateFormatConverter(&pConverter);
    }


    if (SUCCEEDED(hr)) {
        if (width != 0 || height != 0) {
            UINT originalWidth, originalHeight;
            hr = pSource->GetSize(&originalWidth, &originalHeight);
            if (SUCCEEDED(hr)) {
                if (width == 0) {
                    FLOAT scalar = static_cast<FLOAT>(height) / static_cast<FLOAT>(originalHeight);
                    width = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
                }
                else if (height == 0) {
                    FLOAT scalar = static_cast<FLOAT>(width) / static_cast<FLOAT>(originalWidth);
                    height = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
                }

                hr = pIWICFactory->CreateBitmapScaler(&pScaler);
                if (SUCCEEDED(hr)) {
                    hr = pScaler->Initialize(
                        pSource,
                        width,
                        height,
                        WICBitmapInterpolationModeCubic
                        );
                }
                if (SUCCEEDED(hr))  {
                    hr = pConverter->Initialize(
                        pScaler,
                        GUID_WICPixelFormat32bppPBGRA,
                        WICBitmapDitherTypeNone,
                        nullptr,
                        0.f,
                        WICBitmapPaletteTypeMedianCut
                        );
                }
            }
        }
        else {
            hr = pConverter->Initialize(
                pSource,
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                nullptr,
                0.f,
                WICBitmapPaletteTypeMedianCut
                );
        }
    }
    if (SUCCEEDED(hr))  {
        hr = pRenderTarget->CreateBitmapFromWicBitmap(
            pConverter,
            nullptr,
            ppBitmap
            );
    }

    ::SafeRelease(pDecoder);
    ::SafeRelease(pSource);
    ::SafeRelease(pStream);
    ::SafeRelease(pConverter);
    ::SafeRelease(pScaler);

    return hr;
}