I’m trying to copy some binary data from my IStream instance (since Gdiplus::Image only saves to IStream-deriving objects, or a file path) to a char pointer from which I can read simply by knowing the allocated binary size and have access to the pointer.
My class is as follows:
Upload::Upload(Gdiplus::Bitmap* bitmap, CLSID clsEncoderId)
{
int result;
STATSTG statResult;
result = CreateStreamOnHGlobal(0, TRUE, &m_hBufferStream);
if (result != S_OK)
MessageBoxW(NULL, _T("Upload::Upload(): Could not create stream"), _T("Point"), MB_OK | MB_ICONERROR);
else
{
if (bitmap->Save(m_hBufferStream, &clsEncoderId, NULL) != Gdiplus::Ok)
MessageBoxW(NULL, _T("Upload::Upload(): Could not save() image"), _T("Point"), MB_OK | MB_ICONERROR);
}
if (m_hBufferStream->Stat(&statResult, STATFLAG_NONAME) != S_OK)
return;
Gdiplus::Image test(m_hBufferStream, TRUE);
test.Save(_T("hejs.png"), &clsEncoderId, NULL);
m_iSize = statResult.cbSize.LowPart;
}
char* Upload::GetBinaryData()
{
char* buffer = (char*)malloc(m_iSize);
ULONG size = 0;
m_hBufferStream->Read(buffer, m_iSize, &size);
return buffer;
}
In my function that processes the Upload instance I do this:
char* pBuffer = upload->GetBinaryData();
buffer.write(pBuffer, upload->GetSize());
But the memory stored is wrong (oddly it seems like a pattern though).
What am I doing wrong?
Thanks in advance.
P.S.:
The test Image-instance successfully saves to the file after reading from m_hBufferStream.
First of all,
IStream::Read()is not required to read exactly the specified number of bytes – it is required to read no more than that number. Actual number is stored inside the veriable pointed to by the third parameter.Second, you don’t check the
HRESULTreturned byRead().A much better strategy would be to call
Read()in a loop, check its return value and adjust the pointer to the buffer according to how many bytes have been actually read.