d3dx9/tests: Add tests for DDS header handling.

This commit is contained in:
Józef Kucia 2012-06-01 18:04:48 +02:00 committed by Alexandre Julliard
parent bdd42942c0
commit cbb9002aa6

View file

@ -19,6 +19,7 @@
*/
#define COBJMACROS
#include <assert.h>
#include "wine/test.h"
#include "d3dx9tex.h"
#include "resources.h"
@ -138,13 +139,18 @@ static HRESULT create_file(const char *filename, const unsigned char *data, cons
return D3DERR_INVALIDCALL;
}
/* dds_header.flags */
#define DDS_CAPS 0x00000001
#define DDS_HEIGHT 0x00000002
#define DDS_WIDTH 0x00000004
#define DDS_PITCH 0x00000008
#define DDS_PIXELFORMAT 0x00001000
#define DDS_LINEARSIZE 0x00080000
/* dds_header.caps */
#define DDS_CAPS_TEXTURE 0x00001000
/* dds_pixel_format.flags */
#define DDS_PF_ALPHA 0x00000001
#define DDS_PF_ALPHA_ONLY 0x00000002
#define DDS_PF_FOURCC 0x00000004
@ -152,6 +158,57 @@ static HRESULT create_file(const char *filename, const unsigned char *data, cons
#define DDS_PF_LUMINANCE 0x00020000
#define DDS_PF_BUMPDUDV 0x00080000
struct dds_pixel_format
{
DWORD size;
DWORD flags;
DWORD fourcc;
DWORD bpp;
DWORD rmask;
DWORD gmask;
DWORD bmask;
DWORD amask;
};
struct dds_header
{
DWORD magic;
DWORD size;
DWORD flags;
DWORD height;
DWORD width;
DWORD pitch_or_linear_size;
DWORD depth;
DWORD miplevels;
DWORD reserved[11];
struct dds_pixel_format pixel_format;
DWORD caps;
DWORD caps2;
DWORD reserved2[3];
};
/* fills dds_header with reasonable default values */
static void fill_dds_header(struct dds_header *header)
{
memset(header, 0, sizeof(*header));
header->magic = MAKEFOURCC('D','D','S',' ');
header->size = sizeof(*header);
header->flags = DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT;
header->height = 4;
header->width = 4;
header->pixel_format.size = sizeof(header->pixel_format);
/* X8R8G8B8 */
header->pixel_format.flags = DDS_PF_RGB;
header->pixel_format.fourcc = 0;
header->pixel_format.bpp = 32;
header->pixel_format.rmask = 0xff0000;
header->pixel_format.gmask = 0x00ff00;
header->pixel_format.bmask = 0x0000ff;
header->pixel_format.amask = 0;
header->caps = DDS_CAPS_TEXTURE;
}
static void check_dds_pixel_format(DWORD flags, DWORD fourcc, DWORD bpp,
DWORD rmask, DWORD gmask, DWORD bmask, DWORD amask,
D3DFORMAT expected_format)
@ -160,44 +217,19 @@ static void check_dds_pixel_format(DWORD flags, DWORD fourcc, DWORD bpp,
D3DXIMAGE_INFO info;
struct
{
DWORD magic;
DWORD size;
DWORD flags;
DWORD height;
DWORD width;
DWORD padding[14];
struct
{
DWORD size;
DWORD flags;
DWORD fourcc;
DWORD bpp;
DWORD rmask;
DWORD gmask;
DWORD bmask;
DWORD amask;
} pixel_format;
DWORD caps;
DWORD padding2[4];
struct dds_header header;
BYTE data[256];
} dds;
memset(&dds, 0, sizeof(dds));
dds.magic = MAKEFOURCC('D','D','S',' ');
dds.size = 124;
dds.flags = DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT;
dds.height = 4;
dds.width = 4;
dds.pixel_format.size = sizeof(dds.pixel_format);
dds.pixel_format.flags = flags;
dds.pixel_format.fourcc = fourcc;
dds.pixel_format.bpp = bpp;
dds.pixel_format.rmask = rmask;
dds.pixel_format.gmask = gmask;
dds.pixel_format.bmask = bmask;
dds.pixel_format.amask = amask;
dds.caps = DDS_CAPS_TEXTURE;
fill_dds_header(&dds.header);
dds.header.pixel_format.flags = flags;
dds.header.pixel_format.fourcc = fourcc;
dds.header.pixel_format.bpp = bpp;
dds.header.pixel_format.rmask = rmask;
dds.header.pixel_format.gmask = gmask;
dds.header.pixel_format.bmask = bmask;
dds.header.pixel_format.amask = amask;
memset(dds.data, 0, sizeof(dds.data));
hr = D3DXGetImageInfoFromFileInMemory(&dds, sizeof(dds), &info);
ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x for pixel format %#x, expected %#x\n", hr, expected_format, D3D_OK);
@ -205,6 +237,91 @@ static void check_dds_pixel_format(DWORD flags, DWORD fourcc, DWORD bpp,
ok(info.Format == expected_format, "D3DXGetImageInfoFromFileInMemory returned format %#x, expected %#x\n", info.Format, expected_format);
}
static void test_dds_header_handling(void)
{
int i;
HRESULT hr;
D3DXIMAGE_INFO info;
struct
{
struct dds_header header;
BYTE data[256];
} dds;
struct
{
struct dds_pixel_format pixel_format;
DWORD flags;
DWORD width;
DWORD height;
DWORD pitch;
DWORD pixel_data_size;
HRESULT expected_result;
} tests[] = {
/* pitch is ignored */
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, 0, 4, 4, 0,
63 /* pixel data size */, D3DXERR_INVALIDDATA },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 0 /* pitch */,
64, D3D_OK },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 1 /* pitch */,
64, D3D_OK },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 2 /* pitch */,
64, D3D_OK },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 3 /* pitch */,
64, D3D_OK },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 4 /* pitch */,
64, D3D_OK },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 16 /* pitch */,
64, D3D_OK },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 1024 /* pitch */,
64, D3D_OK },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, -1 /* pitch */,
64, D3D_OK },
/* linear size is ignored */
{ { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, 0, 4, 4, 0,
7 /* pixel data size */, D3DXERR_INVALIDDATA },
{ { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 0 /* linear size */,
8, D3D_OK },
{ { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 1 /* linear size */,
8, D3D_OK },
{ { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 2 /* linear size */,
8, D3D_OK },
{ { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 9 /* linear size */,
8, D3D_OK },
{ { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 16 /* linear size */,
8, D3D_OK },
{ { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, -1 /* linear size */,
8, D3D_OK },
/* integer overflows */
{ { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000000, 0x80000000 /* 0x80000000 * 0x80000000 * 4 = 0 */, 0,
64, D3D_OK },
{ { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x8000100, 0x800100 /* 0x8000100 * 0x800100 * 4 = 262144 */, 0,
64, D3DXERR_INVALIDDATA },
{ { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000001, 0x80000001 /* 0x80000001 * 0x80000001 * 4 = 4 */, 0,
4, D3D_OK },
{ { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000001, 0x80000001 /* 0x80000001 * 0x80000001 * 4 = 4 */, 0,
3 /* pixel data size */, D3DXERR_INVALIDDATA }
};
memset(&dds, 0, sizeof(dds));
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
{
DWORD file_size = sizeof(dds.header) + tests[i].pixel_data_size;
assert(file_size <= sizeof(dds));
fill_dds_header(&dds.header);
dds.header.flags |= tests[i].flags;
dds.header.width = tests[i].width;
dds.header.height = tests[i].height;
dds.header.pitch_or_linear_size = tests[i].pitch;
memcpy(&dds.header.pixel_format, &tests[i].pixel_format, sizeof(struct dds_pixel_format));
hr = D3DXGetImageInfoFromFileInMemory(&dds, file_size, &info);
ok(hr == tests[i].expected_result, "%d: D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", i, hr, tests[i].expected_result);
}
}
static void test_D3DXGetImageInfo(void)
{
HRESULT hr;
@ -404,6 +521,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);
test_dds_header_handling();
hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit) - 1, &info);
ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);