[PATCH 3/6] d3dx9_36: Implement D3DXGetImageInfoFromFileInMemory using WindowsCodecs (based on work from Tony Wasserka) (try 2)

Christian Costa titan.costa at wanadoo.fr
Mon Apr 5 13:28:19 CDT 2010


--
Check return of CoInitializeEx and some WIC calls. Return an error for unsupported file and pixel formats.
---

 dlls/d3dx9_36/Makefile.in     |    2 -
 dlls/d3dx9_36/surface.c       |  113 ++++++++++++++++++++++++++++++++++++++++-
 dlls/d3dx9_36/tests/texture.c |   40 ++++++---------
 3 files changed, 127 insertions(+), 28 deletions(-)
-------------- next part --------------
diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in
index 15c208c..712077b 100644
--- a/dlls/d3dx9_36/Makefile.in
+++ b/dlls/d3dx9_36/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = d3dx9_36.dll
 IMPORTLIB = d3dx9
-IMPORTS   = d3d9 gdi32 user32 kernel32
+IMPORTS   = d3d9 ole32 gdi32 user32 kernel32
 EXTRALIBS = $(LIBWPP)
 
 C_SRCS = \
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 699dbcb..ea661a7 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -21,6 +21,9 @@
 #include "wine/unicode.h"
 #include "d3dx9_36_private.h"
 
