From 3a98a6295a0540a67783db0d4ac7ef0cd239c9b3 Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Fri, 9 Apr 2010 08:43:17 +0200 Subject: [PATCH] d3dx9_36: Implement D3DXGetImageInfoFromFileInMemory using WindowsCodecs (based on work from Tony Wasserka). --- 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(-) diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in index 15c208ccb62..712077b5227 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 699dbcba614..0a882b54827 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; + HRESULT initresult; - 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; + + initresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + 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); + + if (SUCCEEDED(initresult)) + 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 f2511161ecc..2d6f7688e35 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); -- 2.11.4.GIT