d3dx9: Check the size of a DDS file in D3DXGetImageInfoFromFileInMemory.
This commit is contained in:
parent
42dd957c50
commit
e91300a318
|
@ -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 = 0;
|
||||
|
||||
if (length < sizeof(*header) || !info)
|
||||
return D3DXERR_INVALIDDATA;
|
||||
|
@ -311,13 +338,37 @@ 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);
|
||||
}
|
||||
|
||||
expected_length *= faces;
|
||||
expected_length += sizeof(*header);
|
||||
if (length < expected_length)
|
||||
return D3DXERR_INVALIDDATA;
|
||||
|
||||
info->ImageFileFormat = D3DXIFF_DDS;
|
||||
|
||||
return D3D_OK;
|
||||
|
|
|
@ -404,10 +404,17 @@ 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);
|
||||
|
||||
hr = D3DXGetImageInfoFromFileInMemory(dds_24bit, sizeof(dds_24bit) - 1, &info);
|
||||
ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
|
||||
|
||||
hr = D3DXGetImageInfoFromFileInMemory(dds_cube_map, sizeof(dds_cube_map) - 1, &info);
|
||||
ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
|
||||
|
||||
hr = D3DXGetImageInfoFromFileInMemory(dds_volume_map, sizeof(dds_volume_map) - 1, &info);
|
||||
todo_wine ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
|
||||
|
||||
|
||||
/* cleanup */
|
||||
|
|
Loading…
Reference in New Issue