maintainers: Update the Direct3D section.
[wine.git] / dlls / msvfw32 / tests / msvfw.c
blobb22b466f595ab527c736d9647e5f5f58283246ae
1 /*
2 * Unit tests for video playback
4 * Copyright 2008,2010 Jörg Höhle
5 * Copyright 2008 Austin English
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define WIN32_LEAN_AND_MEAN
23 #include <windows.h>
24 #include <vfw.h>
26 #include "wine/test.h"
28 static inline int get_stride(int width, int depth)
30 return ((depth * width + 31) >> 3) & ~3;
33 static void test_OpenCase(void)
35 HIC h;
36 ICINFO info;
37 /* Check if default handler works */
38 h = ICOpen(mmioFOURCC('v','i','d','c'),0,ICMODE_DECOMPRESS);
39 ok(0!=h,"ICOpen(vidc.0) failed\n");
40 if (h) {
41 info.dwSize = sizeof(info);
42 info.szName[0] = 0;
43 ICGetInfo(h, &info, sizeof(info));
44 trace("The default decompressor is %s\n", wine_dbgstr_w(info.szName));
45 ok(ICClose(h)==ICERR_OK,"ICClose failed\n");
47 h = ICOpen(mmioFOURCC('v','i','d','c'),0,ICMODE_COMPRESS);
48 ok(0!=h || broken(h == 0),"ICOpen(vidc.0) failed\n"); /* Not present in Win8 */
49 if (h) {
50 info.dwSize = sizeof(info);
51 info.szName[0] = 0;
52 ICGetInfo(h, &info, sizeof(info));
53 trace("The default compressor is %s\n", wine_dbgstr_w(info.szName));
54 ok(ICClose(h)==ICERR_OK,"ICClose failed\n");
57 /* Open a compressor with combinations of lowercase
58 * and uppercase compressortype and handler.
60 h = ICOpen(mmioFOURCC('v','i','d','c'),mmioFOURCC('m','s','v','c'),ICMODE_DECOMPRESS);
61 ok(0!=h,"ICOpen(vidc.msvc) failed\n");
62 if (h) {
63 ok(ICClose(h)==ICERR_OK,"ICClose failed\n");
65 h = ICOpen(mmioFOURCC('v','i','d','c'),mmioFOURCC('M','S','V','C'),ICMODE_DECOMPRESS);
66 ok(0!=h,"ICOpen(vidc.MSVC) failed\n");
67 if (h) {
68 ok(ICClose(h)==ICERR_OK,"ICClose failed\n");
70 h = ICOpen(mmioFOURCC('V','I','D','C'),mmioFOURCC('m','s','v','c'),ICMODE_DECOMPRESS);
71 ok(0!=h,"ICOpen(VIDC.msvc) failed\n");
72 if (h) {
73 ok(ICClose(h)==ICERR_OK,"ICClose failed\n");
75 h = ICOpen(mmioFOURCC('V','I','D','C'),mmioFOURCC('M','S','V','C'),ICMODE_DECOMPRESS);
76 ok(0!=h,"ICOpen(VIDC.MSVC) failed\n");
77 if (h) {
78 ok(ICClose(h)==ICERR_OK,"ICClose failed\n");
80 h = ICOpen(mmioFOURCC('v','i','d','c'),mmioFOURCC('m','S','v','C'),ICMODE_DECOMPRESS);
81 ok(0!=h,"ICOpen(vidc.mSvC) failed\n");
82 if (h) {
83 ok(ICClose(h)==ICERR_OK,"ICClose failed\n");
85 h = ICOpen(mmioFOURCC('v','I','d','C'),mmioFOURCC('m','s','v','c'),ICMODE_DECOMPRESS);
86 ok(0!=h,"ICOpen(vIdC.msvc) failed\n");
87 if (h) {
88 ok(ICClose(h)==ICERR_OK,"ICClose failed\n");
92 static void test_Locate(void)
94 static BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER),32,8, 1,8, BI_RLE8, 0,100000,100000, 0,0};
95 static BITMAPINFOHEADER bo = {sizeof(BITMAPINFOHEADER),32,8, 1,8, BI_RGB, 0,100000,100000, 0,0};
96 BITMAPINFOHEADER tmp = {sizeof(BITMAPINFOHEADER)};
97 HIC h;
98 DWORD err;
100 /* Oddly, MSDN documents that ICLocate takes BITMAPINFOHEADER
101 * pointers, while ICDecompressQuery takes the larger
102 * BITMAPINFO. Probably it's all the same as long as the
103 * variable length color quads are present when they are
104 * needed. */
106 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
107 ok(h != 0, "RLE8->RGB failed\n");
108 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
110 bo.biHeight = - bo.biHeight;
111 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
112 ok(h == 0, "RLE8->RGB height<0 succeeded\n");
113 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
114 bo.biHeight = - bo.biHeight;
116 bi.biCompression = mmioFOURCC('c','v','i','d'); /* Cinepak */
117 h = ICOpen(ICTYPE_VIDEO, mmioFOURCC('c','v','i','d'), ICMODE_DECOMPRESS);
118 if (h == 0) win_skip("Cinepak/ICCVID codec not found\n");
119 else {
120 bo.biBitCount = bi.biBitCount = 32;
121 err = ICDecompressQuery(h, &bi, &bo);
122 ok(err == ICERR_OK, "Query cvid->RGB32: %ld\n", err);
124 err = ICDecompressQuery(h, &bi, NULL);
125 ok(err == ICERR_OK, "Query cvid 32: %ld\n", err);
127 bo.biHeight = -bo.biHeight;
128 err = ICDecompressQuery(h, &bi, &bo);
129 ok(err == ICERR_OK, "Query cvid->RGB32 height<0: %ld\n", err);
130 bo.biHeight = -bo.biHeight;
132 bi.biWidth = 17;
134 bi.biBitCount = 8;
135 err = ICDecompressGetFormat(h, &bi, &tmp);
136 ok(err == ICERR_OK, "Query cvid output format: %ld\n", err);
137 ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
138 ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %ld\n",
139 get_stride(17, 24) * 8, tmp.biSizeImage);
141 bi.biBitCount = 15;
142 err = ICDecompressGetFormat(h, &bi, &tmp);
143 ok(err == ICERR_OK, "Query cvid output format: %ld\n", err);
144 ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
145 ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %ld\n",
146 get_stride(17, 24) * 8, tmp.biSizeImage);
148 bi.biBitCount = 16;
149 err = ICDecompressGetFormat(h, &bi, &tmp);
150 ok(err == ICERR_OK, "Query cvid output format: %ld\n", err);
151 ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
152 ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %ld\n",
153 get_stride(17, 24) * 8, tmp.biSizeImage);
155 bi.biBitCount = 24;
156 err = ICDecompressGetFormat(h, &bi, &tmp);
157 ok(err == ICERR_OK, "Query cvid output format: %ld\n", err);
158 ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
159 ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %ld\n",
160 get_stride(17, 24) * 8, tmp.biSizeImage);
162 bi.biBitCount = 32;
163 err = ICDecompressGetFormat(h, &bi, &tmp);
164 ok(err == ICERR_OK, "Query cvid output format: %ld\n", err);
165 ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
166 ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %ld\n",
167 get_stride(17, 24) * 8, tmp.biSizeImage);
169 bi.biWidth = 32;
171 ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
173 bo.biBitCount = bi.biBitCount = 8;
174 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
175 todo_wine ok(h != 0, "cvid->RGB8 failed\n");
176 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
177 bo.biHeight = - bo.biHeight;
178 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
179 todo_wine ok(h != 0, "cvid->RGB8 height<0 failed\n");
180 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
181 bo.biHeight = - bo.biHeight;
183 bo.biBitCount = bi.biBitCount = 16;
184 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
185 ok(h != 0, "cvid->RGB16 failed\n");
186 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
187 bo.biHeight = - bo.biHeight;
188 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
189 ok(h != 0, "cvid->RGB16 height<0 failed\n");
190 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
191 bo.biHeight = - bo.biHeight;
193 bo.biBitCount = bi.biBitCount = 32;
194 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
195 ok(h != 0, "cvid->RGB32 failed\n");
196 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
197 bo.biHeight = - bo.biHeight;
198 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
199 ok(h != 0, "cvid->RGB32 height<0 failed\n");
200 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
201 bo.biHeight = - bo.biHeight;
203 bi.biCompression = mmioFOURCC('C','V','I','D');
204 /* Unlike ICOpen, upper case fails with ICLocate. */
205 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
206 ok(h == 0, "CVID->RGB32 upper case succeeded\n");
207 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
210 bi.biCompression = mmioFOURCC('M','S','V','C'); /* MS Video 1 */
212 bo.biBitCount = bi.biBitCount = 16;
213 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
214 ok(h != 0, "MSVC->RGB16 failed\n");
215 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
217 bo.biHeight = - bo.biHeight;
218 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
219 todo_wine ok(h != 0, "MSVC->RGB16 height<0 failed\n");
220 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
221 bo.biHeight = - bo.biHeight;
223 bo.biHeight--;
224 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
225 ok(h == 0, "MSVC->RGB16 height too small succeeded\n");
226 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
227 bo.biHeight++;
229 /* ICLocate wants upper case MSVC */
230 bi.biCompression = mmioFOURCC('m','s','v','c');
231 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
232 ok(h == 0, "msvc->RGB16 succeeded\n");
233 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
235 bi.biCompression = mmioFOURCC('M','S','V','C');
236 h = ICOpen(ICTYPE_VIDEO, mmioFOURCC('M','S','V','C'), ICMODE_DECOMPRESS);
237 ok(h != 0, "No MSVC codec installed!?\n");
238 if (h != 0) {
239 err = ICDecompressQuery(h, &bi, &bo);
240 ok(err == ICERR_OK, "Query MSVC->RGB16: %ld\n", err);
242 err = ICDecompressQuery(h, &bi, NULL);
243 ok(err == ICERR_OK, "Query MSVC 16: %ld\n", err);
245 bo.biHeight = -bo.biHeight;
246 err = ICDecompressQuery(h, &bi, &bo);
247 todo_wine ok(err == ICERR_OK, "Query MSVC->RGB16 height<0: %ld\n", err);
248 bo.biHeight = -bo.biHeight;
250 bo.biBitCount = 24;
251 err = ICDecompressQuery(h, &bi, &bo);
252 ok(err == ICERR_OK, "Query MSVC 16->24: %ld\n", err);
253 bo.biBitCount = 16;
255 bi.biWidth = 553;
257 bi.biBitCount = 8;
258 err = ICDecompressGetFormat(h, &bi, &tmp);
259 ok(err == ICERR_OK, "Query MSVC output format: %ld\n", err);
260 ok(tmp.biBitCount == 8, "Expected 8 bit, got %d bit\n", tmp.biBitCount);
261 ok(tmp.biWidth == 552, "Expected width 552, got %ld\n", tmp.biWidth);
262 ok(tmp.biSizeImage == get_stride(552, 8) * 8, "Expected size %d, got %ld\n",
263 get_stride(552, 8) * 8, tmp.biSizeImage);
265 bi.biBitCount = 15;
266 err = ICDecompressGetFormat(h, &bi, &tmp);
267 ok(err == ICERR_BADFORMAT, "Query MSVC output format: %ld\n", err);
269 bi.biBitCount = 16;
270 err = ICDecompressGetFormat(h, &bi, &tmp);
271 ok(err == ICERR_OK, "Query MSVC output format: %ld\n", err);
272 ok(tmp.biBitCount == 16, "Expected 16 bit, got %d bit\n", tmp.biBitCount);
273 ok(tmp.biWidth == 552, "Expected width 552, got %ld\n", tmp.biWidth);
274 ok(tmp.biSizeImage == get_stride(552, 16) * 8, "Expected size %d, got %ld\n",
275 get_stride(552, 16) * 8, tmp.biSizeImage);
277 bi.biBitCount = 24;
278 err = ICDecompressGetFormat(h, &bi, &tmp);
279 ok(err == ICERR_BADFORMAT, "Query MSVC output format: %ld\n", err);
281 bi.biBitCount = 32;
282 err = ICDecompressGetFormat(h, &bi, &tmp);
283 ok(err == ICERR_BADFORMAT, "Query MSVC output format: %ld\n", err);
285 bi.biHeight = 17;
286 bi.biBitCount = 8;
287 err = ICDecompressGetFormat(h, &bi, &tmp);
288 ok(err == ICERR_OK, "Query MSVC output format: %ld\n", err);
289 ok(tmp.biHeight == 16, "Expected height 16, got %ld\n", tmp.biHeight);
290 bi.biHeight = 8;
292 bi.biWidth = 32;
294 bi.biCompression = mmioFOURCC('m','s','v','c');
295 err = ICDecompressQuery(h, &bi, &bo);
296 ok(err == ICERR_BADFORMAT, "Query msvc->RGB16: %ld\n", err);
298 ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
301 bi.biCompression = BI_RGB;
302 bo.biBitCount = bi.biBitCount = 8;
303 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
304 ok(h != 0, "RGB8->RGB identity failed\n");
305 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
307 bi.biCompression = BI_RLE8;
308 h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
309 ok(h != 0, "RLE8->RGB again failed\n");
310 if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
313 static void test_ICSeqCompress(void)
315 /* The purpose of this test is to validate sequential frame compressing
316 * functions. The MRLE codec will be used because Wine supports it and
317 * it is present in any Windows.
319 HIC h;
320 DWORD err, vidc = mmioFOURCC('v','i','d','c'), mrle = mmioFOURCC('m', 'r', 'l', 'e');
321 DWORD i;
322 LONG frame_len;
323 BOOL key_frame, ret;
324 char *frame;
325 COMPVARS pc;
326 struct { BITMAPINFOHEADER header; RGBQUAD map[256]; }
327 input_header = { {sizeof(BITMAPINFOHEADER), 32, 1, 1, 8, 0, 32*8, 0, 0, 256, 256},
328 {{255,0,0}, {0,255,0}, {0,0,255}, {255,255,255}}};
329 PBITMAPINFO bitmap = (PBITMAPINFO) &input_header;
330 static BYTE input[32] = {1,2,3,3,3,3,2,3,1};
331 static const BYTE output_kf[] = {1,1,1,2,4,3,0,3,2,3,1,0,23,0,0,0,0,1}, /* key frame*/
332 output_nkf[] = {0,0,0,1}; /* non key frame */
334 h = ICOpen(vidc, mrle, ICMODE_COMPRESS);
335 ok(h != NULL, "Expected non-NULL\n");
337 pc.cbSize = sizeof(pc);
338 pc.dwFlags = ICMF_COMPVARS_VALID;
339 pc.fccType = vidc;
340 pc.fccHandler = mrle;
341 pc.hic = h;
342 pc.lpbiIn = NULL;
343 pc.lpbiOut = NULL;
344 pc.lpBitsOut = pc.lpBitsPrev = pc.lpState = NULL;
345 pc.lQ = ICQUALITY_DEFAULT;
346 pc.lKey = 1;
347 pc.lDataRate = 300;
348 pc.lpState = NULL;
349 pc.cbState = 0;
351 ret = ICSeqCompressFrameStart(&pc, bitmap);
352 ok(ret == TRUE, "Expected TRUE\n");
353 /* Check that reserved pointers were allocated */
354 ok(pc.lpbiIn != NULL, "Expected non-NULL\n");
355 ok(pc.lpbiOut != NULL, "Expected non-NULL\n");
357 for(i = 0; i < 9; i++)
359 frame_len = 0;
360 frame = ICSeqCompressFrame(&pc, 0, input, &key_frame, &frame_len);
361 ok(frame != NULL, "Frame[%ld]: Expected non-NULL\n", i);
362 if (frame_len == sizeof(output_nkf))
363 ok(!memcmp(output_nkf, frame, frame_len), "Frame[%ld]: Contents do not match\n", i);
364 else if (frame_len == sizeof(output_kf))
365 ok(!memcmp(output_kf, frame, frame_len), "Frame[%ld]: Contents do not match\n", i);
366 else
367 ok(0, "Unknown frame size of %ld byten\n", frame_len);
370 ICSeqCompressFrameEnd(&pc);
371 ICCompressorFree(&pc);
372 /* ICCompressorFree already closed the HIC */
373 err = ICClose(h);
374 ok(err == ICERR_BADHANDLE, "Expected -8, got %ld\n", err);
377 static ICINFO enum_info;
379 static LRESULT CALLBACK enum_driver_proc(DWORD_PTR id, HDRVR driver, UINT msg,
380 LPARAM lparam1, LPARAM lparam2)
382 ICINFO *info = (ICINFO *)lparam1;
384 ok(!id, "Got unexpected id %#Ix.\n", id);
385 ok(msg == ICM_GETINFO, "Got unexpected message %#x.\n", msg);
386 ok(info == &enum_info, "Expected lparam1 %p, got %p.\n", &enum_info, info);
387 ok(lparam2 == sizeof(ICINFO), "Got lparam2 %Id.\n", lparam2);
389 ok(!info->fccType, "Got unexpected type %#lx.\n", info->fccType);
390 ok(!info->fccHandler, "Got unexpected handler %#lx.\n", info->fccHandler);
391 ok(!info->dwFlags, "Got unexpected flags %#lx.\n", info->dwFlags);
392 ok(!info->dwVersion, "Got unexpected version %#lx.\n", info->dwVersion);
393 ok(info->dwVersionICM == ICVERSION, "Got unexpected ICM version %#lx.\n", info->dwVersionICM);
394 ok(!info->szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(info->szName));
395 ok(!info->szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(info->szDescription));
396 ok(!info->szDriver[0], "Got unexpected driver %s.\n", wine_dbgstr_w(info->szDriver));
398 info->dwVersion = 0xdeadbeef;
399 return sizeof(ICINFO);
402 static void test_ICInfo(void)
404 static const DWORD test_type = mmioFOURCC('w','i','n','e');
405 static const DWORD test_handler = mmioFOURCC('t','e','s','t');
406 DWORD i = 0, found = 0;
407 char buffer[MAX_PATH];
408 ICINFO info, info2;
409 unsigned char *fcc;
410 DWORD size;
411 BOOL ret;
412 HKEY key;
413 LONG res;
415 for (;;)
417 memset(&info, 0x55, sizeof(info));
418 info.dwSize = sizeof(info);
419 if (!ICInfo(0, i++, &info))
420 break;
421 trace("Codec name: %s, fccHandler: 0x%08lx\n", wine_dbgstr_w(info.szName), info.fccHandler);
422 ok(info.fccType, "Expected nonzero type.\n");
423 ok(info.fccHandler, "Expected nonzero handler.\n");
424 ok(!info.dwFlags, "Got unexpected flags %#lx.\n", info.dwFlags);
425 ok(!info.dwVersion, "Got unexpected version %#lx.\n", info.dwVersion);
426 ok(info.dwVersionICM == ICVERSION, "Got unexpected ICM version %#lx.\n", info.dwVersionICM);
427 ok(!info.szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szName));
428 ok(!info.szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szDescription));
430 ok(ICInfo(info.fccType, info.fccHandler, &info2),
431 "ICInfo failed on fcc 0x%08lx\n", info.fccHandler);
433 fcc = (unsigned char *)&info.fccHandler;
434 if (!isalpha(fcc[0])) continue;
436 found++;
437 /* Test getting info with a different case - bug 41602 */
438 fcc[0] ^= 0x20;
439 ok(ICInfo(info.fccType, info.fccHandler, &info2),
440 "ICInfo failed on fcc 0x%08lx\n", info.fccHandler);
442 ok(found != 0, "expected at least one codec\n");
444 memset(&info, 0x55, sizeof(info));
445 info.dwSize = sizeof(info);
446 ok(!ICInfo(ICTYPE_VIDEO, mmioFOURCC('f','a','k','e'), &info), "expected failure\n");
447 ok(info.fccType == ICTYPE_VIDEO, "got 0x%08lx\n", info.fccType);
448 ok(info.fccHandler == mmioFOURCC('f','a','k','e'), "got 0x%08lx\n", info.fccHandler);
449 ok(!info.dwFlags, "Got unexpected flags %#lx.\n", info.dwFlags);
450 ok(!info.dwVersion, "Got unexpected version %#lx.\n", info.dwVersion);
451 ok(info.dwVersionICM == ICVERSION, "Got unexpected ICM version %#lx.\n", info.dwVersionICM);
452 ok(!info.szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szName));
453 ok(!info.szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szDescription));
454 ok(!info.szDriver[0], "Got unexpected driver %s.\n", wine_dbgstr_w(info.szDriver));
456 if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT"
457 "\\CurrentVersion\\Drivers32", 0, KEY_ALL_ACCESS, &key))
459 ret = ICInstall(test_type, test_handler, (LPARAM)"bogus", NULL, ICINSTALL_DRIVER);
460 ok(ret, "Failed to install driver.\n");
462 size = sizeof(buffer);
463 res = RegQueryValueExA(key, "wine.test", NULL, NULL, (BYTE *)buffer, &size);
464 ok(!res, "Failed to query value, error %ld.\n", res);
465 ok(!strcmp(buffer, "bogus"), "Got unexpected value \"%s\".\n", buffer);
467 memset(&info, 0x55, sizeof(info));
468 info.dwSize = sizeof(info);
469 ok(ICInfo(test_type, test_handler, &info), "Expected success.\n");
470 ok(info.fccType == test_type, "Got unexpected type %#lx.\n", info.fccType);
471 ok(info.fccHandler == test_handler, "Got unexpected handler %#lx.\n", info.fccHandler);
472 ok(!info.dwFlags, "Got unexpected flags %#lx.\n", info.dwFlags);
473 ok(!info.dwVersion, "Got unexpected version %#lx.\n", info.dwVersion);
474 ok(info.dwVersionICM == ICVERSION, "Got unexpected ICM version %#lx.\n", info.dwVersionICM);
475 ok(!info.szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szName));
476 ok(!info.szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szDescription));
477 ok(!lstrcmpW(info.szDriver, L"bogus"), "Got unexpected driver %s.\n", wine_dbgstr_w(info.szDriver));
479 /* Drivers installed after msvfw32 is loaded are not enumerated. */
480 todo_wine
481 ok(!ICInfo(test_type, 0, &info), "Expected failure.\n");
483 ret = ICRemove(test_type, test_handler, 0);
484 ok(ret, "Failed to remove driver.\n");
486 res = RegDeleteValueA(key, "wine.test");
487 ok(res == ERROR_FILE_NOT_FOUND, "Got error %lu.\n", res);
488 RegCloseKey(key);
490 else
491 win_skip("Not enough permissions to register codec drivers.\n");
493 if (WritePrivateProfileStringA("drivers32", "wine.test", "bogus", "system.ini"))
495 memset(&info, 0x55, sizeof(info));
496 info.dwSize = sizeof(info);
497 ok(ICInfo(test_type, test_handler, &info), "Expected success.\n");
498 ok(info.fccType == test_type, "Got unexpected type %#lx.\n", info.fccType);
499 ok(info.fccHandler == test_handler, "Got unexpected handler %#lx.\n", info.fccHandler);
500 ok(!info.dwFlags, "Got unexpected flags %#lx.\n", info.dwFlags);
501 ok(!info.dwVersion, "Got unexpected version %#lx.\n", info.dwVersion);
502 ok(info.dwVersionICM == ICVERSION, "Got unexpected ICM version %#lx.\n", info.dwVersionICM);
503 ok(!info.szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szName));
504 ok(!info.szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szDescription));
505 ok(!lstrcmpW(info.szDriver, L"bogus"), "Got unexpected driver %s.\n", wine_dbgstr_w(info.szDriver));
507 /* Drivers installed after msvfw32 is loaded are not enumerated. */
508 todo_wine
509 ok(!ICInfo(test_type, 0, &info), "Expected failure.\n");
511 ret = WritePrivateProfileStringA("drivers32", "wine.test", NULL, "system.ini");
512 ok(ret, "Failed to remove INI entry.\n");
515 ret = ICInstall(test_type, test_handler, (LPARAM)enum_driver_proc, NULL, ICINSTALL_FUNCTION);
516 ok(ret, "Failed to install driver.\n");
518 memset(&enum_info, 0x55, sizeof(enum_info));
519 enum_info.dwSize = sizeof(enum_info);
520 ok(ICInfo(test_type, test_handler, &enum_info), "Expected success.\n");
521 ok(!enum_info.fccType, "Got unexpected type %#lx.\n", enum_info.fccType);
522 ok(!enum_info.fccHandler, "Got unexpected handler %#lx.\n", enum_info.fccHandler);
523 ok(!enum_info.dwFlags, "Got unexpected flags %#lx.\n", enum_info.dwFlags);
524 ok(enum_info.dwVersion == 0xdeadbeef, "Got unexpected version %#lx.\n", enum_info.dwVersion);
525 ok(enum_info.dwVersionICM == ICVERSION, "Got unexpected ICM version %#lx.\n", enum_info.dwVersionICM);
526 ok(!enum_info.szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(enum_info.szName));
527 ok(!enum_info.szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(enum_info.szDescription));
528 ok(!enum_info.szDriver[0], "Got unexpected driver %s.\n", wine_dbgstr_w(enum_info.szDriver));
530 /* Functions installed after msvfw32 is loaded are enumerated. */
531 memset(&enum_info, 0x55, sizeof(enum_info));
532 enum_info.dwSize = sizeof(enum_info);
533 ok(ICInfo(test_type, 0, &enum_info), "Expected success.\n");
534 ok(!enum_info.fccType, "Got unexpected type %#lx.\n", enum_info.fccType);
535 ok(!enum_info.fccHandler, "Got unexpected handler %#lx.\n", enum_info.fccHandler);
536 ok(!enum_info.dwFlags, "Got unexpected flags %#lx.\n", enum_info.dwFlags);
537 ok(enum_info.dwVersion == 0xdeadbeef, "Got unexpected version %#lx.\n", enum_info.dwVersion);
538 ok(enum_info.dwVersionICM == ICVERSION, "Got unexpected ICM version %#lx.\n", enum_info.dwVersionICM);
539 ok(!enum_info.szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(enum_info.szName));
540 ok(!enum_info.szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(enum_info.szDescription));
541 ok(!enum_info.szDriver[0], "Got unexpected driver %s.\n", wine_dbgstr_w(enum_info.szDriver));
543 ret = ICRemove(test_type, test_handler, 0);
544 ok(ret, "Failed to remove driver.\n");
547 static int get_display_format_test;
549 static DWORD get_size_image(LONG width, LONG height, WORD depth)
551 DWORD ret = width * depth;
552 ret = (ret + 7) / 8; /* divide by byte size, rounding up */
553 ret = (ret + 3) & ~3; /* align to 4 bytes */
554 ret *= abs(height);
555 return ret;
558 static const RGBQUAD color_yellow = {0x00, 0xff, 0xff, 0x00};
560 static BITMAPINFOHEADER gdf_in, *gdf_out;
562 static LRESULT CALLBACK gdf_driver_proc(DWORD_PTR id, HDRVR driver, UINT msg,
563 LPARAM lparam1, LPARAM lparam2)
565 LRESULT ret = 0;
567 if (winetest_debug > 1)
568 trace("(%#Ix, %p, %#x, %#Ix, %#Ix)\n", id, driver, msg, lparam1, lparam2);
570 switch(msg)
572 case DRV_LOAD:
573 case DRV_OPEN:
574 case DRV_CLOSE:
575 case DRV_FREE:
576 return 1;
577 case ICM_DECOMPRESS_QUERY:
579 BITMAPINFOHEADER *out = (BITMAPINFOHEADER *)lparam2;
580 DWORD expected_size;
582 ok(lparam1 == (LPARAM)&gdf_in, "got input %#Ix\n", lparam1);
584 if (!out)
585 return ICERR_OK;
587 ok(out == gdf_out, "got output %p\n", out);
589 ok(out->biSize == sizeof(*out), "got size %ld\n", out->biSize);
590 expected_size = get_size_image(out->biWidth, out->biHeight, out->biBitCount);
591 ok(out->biSizeImage == expected_size, "expected image size %ld, got %ld\n",
592 expected_size, out->biSizeImage);
594 ok(out->biPlanes == 0xcccc, "got planes %d\n", out->biPlanes);
595 ok(out->biXPelsPerMeter == 0xcccccccc && out->biYPelsPerMeter == 0xcccccccc,
596 "got resolution %ldx%ld\n", out->biXPelsPerMeter, out->biYPelsPerMeter);
597 ok(out->biClrUsed == 0xcccccccc, "got biClrUsed %lu\n", out->biClrUsed);
598 ok(out->biClrImportant == 0xcccccccc, "got biClrImportant %lu\n", out->biClrImportant);
600 switch (get_display_format_test)
602 case 0:
603 return ICERR_OK;
604 case 1:
605 if (out->biWidth == 30 && out->biHeight == 40 && out->biCompression == BI_RGB && out->biBitCount == 16)
606 return ICERR_OK;
607 break;
608 case 2:
609 if (out->biWidth == 30 && out->biHeight == 40 && out->biCompression == BI_BITFIELDS && out->biBitCount == 16)
610 return ICERR_OK;
611 break;
612 case 3:
613 if (out->biWidth == 30 && out->biHeight == 40 && out->biCompression == BI_RGB && out->biBitCount == 24)
614 return ICERR_OK;
615 break;
616 case 4:
617 if (out->biWidth == 30 && out->biHeight == 40 && out->biCompression == BI_RGB && out->biBitCount == 32)
618 return ICERR_OK;
619 break;
620 case 5:
621 if (out->biWidth == 10 && out->biHeight == 20 && out->biCompression == BI_RGB && out->biBitCount == 32)
622 return ICERR_OK;
623 break;
624 case 6:
625 break;
628 return ICERR_BADFORMAT;
630 case ICM_DECOMPRESS_GET_FORMAT:
632 BITMAPINFOHEADER *out = (BITMAPINFOHEADER *)lparam2;
634 ok(lparam1 == (LPARAM)&gdf_in, "got input %#Ix\n", lparam1);
635 if (out)
637 ok(out == gdf_out, "got output %p\n", out);
639 memset(out, 0x55, sizeof(*out));
640 out->biWidth = 50;
641 out->biHeight = 60;
642 out->biBitCount = 0xdead;
643 out->biCompression = 0xbeef;
644 out->biSizeImage = 0;
646 return ICERR_OK;
649 case ICM_DECOMPRESS_GET_PALETTE:
651 BITMAPINFO *out = (BITMAPINFO *)lparam2;
653 ok(lparam1 == (LPARAM)&gdf_in, "got input %#Ix\n", lparam1);
654 if (out)
656 ok(out == (BITMAPINFO *)gdf_out, "got output %p\n", out);
658 out->bmiHeader.biClrUsed = 1;
659 out->bmiColors[0] = color_yellow;
661 return 0xdeadbeef;
666 return ret;
669 static void check_bitmap_header_(int line, BITMAPINFOHEADER *header, LONG width, LONG height, WORD depth, DWORD compression)
671 ok_(__FILE__, line)(header->biWidth == width, "expected %ld, got %ld\n", width, header->biWidth);
672 ok_(__FILE__, line)(header->biHeight == height, "expected %ld, got %ld\n", height, header->biHeight);
673 ok_(__FILE__, line)(header->biBitCount == depth, "expected %d, got %d\n", depth, header->biBitCount);
674 ok_(__FILE__, line)(header->biCompression == compression, "expected %#lx, got %#lx\n", compression, header->biCompression);
676 #define check_bitmap_header(a,b,c,d,e) check_bitmap_header_(__LINE__,a,b,c,d,e)
678 static void test_ICGetDisplayFormat(void)
680 static const DWORD testcc = mmioFOURCC('t','e','s','t');
681 char outbuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
682 BITMAPINFO *out_bmi;
683 LRESULT lres;
684 BOOL ret;
685 HIC hic;
687 memset(&gdf_in, 0xcc, sizeof(gdf_in));
688 gdf_in.biSize = sizeof(gdf_in);
689 gdf_in.biWidth = 10;
690 gdf_in.biHeight = 20;
691 gdf_in.biBitCount = 1;
692 gdf_in.biCompression = testcc;
694 ret = ICInstall(ICTYPE_VIDEO, testcc, (LPARAM)gdf_driver_proc, NULL, ICINSTALL_FUNCTION);
695 ok(ret, "ICInstall failed\n");
697 hic = ICOpen(ICTYPE_VIDEO, testcc, ICMODE_DECOMPRESS);
698 ok(ret, "ICOpen failed\n");
700 memset(outbuf, 0, sizeof(outbuf));
701 gdf_out = (BITMAPINFOHEADER *)outbuf;
703 /* ICGetDisplayFormat tries several default formats; make sure those work */
704 get_display_format_test = 0;
705 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40);
706 ok(hic != NULL, "ICGetDisplayFormat failed\n");
707 check_bitmap_header(gdf_out, 30, 40, 1, BI_RGB);
709 get_display_format_test = 1;
710 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40);
711 ok(hic != NULL, "ICGetDisplayFormat failed\n");
712 check_bitmap_header(gdf_out, 30, 40, 16, BI_RGB);
714 get_display_format_test = 2;
715 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40);
716 ok(hic != NULL, "ICGetDisplayFormat failed\n");
717 check_bitmap_header(gdf_out, 30, 40, 16, BI_BITFIELDS);
719 get_display_format_test = 3;
720 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40);
721 ok(hic != NULL, "ICGetDisplayFormat failed\n");
722 check_bitmap_header(gdf_out, 30, 40, 24, BI_RGB);
724 get_display_format_test = 4;
725 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40);
726 ok(hic != NULL, "ICGetDisplayFormat failed\n");
727 check_bitmap_header(gdf_out, 30, 40, 32, BI_RGB);
729 get_display_format_test = 5;
730 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40);
731 ok(hic != NULL, "ICGetDisplayFormat failed\n");
732 check_bitmap_header(gdf_out, 10, 20, 32, BI_RGB);
734 /* if every default format is rejected, the output of
735 * ICM_DECOMPRESS_GET_FORMAT is returned */
736 get_display_format_test = 6;
737 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40);
738 ok(hic != NULL, "ICGetDisplayFormat failed\n");
739 check_bitmap_header(gdf_out, 50, 60, 0xdead, 0xbeef);
741 /* given bpp is treated as a lower bound */
742 get_display_format_test = 1;
743 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 24, 30, 40);
744 ok(hic != NULL, "ICGetDisplayFormat failed\n");
745 check_bitmap_header(gdf_out, 50, 60, 0xdead, 0xbeef);
747 get_display_format_test = 3;
748 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 24, 30, 40);
749 ok(hic != NULL, "ICGetDisplayFormat failed\n");
750 check_bitmap_header(gdf_out, 30, 40, 24, BI_RGB);
752 get_display_format_test = 0;
754 /* width or height <= 0 causes the input width and height to be supplied */
755 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 0, 40);
756 ok(hic != NULL, "ICGetDisplayFormat failed\n");
757 check_bitmap_header(gdf_out, 10, 20, 1, BI_RGB);
759 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 0);
760 ok(hic != NULL, "ICGetDisplayFormat failed\n");
761 check_bitmap_header(gdf_out, 10, 20, 1, BI_RGB);
763 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, -10, 40);
764 ok(hic != NULL, "ICGetDisplayFormat failed\n");
765 check_bitmap_header(gdf_out, 10, 20, 1, BI_RGB);
767 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, -10);
768 ok(hic != NULL, "ICGetDisplayFormat failed\n");
769 check_bitmap_header(gdf_out, 10, 20, 1, BI_RGB);
771 /* zero bpp causes 32 bpp to be supplied */
772 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 0, 30, 40);
773 ok(hic != NULL, "ICGetDisplayFormat failed\n");
774 ok(gdf_out->biBitCount == 32 || gdf_out->biBitCount == 24,
775 "got %d\n", gdf_out->biBitCount);
776 ok(gdf_out->biCompression == BI_RGB, "got %#lx\n", gdf_out->biCompression);
778 /* specifying 8 bpp yields a request for palette colours */
779 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 8, 30, 40);
780 ok(hic != NULL, "ICGetDisplayFormat failed\n");
781 check_bitmap_header(gdf_out, 30, 40, 8, BI_RGB);
782 ok(gdf_out->biClrUsed == 1, "got biClrUsed %lu\n", gdf_out->biClrUsed);
783 out_bmi = (BITMAPINFO *)gdf_out;
784 ok(!memcmp(&out_bmi->bmiColors[0], &color_yellow, sizeof(color_yellow)),
785 "got wrong colour\n");
787 lres = ICClose(hic);
788 ok(lres == ICERR_OK, "got %Id\n", lres);
790 ret = ICRemove(ICTYPE_VIDEO, testcc, 0);
791 ok(ret, "ICRemove failed\n");
794 START_TEST(msvfw)
796 test_OpenCase();
797 test_Locate();
798 test_ICSeqCompress();
799 test_ICInfo();
800 test_ICGetDisplayFormat();