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 static void test_ICInfo(void) 378 { 379 ICINFO info, info2; 380 DWORD i, found; 381 unsigned char *fcc; 382 383 for (i = found = 0; ICInfo(0, i, &info); i++) 384 { 385 trace("Codec name: %s, fccHandler: 0x%08x\n", wine_dbgstr_w(info.szName), info.fccHandler); 386 ok(info.fccType, "expected nonzero fccType\n"); 387 388 ok(ICInfo(info.fccType, info.fccHandler, &info2), 389 "ICInfo failed on fcc 0x%08x\n", info.fccHandler); 390 391 fcc = (unsigned char *)&info.fccHandler; 392 if (!isalpha(fcc[0])) continue; 393 394 found++; 395 /* Test getting info with a different case - bug 41602 */ 396 fcc[0] ^= 0x20; 397 ok(ICInfo(info.fccType, info.fccHandler, &info2), 398 "ICInfo failed on fcc 0x%08x\n", info.fccHandler); 399 } 400 ok(found != 0, "expected at least one codec\n"); 401 402 memset(&info, 0, sizeof(info)); 403 ok(!ICInfo(ICTYPE_VIDEO, mmioFOURCC('f','a','k','e'), &info), "expected failure\n"); 404 ok(info.fccType == ICTYPE_VIDEO, "got 0x%08x\n", info.fccType); 405 ok(info.fccHandler == mmioFOURCC('f','a','k','e'), "got 0x%08x\n", info.fccHandler); 406 } 407 408 static int get_display_format_test; 409 410 static DWORD get_size_image(LONG width, LONG height, WORD depth) 411 { 412 DWORD ret = width * depth; 413 ret = (ret + 7) / 8; /* divide by byte size, rounding up */ 414 ret = (ret + 3) & ~3; /* align to 4 bytes */ 415 ret *= abs(height); 416 return ret; 417 } 418 419 static const RGBQUAD color_yellow = {0x00, 0xff, 0xff, 0x00}; 420 421 static BITMAPINFOHEADER gdf_in, *gdf_out; 422 423 static LRESULT CALLBACK gdf_driver_proc(DWORD_PTR id, HDRVR driver, UINT msg, 424 LPARAM lparam1, LPARAM lparam2) 425 { 426 LRESULT ret = 0; 427 428 if (winetest_debug > 1) 429 trace("(%#lx, %p, %#x, %#lx, %#lx)\n", id, driver, msg, lparam1, lparam2); 430 431 switch(msg) 432 { 433 case DRV_LOAD: 434 case DRV_OPEN: 435 case DRV_CLOSE: 436 case DRV_FREE: 437 return 1; 438 case ICM_DECOMPRESS_QUERY: 439 { 440 BITMAPINFOHEADER *out = (BITMAPINFOHEADER *)lparam2; 441 DWORD expected_size; 442 443 ok(lparam1 == (LPARAM)&gdf_in, "got input %#lx\n", lparam1); 444 445 if (!out) 446 return ICERR_OK; 447 448 ok(out == gdf_out, "got output %p\n", out); 449 450 ok(out->biSize == sizeof(*out), "got size %d\n", out->biSize); 451 expected_size = get_size_image(out->biWidth, out->biHeight, out->biBitCount); 452 ok(out->biSizeImage == expected_size, "expected image size %d, got %d\n", 453 expected_size, out->biSizeImage); 454 455 ok(out->biPlanes == 0xcccc, "got planes %d\n", out->biPlanes); 456 ok(out->biXPelsPerMeter == 0xcccccccc && out->biYPelsPerMeter == 0xcccccccc, 457 "got resolution %dx%d\n", out->biXPelsPerMeter, out->biYPelsPerMeter); 458 ok(out->biClrUsed == 0xcccccccc, "got biClrUsed %u\n", out->biClrUsed); 459 ok(out->biClrImportant == 0xcccccccc, "got biClrImportant %u\n", out->biClrImportant); 460 461 switch (get_display_format_test) 462 { 463 case 0: 464 return ICERR_OK; 465 case 1: 466 if (out->biWidth == 30 && out->biHeight == 40 && out->biCompression == BI_RGB && out->biBitCount == 16) 467 return ICERR_OK; 468 break; 469 case 2: 470 if (out->biWidth == 30 && out->biHeight == 40 && out->biCompression == BI_BITFIELDS && out->biBitCount == 16) 471 return ICERR_OK; 472 break; 473 case 3: 474 if (out->biWidth == 30 && out->biHeight == 40 && out->biCompression == BI_RGB && out->biBitCount == 24) 475 return ICERR_OK; 476 break; 477 case 4: 478 if (out->biWidth == 30 && out->biHeight == 40 && out->biCompression == BI_RGB && out->biBitCount == 32) 479 return ICERR_OK; 480 break; 481 case 5: 482 if (out->biWidth == 10 && out->biHeight == 20 && out->biCompression == BI_RGB && out->biBitCount == 32) 483 return ICERR_OK; 484 break; 485 case 6: 486 break; 487 } 488 489 return ICERR_BADFORMAT; 490 } 491 case ICM_DECOMPRESS_GET_FORMAT: 492 { 493 BITMAPINFOHEADER *out = (BITMAPINFOHEADER *)lparam2; 494 495 ok(lparam1 == (LPARAM)&gdf_in, "got input %#lx\n", lparam1); 496 if (out) 497 { 498 ok(out == gdf_out, "got output %p\n", out); 499 500 memset(out, 0x55, sizeof(*out)); 501 out->biWidth = 50; 502 out->biHeight = 60; 503 out->biBitCount = 0xdead; 504 out->biCompression = 0xbeef; 505 out->biSizeImage = 0; 506 507 return ICERR_OK; 508 } 509 } 510 case ICM_DECOMPRESS_GET_PALETTE: 511 { 512 BITMAPINFO *out = (BITMAPINFO *)lparam2; 513 514 ok(lparam1 == (LPARAM)&gdf_in, "got input %#lx\n", lparam1); 515 if (out) 516 { 517 ok(out == (BITMAPINFO *)gdf_out, "got output %p\n", out); 518 519 out->bmiHeader.biClrUsed = 1; 520 out->bmiColors[0] = color_yellow; 521 522 return 0xdeadbeef; 523 } 524 } 525 } 526 527 return ret; 528 } 529 530 static void check_bitmap_header_(int line, BITMAPINFOHEADER *header, LONG width, LONG height, WORD depth, DWORD compression) 531 { 532 ok_(__FILE__, line)(header->biWidth == width, "expected %d, got %d\n", width, header->biWidth); 533 ok_(__FILE__, line)(header->biHeight == height, "expected %d, got %d\n", height, header->biHeight); 534 ok_(__FILE__, line)(header->biBitCount == depth, "expected %d, got %d\n", depth, header->biBitCount); 535 ok_(__FILE__, line)(header->biCompression == compression, "expected %#x, got %#x\n", compression, header->biCompression); 536 } 537 #define check_bitmap_header(a,b,c,d,e) check_bitmap_header_(__LINE__,a,b,c,d,e) 538 539 static void test_ICGetDisplayFormat(void) 540 { 541 static const DWORD testcc = mmioFOURCC('t','e','s','t'); 542 #ifdef __REACTOS__ 543 char outbuf[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)]; 544 #else 545 char outbuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; 546 #endif 547 BITMAPINFO *out_bmi; 548 LRESULT lres; 549 BOOL ret; 550 HIC hic; 551 552 memset(&gdf_in, 0xcc, sizeof(gdf_in)); 553 gdf_in.biSize = sizeof(gdf_in); 554 gdf_in.biWidth = 10; 555 gdf_in.biHeight = 20; 556 gdf_in.biBitCount = 1; 557 gdf_in.biCompression = testcc; 558 559 ret = ICInstall(ICTYPE_VIDEO, testcc, (LPARAM)gdf_driver_proc, NULL, ICINSTALL_FUNCTION); 560 ok(ret, "ICInstall failed\n"); 561 562 hic = ICOpen(ICTYPE_VIDEO, testcc, ICMODE_DECOMPRESS); 563 ok(ret, "ICOpen failed\n"); 564 565 memset(outbuf, 0, sizeof(outbuf)); 566 gdf_out = (BITMAPINFOHEADER *)outbuf; 567 568 /* ICGetDisplayFormat tries several default formats; make sure those work */ 569 get_display_format_test = 0; 570 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40); 571 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 572 check_bitmap_header(gdf_out, 30, 40, 1, BI_RGB); 573 574 get_display_format_test = 1; 575 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40); 576 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 577 check_bitmap_header(gdf_out, 30, 40, 16, BI_RGB); 578 579 get_display_format_test = 2; 580 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40); 581 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 582 check_bitmap_header(gdf_out, 30, 40, 16, BI_BITFIELDS); 583 584 get_display_format_test = 3; 585 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40); 586 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 587 check_bitmap_header(gdf_out, 30, 40, 24, BI_RGB); 588 589 get_display_format_test = 4; 590 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40); 591 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 592 check_bitmap_header(gdf_out, 30, 40, 32, BI_RGB); 593 594 get_display_format_test = 5; 595 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40); 596 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 597 check_bitmap_header(gdf_out, 10, 20, 32, BI_RGB); 598 599 /* if every default format is rejected, the output of 600 * ICM_DECOMPRESS_GET_FORMAT is returned */ 601 get_display_format_test = 6; 602 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 40); 603 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 604 check_bitmap_header(gdf_out, 50, 60, 0xdead, 0xbeef); 605 606 /* given bpp is treated as a lower bound */ 607 get_display_format_test = 1; 608 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 24, 30, 40); 609 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 610 check_bitmap_header(gdf_out, 50, 60, 0xdead, 0xbeef); 611 612 get_display_format_test = 3; 613 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 24, 30, 40); 614 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 615 check_bitmap_header(gdf_out, 30, 40, 24, BI_RGB); 616 617 get_display_format_test = 0; 618 619 /* width or height <= 0 causes the input width and height to be supplied */ 620 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 0, 40); 621 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 622 check_bitmap_header(gdf_out, 10, 20, 1, BI_RGB); 623 624 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, 0); 625 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 626 check_bitmap_header(gdf_out, 10, 20, 1, BI_RGB); 627 628 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, -10, 40); 629 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 630 check_bitmap_header(gdf_out, 10, 20, 1, BI_RGB); 631 632 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 1, 30, -10); 633 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 634 check_bitmap_header(gdf_out, 10, 20, 1, BI_RGB); 635 636 /* zero bpp causes 32 bpp to be supplied */ 637 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 0, 30, 40); 638 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 639 ok(gdf_out->biBitCount == 32 || gdf_out->biBitCount == 24, 640 "got %d\n", gdf_out->biBitCount); 641 ok(gdf_out->biCompression == BI_RGB, "got %#x\n", gdf_out->biCompression); 642 643 /* specifying 8 bpp yields a request for palette colours */ 644 hic = ICGetDisplayFormat(hic, &gdf_in, gdf_out, 8, 30, 40); 645 ok(hic != NULL, "ICGetDisplayFormat failed\n"); 646 check_bitmap_header(gdf_out, 30, 40, 8, BI_RGB); 647 ok(gdf_out->biClrUsed == 1, "got biClrUsed %u\n", gdf_out->biClrUsed); 648 out_bmi = (BITMAPINFO *)gdf_out; 649 ok(!memcmp(&out_bmi->bmiColors[0], &color_yellow, sizeof(color_yellow)), 650 "got wrong colour\n"); 651 652 lres = ICClose(hic); 653 ok(lres == ICERR_OK, "got %ld\n", lres); 654 655 ret = ICRemove(ICTYPE_VIDEO, testcc, 0); 656 ok(ret, "ICRemove failed\n"); 657 } 658 659 START_TEST(msvfw) 660 { 661 test_OpenCase(); 662 test_Locate(); 663 test_ICSeqCompress(); 664 test_ICInfo(); 665 test_ICGetDisplayFormat(); 666 } 667