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;
|
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
|
* 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
|
* 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;
|
const struct dds_header *header = buffer;
|
||||||
|
UINT expected_length = 0;
|
||||||
|
|
||||||
if (length < sizeof(*header) || !info)
|
if (length < sizeof(*header) || !info)
|
||||||
return D3DXERR_INVALIDDATA;
|
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)
|
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;
|
info->ResourceType = D3DRTYPE_CUBETEXTURE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
faces = 1;
|
||||||
info->ResourceType = D3DRTYPE_TEXTURE;
|
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;
|
info->ImageFileFormat = D3DXIFF_DDS;
|
||||||
|
|
||||||
return D3D_OK;
|
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, 16, 0x00ff, 0xff00, 0, 0, D3DFMT_V8U8);
|
||||||
check_dds_pixel_format(DDS_PF_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, D3DFMT_V16U16);
|
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);
|
||||||
hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit) - 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(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 */
|
/* cleanup */
|
||||||
|
|
Loading…
Reference in New Issue