[PATCH 1/3] d3dx9_36: Add support for DIB file in D3DXGetImageInfoFromFileInMemory.
Christian Costa
titan.costa at gmail.com
Sun Apr 21 16:56:55 CDT 2013
---
dlls/d3dx9_36/surface.c | 77 ++++++++++++++++++++++++++++++++++++++---
dlls/d3dx9_36/tests/surface.c | 6 +--
2 files changed, 74 insertions(+), 9 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index ea77497..c71622a 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -675,6 +675,63 @@ HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, co
return D3D_OK;
}
+static BOOL convert_dib_to_bmp(void **data, UINT *size)
+{
+ ULONG header_size;
+ ULONG offset;
+ BITMAPFILEHEADER *header;
+ BYTE *new_data;
+ UINT new_size;
+
+ if ((*size < 4) || (*size < (header_size = *(ULONG*)*data)))
+ return FALSE;
+
+ if (header_size == sizeof(BITMAPINFOHEADER))
+ {
+ BITMAPINFOHEADER *header = (BITMAPINFOHEADER*)*data;
+ ULONG count = header->biClrUsed;
+
+ if (!count && header->biBitCount <= 8)
+ count = 1 << header->biBitCount;
+
+ offset = sizeof(BITMAPFILEHEADER) + header_size + sizeof(RGBQUAD) * count;
+ }
+ else if (header_size == sizeof(BITMAPCOREHEADER))
+ {
+ BITMAPCOREHEADER *header = (BITMAPCOREHEADER*)*data;
+ ULONG count = 0;
+
+ if (header->bcBitCount <= 8)
+ count = 1 << header->bcBitCount;
+
+ offset = sizeof(BITMAPFILEHEADER) + header_size + sizeof(RGBTRIPLE) * count;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ TRACE("Converting DIB file to BMP\n");
+
+ new_size = *size + sizeof(BITMAPFILEHEADER);
+ new_data = HeapAlloc(GetProcessHeap(), 0, new_size);
+ CopyMemory(new_data + sizeof(BITMAPFILEHEADER), *data, *size);
+
+ /* Add BMP header */
+ header = (BITMAPFILEHEADER*)new_data;
+ header->bfType = 0x4d42; /* BM */
+ header->bfSize = new_size;
+ header->bfReserved1 = 0;
+ header->bfReserved2 = 0;
+ header->bfOffBits = offset;
+
+ /* Update input data */
+ *data = new_data;
+ *size = new_size;
+
+ return TRUE;
+}
+
/************************************************************
* D3DXGetImageInfoFromFileInMemory
*
@@ -696,13 +753,14 @@ HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, co
* datasize may be bigger than the actual file size
*
*/
-HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3DXIMAGE_INFO *info)
+HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(const void *data, UINT datasize, D3DXIMAGE_INFO *info)
{
IWICImagingFactory *factory;
IWICBitmapDecoder *decoder = NULL;
IWICStream *stream;
HRESULT hr;
HRESULT initresult;
+ BOOL dib;
TRACE("(%p, %d, %p)\n", data, datasize, info);
@@ -717,6 +775,9 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3D
return get_image_info_from_dds(data, datasize, info);
}
+ /* In case of DIB file, convert it to BMP */
+ dib = convert_dib_to_bmp((void**)&data, &datasize);
+
initresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory);
@@ -732,8 +793,6 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3D
if (FAILED(hr)) {
if ((datasize >= 2) && (!strncmp(data, "P3", 2) || !strncmp(data, "P6", 2)))
FIXME("File type PPM is not supported yet\n");
- else if ((datasize >= 4) && (*(DWORD*)data == sizeof(BITMAPINFOHEADER)))
- FIXME("File type DIB is not supported yet\n");
else if ((datasize >= 10) && !strncmp(data, "#?RADIANCE", 10))
FIXME("File type HDR is not supported yet\n");
else if ((datasize >= 2) && (!strncmp(data, "PF", 2) || !strncmp(data, "Pf", 2)))
@@ -747,8 +806,13 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3D
hr = IWICBitmapDecoder_GetContainerFormat(decoder, &container_format);
if (SUCCEEDED(hr)) {
if (IsEqualGUID(&container_format, &GUID_ContainerFormatBmp)) {
- TRACE("File type is BMP\n");
- info->ImageFileFormat = D3DXIFF_BMP;
+ if (dib) {
+ TRACE("File type is DIB\n");
+ info->ImageFileFormat = D3DXIFF_DIB;
+ } else {
+ TRACE("File type is BMP\n");
+ info->ImageFileFormat = D3DXIFF_BMP;
+ }
} else if (IsEqualGUID(&container_format, &GUID_ContainerFormatPng)) {
TRACE("File type is PNG\n");
info->ImageFileFormat = D3DXIFF_PNG;
@@ -805,6 +869,9 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3D
if (SUCCEEDED(initresult))
CoUninitialize();
+ if (dib)
+ HeapFree(GetProcessHeap(), 0, (void*)data);
+
if (FAILED(hr)) {
TRACE("Invalid or unsupported image file\n");
return D3DXERR_INVALIDDATA;
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index bb1104b..759f9e1 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -377,10 +377,8 @@ static void test_D3DXGetImageInfo(void)
/* D3DXGetImageInfoFromResource */
- todo_wine {
- hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &info); /* RT_BITMAP */
- ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
- }
+ hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &info); /* RT_BITMAP */
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL);
ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
More information about the wine-patches
mailing list