[PATCH] d3dx9_36: Add support for DIB file in D3DXGetImageInfoFromFileInMemory. (try 3) (resend)
Christian Costa
titan.costa at gmail.com
Wed Apr 24 16:40:19 CDT 2013
With the right patch with time.
Try 3:
- Hardcode size of BITMAPCOREHEADER2 instead of declaring the structure
Try 2:
- handle BITMAPV4HEADER, BITMAPV5HEADER and BITMAPCOREHEADER2
- handle BITMAPINFOHEADER with BI_BITFIELDS compression
---
dlls/d3dx9_36/surface.c | 85 +++++++++++++++++++++++++++++++++++++++--
dlls/d3dx9_36/tests/surface.c | 6 +--
2 files changed, 82 insertions(+), 9 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index ea77497..af7b89e 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -675,6 +675,71 @@ HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, co
return D3D_OK;
}
+static BOOL convert_dib_to_bmp(void **data, UINT *size)
+{
+ ULONG header_size;
+ ULONG count = 0;
+ ULONG offset;
+ BITMAPFILEHEADER *header;
+ BYTE *new_data;
+ UINT new_size;
+
+ if ((*size < 4) || (*size < (header_size = *(ULONG*)*data)))
+ return FALSE;
+
+ if ((header_size == sizeof(BITMAPINFOHEADER)) ||
+ (header_size == sizeof(BITMAPV4HEADER)) ||
+ (header_size == sizeof(BITMAPV5HEADER)) ||
+ (header_size == 64 /* sizeof(BITMAPCOREHEADER2) */))
+ {
+ /* All structures begin with the same memory layout as BITMAPINFOHEADER */
+ BITMAPINFOHEADER *info_header = (BITMAPINFOHEADER*)*data;
+ count = info_header->biClrUsed;
+
+ if (!count && info_header->biBitCount <= 8)
+ count = 1 << info_header->biBitCount;
+
+ offset = sizeof(BITMAPFILEHEADER) + header_size + sizeof(RGBQUAD) * count;
+
+ /* For BITMAPINFOHEADER with BI_BITFIELDS compression, there are 3 additional color masks after header */
+ if ((info_header->biSize == sizeof(BITMAPINFOHEADER)) && (info_header->biCompression == BI_BITFIELDS))
+ offset += 3 * sizeof(DWORD);
+ }
+ else if (header_size == sizeof(BITMAPCOREHEADER))
+ {
+ BITMAPCOREHEADER *core_header = (BITMAPCOREHEADER*)*data;
+
+ if (core_header->bcBitCount <= 8)
+ count = 1 << core_header->bcBitCount;
+
+ offset = sizeof(BITMAPFILEHEADER) + header_size + sizeof(RGBTRIPLE) * count;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ TRACE("Converting DIB file to BMP\n");
+
+ new_size = *size + sizeof(BITMAPFILEHEADER);
+ new_data = HeapAlloc(GetProcessHeap(), 0, new_size);
+ CopyMemory(new_data + sizeof(BITMAPFILEHEADER), *data, *size);
+
+ /* Add BMP header */
+ header = (BITMAPFILEHEADER*)new_data;
+ header->bfType = 0x4d42; /* BM */
+ header->bfSize = new_size;
+ header->bfReserved1 = 0;
+ header->bfReserved2 = 0;
+ header->bfOffBits = offset;
+
+ /* Update input data */
+ *data = new_data;
+ *size = new_size;
+
+ return TRUE;
+}
+
/************************************************************
* D3DXGetImageInfoFromFileInMemory
*
@@ -696,13 +761,14 @@ HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, co
* datasize may be bigger than the actual file size
*
*/
-HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3DXIMAGE_INFO *info)
+HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(const void *data, UINT datasize, D3DXIMAGE_INFO *info)
{
IWICImagingFactory *factory;
IWICBitmapDecoder *decoder = NULL;
IWICStream *stream;
HRESULT hr;
HRESULT initresult;
+ BOOL dib;
TRACE("(%p, %d, %p)\n", data, datasize, info);
@@ -717,6 +783,9 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3D
return get_image_info_from_dds(data, datasize, info);
}
+ /* In case of DIB file, convert it to BMP */
+ dib = convert_dib_to_bmp((void**)&data, &datasize);
+
initresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory);
@@ -732,8 +801,6 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3D
if (FAILED(hr)) {
if ((datasize >= 2) && (!strncmp(data, "P3", 2) || !strncmp(data, "P6", 2)))
FIXME("File type PPM is not supported yet\n");
- else if ((datasize >= 4) && (*(DWORD*)data == sizeof(BITMAPINFOHEADER)))
- FIXME("File type DIB is not supported yet\n");
else if ((datasize >= 10) && !strncmp(data, "#?RADIANCE", 10))
FIXME("File type HDR is not supported yet\n");
else if ((datasize >= 2) && (!strncmp(data, "PF", 2) || !strncmp(data, "Pf", 2)))
@@ -747,8 +814,13 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3D
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;
+ if (dib) {
+ TRACE("File type is DIB\n");
+ info->ImageFileFormat = D3DXIFF_DIB;
+ } else {
+ 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;
@@ -805,6 +877,9 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(LPCVOID data, UINT datasize, D3D
if (SUCCEEDED(initresult))
CoUninitialize();
+ if (dib)
+ HeapFree(GetProcessHeap(), 0, (void*)data);
+
if (FAILED(hr)) {
TRACE("Invalid or unsupported image file\n");
return D3DXERR_INVALIDDATA;
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index bb1104b..759f9e1 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -377,10 +377,8 @@ static void test_D3DXGetImageInfo(void)
/* D3DXGetImageInfoFromResource */
- todo_wine {
- hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &info); /* RT_BITMAP */
- ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
- }
+ hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &info); /* RT_BITMAP */
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL);
ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
More information about the wine-patches
mailing list