d3dx9_36: Implement D3DXGetImageInfoFromFileInMemory using WindowsCodecs (based on work from Tony Wasserka).

This commit is contained in:
Christian Costa 2010-04-09 08:43:17 +02:00 committed by Alexandre Julliard
parent e9bae2cfaf
commit 3a98a6295a
3 changed files with 127 additions and 28 deletions

View File

@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
MODULE = d3dx9_36.dll MODULE = d3dx9_36.dll
IMPORTLIB = d3dx9 IMPORTLIB = d3dx9
IMPORTS = d3d9 gdi32 user32 kernel32 IMPORTS = d3d9 ole32 gdi32 user32 kernel32
EXTRALIBS = $(LIBWPP) EXTRALIBS = $(LIBWPP)
C_SRCS = \ C_SRCS = \

View File

@ -21,6 +21,9 @@
#include "wine/unicode.h" #include "wine/unicode.h"
#include "d3dx9_36_private.h" #include "d3dx9_36_private.h"
#include "initguid.h"
#include "wincodec.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3dx); WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
@ -47,12 +50,114 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
*/ */
HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3DXIMAGE_INFO *info) 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; FIXME("(%p, %d, %p): partially implemented\n", data, datasize, info);
if( !data || !datasize ) return D3DERR_INVALIDCALL;
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;
} }
/************************************************************ /************************************************************

View File

@ -92,10 +92,8 @@ static void test_D3DXGetImageInfo(void)
/* D3DXGetImageInfoFromFile */ /* D3DXGetImageInfoFromFile */
if(testbitmap_ok) { if(testbitmap_ok) {
todo_wine {
hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", &info); hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", &info);
ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
}
hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", NULL); /* valid image, second parameter is NULL */ hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", NULL); /* valid image, second parameter is NULL */
ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK); 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 */ hr = D3DXGetImageInfoFromFileA("testdummy.bmp", NULL); /* invalid image, second parameter is NULL */
ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
todo_wine {
hr = D3DXGetImageInfoFromFileA("testdummy.bmp", &info); hr = D3DXGetImageInfoFromFileA("testdummy.bmp", &info);
ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
}
} else skip("Couldn't create \"testdummy.bmp\"\n"); } else skip("Couldn't create \"testdummy.bmp\"\n");
hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", &info); hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", &info);
@ -134,10 +130,10 @@ static void test_D3DXGetImageInfo(void)
hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL); hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL);
ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
}
hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &info); /* RT_RCDATA */ hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &info); /* RT_RCDATA */
ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
}
hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), &info); hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), &info);
ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
@ -156,13 +152,11 @@ static void test_D3DXGetImageInfo(void)
/* D3DXGetImageInfoFromFileInMemory */ /* D3DXGetImageInfoFromFileInMemory */
todo_wine {
hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), &info); hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), &info);
ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)+5, &info); /* too large size */ hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)+5, &info); /* too large size */
ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
}
hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), NULL); hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), NULL);
ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
@ -170,16 +164,16 @@ static void test_D3DXGetImageInfo(void)
hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), NULL); hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), NULL);
ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
todo_wine {
hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), &info); hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), &info);
ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
todo_wine {
hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)-1, &info); hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)-1, &info);
ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
}
hr = D3DXGetImageInfoFromFileInMemory(bmp01+1, sizeof(bmp01)-1, &info); hr = D3DXGetImageInfoFromFileInMemory(bmp01+1, sizeof(bmp01)-1, &info);
ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
}
hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, &info); hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, &info);
ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);