I came across this example and couldn't figure out how to change stream->InitializeFromFilename
to something that outputs to STDOUT, inside the HRESULT SavePixelsToFile32bppPBGRA(UINT width, UINT height, UINT stride, LPBYTE pixels, LPWSTR filePath, const GUID &format)
function. Tried using stream->InitializeFromMemory
but hit a wall due to minimal C++ experience.
Reasons behind this is that i'm building something and would like to pipe the stdout of the example using something else.
Thanks to @SimonMourier, I was able to update his code to achieve what was needed.
SavePixelsToFile32bppPBGRA now writes the data to an IStream pointer, streamOut. It also invokes a new function at the end, to output data.
HRESULT SavePixelsToFile32bppPBGRA(UINT width, UINT height, UINT stride, LPBYTE pixels, const GUID& format)
{
if (!pixels)
return E_INVALIDARG;
HRESULT hr = S_OK;
IWICImagingFactory* factory = nullptr;
IWICBitmapEncoder* encoder = nullptr;
IWICBitmapFrameEncode* frame = nullptr;
IWICStream* streamOut = nullptr;
IStream * streamIn = nullptr;
GUID pf = GUID_WICPixelFormat32bppPBGRA;
BOOL coInit = CoInitialize(nullptr);
HRCHECK(CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory)));
HRCHECK(factory->CreateStream(&streamOut));
HRCHECK(CreateStreamOnHGlobal(NULL, true, &streamIn));
HRCHECK(streamOut->InitializeFromIStream(streamIn));
HRCHECK(factory->CreateEncoder(format, nullptr, &encoder));
HRCHECK(encoder->Initialize(streamOut, WICBitmapEncoderNoCache));
HRCHECK(encoder->CreateNewFrame(&frame, nullptr)); // we don't use options here
HRCHECK(frame->Initialize(nullptr)); // we dont' use any options here
HRCHECK(frame->SetSize(width, height));
HRCHECK(frame->SetPixelFormat(&pf));
HRCHECK(frame->WritePixels(height, stride, stride * height, pixels));
HRCHECK(frame->Commit());
HRCHECK(encoder->Commit());
sendIStreamToOutput(streamOut);
cleanup:
RELEASE(streamIn);
RELEASE(streamOut);
RELEASE(frame);
RELEASE(encoder);
RELEASE(factory);
if (coInit) CoUninitialize();
return hr;
}
sendIStreamToOutput reads the data from the IStream and writes it to std::cout (with binary mode active).
void sendIStreamToOutput (IStream * pIStream) {
STATSTG sts;
pIStream->Stat(&sts, STATFLAG_DEFAULT);
ULARGE_INTEGER uli = sts.cbSize;
LARGE_INTEGER zero;
zero.QuadPart = 0;
ULONG size = (ULONG)uli.QuadPart;
char* bits = new char[size];
ULONG written;
pIStream->Seek(zero, STREAM_SEEK_SET, NULL);
pIStream->Read(bits, size, &written);
std::ostream& lhs = std::cout;
_setmode(_fileno(stdout), _O_BINARY);
lhs.write(bits, size);
fflush(stdout);
delete[] bits;
}