Memory Buffer into GDI+ Image(FromStream)

I have the following code that loads a bitmap file from a zip file (using Zip Utils) and copies the memory buffer into a HGblobal, so that it can be loaded into a GDI+ Image object from a Stream.
The code compiles fine - however the bitmap is corrupt. Am I using the correct methods here?

Appreciate any thoughts or suggestions.
void CASI::LoadResources(std::wstring strFolder)
{
	std::wstring strPath; 
	HGLOBAL hBuffer;
 
	strPath = strFolder + L"ASI.zip";
	HZIP hz = OpenZip(strPath.c_str(),0);
	ZIPENTRY ze; int i; FindZipItem(hz,L"background.bmp",true,&i,&ze);
	char *ibuf = new char[ze.unc_size];
	hBuffer = ::GlobalAlloc(GMEM_MOVEABLE,ze.unc_size);
	UnzipItem(hz, i, ibuf, ze.unc_size);
 
	if(hBuffer)
	{
		void* pBuffer = ::GlobalLock(hBuffer);
		if(pBuffer)
		{
			CopyMemory(pBuffer, ibuf, ze.unc_size);
			IStream* pStream = NULL;
 
			if(::CreateStreamOnHGlobal(hBuffer,FALSE,&pStream) == S_OK)
			{
				m_BackImage = Gdiplus::Image::FromStream(pStream,false);
				pStream->Release();
				if(m_BackImage)
				{
					if(m_BackImage->GetLastStatus() == Ok)
					{
						::GlobalUnlock(hBuffer);
						::GlobalFree(hBuffer);
					}
				}
			}
			::GlobalUnlock(hBuffer);
		}
		::GlobalFree(hBuffer);          
	}
	delete[] ibuf;
	CloseZip(hz); 
}

Open in new window

M204Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

JohnGabyCommented:
I don't think that you cannot free the memory block until you delete the Image object.  I believe that you can specify that the memory block be free'd on the last release of the storage, however.
JohnGabyCommented:
Make that 'I don't think you CAN free the memory block...'
jkrCommented:
Your code seems to be pretty identical to http://www.codeproject.com/KB/GDI-plus/cgdiplusbitmap.aspx - are you sure the bitmap format in the memory buffer is correct? If that is a plain .bmp file, this is quite unlikely to work.
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

JohnGabyCommented:
It is not identical.  On success, the code to which you refer returns without deleting the HGLOBAL memory block.  He is deleting the block before he returns.  I do not believe that you can do that.  Gdiplus does not keep a copy of the image in memory, and therefore needs the stream for the life of the object.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
M204Author Commented:
Many thanks for your help - this works great now.
Andrew
JohnGabyCommented:
By the way, Gdiplus can read .jpg and .png files as well.  You might want to simply convert your .bmp file to one of those formats before you put it in the resource.  This would let you avoid the need to zip the file, and would reduce the size of the memory block you would need to allocate.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.