1 /* 2 * Unit tests for video playback 3 * 4 * Copyright 2008,2010 Jörg Höhle 5 * Copyright 2008 Austin English 6 * 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. 11 * 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. 16 * 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 20 */ 21 22 #define WIN32_LEAN_AND_MEAN 23 #include <windows.h> 24 #include <vfw.h> 25 26 #include "wine/test.h" 27 28 static inline int get_stride(int width, int depth) 29 { 30 return ((depth * width + 31) >> 3) & ~3; 31 } 32 33 static void test_OpenCase(void) 34 { 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"); 46 } 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"); 55 } 56 57 /* Open a compressor with combinations of lowercase 58 * and uppercase compressortype and handler. 59 */ 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"); 64 } 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"); 69 } 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"); 74 } 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"); 79 } 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"); 84 } 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"); 89 } 90 } 91 92 static void test_Locate(void) 93 { 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; 99 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. */ 105 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"); 109 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; 115 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: %d\n", err); 123 124 err = ICDecompressQuery(h, &bi, NULL); 125 ok(err == ICERR_OK, "Query cvid 32: %d\n", err); 126 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; 131 132 bi.biWidth = 17; 133 134 bi.biBitCount = 8; 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); 140 141 bi.biBitCount = 15; 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); 147 148 bi.biBitCount = 16; 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); 154 155 bi.biBitCount = 24; 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); 161 162 bi.biBitCount = 32; 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); 168 169 bi.biWidth = 32; 170 171 ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); 172 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; 182 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; 192 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; 202 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"); 208 } 209 210 bi.biCompression = mmioFOURCC('M','S','V','C'); /* MS Video 1 */ 211 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"); 216 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; 222 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++; 228 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"); 234 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: %d\n", err); 241 242 err = ICDecompressQuery(h, &bi, NULL); 243 ok(err == ICERR_OK, "Query MSVC 16: %d\n", err); 244 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; 249 250 bo.biBitCount = 24; 251 err = ICDecompressQuery(h, &bi, &bo); 252 ok(err == ICERR_OK, "Query MSVC 16->24: %d\n", err); 253 bo.biBitCount = 16; 254 255 bi.biWidth = 553; 256 257 bi.biBitCount = 8; 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); 264 265 bi.biBitCount = 15; 266 err = ICDecompressGetFormat(h, &bi, &tmp); 267 ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err); 268 269 bi.biBitCount = 16; 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); 276 277 bi.biBitCount = 24; 278 err = ICDecompressGetFormat(h, &bi, &tmp); 279 ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err); 280 281 bi.biBitCount = 32; 282 err = ICDecompressGetFormat(h, &bi, &tmp); 283 ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err); 284 285 bi.biHeight = 17; 286 bi.biBitCount = 8; 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); 290 bi.biHeight = 8; 291 292 bi.biWidth = 32; 293 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); 297 298 ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); 299 } 300 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"); 306 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"); 311 } 312 313 static void test_ICSeqCompress(void) 314 { 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. 318 */ 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 */ 333 334 h = ICOpen(vidc, mrle, ICMODE_COMPRESS); 335 ok(h != NULL, "Expected non-NULL\n"); 336 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; 350 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"); 356 357 for(i = 0; i < 9; i++) 358 { 359 frame_len = 0; 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); 366 else 367 ok(0, "Unknown frame size of %d byten\n", frame_len); 368 } 369 370 ICSeqCompressFrameEnd(&pc); 371 ICCompressorFree(&pc); 372 /* ICCompressorFree already closed the HIC */ 373 err = ICClose(h); 374 ok(err == ICERR_BADHANDLE, "Expected -8, got %d\n", err); 375 } 376 377 struct msg_result 378 { 379 int msg_index; 380 UINT msg; 381 BOOL output_format; 382 int width; 383 int height; 384 int bits; 385 int compression; 386 LRESULT result; 387 BOOL todo; 388 }; 389 390 static struct msg_result expected_msgs[] = 391 { 392 /* Wine bug - shouldn't be called */ 393 { 0, DRV_LOAD, FALSE, 0, 0, 0, 0, TRUE, TRUE}, 394 { 0, DRV_ENABLE, FALSE, 0, 0, 0, 0, 0, TRUE}, 395 396 { 0, DRV_OPEN, FALSE, 0, 0, 0, 0, 0xdeadbeef, FALSE}, 397 398 /* test 1 */ 399 { 1, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 400 { 2, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_BADFORMAT, FALSE}, 401 { 3, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 8, BI_RGB, ICERR_BADFORMAT, FALSE}, 402 { 4, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 16, BI_RGB, ICERR_BADFORMAT, FALSE}, 403 { 5, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 16, BI_BITFIELDS, ICERR_BADFORMAT, FALSE}, 404 { 6, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 24, BI_RGB, ICERR_BADFORMAT, FALSE}, 405 { 7, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_BADFORMAT, FALSE}, 406 { 8, ICM_DECOMPRESS_GET_FORMAT, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, 407 408 /* test 2 */ 409 { 9, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 410 {10, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_BADFORMAT, FALSE}, 411 {11, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 8, BI_RGB, ICERR_BADFORMAT, FALSE}, 412 {12, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 16, BI_RGB, ICERR_OK, FALSE}, 413 414 /* test 3 */ 415 {13, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 416 {14, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 417 {15, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 8, BI_RGB, ICERR_BADFORMAT, FALSE}, 418 {16, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 16, BI_RGB, ICERR_OK, FALSE}, 419 420 /* test 4 */ 421 {17, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 422 {18, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_BADFORMAT, FALSE}, 423 {19, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 24, BI_RGB, ICERR_BADFORMAT, FALSE}, 424 {20, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_BADFORMAT, FALSE}, 425 {21, ICM_DECOMPRESS_GET_FORMAT, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, 426 427 /* test 5 */ 428 {22, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 429 {23, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 430 {24, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, 431 432 /* test 6 */ 433 {25, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 434 {26, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 435 {27, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, 436 437 /* test 7 */ 438 {28, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 439 {29, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 440 {30, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 9, BI_RGB, ICERR_BADFORMAT, FALSE}, 441 {31, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_BADFORMAT, FALSE}, 442 {32, ICM_DECOMPRESS_GET_FORMAT, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, 443 444 /* test 8 */ 445 {33, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 446 {34, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 447 {35, ICM_DECOMPRESS_QUERY, TRUE, 800, 600, 32, BI_RGB, ICERR_OK, FALSE}, 448 449 /* test 9 */ 450 {36, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 451 {37, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 452 {38, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, 453 454 /* test 10 */ 455 {39, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 456 {40, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 457 {41, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, 458 459 /* test 11 */ 460 {42, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 461 {43, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 462 {44, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 8, BI_RGB, ICERR_OK, FALSE}, 463 {45, ICM_DECOMPRESS_GET_PALETTE, FALSE, 0, 0, 0, 0, ICERR_UNSUPPORTED, FALSE}, 464 465 /* test 12 */ 466 {46, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 467 {47, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 468 {48, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 16, BI_RGB, ICERR_OK, FALSE}, 469 470 /* test 13 */ 471 {49, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 472 {50, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 473 {51, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 24, BI_RGB, ICERR_OK, FALSE}, 474 475 /* test 14 */ 476 {52, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, 477 {53, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, 478 {54, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 4, BI_RGB, ICERR_OK, FALSE}, 479 480 /* Wine bug - shouldn't be called */ 481 {55, DRV_DISABLE, FALSE, 0, 0, 0, 0, ICERR_OK, TRUE}, 482 {55, DRV_FREE, FALSE, 0, 0, 0, 0, ICERR_OK, TRUE}, 483 }; 484 485 static int msg_index = 0; 486 487 static struct msg_result *get_expected_msg(UINT msg) 488 { 489 int i = 0; 490 for(; i < sizeof(expected_msgs) / sizeof(expected_msgs[0]); i++) 491 { 492 if (expected_msgs[i].msg_index == msg_index && expected_msgs[i].msg == msg) 493 return &expected_msgs[i]; 494 } 495 return NULL; 496 } 497 498 LRESULT WINAPI driver_proc_test(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, 499 LPARAM lParam1, LPARAM lParam2) 500 { 501 struct msg_result *expected = get_expected_msg(msg); 502 LRESULT res = expected ? expected->result : ICERR_UNSUPPORTED; 503 504 if (msg == DRV_CLOSE) 505 return ICERR_OK; 506 507 if (!expected) 508 { 509 ok(0, "unexpected message: %04x %ld %ld at msg index %d\n", 510 msg, lParam1, lParam2, msg_index); 511 return ICERR_UNSUPPORTED; 512 } 513 else if (expected->todo) 514 { 515 todo_wine ok(0, "unexpected message: %04x %ld %ld at msg index %d\n", 516 msg, lParam1, lParam2, msg_index); 517 return res; 518 } 519 520 switch (msg) 521 { 522 case ICM_DECOMPRESS_QUERY: 523 { 524 BITMAPINFOHEADER *out = (BITMAPINFOHEADER *)lParam2; 525 526 if (!lParam2) 527 { 528 trace("query -> without format\n"); 529 ok(!expected->output_format, "Expected no output format pointer\n"); 530 break; 531 } 532 533 ok(expected->output_format, "Expected output format pointer\n"); 534 ok(out->biWidth == expected->width, 535 "Expected width %d, got %d\n", expected->width, out->biWidth); 536 ok(out->biHeight == expected->height, 537 "Expected height %d, got %d\n", expected->height, out->biHeight); 538 ok(out->biBitCount == expected->bits, 539 "Expected biBitCount %d, got %d\n", expected->bits, out->biBitCount); 540 ok(out->biCompression == expected->compression, 541 "Expected compression %d, got %d\n", expected->compression, out->biCompression); 542 ok(out->biSizeImage == get_stride(out->biWidth, out->biBitCount) * out->biHeight, 543 "Expected biSizeImage %d, got %d\n", get_stride(out->biWidth, out->biBitCount) * out->biHeight, 544 out->biSizeImage); 545 546 trace("query -> width: %d, height: %d, bit: %d, compression: %d, size: %d\n", 547 out->biWidth, out->biHeight, out->biBitCount, out->biCompression, out->biSizeImage); 548 break; 549 } 550 551 case ICM_DECOMPRESS_GET_FORMAT: 552 { 553 BITMAPINFOHEADER *out = (BITMAPINFOHEADER *)lParam2; 554 555 if (!lParam2) 556 { 557 trace("format -> without format\n"); 558 ok(!expected->output_format, "Expected no output format pointer\n"); 559 break; 560 } 561 562 ok(expected->output_format, "Expected output format pointer\n"); 563 ok(out->biWidth == expected->width, 564 "Expected width %d, got %d\n", expected->width, out->biWidth); 565 ok(out->biHeight == expected->height, 566 "Expected height %d, got %d\n", expected->height, out->biHeight); 567 ok(out->biBitCount == expected->bits, 568 "Expected biBitCount %d, got %d\n", expected->bits, out->biBitCount); 569 ok(out->biCompression == expected->compression, 570 "Expected compression %d, got %d\n", expected->compression, out->biCompression); 571 572 trace("format -> width: %d, height: %d, bit: %d, compression: %d, size: %d\n", 573 out->biWidth, out->biHeight, out->biBitCount, out->biCompression, out->biSizeImage); 574 575 out->biBitCount = 64; 576 break; 577 } 578 } 579 580 msg_index++; 581 return res; 582 } 583 584 585 void test_ICGetDisplayFormat(void) 586 { 587 static const struct 588 { 589 int bits_wanted; 590 int bits_expected; 591 int dx; 592 int width_expected; 593 int dy; 594 int height_expected; 595 int msg_index; 596 } 597 tests[] = 598 { 599 { 8, 64, 0, 640, 0, 480, 9}, 600 { 8, 16, 0, 640, 0, 480, 13}, 601 { 8, 16, 0, 640, 0, 480, 17}, 602 {24, 64, 0, 640, 0, 480, 22}, 603 {32, 32, 0, 640, 0, 480, 25}, 604 { 0, 32, 0, 640, 0, 480, 28}, 605 { 9, 64, 0, 640, 0, 480, 33}, 606 {32, 32, 800, 800, 600, 600, 36}, 607 {32, 32, -1, 640, -1, 480, 39}, 608 {32, 32, -90, 640, -60, 480, 42}, 609 { 8, 8, 270, 270, 270, 270, 46}, 610 {16, 16, 270, 270, 270, 270, 49}, 611 {24, 24, 270, 270, 270, 270, 52}, 612 { 4, 4, 0, 640, 0, 480, 55}, 613 }; 614 615 HIC ic, ic2; 616 BITMAPINFOHEADER in; 617 BITMAPINFOHEADER out; 618 int real_depth; 619 int i; 620 621 ic = ICOpenFunction(ICTYPE_VIDEO, 0xdeadbeef, ICMODE_DECOMPRESS, driver_proc_test); 622 ok(!!ic, "Opening driver failed\n"); 623 624 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) 625 { 626 memset(&in, 0, sizeof(in)); 627 memset(&out, 0, sizeof(out)); 628 629 in.biSize = sizeof(in); 630 in.biWidth = 640; 631 in.biHeight = 480; 632 in.biPlanes = 1; 633 in.biBitCount = 32; 634 in.biCompression = BI_PNG; 635 in.biSizeImage = 1024; 636 637 out.biBitCount = 16; 638 out.biWidth = 320; 639 out.biHeight = 240; 640 641 ic2 = ICGetDisplayFormat(ic, &in, &out, tests[i].bits_wanted, tests[i].dx, tests[i].dy); 642 ok(!!ic2, "Expected ICGetDisplayFormat to succeeded\n"); 643 644 ok(out.biBitCount == tests[i].bits_expected, 645 "Expected biBitCount %d, got %d\n", tests[i].bits_expected, out.biBitCount); 646 ok(out.biWidth == tests[i].width_expected, 647 "Expected biWidth %d, got %d\n", tests[i].width_expected, out.biWidth); 648 ok(out.biHeight == tests[i].height_expected, 649 "Expected biHeight %d, got %d\n", tests[i].height_expected, out.biHeight); 650 real_depth = (out.biBitCount > 32) ? 32 : out.biBitCount; 651 ok(out.biSizeImage == get_stride(out.biWidth, real_depth) * out.biHeight, 652 "Expected biSizeImage %d, got %d\n", get_stride(out.biWidth, real_depth) * out.biHeight, 653 out.biSizeImage); 654 ok(msg_index == tests[i].msg_index, 655 "Expected msg_index %d, got %d\n", tests[i].msg_index, msg_index); 656 } 657 658 ICClose(ic); 659 } 660 661 static void test_ICInfo(void) 662 { 663 ICINFO info, info2; 664 DWORD i, found; 665 unsigned char *fcc; 666 667 for (i = found = 0; ICInfo(0, i, &info); i++) 668 { 669 trace("Codec name: %s, fccHandler: 0x%08x\n", wine_dbgstr_w(info.szName), info.fccHandler); 670 671 ok(ICInfo(info.fccType, info.fccHandler, &info2), 672 "ICInfo failed on fcc 0x%08x\n", info.fccHandler); 673 674 fcc = (unsigned char *)&info.fccHandler; 675 if (!isalpha(fcc[0])) continue; 676 677 found++; 678 /* Test getting info with a different case - bug 41602 */ 679 if (fcc[0] & 0x20) 680 { 681 fcc[0] &= ~0x20; 682 ok(ICInfo(info.fccType, info.fccHandler, &info2), 683 "ICInfo failed on fcc 0x%08x using lowercase fccHandler\n", info.fccHandler); 684 } 685 else 686 { 687 fcc[0] |= 0x20; 688 ok(ICInfo(info.fccType, info.fccHandler, &info2), 689 "ICInfo failed on fcc 0x%08x using uppercase fccHandler\n", info.fccHandler); 690 } 691 } 692 ok(found != 0, "expected at least one codec\n"); 693 } 694 695 START_TEST(msvfw) 696 { 697 test_OpenCase(); 698 test_Locate(); 699 test_ICSeqCompress(); 700 test_ICGetDisplayFormat(); 701 test_ICInfo(); 702 } 703