[PATCH v2 4/8] qedit/tests: Add tests for GetBitmapBits.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Fri Oct 23 10:18:54 CDT 2020
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
dlls/qedit/tests/mediadet.c | 220 +++++++++++++++++++++++++++++++++++-
1 file changed, 218 insertions(+), 2 deletions(-)
diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c
index 18a4412..8c5ef4b 100644
--- a/dlls/qedit/tests/mediadet.c
+++ b/dlls/qedit/tests/mediadet.c
@@ -170,7 +170,9 @@ static DWORD WINAPI testfilter_frame_thread(void *arg)
struct testfilter *filter = arg;
IMemAllocator *allocator;
IMediaSample *sample;
+ unsigned i;
HRESULT hr;
+ DWORD fill;
BYTE *data;
hr = IMemInputPin_GetAllocator(filter->source.pMemInputPin, &allocator);
@@ -190,7 +192,13 @@ static DWORD WINAPI testfilter_frame_thread(void *arg)
hr = IMediaSample_GetPointer(sample, &data);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- memset(data, 0, 640 * 480 * 3);
+ fill = (start_time / 10000 & 0xffffff) ^ 0xccaabb;
+ for (i = 0; i < 640 * 480 * 3; i += 3)
+ {
+ data[i] = fill ^ i;
+ data[i + 1] = fill >> 8 ^ i;
+ data[i + 2] = fill >> 16 ^ i;
+ }
hr = IMediaSample_SetActualDataLength(sample, 640 * 480 * 3);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -609,6 +617,157 @@ static BOOL unpack_avi_file(int id, WCHAR name[MAX_PATH])
return ret && written == size;
}
+static void stretch_line(BYTE *dst, ULONG dst_width, BYTE *src, ULONG src_width)
+{
+ ULONG ratio, rem, drift, i = dst_width;
+
+ if (dst_width < src_width)
+ {
+ ratio = src_width / dst_width;
+ rem = src_width % dst_width;
+ drift = 0;
+ while (i--)
+ {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst += 3;
+ src += ratio * 3;
+ if (drift < rem)
+ {
+ src += 3;
+ drift += dst_width;
+ }
+ drift -= rem;
+ }
+ }
+ else if (dst_width > src_width)
+ {
+ drift = dst_width - 1;
+ while (i--)
+ {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst += 3;
+ if (drift < src_width)
+ {
+ drift += dst_width;
+ src += 3;
+ }
+ drift -= src_width;
+ }
+ }
+ else
+ {
+ memcpy(dst, src, dst_width * 3);
+ dst += dst_width * 3;
+ }
+
+ /* Fill the stride padding with zeros */
+ i = (dst_width * 3) % 4;
+ if (i)
+ for (i = 4 - i; i--;)
+ *dst++ = 0;
+}
+
+static void stretch_to_bitmap(BYTE *dst, ULONG dst_width, ULONG dst_height, BYTE *src, ULONG src_width, ULONG src_height)
+{
+ ULONG dst_stride = (dst_width * 3 + 3) & ~3;
+ ULONG src_stride = (src_width * 3 + 3) & ~3;
+ ULONG ratio, rem, drift, i = dst_height;
+ BYTE *dup;
+
+ if (dst_height < src_height)
+ {
+ ratio = src_height / dst_height;
+ rem = src_height % dst_height;
+ drift = 0;
+ while (i--)
+ {
+ stretch_line(dst, dst_width, src, src_width);
+ dst += dst_stride;
+ src += ratio * src_stride;
+ if (drift < rem)
+ {
+ src += src_stride;
+ drift += dst_height;
+ }
+ drift -= rem;
+ }
+ }
+ else
+ {
+ drift = dst_height - 1;
+ while (i--)
+ {
+ stretch_line(dst, dst_width, src, src_width);
+ dup = dst;
+ dst += dst_stride;
+ while (drift >= src_height && i--)
+ {
+ memcpy(dst, dup, dst_stride);
+ dst += dst_stride;
+ drift -= src_height;
+ }
+ drift += dst_height - src_height;
+ src += src_stride;
+ }
+ }
+}
+
+#define check_bitmap(buffer, width, height, seek_time) check_bitmap_(__LINE__, buffer, width, height, seek_time)
+static void check_bitmap_(unsigned line, void *buffer, LONG width, LONG height, double seek_time)
+{
+ DWORD fill = (DWORD)(seek_time * 1000.0) ^ 0xccaabb;
+ BYTE *p = (BYTE*)buffer + sizeof(BITMAPINFOHEADER);
+ DWORD line_width = (width * 3 + 3) & ~3;
+ BYTE *img, *src = malloc(640 * 480 * 3);
+ const BITMAPINFOHEADER *h = buffer;
+ unsigned i, j, v;
+
+ ok_(__FILE__,line)(h->biSize == sizeof(BITMAPINFOHEADER), "Got biSize %u.\n", h->biSize);
+ ok_(__FILE__,line)(h->biWidth == width, "Got biWidth %d.\n", h->biWidth);
+ ok_(__FILE__,line)(h->biHeight == height, "Got biHeight %d.\n", h->biHeight);
+ ok_(__FILE__,line)(h->biPlanes == 1, "Got biPlanes %d.\n", h->biPlanes);
+ ok_(__FILE__,line)(h->biBitCount == 24, "Got biBitCount %d.\n", h->biBitCount);
+ ok_(__FILE__,line)(h->biCompression == BI_RGB, "Got biCompression %d.\n", h->biCompression);
+ ok_(__FILE__,line)(h->biXPelsPerMeter == 0, "Got biXPelsPerMeter %d.\n", h->biXPelsPerMeter);
+ ok_(__FILE__,line)(h->biYPelsPerMeter == 0, "Got biYPelsPerMeter %d.\n", h->biYPelsPerMeter);
+ ok_(__FILE__,line)(h->biClrUsed == 0, "Got biClrUsed %d.\n", h->biClrUsed);
+ ok_(__FILE__,line)(h->biClrImportant == 0, "Got biClrImportant %d.\n", h->biClrImportant);
+
+ /* The lines are reversed since our source was top-down */
+ src = malloc(640 * 480 * 3);
+ img = src;
+ for (j = 640 * 480 * 3; j != 0;)
+ {
+ j -= 640 * 3;
+ v = j;
+ for (i = 0; i < 640 * 3; i += 3, v += 3)
+ {
+ img[i] = fill ^ v;
+ img[i + 1] = fill >> 8 ^ v;
+ img[i + 2] = fill >> 16 ^ v;
+ }
+ img += 640 * 3;
+ }
+
+ img = malloc(line_width * height);
+ stretch_to_bitmap(img, width, height, src, 640, 480);
+ free(src);
+
+ for (i = 0; i < line_width * height; i += 3)
+ if (p[i] != img[i] || p[i + 1] != img[i + 1] || p[i + 2] != img[i + 2])
+ {
+ ok_(__FILE__,line)(0, "Wrong bitmap data at offset %u (got 0x%06x, expected 0x%06x).\n",
+ p + i - (BYTE*)buffer, p[i] | p[i + 1] << 8 | p[i + 2] << 16,
+ img[i] | img[i + 1] << 8 | img[i + 2] << 16);
+ break;
+ }
+ free(img);
+}
+
static BOOL init_tests(void)
{
return unpack_avi_file(TEST_AVI_RES, test_avi_filename)
@@ -1300,7 +1459,7 @@ static void test_bitmap_grab_mode(void)
&TIME_FORMAT_BYTE,
&TIME_FORMAT_MEDIA_TIME
};
- char *buf = malloc(640 * 480 * 3);
+ char *buf = malloc(sizeof(BITMAPINFOHEADER) + 960 * 720 * 3);
struct testfilter testfilter;
FILTER_INFO filter_info;
IReferenceClock *clock;
@@ -1327,6 +1486,9 @@ static void test_bitmap_grab_mode(void)
hr = IMediaDet_EnterBitmapGrabMode(detector, 0.0);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ size = sizeof(BITMAPINFOHEADER) + 640 * 480 * 3;
+ hr = IMediaDet_GetBitmapBits(detector, 0.0, &size, buf, 640, 480);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
hr = IMediaDet_GetSampleGrabber(detector, &sg);
ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
@@ -1493,6 +1655,42 @@ static void test_bitmap_grab_mode(void)
ok(clock == NULL, "Got non-NULL clock.\n");
IMediaFilter_Release(mf);
+ /* Despite what MSDN states, size must be properly supplied on newer Windows versions */
+ hr = IMediaDet_GetBitmapBits(detector, 0.0, NULL, NULL, 640, 480);
+ todo_wine ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+ size = -1;
+ hr = IMediaDet_GetBitmapBits(detector, 0.0, &size, buf, 640, 480);
+ todo_wine ok(hr == E_INVALIDARG || broken(hr == S_OK) /* WinXP */, "Got hr %#x.\n", hr);
+ size = 640 * 480 * 3;
+ hr = IMediaDet_GetBitmapBits(detector, 0.0, &size, buf, 640, 480);
+ todo_wine ok(hr == E_OUTOFMEMORY || broken(hr == S_OK) /* WinXP */, "Got hr %#x.\n", hr);
+ ok(size == 640 * 480 * 3, "Got size %d.\n", size);
+ size = sizeof(BITMAPINFOHEADER) + 640 * 480 * 3;
+ hr = IMediaDet_GetBitmapBits(detector, -1.0, &size, buf, 640, 480);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = IMediaDet_GetBitmapBits(detector, 2.5, &size, buf, 640, 480);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine check_bitmap(buf, 640, 480, 2.5);
+
+ /* GetBitmapBits/WriteBitmapBits can scale the image */
+ size = sizeof(BITMAPINFOHEADER) + 960 * 720 * 3;
+ hr = IMediaDet_GetBitmapBits(detector, 1.5, &size, buf, 131, 151);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(size == sizeof(BITMAPINFOHEADER) + 960 * 720 * 3, "Got size %d.\n", size);
+ todo_wine check_bitmap(buf, 131, 151, 1.5);
+ hr = IMediaDet_GetBitmapBits(detector, 4.0, NULL, buf, 503, 79);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine check_bitmap(buf, 503, 79, 4.0);
+ hr = IMediaDet_GetBitmapBits(detector, 1.52, NULL, buf, 139, 487);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine check_bitmap(buf, 139, 487, 1.52);
+ hr = IMediaDet_GetBitmapBits(detector, 2.12, NULL, buf, 640, 641);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine check_bitmap(buf, 640, 641, 2.12);
+ hr = IMediaDet_GetBitmapBits(detector, 3.25, NULL, buf, 960, 720);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine check_bitmap(buf, 960, 720, 3.25);
+
/* Changing filter resets bitmap grab mode */
testfilter.bitmap_grab_mode = FALSE;
hr = IMediaDet_put_Filter(detector, &testfilter.filter.IUnknown_inner);
@@ -1503,6 +1701,24 @@ static void test_bitmap_grab_mode(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(count == 1, "Got %d streams.\n", count);
+ /* GetBitmapBits enables it only if it retrieves the image */
+ testfilter.bitmap_grab_mode = TRUE;
+ hr = IMediaDet_GetBitmapBits(detector, 1.25, &size, NULL, 640, 480);
+ todo_wine ok(hr == S_OK, "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);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(count == 1, "Got %d streams.\n", count);
+
+ hr = IMediaDet_GetBitmapBits(detector, 1.25, NULL, buf, 640, 480);
+ todo_wine 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);
+ hr = IMediaDet_get_OutputStreams(detector, &count);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
ref = IMediaDet_Release(detector);
ok(!ref, "Got outstanding refcount %d.\n", ref);
ref = IBaseFilter_Release(&testfilter.filter.IBaseFilter_iface);
--
2.21.0
More information about the wine-devel
mailing list