[PATCH 7/7] qedit: Implement IMediaDet::WriteBitmapBits.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Oct 19 11:48:59 CDT 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at 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);
-- 
2.21.0




More information about the wine-devel mailing list