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
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)
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");
41 info
.dwSize
= sizeof(info
);
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 */
50 info
.dwSize
= sizeof(info
);
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");
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");
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");
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");
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");
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");
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
)};
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
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");
120 bo
.biBitCount
= bi
.biBitCount
= 32;
121 err
= ICDecompressQuery(h
, &bi
, &bo
);
122 ok(err
== ICERR_OK
, "Query cvid->RGB32: %d\n", err
);
124 err
= ICDecompressQuery(h
, &bi
, NULL
);
125 ok(err
== ICERR_OK
, "Query cvid 32: %d\n", err
);
127 bo
.biHeight
= -bo
.biHeight
;
128 err
= ICDecompressQuery(h
, &bi
, &bo
);
129 ok(err
== ICERR_OK
, "Query cvid->RGB32 height<0: %d\n", err
);
130 bo
.biHeight
= -bo
.biHeight
;
135 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
136 ok(err
== ICERR_OK
, "Query cvid output format: %d\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 %d\n",
139 get_stride(17, 24) * 8, tmp
.biSizeImage
);
142 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
143 ok(err
== ICERR_OK
, "Query cvid output format: %d\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 %d\n",
146 get_stride(17, 24) * 8, tmp
.biSizeImage
);
149 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
150 ok(err
== ICERR_OK
, "Query cvid output format: %d\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 %d\n",
153 get_stride(17, 24) * 8, tmp
.biSizeImage
);
156 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
157 ok(err
== ICERR_OK
, "Query cvid output format: %d\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 %d\n",
160 get_stride(17, 24) * 8, tmp
.biSizeImage
);
163 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
164 ok(err
== ICERR_OK
, "Query cvid output format: %d\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 %d\n",
167 get_stride(17, 24) * 8, tmp
.biSizeImage
);
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
;
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");
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");
239 err
= ICDecompressQuery(h
, &bi
, &bo
);
240 ok(err
== ICERR_OK
, "Query MSVC->RGB16: %d\n", err
);
242 err
= ICDecompressQuery(h
, &bi
, NULL
);
243 ok(err
== ICERR_OK
, "Query MSVC 16: %d\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: %d\n", err
);
248 bo
.biHeight
= -bo
.biHeight
;
251 err
= ICDecompressQuery(h
, &bi
, &bo
);
252 ok(err
== ICERR_OK
, "Query MSVC 16->24: %d\n", err
);
258 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
259 ok(err
== ICERR_OK
, "Query MSVC output format: %d\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 %d\n", tmp
.biWidth
);
262 ok(tmp
.biSizeImage
== get_stride(552, 8) * 8, "Expected size %d, got %d\n",
263 get_stride(552, 8) * 8, tmp
.biSizeImage
);
266 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
267 ok(err
== ICERR_BADFORMAT
, "Query MSVC output format: %d\n", err
);
270 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
271 ok(err
== ICERR_OK
, "Query MSVC output format: %d\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 %d\n", tmp
.biWidth
);
274 ok(tmp
.biSizeImage
== get_stride(552, 16) * 8, "Expected size %d, got %d\n",
275 get_stride(552, 16) * 8, tmp
.biSizeImage
);
278 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
279 ok(err
== ICERR_BADFORMAT
, "Query MSVC output format: %d\n", err
);
282 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
283 ok(err
== ICERR_BADFORMAT
, "Query MSVC output format: %d\n", err
);
287 err
= ICDecompressGetFormat(h
, &bi
, &tmp
);
288 ok(err
== ICERR_OK
, "Query MSVC output format: %d\n", err
);
289 ok(tmp
.biHeight
== 16, "Expected height 16, got %d\n", tmp
.biHeight
);
294 bi
.biCompression
= mmioFOURCC('m','s','v','c');
295 err
= ICDecompressQuery(h
, &bi
, &bo
);
296 ok(err
== ICERR_BADFORMAT
, "Query msvc->RGB16: %d\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.
320 DWORD err
, vidc
= mmioFOURCC('v','i','d','c'), mrle
= mmioFOURCC('m', 'r', 'l', 'e');
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
;
340 pc
.fccHandler
= mrle
;
344 pc
.lpBitsOut
= pc
.lpBitsPrev
= pc
.lpState
= NULL
;
345 pc
.lQ
= ICQUALITY_DEFAULT
;
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
++)
360 frame
= ICSeqCompressFrame(&pc
, 0, input
, &key_frame
, &frame_len
);
361 ok(frame
!= NULL
, "Frame[%d]: Expected non-NULL\n", i
);
362 if (frame_len
== sizeof(output_nkf
))
363 ok(!memcmp(output_nkf
, frame
, frame_len
), "Frame[%d]: Contents do not match\n", i
);
364 else if (frame_len
== sizeof(output_kf
))
365 ok(!memcmp(output_kf
, frame
, frame_len
), "Frame[%d]: Contents do not match\n", i
);
367 ok(0, "Unknown frame size of %d byten\n", frame_len
);
370 ICSeqCompressFrameEnd(&pc
);
371 ICCompressorFree(&pc
);
372 /* ICCompressorFree already closed the HIC */
374 ok(err
== ICERR_BADHANDLE
, "Expected -8, got %d\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 %#lx.\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 %ld.\n", lparam2
);
389 ok(!info
->fccType
, "Got unexpected type %#x.\n", info
->fccType
);
390 ok(!info
->fccHandler
, "Got unexpected handler %#x.\n", info
->fccHandler
);
391 ok(!info
->dwFlags
, "Got unexpected flags %#x.\n", info
->dwFlags
);
392 ok(!info
->dwVersion
, "Got unexpected version %#x.\n", info
->dwVersion
);
393 ok(info
->dwVersionICM
== ICVERSION
, "Got unexpected ICM version %#x.\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
];
417 memset(&info
, 0x55, sizeof(info
));
418 info
.dwSize
= sizeof(info
);
419 if (!ICInfo(0, i
++, &info
))
421 trace("Codec name: %s, fccHandler: 0x%08x\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 %#x.\n", info
.dwFlags
);
425 ok(!info
.dwVersion
, "Got unexpected version %#x.\n", info
.dwVersion
);
426 ok(info
.dwVersionICM
== ICVERSION
, "Got unexpected ICM version %#x.\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%08x\n", info
.fccHandler
);
433 fcc
= (unsigned char *)&info
.fccHandler
;
434 if (!isalpha(fcc
[0])) continue;
437 /* Test getting info with a different case - bug 41602 */
439 ok(ICInfo(info
.fccType
, info
.fccHandler
, &info2
),
440 "ICInfo failed on fcc 0x%08x\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%08x\n", info
.fccType
);
448 ok(info
.fccHandler
== mmioFOURCC('f','a','k','e'), "got 0x%08x\n", info
.fccHandler
);
449 ok(!info
.dwFlags
, "Got unexpected flags %#x.\n", info
.dwFlags
);
450 ok(!info
.dwVersion
, "Got unexpected version %#x.\n", info
.dwVersion
);
451 ok(info
.dwVersionICM
== ICVERSION
, "Got unexpected ICM version %#x.\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 %d.\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 %#x.\n", info
.fccType
);
471 ok(info
.fccHandler
== test_handler
, "Got unexpected handler %#x.\n", info
.fccHandler
);
472 ok(!info
.dwFlags
, "Got unexpected flags %#x.\n", info
.dwFlags
);
473 ok(!info
.dwVersion
, "Got unexpected version %#x.\n", info
.dwVersion
);
474 ok(info
.dwVersionICM
== ICVERSION
, "Got unexpected ICM version %#x.\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. */
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 %u.\n", res
);
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 %#x.\n", info
.fccType
);
499 ok(info
.fccHandler
== test_handler
, "Got unexpected handler %#x.\n", info
.fccHandler
);
500 ok(!info
.dwFlags
, "Got unexpected flags %#x.\n", info
.dwFlags
);
501 ok(!info
.dwVersion
, "Got unexpected version %#x.\n", info
.dwVersion
);
502 ok(info
.dwVersionICM
== ICVERSION
, "Got unexpected ICM version %#x.\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. */
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 %#x.\n", enum_info
.fccType
);
522 ok(!enum_info
.fccHandler
, "Got unexpected handler %#x.\n", enum_info
.fccHandler
);
523 ok(!enum_info
.dwFlags
, "Got unexpected flags %#x.\n", enum_info
.dwFlags
);
524 ok(enum_info
.dwVersion
== 0xdeadbeef, "Got unexpected version %#x.\n", enum_info
.dwVersion
);
525 ok(enum_info
.dwVersionICM
== ICVERSION
, "Got unexpected ICM version %#x.\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 %#x.\n", enum_info
.fccType
);
535 ok(!enum_info
.fccHandler
, "Got unexpected handler %#x.\n", enum_info
.fccHandler
);
536 ok(!enum_info
.dwFlags
, "Got unexpected flags %#x.\n", enum_info
.dwFlags
);
537 ok(enum_info
.dwVersion
== 0xdeadbeef, "Got unexpected version %#x.\n", enum_info
.dwVersion
);
538 ok(enum_info
.dwVersionICM
== ICVERSION
, "Got unexpected ICM version %#x.\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 */
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
)
567 if (winetest_debug
> 1)
568 trace("(%#lx, %p, %#x, %#lx, %#lx)\n", id
, driver
, msg
, lparam1
, lparam2
);
577 case ICM_DECOMPRESS_QUERY
:
579 BITMAPINFOHEADER
*out
= (BITMAPINFOHEADER
*)lparam2
;
582 ok(lparam1
== (LPARAM
)&gdf_in
, "got input %#lx\n", lparam1
);
587 ok(out
== gdf_out
, "got output %p\n", out
);
589 ok(out
->biSize
== sizeof(*out
), "got size %d\n", out
->biSize
);
590 expected_size
= get_size_image(out
->biWidth
, out
->biHeight
, out
->biBitCount
);
591 ok(out
->biSizeImage
== expected_size
, "expected image size %d, got %d\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 %dx%d\n", out
->biXPelsPerMeter
, out
->biYPelsPerMeter
);
597 ok(out
->biClrUsed
== 0xcccccccc, "got biClrUsed %u\n", out
->biClrUsed
);
598 ok(out
->biClrImportant
== 0xcccccccc, "got biClrImportant %u\n", out
->biClrImportant
);
600 switch (get_display_format_test
)
605 if (out
->biWidth
== 30 && out
->biHeight
== 40 && out
->biCompression
== BI_RGB
&& out
->biBitCount
== 16)
609 if (out
->biWidth
== 30 && out
->biHeight
== 40 && out
->biCompression
== BI_BITFIELDS
&& out
->biBitCount
== 16)
613 if (out
->biWidth
== 30 && out
->biHeight
== 40 && out
->biCompression
== BI_RGB
&& out
->biBitCount
== 24)
617 if (out
->biWidth
== 30 && out
->biHeight
== 40 && out
->biCompression
== BI_RGB
&& out
->biBitCount
== 32)
621 if (out
->biWidth
== 10 && out
->biHeight
== 20 && out
->biCompression
== BI_RGB
&& out
->biBitCount
== 32)
628 return ICERR_BADFORMAT
;
630 case ICM_DECOMPRESS_GET_FORMAT
:
632 BITMAPINFOHEADER
*out
= (BITMAPINFOHEADER
*)lparam2
;
634 ok(lparam1
== (LPARAM
)&gdf_in
, "got input %#lx\n", lparam1
);
637 ok(out
== gdf_out
, "got output %p\n", out
);
639 memset(out
, 0x55, sizeof(*out
));
642 out
->biBitCount
= 0xdead;
643 out
->biCompression
= 0xbeef;
644 out
->biSizeImage
= 0;
649 case ICM_DECOMPRESS_GET_PALETTE
:
651 BITMAPINFO
*out
= (BITMAPINFO
*)lparam2
;
653 ok(lparam1
== (LPARAM
)&gdf_in
, "got input %#lx\n", lparam1
);
656 ok(out
== (BITMAPINFO
*)gdf_out
, "got output %p\n", out
);
658 out
->bmiHeader
.biClrUsed
= 1;
659 out
->bmiColors
[0] = color_yellow
;
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 %d, got %d\n", width
, header
->biWidth
);
672 ok_(__FILE__
, line
)(header
->biHeight
== height
, "expected %d, got %d\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 %#x, got %#x\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])];
687 memset(&gdf_in
, 0xcc, sizeof(gdf_in
));
688 gdf_in
.biSize
= sizeof(gdf_in
);
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 %#x\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 %u\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");
788 ok(lres
== ICERR_OK
, "got %ld\n", lres
);
790 ret
= ICRemove(ICTYPE_VIDEO
, testcc
, 0);
791 ok(ret
, "ICRemove failed\n");
798 test_ICSeqCompress();
800 test_ICGetDisplayFormat();