=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: d3dx9/tests: Add tests for DDS header handling.

Alexandre Julliard julliard at winehq.org
Mon Jun 4 13:27:12 CDT 2012


Module: wine
Branch: master
Commit: cbb9002aa65a2e923015d8073d2d07b9585d97c5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cbb9002aa65a2e923015d8073d2d07b9585d97c5

Author: Józef Kucia <joseph.kucia at gmail.com>
Date:   Fri Jun  1 18:04:48 2012 +0200

d3dx9/tests: Add tests for DDS header handling.

---

 dlls/d3dx9_36/tests/surface.c |  189 +++++++++++++++++++++++++++++++++--------
 1 files changed, 154 insertions(+), 35 deletions(-)

diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index 78ec0ca..3b8ed6e 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -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);
 




More information about the wine-cvs mailing list