Owen Rudge : d3dx9: Implement D3DXLoadSurfaceFromFileInMemory.

Alexandre Julliard julliard at winehq.org
Wed Sep 1 11:08:54 CDT 2010


Module: wine
Branch: master
Commit: 258dba1a521cff3226db523b012ef3de2599e578
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=258dba1a521cff3226db523b012ef3de2599e578

Author: Owen Rudge <orudge at codeweavers.com>
Date:   Tue Aug 31 10:43:35 2010 -0500

d3dx9: Implement D3DXLoadSurfaceFromFileInMemory.

---

 dlls/d3dx9_36/surface.c       |  125 +++++++++++++++++++++++++++++++++++++++-
 dlls/d3dx9_36/tests/surface.c |   18 +++---
 2 files changed, 129 insertions(+), 14 deletions(-)

diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 199209f..f82f1b1 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -304,11 +304,128 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(LPDIRECT3DSURFACE9 pDestSurface,
                                                D3DCOLOR Colorkey,
                                                D3DXIMAGE_INFO *pSrcInfo)
 {
-    FIXME("(%p, %p, %p, %p, %d, %p, %d, %x, %p): stub\n", pDestSurface, pDestPalette,
-        pDestRect, pSrcData, SrcDataSize, pSrcRect, dwFilter, Colorkey, pSrcInfo);
+    D3DXIMAGE_INFO imginfo;
+    HRESULT hr;
+
+    TRACE("(%p, %p, %p, %p, %d, %p, %d, %x, %p)\n", pDestSurface, pDestPalette, pDestRect, pSrcData,
+        SrcDataSize, pSrcRect, dwFilter, Colorkey, pSrcInfo);
+
+    if (!pDestSurface || !pSrcData | !SrcDataSize)
+        return D3DERR_INVALIDCALL;
+
+    hr = D3DXGetImageInfoFromFileInMemory(pSrcData, SrcDataSize, &imginfo);
+
+    if (FAILED(hr))
+        return hr;
+
+    switch (imginfo.ImageFileFormat)
+    {
+        case D3DXIFF_BMP:
+        case D3DXIFF_PNG:
+        case D3DXIFF_JPG:
+        {
+            IWICImagingFactory *factory;
+            IWICBitmapDecoder *decoder;
+            IWICBitmapFrameDecode *bitmapframe;
+            IWICStream *stream;
+
+            const PixelFormatDesc *formatdesc;
+            WICRect wicrect;
+            RECT rect;
+
+            CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+
+            if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory)))
+                goto cleanup_err;
+
+            if (FAILED(IWICImagingFactory_CreateStream(factory, &stream)))
+            {
+                IWICImagingFactory_Release(factory);
+                goto cleanup_err;
+            }
+
+            IWICStream_InitializeFromMemory(stream, (BYTE*)pSrcData, SrcDataSize);
+
+            hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream*)stream, NULL, 0, &decoder);
+
+            IStream_Release(stream);
+            IWICImagingFactory_Release(factory);
+
+            if (FAILED(hr))
+                goto cleanup_err;
+
+            hr = IWICBitmapDecoder_GetFrame(decoder, 0, &bitmapframe);
+
+            if (FAILED(hr))
+                goto cleanup_bmp;
+
+            if (pSrcRect)
+            {
+                wicrect.X = pSrcRect->left;
+                wicrect.Y = pSrcRect->top;
+                wicrect.Width = pSrcRect->right - pSrcRect->left;
+                wicrect.Height = pSrcRect->bottom - pSrcRect->top;
+            }
+            else
+            {
+                wicrect.X = 0;
+                wicrect.Y = 0;
+                wicrect.Width = imginfo.Width;
+                wicrect.Height = imginfo.Height;
+            }
+
+            SetRect(&rect, 0, 0, wicrect.Width, wicrect.Height);
+
+            formatdesc = get_format_info(imginfo.Format);
+
+            if (formatdesc->format == D3DFMT_UNKNOWN)
+            {
+                FIXME("Unsupported pixel format\n");
+                hr = D3DXERR_INVALIDDATA;
+            }
+            else
+            {
+                BYTE *buffer;
+                DWORD pitch;
+
+                pitch = formatdesc->bytes_per_pixel * wicrect.Width;
+                buffer = HeapAlloc(GetProcessHeap(), 0, pitch * wicrect.Height);
+
+                hr = IWICBitmapFrameDecode_CopyPixels(bitmapframe, &wicrect, pitch,
+                                                      pitch * wicrect.Height, buffer);
+
+                if (SUCCEEDED(hr))
+                {
+                    hr = D3DXLoadSurfaceFromMemory(pDestSurface, pDestPalette, pDestRect,
+                                                   buffer, imginfo.Format, pitch,
+                                                   NULL, &rect, dwFilter, Colorkey);
+                }
+
+                HeapFree(GetProcessHeap(), 0, buffer);
+            }
 
-    if( !pDestSurface || !pSrcData | !SrcDataSize ) return D3DERR_INVALIDCALL;
-    return E_NOTIMPL;
+cleanup_bmp:
+            IWICBitmapFrameDecode_Release(bitmapframe);
+            IWICBitmapDecoder_Release(decoder);
+
+cleanup_err:
+            CoUninitialize();
+
+            if (FAILED(hr))
+                return D3DXERR_INVALIDDATA;
+
+            break;
+        }
+
+        default:
+            FIXME("Unsupported image file format\n");
+            return E_NOTIMPL;
+    }
+
+    if (pSrcInfo)
+        *pSrcInfo = imginfo;
+
+    return D3D_OK;
 }
 
 /************************************************************
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index a996e6d..ab47c6f 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -252,10 +252,8 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
     } else skip("Couldn't create \"testbitmap.bmp\"\n");
 
     if(testdummy_ok) {
-        todo_wine {
-            hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testdummy.bmp", NULL, D3DX_DEFAULT, 0, NULL);
-            ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
-        }
+        hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testdummy.bmp", NULL, D3DX_DEFAULT, 0, NULL);
+        ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
     } else skip("Couldn't create \"testdummy.bmp\"\n");
 
     hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0, NULL);
@@ -269,11 +267,11 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
     todo_wine {
         hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDB_BITMAP_1x1), NULL, D3DX_DEFAULT, 0, NULL);
         ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
-
-        hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDD_BITMAPDATA_1x1), NULL, D3DX_DEFAULT, 0, NULL);
-        ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
     }
 
+    hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDD_BITMAPDATA_1x1), NULL, D3DX_DEFAULT, 0, NULL);
+    ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+
     hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0, NULL);
     ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
 
@@ -288,11 +286,11 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
     todo_wine {
         hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp01, sizeof(bmp01), NULL, D3DX_DEFAULT, 0, NULL);
         ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
-
-        hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, noimage, sizeof(noimage), NULL, D3DX_DEFAULT, 0, NULL);
-        ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
     }
 
+    hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, noimage, sizeof(noimage), NULL, D3DX_DEFAULT, 0, NULL);
+    ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
     hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp01, 0, NULL, D3DX_DEFAULT, 0, NULL);
     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
 




More information about the wine-cvs mailing list