Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/mediadet.c | 62 +++++++++++++++++++++++++++++++++++-- dlls/qedit/tests/mediadet.c | 35 ++++++++++----------- 2 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index f874095..306fdc3 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -920,9 +920,65 @@ static HRESULT WINAPI MediaDet_WriteBitmapBits(IMediaDet* iface, double StreamTime, LONG Width, LONG Height, BSTR Filename) { - MediaDetImpl *This = impl_from_IMediaDet(iface); - FIXME("(%p)->(%f %d %d %p): not implemented!\n", This, StreamTime, Width, Height, Filename); - return E_NOTIMPL; + MediaDetImpl *detector = impl_from_IMediaDet(iface); + BITMAPFILEHEADER *hdr; + HANDLE file, mapping; + LONG size, size_hi; + HRESULT hr; + char *buf; + + TRACE("(%p)->(%f %d %d %s)\n", detector, StreamTime, Width, Height, debugstr_w(Filename)); + + if (!Filename) + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + + /* WriteBitmapBits rounds the width up to a multiple of 4 */ + Width = (Width + 3) & ~3; + size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + Width * 3 * Height; + + file = CreateFileW(Filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) + return HRESULT_FROM_WIN32(GetLastError()); + + size_hi = 0; + if (SetFilePointer(file, size, &size_hi, FILE_BEGIN) == INVALID_SET_FILE_POINTER || + !SetEndOfFile(file) || + !(mapping = CreateFileMappingW(file, NULL, PAGE_READWRITE, 0, 0, NULL))) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + CloseHandle(file); + DeleteFileW(Filename); + return hr; + } + + if (!(buf = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0))) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto err; + } + + hdr = (BITMAPFILEHEADER*)buf; + hdr->bfType = 0x4d42; + hdr->bfSize = size; + hdr->bfReserved1 = 0; + hdr->bfReserved2 = 0; + hdr->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + hr = IMediaDet_GetBitmapBits(&detector->IMediaDet_iface, StreamTime, NULL, + buf + sizeof(BITMAPFILEHEADER), Width, Height); + UnmapViewOfFile(buf); + if (FAILED(hr)) + goto err; + + CloseHandle(mapping); + CloseHandle(file); + return S_OK; + +err: + CloseHandle(mapping); + CloseHandle(file); + DeleteFileW(Filename); + return hr; }
static HRESULT WINAPI MediaDet_get_StreamMediaType(IMediaDet* iface, diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c index 951bf04..adb0d36 100644 --- a/dlls/qedit/tests/mediadet.c +++ b/dlls/qedit/tests/mediadet.c @@ -1565,7 +1565,6 @@ static void test_bitmap_grab_mode(void)
ok(GetTempPathW(MAX_PATH, temp_path), "GetTempPath failed, error: 0x%08x.\n", GetLastError()); ok(GetTempFileNameW(temp_path, L"DES", 0, filename), "GetTempFileName failed, error: 0x%08x.\n", GetLastError()); - DeleteFileW(filename);
hr = CoCreateInstance(&CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, &IID_IMediaDet, (void **)&detector); @@ -1577,7 +1576,7 @@ static void test_bitmap_grab_mode(void) hr = IMediaDet_GetBitmapBits(detector, 0.0, &size, buf, 640, 480); ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); hr = IMediaDet_WriteBitmapBits(detector, 0.0, 640, 480, filename); - todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); hr = IMediaDet_GetSampleGrabber(detector, &sg); ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
@@ -1775,22 +1774,22 @@ static void test_bitmap_grab_mode(void) check_bitmap(buf, 960, 720, 3.25);
hr = IMediaDet_WriteBitmapBits(detector, 0.0, 640, 480, NULL); - todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Got hr %#x.\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Got hr %#x.\n", hr); hr = IMediaDet_WriteBitmapBits(detector, 1.6, 640, 480, filename); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine check_bitmap_file(filename, buf, 640, 480, 1.6); + ok(hr == S_OK, "Got hr %#x.\n", hr); + check_bitmap_file(filename, buf, 640, 480, 1.6); hr = IMediaDet_WriteBitmapBits(detector, 3.08, 487, 337, filename); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine check_bitmap_file(filename, buf, 487, 337, 3.08); + ok(hr == S_OK, "Got hr %#x.\n", hr); + check_bitmap_file(filename, buf, 487, 337, 3.08); hr = IMediaDet_WriteBitmapBits(detector, 2.68, 11, 250, filename); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine check_bitmap_file(filename, buf, 11, 250, 2.68); + ok(hr == S_OK, "Got hr %#x.\n", hr); + check_bitmap_file(filename, buf, 11, 250, 2.68); hr = IMediaDet_WriteBitmapBits(detector, 0.44, 441, 363, filename); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine check_bitmap_file(filename, buf, 441, 363, 0.44); + ok(hr == S_OK, "Got hr %#x.\n", hr); + check_bitmap_file(filename, buf, 441, 363, 0.44); hr = IMediaDet_WriteBitmapBits(detector, 4.04, 809, 701, filename); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine check_bitmap_file(filename, buf, 809, 701, 4.04); + ok(hr == S_OK, "Got hr %#x.\n", hr); + check_bitmap_file(filename, buf, 809, 701, 4.04);
/* Changing filter resets bitmap grab mode */ testfilter.bitmap_grab_mode = FALSE; @@ -1832,7 +1831,7 @@ static void test_bitmap_grab_mode(void) /* As does WriteBitmapBits */ testfilter.bitmap_grab_mode = TRUE; hr = IMediaDet_WriteBitmapBits(detector, 1.75, 640, 480, NULL); - todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Got hr %#x.\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Got hr %#x.\n", hr); hr = IMediaDet_GetSampleGrabber(detector, &sg); ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); hr = IMediaDet_get_OutputStreams(detector, &count); @@ -1840,12 +1839,12 @@ static void test_bitmap_grab_mode(void) ok(count == 1, "Got %d streams.\n", count);
hr = IMediaDet_WriteBitmapBits(detector, 1.75, 640, 480, filename); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaDet_GetSampleGrabber(detector, &sg); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - if (SUCCEEDED(hr)) ISampleGrabber_Release(sg); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ISampleGrabber_Release(sg); hr = IMediaDet_get_OutputStreams(detector, &count); - todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
DeleteFileW(filename); ref = IMediaDet_Release(detector);