[PATCH 1/3] d3dx9_36: Add support for DIB file in D3DXGetImageInfoFromFileInMemory. (try 2)
Christian Costa
titan.costa at gmail.com
Mon Apr 22 16:08:00 CDT 2013
Try 2:
- handle BITMAPV4HEADER, BITMAPV5HEADER and BITMAPCOREHEADER2
- handle BITMAPINFOHEADER with BI_BITFIELDS compression
---
dlls/d3dx9_36/surface.c | 107 +++++++++++++++++++++++++++++++++++++++--
dlls/d3dx9_36/tests/surface.c | 6 +-
2 files changed, 104 insertions(+), 9 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index ea77497..f7576dc 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -28,6 +28,28 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
+typedef struct {
+ DWORD bc2Size;
+ DWORD bc2Width;
+ DWORD bc2Height;
+ WORD bc2Planes;
+ WORD bc2BitCount;
+ DWORD bc2Compression;
+ DWORD bc2SizeImage;
+ DWORD bc2XRes;
+ DWORD bc2YRes;
+ DWORD bc2ClrUsed;
+ DWORD bc2ClrImportant;
+ /* same as BITMAPINFOHEADER until this point */
+ WORD bc2ResUnit;
+ WORD bc2Reserved;
+ WORD bc2Orientation;
+ WORD bc2Halftoning;
+ DWORD bc2HalftoneSize1;
+ DWORD bc2HalftoneSize2;
+ DWORD bc2ColorSpace;
+ DWORD bc2AppData;
+} BITMAPCOREHEADER2;
/* Wine-specific WIC GUIDs */
DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47,0x3f,0xc1,0x7c,0xd3,0x22);
@@ -675,6 +697,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 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 == sizeof(BITMAPCOREHEADER2)))
+ {
+ /* All structures have the same memory layout as BITMAPINFOHEADER */
+ BITMAPINFOHEADER *header = (BITMAPINFOHEADER*)*data;
+ ULONG count = header->biClrUsed;
+
+ if (!count && header->biBitCount <= 8)
+ count = 1 << 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 ((header->biSize == sizeof(BITMAPINFOHEADER)) && (header->biCompression == BI_BITFIELDS))
+ offset += 3 * sizeof(DWORD);
+ }
+ else if (header_size == sizeof(BITMAPCOREHEADER))
+ {
+ BITMAPCOREHEADER *header = (BITMAPCOREHEADER*)*data;
+ ULONG count = 0;
+
+ if (header->bcBitCount <= 8)
+ count = 1 << 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 +783,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 +805,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 +823,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 +836,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 +899,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