[2/8] d3dx9: Check the size of a DDS file in D3DXGetImageInfoFromFileInMemory.
Józef Kucia
joseph.kucia at gmail.com
Wed May 9 16:32:05 CDT 2012
---
dlls/d3dx9_36/surface.c | 51 ++++++++++++++++++++++++++++++++++++++++-
dlls/d3dx9_36/tests/surface.c | 6 +---
2 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 2217abd..c842f6c 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -269,6 +269,29 @@ static D3DFORMAT dds_pixel_format_to_d3dformat(const struct dds_pixel_format *pi
return D3DFMT_UNKNOWN;
}
+static HRESULT calculate_dds_surface_size(const D3DXIMAGE_INFO *img_info,
+ UINT width, UINT height, UINT *pitch, UINT *size)
+{
+ const PixelFormatDesc *format_desc = get_format_info(img_info->Format);
+ if (format_desc->format == D3DFMT_UNKNOWN)
+ return E_NOTIMPL;
+
+ if (format_desc->block_width != 1 || format_desc->block_height != 1)
+ {
+ *pitch = format_desc->block_byte_count
+ * max(1, (width + format_desc->block_width - 1) / format_desc->block_width);
+ *size = *pitch
+ * max(1, (height + format_desc->block_height - 1) / format_desc->block_height);
+ }
+ else
+ {
+ *pitch = width * format_desc->bytes_per_pixel;
+ *size = *pitch * height;
+ }
+
+ return D3D_OK;
+}
+
/************************************************************
* get_image_info_from_dds
*
@@ -285,9 +308,13 @@ static D3DFORMAT dds_pixel_format_to_d3dformat(const struct dds_pixel_format *pi
* Failure: D3DXERR_INVALIDDATA
*
*/
-static HRESULT get_image_info_from_dds(const void *buffer, DWORD length, D3DXIMAGE_INFO *info)
+static HRESULT get_image_info_from_dds(const void *buffer, UINT length, D3DXIMAGE_INFO *info)
{
+ UINT i;
+ UINT faces = 0;
+ UINT width, height;
const struct dds_header *header = buffer;
+ UINT expected_length = sizeof(*header);
if (length < sizeof(*header) || !info)
return D3DXERR_INVALIDDATA;
@@ -311,13 +338,35 @@ static HRESULT get_image_info_from_dds(const void *buffer, DWORD length, D3DXIMA
}
else if (header->caps2 & DDS_CAPS2_CUBEMAP)
{
+ DWORD face;
+ for (face = DDS_CAPS2_CUBEMAP_POSITIVEX; face <= DDS_CAPS2_CUBEMAP_NEGATIVEZ; face <<= 1)
+ {
+ if (header->caps2 & face)
+ faces++;
+ }
info->ResourceType = D3DRTYPE_CUBETEXTURE;
}
else
{
+ faces = 1;
info->ResourceType = D3DRTYPE_TEXTURE;
}
+ /* calculate the expected length */
+ width = info->Width;
+ height = info->Height;
+ for (i = 0; i < info->MipLevels; i++)
+ {
+ UINT pitch, size = 0;
+ calculate_dds_surface_size(info, width, height, &pitch, &size);
+ expected_length += size;
+ width = max(1, width / 2);
+ height = max(1, width / 2);
+ }
+
+ if (length < expected_length)
+ return D3DXERR_INVALIDDATA;
+
info->ImageFileFormat = D3DXIFF_DDS;
return D3D_OK;
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index 0ef57cd..32b00bb 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -404,10 +404,8 @@ static void test_D3DXGetImageInfo(void)
check_dds_pixel_format(DDS_PF_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0, 0, D3DFMT_V8U8);
check_dds_pixel_format(DDS_PF_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, D3DFMT_V16U16);
- todo_wine {
- hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit) - 1, &info);
- ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
- }
+ hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit) - 1, &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
/* cleanup */
--
1.7.8.6
More information about the wine-patches
mailing list