#include "Sdk.h"
#include "RcUtils.h"
#include "DllMgr.h"
BOOL
BitmapFromPNGResource(UINT pngResourceID,
HBITMAP *phbm
) {
HMODULE hinst = DllMgr_GetObject()->Instance;
HRSRC hResource = NULL;
HGLOBAL hImage = NULL;
LPVOID pImage = NULL;
DWORD dwSize = 0;
HGLOBAL gbuf = NULL;
LPVOID buf = NULL;
HRESULT hr = S_FALSE;
IStream* pStream = NULL;
IWICBitmapDecoder* pwicDecoder = NULL;
IWICBitmapSource* pwicBitmap = NULL;
IWICBitmapFrameDecode* pwicFrame = NULL;
IWICBitmapSource* pwicBitmapSource = NULL;
UINT nFrameCount = 0;
UINT bmpWidth = 0;
UINT bmpHeight = 0;
BITMAPINFO bminfo = {0};
HDC hdcScreen = NULL;
void* pvImageBits = NULL;
UINT cbStride = 0;
UINT cbImage = 0;
HBITMAP hbm = NULL;
BOOL Result = FALSE;
__try {
if(phbm == NULL) {
__leave;
}
*phbm = NULL;
// RC stuff
hResource = FindResourceW(hinst,
MAKEINTRESOURCE(pngResourceID),
L"PNG"
);
if(hResource == NULL) {
__leave;
}
hImage = LoadResource(hinst, hResource);
if(hImage == NULL) {
__leave;
}
pImage = LockResource(hImage);
if(pImage == NULL) {
__leave;
}
dwSize = SizeofResource(hinst, hResource);
if(dwSize == 0) {
__leave;
}
gbuf = GlobalAlloc(GMEM_MOVEABLE, dwSize);
if(gbuf == NULL) {
__leave;
}
buf = GlobalLock(gbuf);
if(buf == NULL) {
__leave;
}
memmove(buf, pImage, dwSize);
hr = CreateStreamOnHGlobal(gbuf, FALSE, &pStream);
if(hr != S_OK) {
__leave;
}
// we have IStream; decoder stuff
hr = CoCreateInstance(&CLSID_WICPngDecoder,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IWICBitmapDecoder,
(void **)&pwicDecoder
);
if(pwicDecoder == NULL) {
__leave;
}
hr = IWICBitmapDecoder_Initialize(pwicDecoder,
pStream,
WICDecodeMetadataCacheOnLoad
);
if(FAILED(hr)) {
__leave;
}
nFrameCount = 0;
hr = IWICBitmapDecoder_GetFrameCount(pwicDecoder,
&nFrameCount
);
if(FAILED(hr)) {
__leave;
}
if(nFrameCount != 1) {
__leave;
}
hr = IWICBitmapDecoder_GetFrame(pwicDecoder,
0,
&pwicFrame
);
if(pwicFrame == NULL) {
__leave;
}
hr = IWICBitmapFrameDecode_QueryInterface(pwicFrame,
&IID_IWICBitmapSource,
(void **)&pwicBitmapSource
);
if(pwicBitmapSource == NULL) {
__leave;
}
hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppPBGRA,
pwicBitmapSource,
&pwicBitmap
);
if(FAILED(hr)) {
__leave;
}
// ok, we get IWICBitmapSource
bmpWidth = 0;
bmpHeight = 0;
hr = IWICBitmapSource_GetSize(pwicBitmap,
&bmpWidth,
&bmpHeight
);
if(FAILED(hr)) {
__leave;
}
if(bmpWidth == 0 || bmpHeight == 0) {
__leave;
}
memset(&bminfo, 0, sizeof(bminfo));
bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bminfo.bmiHeader.biWidth = bmpWidth;
bminfo.bmiHeader.biHeight = -((LONG)bmpHeight);
bminfo.bmiHeader.biPlanes = 1;
bminfo.bmiHeader.biBitCount = 32;
bminfo.bmiHeader.biCompression = BI_RGB;
hdcScreen = GetDC(NULL);
if(hdcScreen == NULL) {
__leave;
}
hbm = CreateDIBSection(hdcScreen,
&bminfo,
DIB_RGB_COLORS,
&pvImageBits,
NULL,
0
);
if(hbm == NULL) {
__leave;
}
cbStride = bmpWidth * 4;
cbImage = cbStride * bmpHeight;
hr = IWICBitmapSource_CopyPixels(pwicBitmap,
NULL,
cbStride,
cbImage,
(BYTE *)pvImageBits
);
if(FAILED(hr)) {
__leave;
}
*phbm = hbm;
Result = TRUE;
}
__finally {
if(hdcScreen != NULL) {
ReleaseDC(NULL, hdcScreen);
}
if(pwicBitmapSource != NULL) {
IWICBitmapSource_Release(pwicBitmapSource);
}
if(pwicFrame != NULL) {
IWICBitmapFrameDecode_Release(pwicFrame);
}
if(pwicDecoder != NULL) {
IWICBitmapDecoder_Release(pwicDecoder);
}
if(pwicBitmap != NULL) {
IWICBitmapSource_Release(pwicBitmap);
}
if(pStream != NULL) {
IStream_Release(pStream);
}
if(buf != NULL) {
GlobalUnlock(buf);
}
if(gbuf != NULL) {
GlobalFree(gbuf);
}
}
return Result;
}
static
const int kReadFileChunk = 16384;
BOOL
BitmapFromJPGFile(
LPCWSTR JPGFile,
HBITMAP *phbm,
IPicture **ppPicture
) {
HANDLE hJpgFile = NULL;
DWORD dwSize = 0;
HGLOBAL gbuf = NULL;
LPBYTE buf = NULL;
DWORD cbToRead = 0;
DWORD cbBytesRead = 0;
DWORD cbJpgSize = 0;
HRESULT hr = S_FALSE;
IStream* pStream = NULL;
HBITMAP hbm = NULL;
IPicture *pPicture = NULL;
SHORT picType = PICTYPE_UNINITIALIZED;
HDC hdcScreen = NULL;
HDC hdcMem = NULL;
// HBITMAP hbmMem = NULL;
// HBITMAP hbmMemOld = NULL;
// OLE_XSIZE_HIMETRIC cx = 0;
// OLE_XSIZE_HIMETRIC cy = 0;
// int nWidth = 0;
// int nHeight = 0;
BOOL Result = FALSE;
__try {
if(JPGFile == NULL) {
__leave;
}
if(phbm == NULL) {
__leave;
}
*phbm = NULL;
if(ppPicture != NULL) {
*ppPicture = NULL;
}
// RC stuff
hJpgFile = CreateFileW(JPGFile,
FILE_READ_DATA,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hJpgFile == INVALID_HANDLE_VALUE) {
__leave;
}
dwSize = GetFileSize(hJpgFile, NULL);
if(dwSize == INVALID_FILE_SIZE) {
__leave;
}
gbuf = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, dwSize);
if(gbuf == NULL) {
__leave;
}
buf = (LPBYTE)GlobalLock(gbuf);
if(buf == NULL) {
__leave;
}
cbToRead = kReadFileChunk;
while(ReadFile(hJpgFile, (LPVOID)buf, cbToRead, &cbBytesRead, NULL)) {
if(cbBytesRead == 0) {
break;
}
cbJpgSize += cbBytesRead;
buf += cbBytesRead;
}
GlobalUnlock(buf);
hr = CreateStreamOnHGlobal(gbuf, FALSE, &pStream);
if(hr != S_OK) {
__leave;
}
hr = OleLoadPicture(pStream,
0,
FALSE,
&IID_IPicture,
(void **)&pPicture
);
if(hr != S_OK) {
__leave;
}
if(ppPicture != NULL) {
IPicture_QueryInterface(pPicture,
&IID_IPicture,
(void **)ppPicture
);
}
hr = IPicture_get_Type(pPicture, &picType);
if(hr != S_OK) {
__leave;
}
if(picType != PICTYPE_BITMAP) {
__leave;
}
hr = IPicture_get_Handle(pPicture, (OLE_HANDLE *)&hbm);
if(hr != S_OK) {
__leave;
}
#if 0
hr = IPicture_get_Width(pPicture, &cx);
if(hr != S_OK) {
__leave;
}
hr = IPicture_get_Height(pPicture, &cy);
if(hr != S_OK) {
__leave;
}
hdcScreen = GetDC(NULL);
if(hdcScreen == NULL) {
__leave;
}
nWidth = MulDiv(cx, GetDeviceCaps(hdcScreen, LOGPIXELSX), HIMETRIC_INCH);
nHeight = MulDiv(cy, GetDeviceCaps(hdcScreen, LOGPIXELSY), HIMETRIC_INCH);
nWidth *= 1;
nHeight *= 1;
hdcMem = CreateCompatibleDC(hdcScreen);
if(hdcMem == NULL) {
__leave;
}
hbmMem = CreateCompatibleBitmap(hdcMem, nWidth, nHeight);
if(hbmMem == NULL) {
__leave;
}
hbmMemOld = (HBITMAP)SelectObject(hdcMem, (HGDIOBJ)hbmMem);
hr = IPicture_Render(pPicture,
hdcMem,
0,
0,
nWidth,
-nHeight,
0,
0,
cx,
-cy,
NULL
);
SelectObject(hdcMem, (HGDIOBJ)hbmMemOld);
if(hr != S_OK) {
__leave;
}
*phbm = hbmMem;
#else
*phbm = hbm;
#endif
Result = TRUE;
}
__finally {
if(hdcMem != NULL) {
DeleteDC(hdcMem);
}
if(hdcScreen != NULL) {
ReleaseDC(NULL, hdcScreen);
}
if(pPicture != NULL) {
IPicture_Release(pPicture);
}
if(pStream != NULL) {
IStream_Release(pStream);
}
if(buf != NULL) {
GlobalUnlock(buf);
}
if(gbuf != NULL) {
GlobalFree(gbuf);
}
if(hJpgFile != INVALID_HANDLE_VALUE) {
CloseHandle(hJpgFile);
}
}
return Result;
}
BOOL
BitmapFromJPGFile2(
LPCWSTR JPGFile,
HBITMAP *phbm
) {
// HMODULE hinst = DllMgr_GetObject()->Instance;
// HRSRC hResource = NULL;
// HGLOBAL hImage = NULL;
// LPVOID pImage = NULL;
DWORD dwSize = 0;
HGLOBAL gbuf = NULL;
LPBYTE buf = NULL;
HANDLE hJpgFile = NULL;
DWORD cbToRead = 0;
DWORD cbBytesRead = 0;
DWORD cbJpgSize = 0;
HRESULT hr = S_FALSE;
IStream* pStream = NULL;
IWICBitmapDecoder* pwicDecoder = NULL;
IWICBitmapSource* pwicBitmap = NULL;
IWICBitmapFrameDecode* pwicFrame = NULL;
IWICBitmapSource* pwicBitmapSource = NULL;
UINT nFrameCount = 0;
UINT bmpWidth = 0;
UINT bmpHeight = 0;
BITMAPINFO bminfo = {0};
HDC hdcScreen = NULL;
void* pvImageBits = NULL;
UINT cbStride = 0;
UINT cbImage = 0;
HBITMAP hbm = NULL;
BOOL Result = FALSE;
__try {
if(phbm == NULL) {
__leave;
}
*phbm = NULL;
if(JPGFile == NULL) {
__leave;
}
if(phbm == NULL) {
__leave;
}
*phbm = NULL;
// RC stuff
hJpgFile = CreateFileW(JPGFile,
FILE_READ_DATA,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hJpgFile == INVALID_HANDLE_VALUE) {
__leave;
}
dwSize = GetFileSize(hJpgFile, NULL);
if(dwSize == INVALID_FILE_SIZE) {
__leave;
}
gbuf = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, dwSize);
if(gbuf == NULL) {
__leave;
}
buf = (LPBYTE)GlobalLock(gbuf);
if(buf == NULL) {
__leave;
}
cbToRead = kReadFileChunk;
while(ReadFile(hJpgFile, (LPVOID)buf, cbToRead, &cbBytesRead, NULL)) {
if(cbBytesRead == 0) {
break;
}
cbJpgSize += cbBytesRead;
buf += cbBytesRead;
}
GlobalUnlock(buf);
hr = CreateStreamOnHGlobal(gbuf, FALSE, &pStream);
if(hr != S_OK) {
__leave;
}
// we have IStream; decoder stuff
hr = CoCreateInstance(&CLSID_WICJpegDecoder,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IWICBitmapDecoder,
(void **)&pwicDecoder
);
if(pwicDecoder == NULL) {
__leave;
}
hr = IWICBitmapDecoder_Initialize(pwicDecoder,
pStream,
WICDecodeMetadataCacheOnLoad
);
if(FAILED(hr)) {
__leave;
}
nFrameCount = 0;
hr = IWICBitmapDecoder_GetFrameCount(pwicDecoder,
&nFrameCount
);
if(FAILED(hr)) {
__leave;
}
if(nFrameCount != 1) {
__leave;
}
hr = IWICBitmapDecoder_GetFrame(pwicDecoder,
0,
&pwicFrame
);
if(pwicFrame == NULL) {
__leave;
}
hr = IWICBitmapFrameDecode_QueryInterface(pwicFrame,
&IID_IWICBitmapSource,
(void **)&pwicBitmapSource
);
if(pwicBitmapSource == NULL) {
__leave;
}
hr = WICConvertBitmapSource(&GUID_WICPixelFormat24bppBGR,
pwicBitmapSource,
&pwicBitmap
);
if(FAILED(hr)) {
__leave;
}
// ok, we get IWICBitmapSource
bmpWidth = 0;
bmpHeight = 0;
hr = IWICBitmapSource_GetSize(pwicBitmap,
&bmpWidth,
&bmpHeight
);
if(FAILED(hr)) {
__leave;
}
if(bmpWidth == 0 || bmpHeight == 0) {
__leave;
}
memset(&bminfo, 0, sizeof(bminfo));
bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bminfo.bmiHeader.biWidth = bmpWidth;
bminfo.bmiHeader.biHeight = -((LONG)bmpHeight);
bminfo.bmiHeader.biPlanes = 1;
bminfo.bmiHeader.biBitCount = 24;
bminfo.bmiHeader.biCompression = BI_RGB;
{
int nWidth = MulDiv(bmpWidth, GetDeviceCaps(hdcScreen, LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(bmpHeight, GetDeviceCaps(hdcScreen, LOGPIXELSY), HIMETRIC_INCH);
bminfo.bmiHeader.biXPelsPerMeter = nWidth;
bminfo.bmiHeader.biYPelsPerMeter = nHeight;
}
hdcScreen = GetDC(NULL);
if(hdcScreen == NULL) {
__leave;
}
hbm = CreateDIBSection(hdcScreen,
&bminfo,
DIB_RGB_COLORS,
&pvImageBits,
NULL,
0
);
if(hbm == NULL) {
__leave;
}
cbStride = bmpWidth * 4;
cbImage = cbStride * bmpHeight;
hr = IWICBitmapSource_CopyPixels(pwicBitmap,
NULL,
cbStride,
cbImage,
(BYTE *)pvImageBits
);
if(FAILED(hr)) {
__leave;
}
*phbm = hbm;
Result = TRUE;
}
__finally {
if(hdcScreen != NULL) {
ReleaseDC(NULL, hdcScreen);
}
if(pwicBitmapSource != NULL) {
IWICBitmapSource_Release(pwicBitmapSource);
}
if(pwicFrame != NULL) {
IWICBitmapFrameDecode_Release(pwicFrame);
}
if(pwicDecoder != NULL) {
IWICBitmapDecoder_Release(pwicDecoder);
}
if(pwicBitmap != NULL) {
IWICBitmapSource_Release(pwicBitmap);
}
if(pStream != NULL) {
IStream_Release(pStream);
}
if(buf != NULL) {
GlobalUnlock(buf);
}
if(gbuf != NULL) {
GlobalFree(gbuf);
}
}
return Result;
}