I knocked this code up today because I wanted to be able to load PNG images. Since neither LoadImage nor OleLoadPicture can handle PNG, I had a go with Direct3D. Here's the code
#include <windows.h>
#include "d3dx9tex.h"
#include <stdlib.h>
...
HRESULT err;
unsigned int *pix;
IDirect3D9 *d3d9;
IDirect3DDevice9 *d3ddev;
IDirect3DTexture9 *d3dtex;
D3DPRESENT_PARAMETERS d3dpp = {0};
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.Windowed = TRUE;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
err = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
assert(err == S_OK);
D3DXCreateTextureFromFileInMemory(d3ddev, img, size, &d3dtex);
D3DLOCKED_RECT lock;
D3DSURFACE_DESC d3ddesc;
d3dtex->GetLevelDesc(0, &d3ddesc);
pix = new unsigned int[d3ddesc.Width * d3ddesc.Height];
d3dtex->LockRect(0, &lock, NULL, D3DLOCK_READONLY);
unsigned int *dst, *src;
src = (unsigned int *)lock.pBits;
dst = pix;
for (unsigned int y = 0; y < d3ddesc.Height; y++)
{
memcpy(dst, src, d3ddesc.Width * sizeof(unsigned int));
dst += d3ddesc.Width;
src += lock.Pitch/sizeof(unsigned int);
}
d3dtex->UnlockRect(0);
d3dtex->Release();
d3ddev->Release();
d3d9->Release();
The inputs are
img - pointer to the PNG file in memory
size - size of the PNG file in memory
hWnd - handle to your window
The output is
pix - pointer to the RGB image in memory
You will need to add d3d9.lib and d3dx9.lib to the linker options.
As well as PNG, this routine will load bmp, .dds, .dib, .hdr, .jpg, .pfm, .ppm, and .tga
Jim