+#include "initguid.h"
+#include "wincodec.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
 
 
@@ -47,12 +50,114 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
  */
 HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3DXIMAGE_INFO *info)
 {
-    FIXME("(%p, %d, %p): stub\n", data, datasize, info);
+    IWICImagingFactory *factory;
+    IWICBitmapDecoder *decoder = NULL;
+    IWICStream *stream;
+    HRESULT hr;
 
-    if(data && datasize && !info) return D3D_OK;
-    if( !data || !datasize ) return D3DERR_INVALIDCALL;
+    FIXME("(%p, %d, %p): partially implemented\n", data, datasize, info);
 
-    return E_NOTIMPL;
+    /* TODO: Add support for (or at least detect) TGA, DDS, PPM and DIB */
+
+    if (!data || !datasize)
+        return D3DERR_INVALIDCALL;
+
+    if (!info)
+        return D3D_OK;
+
+    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+    if (FAILED(hr))
+        return E_FAIL;
+
+    hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory);
+
+    if (SUCCEEDED(hr)) {
+        IWICImagingFactory_CreateStream(factory, &stream);
+        IWICStream_InitializeFromMemory(stream, (BYTE*)data, datasize);
+        hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream*)stream, NULL, 0, &decoder);
+        IStream_Release(stream);
+        IWICImagingFactory_Release(factory);
+    }
+
+    if (SUCCEEDED(hr)) {
+        GUID container_format;
+        UINT frame_count;
+
+        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;
+            } else if (IsEqualGUID(&container_format, &GUID_ContainerFormatPng)) {
+                TRACE("File type is PNG\n");
+                info->ImageFileFormat = D3DXIFF_PNG;
+            } else if(IsEqualGUID(&container_format, &GUID_ContainerFormatJpeg)) {
+                TRACE("File type is JPG\n");
+                info->ImageFileFormat = D3DXIFF_JPG;
+            } else {
+                WARN("Unsupported image file format %s\n", debugstr_guid(&container_format));
+                hr = D3DXERR_INVALIDDATA;
+            }
+        }
+
+        if (SUCCEEDED(hr))
+            hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
+        if (SUCCEEDED(hr) && !frame_count)
+            hr = D3DXERR_INVALIDDATA;
+
+        if (SUCCEEDED(hr)) {
+            IWICBitmapFrameDecode *frame = NULL;
+
+            hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
+
+            if (SUCCEEDED(hr))
+                hr = IWICBitmapFrameDecode_GetSize(frame, &info->Width, &info->Height);
+
+            if (SUCCEEDED(hr)) {
+                WICPixelFormatGUID pixel_format;
+
+                hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &pixel_format);
+                if (SUCCEEDED(hr)) {
+                    if (IsEqualGUID(&pixel_format, &GUID_WICPixelFormat1bppIndexed))
+                        info->Format = D3DFMT_L8;
+                    else if (IsEqualGUID(&pixel_format, &GUID_WICPixelFormat4bppIndexed))
+                        info->Format = D3DFMT_L8;
+                    else if (IsEqualGUID(&pixel_format, &GUID_WICPixelFormat8bppIndexed))
+                        info->Format = D3DFMT_L8;
+                    else if (IsEqualGUID(&pixel_format, &GUID_WICPixelFormat16bppBGR555))
+                        info->Format = D3DFMT_X1R5G5B5;
+                    else if (IsEqualGUID(&pixel_format, &GUID_WICPixelFormat24bppBGR))
+                        info->Format = D3DFMT_R8G8B8;
+                    else if (IsEqualGUID(&pixel_format, &GUID_WICPixelFormat32bppBGR))
+                        info->Format = D3DFMT_X8R8G8B8;
+                    else {
+                        WARN("Unsupported pixel format %s\n", debugstr_guid(&pixel_format));
+                        hr = D3DXERR_INVALIDDATA;
+                    }
+                }
+            }
+
+            if (frame)
+                 IWICBitmapFrameDecode_Release(frame);
+
+            info->Depth = 1;
+            info->MipLevels = 1;
+            info->ResourceType = D3DRTYPE_TEXTURE;
+        }
+    }
+
+    if (decoder)
+        IWICBitmapDecoder_Release(decoder);
+
+    CoUninitialize();
+
+    if (FAILED(hr)) {
+        /* Missing formats are not detected yet and will fail silently without the FIXME */
+        FIXME("Invalid or unsupported image file\n");
+        return D3DXERR_INVALIDDATA;
+    } 
+
+    return D3D_OK;
 }
 
 /************************************************************
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index f251116..2d6f768 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -92,10 +92,8 @@ static void test_D3DXGetImageInfo(void)
 
     /* D3DXGetImageInfoFromFile */
     if(testbitmap_ok) {
-        todo_wine {
-            hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", &info);
-            ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
-        }
+        hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", &info);
+        ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
 
         hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", NULL); /* valid image, second parameter is NULL */
         ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
@@ -105,10 +103,8 @@ static void test_D3DXGetImageInfo(void)
         hr = D3DXGetImageInfoFromFileA("testdummy.bmp", NULL); /* invalid image, second parameter is NULL */
         ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
 
-        todo_wine {
-            hr = D3DXGetImageInfoFromFileA("testdummy.bmp", &info);
-            ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
-        }
+        hr = D3DXGetImageInfoFromFileA("testdummy.bmp", &info);
+        ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
     } else skip("Couldn't create \"testdummy.bmp\"\n");
 
     hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", &info);
@@ -134,11 +130,11 @@ static void test_D3DXGetImageInfo(void)
 
         hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL);
         ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
-
-        hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &info); /* RT_RCDATA */
-        ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
     }
 
+    hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &info); /* RT_RCDATA */
+    ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+
     hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), &info);
     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
 
@@ -156,13 +152,11 @@ static void test_D3DXGetImageInfo(void)
 
 
     /* D3DXGetImageInfoFromFileInMemory */
-    todo_wine {
-        hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), &info);
-        ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+    hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), &info);
+    ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
 
-        hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)+5, &info); /* too large size */
-        ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
-    }
+    hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)+5, &info); /* too large size */
+    ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
 
     hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), NULL);
     ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
@@ -170,17 +164,17 @@ static void test_D3DXGetImageInfo(void)
     hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), NULL);
     ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
 
-    todo_wine {
-        hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), &info);
-        ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+    hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), &info);
+    ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
 
+    todo_wine {
         hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)-1, &info);
         ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
-
-        hr = D3DXGetImageInfoFromFileInMemory(bmp01+1, sizeof(bmp01)-1, &info);
-        ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
     }
 
+    hr = D3DXGetImageInfoFromFileInMemory(bmp01+1, sizeof(bmp01)-1, &info);
+    ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
     hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, &info);
     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
 


More information about the wine-patches mailing list