[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