d3dx9/tests: Add DDS pixel format tests for D3DXGetImageInfoFromFileInMemory.
[wine] / dlls / d3dx9_36 / util.c
1 /*
2  * Copyright (C) 2009 Tony Wasserka
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  */
19
20 #include "wine/debug.h"
21 #include "d3dx9_36_private.h"
22
23 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
24
25 static void la_from_rgba(const struct vec4 *rgba, struct vec4 *la)
26 {
27     la->x = rgba->x * 0.2125f + rgba->y * 0.7154f + rgba->z * 0.0721f;
28     la->w = rgba->w;
29 }
30
31 static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba)
32 {
33     rgba->x = la->x;
34     rgba->y = la->x;
35     rgba->z = la->x;
36     rgba->w = la->w;
37 }
38
39 /************************************************************
40  * pixel format table providing info about number of bytes per pixel,
41  * number of bits per channel and format type.
42  *
43  * Call get_format_info to request information about a specific format.
44  */
45 static const PixelFormatDesc formats[] =
46 {
47     /* format            bpc              shifts            bpp type            from_rgba     to_rgba */
48     {D3DFMT_R8G8B8,      {0,  8,  8,  8}, { 0, 16,  8,  0}, 3,  FORMAT_ARGB,    NULL,         NULL      },
49     {D3DFMT_A8R8G8B8,    {8,  8,  8,  8}, {24, 16,  8,  0}, 4,  FORMAT_ARGB,    NULL,         NULL      },
50     {D3DFMT_X8R8G8B8,    {0,  8,  8,  8}, { 0, 16,  8,  0}, 4,  FORMAT_ARGB,    NULL,         NULL      },
51     {D3DFMT_A8B8G8R8,    {8,  8,  8,  8}, {24,  0,  8, 16}, 4,  FORMAT_ARGB,    NULL,         NULL      },
52     {D3DFMT_X8B8G8R8,    {0,  8,  8,  8}, { 0,  0,  8, 16}, 4,  FORMAT_ARGB,    NULL,         NULL      },
53     {D3DFMT_R5G6B5,      {0,  5,  6,  5}, { 0, 11,  5,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
54     {D3DFMT_X1R5G5B5,    {0,  5,  5,  5}, { 0, 10,  5,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
55     {D3DFMT_A1R5G5B5,    {1,  5,  5,  5}, {15, 10,  5,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
56     {D3DFMT_R3G3B2,      {0,  3,  3,  2}, { 0,  5,  2,  0}, 1,  FORMAT_ARGB,    NULL,         NULL      },
57     {D3DFMT_A8R3G3B2,    {8,  3,  3,  2}, { 8,  5,  2,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
58     {D3DFMT_A4R4G4B4,    {4,  4,  4,  4}, {12,  8,  4,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
59     {D3DFMT_X4R4G4B4,    {0,  4,  4,  4}, { 0,  8,  4,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
60     {D3DFMT_A2R10G10B10, {2, 10, 10, 10}, {30, 20, 10,  0}, 4,  FORMAT_ARGB,    NULL,         NULL      },
61     {D3DFMT_A2B10G10R10, {2, 10, 10, 10}, {30,  0, 10, 20}, 4,  FORMAT_ARGB,    NULL,         NULL      },
62     {D3DFMT_G16R16,      {0, 16, 16,  0}, { 0,  0, 16,  0}, 4,  FORMAT_ARGB,    NULL,         NULL      },
63     {D3DFMT_A8,          {8,  0,  0,  0}, { 0,  0,  0,  0}, 1,  FORMAT_ARGB,    NULL,         NULL      },
64     {D3DFMT_A8L8,        {8,  8,  0,  0}, { 8,  0,  0,  0}, 2,  FORMAT_ARGB,    la_from_rgba, la_to_rgba},
65     /* marks last element */
66     {D3DFMT_UNKNOWN,     {0,  0,  0,  0}, { 0,  0,  0,  0}, 0,  FORMAT_UNKNOWN, NULL,         NULL      },
67 };
68
69
70 /************************************************************
71  * map_view_of_file
72  *
73  * Loads a file into buffer and stores the number of read bytes in length.
74  *
75  * PARAMS
76  *   filename [I] name of the file to be loaded
77  *   buffer   [O] pointer to destination buffer
78  *   length   [O] size of the obtained data
79  *
80  * RETURNS
81  *   Success: D3D_OK
82  *   Failure:
83  *     see error codes for CreateFileW, GetFileSize, CreateFileMapping and MapViewOfFile
84  *
85  * NOTES
86  *   The caller must UnmapViewOfFile when it doesn't need the data anymore
87  *
88  */
89 HRESULT map_view_of_file(LPCWSTR filename, LPVOID *buffer, DWORD *length)
90 {
91     HANDLE hfile, hmapping = NULL;
92
93     hfile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
94     if(hfile == INVALID_HANDLE_VALUE) goto error;
95
96     *length = GetFileSize(hfile, NULL);
97     if(*length == INVALID_FILE_SIZE) goto error;
98
99     hmapping = CreateFileMappingW(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
100     if(!hmapping) goto error;
101
102     *buffer = MapViewOfFile(hmapping, FILE_MAP_READ, 0, 0, 0);
103     if(*buffer == NULL) goto error;
104
105     CloseHandle(hmapping);
106     CloseHandle(hfile);
107
108     return S_OK;
109
110 error:
111     CloseHandle(hmapping);
112     CloseHandle(hfile);
113     return HRESULT_FROM_WIN32(GetLastError());
114 }
115
116 /************************************************************
117  * load_resource_into_memory
118  *
119  * Loads a resource into buffer and stores the number of
120  * read bytes in length.
121  *
122  * PARAMS
123  *   module  [I] handle to the module
124  *   resinfo [I] handle to the resource's information block
125  *   buffer  [O] pointer to destination buffer
126  *   length  [O] size of the obtained data
127  *
128  * RETURNS
129  *   Success: D3D_OK
130  *   Failure:
131  *     See error codes for SizeofResource, LoadResource and LockResource
132  *
133  * NOTES
134  *   The memory doesn't need to be freed by the caller manually
135  *
136  */
137 HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer, DWORD *length)
138 {
139     HGLOBAL resource;
140
141     *length = SizeofResource(module, resinfo);
142     if(*length == 0) return HRESULT_FROM_WIN32(GetLastError());
143
144     resource = LoadResource(module, resinfo);
145     if( !resource ) return HRESULT_FROM_WIN32(GetLastError());
146
147     *buffer = LockResource(resource);
148     if(*buffer == NULL) return HRESULT_FROM_WIN32(GetLastError());
149
150     return S_OK;
151 }
152
153
154 /************************************************************
155  * get_format_info
156  *
157  * Returns information about the specified format.
158  * If the format is unsupported, it's filled with the D3DFMT_UNKNOWN desc.
159  *
160  * PARAMS
161  *   format [I] format whose description is queried
162  *   desc   [O] pointer to a StaticPixelFormatDesc structure
163  *
164  */
165 const PixelFormatDesc *get_format_info(D3DFORMAT format)
166 {
167     unsigned int i = 0;
168     while(formats[i].format != format && formats[i].format != D3DFMT_UNKNOWN) i++;
169     if (formats[i].format == D3DFMT_UNKNOWN)
170         FIXME("Unknown format %#x (as FOURCC %s).\n", format, debugstr_an((const char *)&format, 4));
171     return &formats[i];
172 }
173
174 const PixelFormatDesc *get_format_info_idx(int idx)
175 {
176     if(idx >= sizeof(formats) / sizeof(formats[0]))
177         return NULL;
178     if(formats[idx].format == D3DFMT_UNKNOWN)
179         return NULL;
180     return &formats[idx];
181 }
182
183 #define WINE_D3DX_TO_STR(x) case x: return #x
184
185 const char *debug_d3dxparameter_class(D3DXPARAMETER_CLASS c)
186 {
187     switch (c)
188     {
189         WINE_D3DX_TO_STR(D3DXPC_SCALAR);
190         WINE_D3DX_TO_STR(D3DXPC_VECTOR);
191         WINE_D3DX_TO_STR(D3DXPC_MATRIX_ROWS);
192         WINE_D3DX_TO_STR(D3DXPC_MATRIX_COLUMNS);
193         WINE_D3DX_TO_STR(D3DXPC_OBJECT);
194         WINE_D3DX_TO_STR(D3DXPC_STRUCT);
195         default:
196             FIXME("Unrecognized D3DXPARAMETER_CLASS %#x.\n", c);
197             return "unrecognized";
198     }
199 }
200
201 const char *debug_d3dxparameter_type(D3DXPARAMETER_TYPE t)
202 {
203     switch (t)
204     {
205         WINE_D3DX_TO_STR(D3DXPT_VOID);
206         WINE_D3DX_TO_STR(D3DXPT_BOOL);
207         WINE_D3DX_TO_STR(D3DXPT_INT);
208         WINE_D3DX_TO_STR(D3DXPT_FLOAT);
209         WINE_D3DX_TO_STR(D3DXPT_STRING);
210         WINE_D3DX_TO_STR(D3DXPT_TEXTURE);
211         WINE_D3DX_TO_STR(D3DXPT_TEXTURE1D);
212         WINE_D3DX_TO_STR(D3DXPT_TEXTURE2D);
213         WINE_D3DX_TO_STR(D3DXPT_TEXTURE3D);
214         WINE_D3DX_TO_STR(D3DXPT_TEXTURECUBE);
215         WINE_D3DX_TO_STR(D3DXPT_SAMPLER);
216         WINE_D3DX_TO_STR(D3DXPT_SAMPLER1D);
217         WINE_D3DX_TO_STR(D3DXPT_SAMPLER2D);
218         WINE_D3DX_TO_STR(D3DXPT_SAMPLER3D);
219         WINE_D3DX_TO_STR(D3DXPT_SAMPLERCUBE);
220         WINE_D3DX_TO_STR(D3DXPT_PIXELSHADER);
221         WINE_D3DX_TO_STR(D3DXPT_VERTEXSHADER);
222         WINE_D3DX_TO_STR(D3DXPT_PIXELFRAGMENT);
223         WINE_D3DX_TO_STR(D3DXPT_VERTEXFRAGMENT);
224         WINE_D3DX_TO_STR(D3DXPT_UNSUPPORTED);
225         default:
226            FIXME("Unrecognized D3DXPARAMETER_TYP %#x.\n", t);
227             return "unrecognized";
228     }
229 }
230
231 #undef WINE_D3DX_TO_STR