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);
}
Beispiel #2
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;
}
Beispiel #3
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);
	}