[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