[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