From: Elizabeth Figura <zfigura(a)codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59097 --- dlls/ir50_32/ir50.c | 110 ++++++++++++++++++++++++----------- dlls/ir50_32/tests/ir50_32.c | 16 ++--- 2 files changed, 84 insertions(+), 42 deletions(-) diff --git a/dlls/ir50_32/ir50.c b/dlls/ir50_32/ir50.c index 29e6e0968d1..4959fd6b44f 100644 --- a/dlls/ir50_32/ir50.c +++ b/dlls/ir50_32/ir50.c @@ -63,16 +63,16 @@ IV50_Open( const ICINFO *icinfo ) return (LRESULT)decoder; } -static LRESULT -IV50_DecompressQuery( LPBITMAPINFO in, LPBITMAPINFO out ) +static LRESULT decompress_query( ICDECOMPRESSEX *params ) { - TRACE("ICM_DECOMPRESS_QUERY %p %p\n", in, out); + const BITMAPINFO *in = (BITMAPINFO *)params->lpbiSrc, *out = (BITMAPINFO *)params->lpbiDst; TRACE("in->planes = %d\n", in->bmiHeader.biPlanes); TRACE("in->bpp = %d\n", in->bmiHeader.biBitCount); TRACE("in->height = %ld\n", in->bmiHeader.biHeight); TRACE("in->width = %ld\n", in->bmiHeader.biWidth); TRACE("in->compr = %#lx\n", in->bmiHeader.biCompression); + TRACE("in offset (%d,%d), size %dx%d\n", params->xSrc, params->ySrc, params->dxSrc, params->dySrc); if (compare_fourcc(in->bmiHeader.biCompression, IV50_MAGIC)) { @@ -80,6 +80,13 @@ IV50_DecompressQuery( LPBITMAPINFO in, LPBITMAPINFO out ) return ICERR_BADFORMAT; } + if (params->xSrc || params->ySrc || params->dxSrc != in->bmiHeader.biWidth + || params->dySrc != in->bmiHeader.biHeight) + { + TRACE("nontrivial source rect\n"); + return ICERR_BADFORMAT; + } + /* output must be same dimensions as input */ if ( out ) { @@ -88,6 +95,7 @@ IV50_DecompressQuery( LPBITMAPINFO in, LPBITMAPINFO out ) TRACE("out->height = %ld\n", out->bmiHeader.biHeight); TRACE("out->width = %ld\n", out->bmiHeader.biWidth); TRACE("out->compr = %#lx\n", out->bmiHeader.biCompression); + TRACE("out offset (%d,%d), size %dx%d\n", params->xDst, params->yDst, params->dxDst, params->dyDst); if (out->bmiHeader.biCompression == BI_RGB) { @@ -107,8 +115,7 @@ IV50_DecompressQuery( LPBITMAPINFO in, LPBITMAPINFO out ) return ICERR_BADFORMAT; } - if (in->bmiHeader.biHeight != abs(out->bmiHeader.biHeight) - || in->bmiHeader.biWidth != out->bmiHeader.biWidth) + if (in->bmiHeader.biWidth != params->dxDst || in->bmiHeader.biHeight != params->dyDst) { TRACE("incompatible output dimensions requested\n"); return ICERR_BADPARAM; @@ -142,14 +149,15 @@ IV50_DecompressGetFormat( LPBITMAPINFO in, LPBITMAPINFO out ) return offsetof(BITMAPINFO, bmiColors[256]); } -static LRESULT IV50_DecompressBegin( IMFTransform *decoder, LPBITMAPINFO in, LPBITMAPINFO out ) +static LRESULT decompress_begin( IMFTransform *decoder, ICDECOMPRESSEX *params ) { + const BITMAPINFO *in = (BITMAPINFO *)params->lpbiSrc, *out = (BITMAPINFO *)params->lpbiDst; IMFMediaType *input_type, *output_type; const GUID *output_subtype; LRESULT r = ICERR_INTERNAL; unsigned int stride; - TRACE("ICM_DECOMPRESS_BEGIN %p %p %p\n", decoder, in, out); + TRACE( "decoder %p, in %p, out %p.\n", decoder, in, out ); if ( !decoder ) return ICERR_BADPARAM; @@ -189,9 +197,8 @@ static LRESULT IV50_DecompressBegin( IMFTransform *decoder, LPBITMAPINFO in, LPB if ( FAILED(IMFMediaType_SetGUID( output_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video )) || FAILED(IMFMediaType_SetGUID( output_type, &MF_MT_SUBTYPE, output_subtype )) ) goto done; - if ( FAILED(IMFMediaType_SetUINT64( - output_type, &MF_MT_FRAME_SIZE, - make_uint64( out->bmiHeader.biWidth, abs(out->bmiHeader.biHeight) ) )) ) + if (FAILED(IMFMediaType_SetUINT64( output_type, &MF_MT_FRAME_SIZE, + make_uint64( params->dxDst, params->dyDst ) ))) goto done; if ( FAILED(IMFMediaType_SetUINT32( output_type, &MF_MT_DEFAULT_STRIDE, stride)) ) goto done; @@ -208,7 +215,7 @@ done: return r; } -static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD size ) +static LRESULT decompress( IMFTransform *decoder, ICDECOMPRESSEX *params ) { IMFSample *in_sample = NULL, *out_sample = NULL; IMFMediaBuffer *in_buf = NULL, *out_buf = NULL; @@ -218,12 +225,12 @@ static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD HRESULT hr; LRESULT r = ICERR_INTERNAL; - TRACE("ICM_DECOMPRESS %p %p %lu\n", decoder, icd, size); + TRACE( "decoder %p, params %p.\n", decoder, params ); if ( FAILED(MFCreateSample( &in_sample )) ) return ICERR_INTERNAL; - if ( FAILED(MFCreateMemoryBuffer( icd->lpbiInput->biSizeImage, &in_buf )) ) + if ( FAILED(MFCreateMemoryBuffer( params->lpbiSrc->biSizeImage, &in_buf )) ) goto done; if ( FAILED(IMFSample_AddBuffer( in_sample, in_buf )) ) @@ -232,7 +239,7 @@ static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD if ( FAILED(MFCreateSample( &out_sample )) ) goto done; - if ( FAILED(MFCreateMemoryBuffer( icd->lpbiOutput->biSizeImage, &out_buf )) ) + if ( FAILED(MFCreateMemoryBuffer( params->lpbiDst->biSizeImage, &out_buf )) ) goto done; if ( FAILED(IMFSample_AddBuffer( out_sample, out_buf )) ) @@ -241,12 +248,12 @@ static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD if ( FAILED(IMFMediaBuffer_Lock( in_buf, &data, NULL, NULL ))) goto done; - memcpy( data, icd->lpInput, icd->lpbiInput->biSizeImage ); + memcpy( data, params->lpSrc, params->lpbiSrc->biSizeImage ); if ( FAILED(IMFMediaBuffer_Unlock( in_buf )) ) goto done; - if ( FAILED(IMFMediaBuffer_SetCurrentLength( in_buf, icd->lpbiInput->biSizeImage )) ) + if ( FAILED(IMFMediaBuffer_SetCurrentLength( in_buf, params->lpbiSrc->biSizeImage )) ) goto done; if ( FAILED(IMFTransform_ProcessInput( decoder, 0, in_sample, 0 )) ) @@ -261,15 +268,17 @@ static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD if ( SUCCEEDED(hr) ) { - LONG width = icd->lpbiOutput->biWidth * (icd->lpbiOutput->biBitCount / 8); - LONG height = abs( icd->lpbiOutput->biHeight ); + LONG depth = params->lpbiDst->biBitCount / 8; + LONG width = params->lpbiDst->biWidth * depth; LONG stride = (width + 3) & ~3; - BYTE *output = (BYTE *)icd->lpOutput; + BYTE *output = params->lpDst; if ( FAILED(IMFMediaBuffer_Lock( out_buf, &data, NULL, NULL ))) goto done; - MFCopyImage( output, stride, data, stride, width, height ); + output += params->yDst * stride; + output += params->xDst * depth; + MFCopyImage( output, stride, data, stride, params->dxDst * depth, params->dyDst ); IMFMediaBuffer_Unlock( out_buf ); r = ICERR_OK; @@ -314,6 +323,21 @@ static LRESULT IV50_GetInfo( ICINFO *icinfo, DWORD dwSize ) return sizeof(ICINFO); } +static void fill_decompressex_params( ICDECOMPRESSEX *params, + BITMAPINFOHEADER *src, BITMAPINFOHEADER *dst ) +{ + memset( params, 0, sizeof(*params) ); + params->lpbiSrc = src; + params->lpbiDst = dst; + params->dxSrc = src->biWidth; + params->dySrc = src->biHeight; + if (dst) + { + params->dxDst = dst->biWidth; + params->dyDst = abs(dst->biHeight); + } +} + /*********************************************************************** * DriverProc (IR50_32.@) */ @@ -353,8 +377,15 @@ LRESULT WINAPI IV50_DriverProc( DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, break; case ICM_DECOMPRESS_QUERY: - r = IV50_DecompressQuery( (LPBITMAPINFO) lParam1, (LPBITMAPINFO) lParam2 ); - break; + { + ICDECOMPRESSEX params; + + fill_decompressex_params( ¶ms, (BITMAPINFOHEADER *)lParam1, (BITMAPINFOHEADER *)lParam2 ); + return decompress_query( ¶ms ); + } + + case ICM_DECOMPRESSEX_QUERY: + return decompress_query( (ICDECOMPRESSEX *)lParam1 ); case ICM_DECOMPRESS_GET_FORMAT: r = IV50_DecompressGetFormat( (LPBITMAPINFO) lParam1, (LPBITMAPINFO) lParam2 ); @@ -365,23 +396,34 @@ LRESULT WINAPI IV50_DriverProc( DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, break; case ICM_DECOMPRESS: - r = IV50_Decompress( decoder, (ICDECOMPRESS *) lParam1, (DWORD) lParam2 ); - break; + { + const ICDECOMPRESS *params = (ICDECOMPRESS *)lParam1; + ICDECOMPRESSEX ex_params; + + fill_decompressex_params( &ex_params, params->lpbiInput, params->lpbiOutput ); + ex_params.dwFlags = params->dwFlags; + ex_params.lpSrc = params->lpInput; + ex_params.lpDst = params->lpOutput; + return decompress( decoder, &ex_params ); + } + + case ICM_DECOMPRESSEX: + return decompress( decoder, (ICDECOMPRESSEX *)lParam1 ); case ICM_DECOMPRESS_BEGIN: - r = IV50_DecompressBegin( decoder, (LPBITMAPINFO) lParam1, (LPBITMAPINFO) lParam2 ); - break; + { + ICDECOMPRESSEX params; - case ICM_DECOMPRESS_END: - r = ICERR_OK; - break; + fill_decompressex_params( ¶ms, (BITMAPINFOHEADER *)lParam1, (BITMAPINFOHEADER *)lParam2 ); + return decompress_begin( decoder, ¶ms ); + } - case ICM_DECOMPRESSEX_QUERY: - FIXME("ICM_DECOMPRESSEX_QUERY\n"); - break; + case ICM_DECOMPRESSEX_BEGIN: + return decompress_begin( decoder, (ICDECOMPRESSEX *)lParam1 ); - case ICM_DECOMPRESSEX: - FIXME("ICM_DECOMPRESSEX\n"); + case ICM_DECOMPRESS_END: + case ICM_DECOMPRESSEX_END: + r = ICERR_OK; break; case ICM_COMPRESS_QUERY: diff --git a/dlls/ir50_32/tests/ir50_32.c b/dlls/ir50_32/tests/ir50_32.c index 00106fb2700..510660a2b30 100644 --- a/dlls/ir50_32/tests/ir50_32.c +++ b/dlls/ir50_32/tests/ir50_32.c @@ -146,7 +146,7 @@ static void test_formats(void) ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, NULL, NULL, 0, 0, 0, 0); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 32, 24, NULL, NULL, 0, 0, 0, 0); todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0); @@ -156,25 +156,25 @@ static void test_formats(void) ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 20, 320, 240, NULL, NULL, 0, 0, 0, 0); todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 0, 0); - todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 320, 240); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 160, 120); - todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); out->bmiHeader.biWidth = 640; ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 240); - todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); out->bmiHeader.biHeight = 480; ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 480); todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExBegin(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExEnd(hic); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICClose(hic); ok(!ret, "Got %Id.\n", ret); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9718