Blame libfreerdp/codec/test/TestFreeRDPRegion.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2014 Thincast Technologies GmbH
Packit 1fb8d4
 * Copyright 2014 Hardening <contact@hardening-consulting.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 * http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <winpr/print.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/codec/region.h>
Packit 1fb8d4
Packit 1fb8d4
static BOOL compareRectangles(const RECTANGLE_16* src1, const RECTANGLE_16* src2, int nb)
Packit 1fb8d4
{
Packit 1fb8d4
	int i;
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < nb; i++, src1++, src2++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (memcmp(src1, src2, sizeof(RECTANGLE_16)))
Packit 1fb8d4
		{
Packit 1fb8d4
			fprintf(stderr,
Packit Service 5a9772
			        "expecting rect %d (%" PRIu16 ",%" PRIu16 "-%" PRIu16 ",%" PRIu16
Packit Service 5a9772
			        ") and have (%" PRIu16 ",%" PRIu16 "-%" PRIu16 ",%" PRIu16 ")\n",
Packit Service 5a9772
			        i, src2->left, src2->top, src2->right, src2->bottom, src1->left, src1->top,
Packit Service 5a9772
			        src1->right, src1->bottom);
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_basic(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit 1fb8d4
	/* R1 + R2 ==> disjointed rects */
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r2 = { 150, 301, 250, 401 };
Packit Service 5a9772
	RECTANGLE_16 r1_r2[] = { { 0, 101, 200, 201 }, { 150, 301, 250, 401 } };
Packit 1fb8d4
	/* r1 */
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 1 || memcmp(rects, &r1, sizeof(RECTANGLE_16)))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	/* r1 + r2 */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r2))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	/* clear region */
Packit 1fb8d4
	region16_clear(&region);
Packit 1fb8d4
	region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (nbRects)
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r1_r3(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r3 = { 150, 151, 250, 251 };
Packit Service 5a9772
	RECTANGLE_16 r1_r3[] = { { 0, 101, 200, 151 }, { 0, 151, 250, 201 }, { 150, 201, 250, 251 } };
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+-----+                +-----+
Packit 1fb8d4
	 * || r1  |                |     |
Packit 1fb8d4
	 * ||   +-+------+         +-----+--------+
Packit 1fb8d4
	 * ||   |    r3  |         |              |
Packit 1fb8d4
	 * |+---+        | ====>   +-----+--------+
Packit 1fb8d4
	 * |    |        |               |        |
Packit 1fb8d4
	 * |    +--------+               +--------+
Packit 1fb8d4
	 */
Packit 1fb8d4
Packit 1fb8d4
	/* R1 + R3  */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	/* R3 + R1  */
Packit 1fb8d4
	region16_clear(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r9_r10(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |   +---+                +---+
Packit 1fb8d4
	 * |+--|r10|-+           +--+---+-+
Packit 1fb8d4
	 * ||r9|   | |           |        |
Packit 1fb8d4
	 * ||  |   | |           |        |
Packit 1fb8d4
	 * ||  |   | |  =====>   |        |
Packit 1fb8d4
	 * ||  |   | |           |        |
Packit 1fb8d4
	 * ||  |   | |           |        |
Packit 1fb8d4
	 * |+--|   |-+           +--+---+-+
Packit 1fb8d4
	 * |   +---+                +---+
Packit 1fb8d4
	 */
Packit Service 5a9772
	RECTANGLE_16 r9 = { 0, 100, 400, 200 };
Packit Service 5a9772
	RECTANGLE_16 r10 = { 200, 0, 300, 300 };
Packit Service 5a9772
	RECTANGLE_16 r9_r10[] = {
Packit Service 5a9772
		{ 200, 0, 300, 100 },
Packit Service 5a9772
		{ 0, 100, 400, 200 },
Packit Service 5a9772
		{ 200, 200, 300, 300 },
Packit 1fb8d4
	};
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r9))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r10))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 3 || !compareRectangles(rects, r9_r10, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r1_r5(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r5 = { 150, 121, 300, 131 };
Packit Service 5a9772
	RECTANGLE_16 r1_r5[] = { { 0, 101, 200, 121 }, { 0, 121, 300, 131 }, { 0, 131, 200, 201 } };
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+--------+               +--------+
Packit 1fb8d4
	 * || r1     |               |        |
Packit 1fb8d4
	 * ||     +--+----+          +--------+----+
Packit 1fb8d4
	 * ||     |  r5   |  =====>  |             |
Packit 1fb8d4
	 * ||     +-------+          +--------+----+
Packit 1fb8d4
	 * ||        |               |        |
Packit 1fb8d4
	 * |+--------+               +--------+
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 *
Packit 1fb8d4
	 */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r5))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r5, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r1_r6(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r6 = { 150, 121, 170, 131 };
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+--------+           +--------+
Packit 1fb8d4
	 * || r1     |           |        |
Packit 1fb8d4
	 * ||   +--+ |           |        |
Packit 1fb8d4
	 * ||   |r6| |  =====>   |        |
Packit 1fb8d4
	 * ||   +--+ |           |        |
Packit 1fb8d4
	 * ||        |           |        |
Packit 1fb8d4
	 * |+--------+           +--------+
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 */
Packit 1fb8d4
	region16_clear(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r6))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 1 || !compareRectangles(rects, &r1, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r1_r2_r4(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r2 = { 150, 301, 250, 401 };
Packit Service 5a9772
	RECTANGLE_16 r4 = { 150, 251, 250, 301 };
Packit Service 5a9772
	RECTANGLE_16 r1_r2_r4[] = { { 0, 101, 200, 201 }, { 150, 251, 250, 401 } };
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+-----+                +-----+
Packit 1fb8d4
	 * || r1  |                |     |
Packit 1fb8d4
	 * ||     |                |     |
Packit 1fb8d4
	 * ||     |                |     |
Packit 1fb8d4
	 * |+-----+        ====>   +-----+
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |    +--------+               +--------+
Packit 1fb8d4
	 * |    |   r4   |               |        |
Packit 1fb8d4
	 * |    +--------+               |        |
Packit 1fb8d4
	 * |    | r2     |               |        |
Packit 1fb8d4
	 * |    |        |               |        |
Packit 1fb8d4
	 * |    +--------+               +--------+
Packit 1fb8d4
	 *
Packit 1fb8d4
	 */
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r2))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r4))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2_r4, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r1_r7_r8(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r7 = { 300, 101, 500, 201 };
Packit Service 5a9772
	RECTANGLE_16 r8 = { 150, 121, 400, 131 };
Packit Service 5a9772
	RECTANGLE_16 r1_r7_r8[] = {
Packit Service 5a9772
		{ 0, 101, 200, 121 }, { 300, 101, 500, 121 }, { 0, 121, 500, 131 },
Packit Service 5a9772
		{ 0, 131, 200, 201 }, { 300, 131, 500, 201 },
Packit 1fb8d4
	};
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+--------+   +--------+           +--------+   +--------+
Packit 1fb8d4
	 * || r1     |   | r7     |           |        |   |        |
Packit 1fb8d4
	 * ||   +------------+    |           +--------+---+--------+
Packit 1fb8d4
	 * ||   |   r8       |    |   =====>  |                     |
Packit 1fb8d4
	 * ||   +------------+    |           +--------+---+--------+
Packit 1fb8d4
	 * ||        |   |        |           |        |   |        |
Packit 1fb8d4
	 * |+--------+   +--------+           +--------+   +--------+
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 */
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r7))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r8))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	region16_clear(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r8))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r7))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	region16_clear(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r8))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r7))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r1_r2_r3_r4(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r2 = { 150, 301, 250, 401 };
Packit Service 5a9772
	RECTANGLE_16 r3 = { 150, 151, 250, 251 };
Packit Service 5a9772
	RECTANGLE_16 r4 = { 150, 251, 250, 301 };
Packit Service 5a9772
	RECTANGLE_16 r1_r2_r3[] = {
Packit Service 5a9772
		{ 0, 101, 200, 151 }, { 0, 151, 250, 201 }, { 150, 201, 250, 251 }, { 150, 301, 250, 401 }
Packit 1fb8d4
	};
Packit Service 5a9772
	RECTANGLE_16 r1_r2_r3_r4[] = { { 0, 101, 200, 151 },
Packit Service 5a9772
		                           { 0, 151, 250, 201 },
Packit Service 5a9772
		                           { 150, 201, 250, 401 } };
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+-----+                +-----+
Packit 1fb8d4
	 * || r1  |                |     |
Packit 1fb8d4
	 * ||   +-+------+         +-----+--------+
Packit 1fb8d4
	 * ||   |    r3  |         |              |
Packit 1fb8d4
	 * |+---+        | ====>   +-----+--------+
Packit 1fb8d4
	 * |    |        |               |        |
Packit 1fb8d4
	 * |    +--------+               +--------+
Packit 1fb8d4
	 * |    +--------+               +--------+
Packit 1fb8d4
	 * |    | r2     |               |        |
Packit 1fb8d4
	 * |    |        |               |        |
Packit 1fb8d4
	 * |    +--------+               +--------+
Packit 1fb8d4
	 */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r2))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 4 || !compareRectangles(rects, r1_r2_r3, 4))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+-----+                 +-----+
Packit 1fb8d4
	 * ||     |                 |     |
Packit 1fb8d4
	 * |+-----+--------+        +-----+--------+
Packit 1fb8d4
	 * ||              |  ==>   |              |
Packit 1fb8d4
	 * |+-----+--------+        +-----+--------+
Packit 1fb8d4
	 * |  	  |        |              |        |
Packit 1fb8d4
	 * |  	  +--------+              |        |
Packit 1fb8d4
	 * |      |  + r4  |              |        |
Packit 1fb8d4
	 * |  	  +--------+              |        |
Packit 1fb8d4
	 * |  	  |        |              |        |
Packit 1fb8d4
	 * |  	  |        |              |        |
Packit 1fb8d4
	 * |  	  +--------+              +--------+
Packit 1fb8d4
	 */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r4))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3_r4, 3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_from_weston(void)
Packit 1fb8d4
{
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * 0: 0,0 -> 640,32 (w=640 h=32)
Packit 1fb8d4
	 * 1: 236,169 -> 268,201 (w=32 h=32)
Packit 1fb8d4
	 * 2: 246,258 -> 278,290 (w=32 h=32)
Packit 1fb8d4
	 */
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 0, 640, 32 };
Packit Service 5a9772
	RECTANGLE_16 r2 = { 236, 169, 268, 201 };
Packit Service 5a9772
	RECTANGLE_16 r3 = { 246, 258, 278, 290 };
Packit Service 5a9772
	RECTANGLE_16 r1_r2_r3[] = { { 0, 0, 640, 32 }, { 236, 169, 268, 201 }, { 246, 258, 278, 290 } };
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |+-------------------------------------------------------------+
Packit 1fb8d4
	 * ||              r1                                             |
Packit 1fb8d4
	 * |+-------------------------------------------------------------+
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |       +---------------+
Packit 1fb8d4
	 * |       |     r2        |
Packit 1fb8d4
	 * |       +---------------+
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |         +---------------+
Packit 1fb8d4
	 * |         |     r3        |
Packit 1fb8d4
	 * |         +---------------+
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r2))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&region, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3, 3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r1_inter_r3(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region, intersection;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r3 = { 150, 151, 250, 251 };
Packit Service 5a9772
	RECTANGLE_16 r1_inter_r3[] = {
Packit Service 5a9772
		{ 150, 151, 200, 201 },
Packit 1fb8d4
	};
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
	region16_init(&intersection);
Packit 1fb8d4
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+-----+
Packit 1fb8d4
	 * || r1  |
Packit 1fb8d4
	 * ||   +-+------+             +-+
Packit 1fb8d4
	 * ||   |    r3  | r1&r3       | |
Packit 1fb8d4
	 * |+---+        | ====>       +-+
Packit 1fb8d4
	 * |    |        |
Packit 1fb8d4
	 * |    +--------+
Packit 1fb8d4
	 */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_intersects_rect(&region, &r3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_intersect_rect(&intersection, &region, &r3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&intersection, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 1 || !compareRectangles(rects, r1_inter_r3, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	region16_uninit(&intersection);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_r1_r3_inter_r11(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region, intersection;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects;
Packit Service 5a9772
	RECTANGLE_16 r1 = { 0, 101, 200, 201 };
Packit Service 5a9772
	RECTANGLE_16 r3 = { 150, 151, 250, 251 };
Packit Service 5a9772
	RECTANGLE_16 r11 = { 170, 151, 600, 301 };
Packit Service 5a9772
	RECTANGLE_16 r1_r3_inter_r11[] = {
Packit Service 5a9772
		{ 170, 151, 250, 251 },
Packit 1fb8d4
	};
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
	region16_init(&intersection);
Packit 1fb8d4
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * +===============================================================
Packit 1fb8d4
	 * |
Packit 1fb8d4
	 * |+-----+
Packit 1fb8d4
	 * ||     |
Packit 1fb8d4
	 * ||     +------+
Packit 1fb8d4
	 * || r1+r3      |          (r1+r3) & r11
Packit 1fb8d4
	 * ||     +----------------+             +--------+
Packit 1fb8d4
	 * |+---+ |      |         |   ====>     |        |
Packit 1fb8d4
	 * |    | |      |         |             |        |
Packit 1fb8d4
	 * |    | |      |         |             |        |
Packit 1fb8d4
	 * |    +-|------+         |             +--------+
Packit 1fb8d4
	 * |      |            r11 |
Packit 1fb8d4
	 * |      +----------------+
Packit 1fb8d4
	 *
Packit 1fb8d4
	 *
Packit 1fb8d4
	 * R1+R3 is made of 3 bands, R11 overlap the second and the third band. The
Packit 1fb8d4
	 * intersection is made of two band that must be reassembled to give only
Packit 1fb8d4
	 * one
Packit 1fb8d4
	 */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &r3))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_intersects_rect(&region, &r11))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_intersect_rect(&intersection, &region, &r11))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&intersection, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 1 || !compareRectangles(rects, r1_r3_inter_r11, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&intersection);
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_norbert_case(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region, intersection;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects, i;
Packit Service 5a9772
	RECTANGLE_16 inRectangles[5] = { { 1680, 0, 1920, 242 },
Packit Service 5a9772
		                             { 294, 242, 971, 776 },
Packit Service 5a9772
		                             { 1680, 242, 1920, 776 },
Packit Service 5a9772
		                             { 1680, 776, 1920, 1036 },
Packit Service 5a9772
		                             { 2, 1040, 53, 1078 } };
Packit Service 5a9772
	RECTANGLE_16 screenRect = { 0, 0, 1920, 1080 };
Packit Service 5a9772
	RECTANGLE_16 expected_inter_extents = { 2, 0, 1920, 1078 };
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
	region16_init(&intersection);
Packit 1fb8d4
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * Consider following as a screen with resolution 1920*1080
Packit 1fb8d4
	 *      | |    |     |           |               |      |
Packit 1fb8d4
	 *      | |2   |53   |294        |971            |1680  |
Packit 1fb8d4
	 *      | |    |     |           |               |      |
Packit 1fb8d4
	 *    0 +=+======================================+======+
Packit 1fb8d4
	 *      | |                                      |      |
Packit 1fb8d4
	 *      |                                        |  R[0]|
Packit 1fb8d4
	 *  242 |            +-----------+               +------+
Packit 1fb8d4
	 *      | |          |           |               |      |
Packit 1fb8d4
	 *      |            |           |               |      |
Packit 1fb8d4
	 *      |            |       R[1]|               |  R[2]|
Packit 1fb8d4
	 *  776 | |          +-----------+               +------+
Packit 1fb8d4
	 *      |                                        |      |
Packit 1fb8d4
	 *      |                                        |  R[3]|
Packit 1fb8d4
	 * 1036 | |                                      +------+
Packit 1fb8d4
	 * 1040 | +----+
Packit 1fb8d4
	 *      | |R[4]|                         Union of R[0-4]|
Packit 1fb8d4
	 * 1078 | +----+    -    -    -    -    -    -    -    -+
Packit 1fb8d4
	 * 1080 |
Packit 1fb8d4
	 *
Packit 1fb8d4
	 *
Packit 1fb8d4
	 * The result is union of R[0] - R[4].
Packit 1fb8d4
	 * After intersected with the full screen rect, the
Packit 1fb8d4
	 * result should keep the same.
Packit 1fb8d4
	 */
Packit 1fb8d4
	for (i = 0; i < 5; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (!region16_union_rect(&region, &region, &inRectangles[i]))
Packit 1fb8d4
			goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!compareRectangles(region16_extents(&region), &expected_inter_extents, 1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_intersect_rect(&intersection, &region, &screenRect))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	rects = region16_rects(&intersection, &nbRects);
Packit 1fb8d4
Packit 1fb8d4
	if (!rects || nbRects != 5 || !compareRectangles(rects, inRectangles, nbRects))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&intersection);
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_norbert2_case(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	const RECTANGLE_16* rects;
Packit 1fb8d4
	UINT32 nbRects = 0;
Packit Service 5a9772
	RECTANGLE_16 rect1 = { 464, 696, 476, 709 };
Packit Service 5a9772
	RECTANGLE_16 rect2 = { 0, 0, 1024, 32 };
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &rect1))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: Error 1 - region16_union_rect failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!(rects = region16_rects(&region, &nbRects)))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: Error 2 - region16_rects failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (nbRects != 1)
Packit 1fb8d4
	{
Packit Service 5a9772
		fprintf(stderr, "%s: Error 3 - expected nbRects == 1 but got %" PRIu32 "\n", __FUNCTION__,
Packit Service 5a9772
		        nbRects);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!compareRectangles(&rects[0], &rect1, 1))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: Error 4 - compare failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &rect2))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: Error 5 - region16_union_rect failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!(rects = region16_rects(&region, &nbRects)))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: Error 6 - region16_rects failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (nbRects != 2)
Packit 1fb8d4
	{
Packit Service 5a9772
		fprintf(stderr, "%s: Error 7 - expected nbRects == 2 but got %" PRIu32 "\n", __FUNCTION__,
Packit Service 5a9772
		        nbRects);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!compareRectangles(&rects[0], &rect2, 1))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: Error 8 - compare failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!compareRectangles(&rects[1], &rect1, 1))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: Error 9 - compare failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int test_empty_rectangle(void)
Packit 1fb8d4
{
Packit 1fb8d4
	REGION16 region, intersection;
Packit 1fb8d4
	int retCode = -1;
Packit 1fb8d4
	int i;
Packit Service 5a9772
	RECTANGLE_16 emptyRectangles[3] = { { 0, 0, 0, 0 }, { 10, 10, 10, 11 }, { 10, 10, 11, 10 } };
Packit Service 5a9772
	RECTANGLE_16 firstRect = { 0, 0, 100, 100 };
Packit Service 5a9772
	RECTANGLE_16 anotherRect = { 100, 100, 200, 200 };
Packit Service 5a9772
	RECTANGLE_16 expected_inter_extents = { 0, 0, 0, 0 };
Packit 1fb8d4
	region16_init(&region);
Packit 1fb8d4
	region16_init(&intersection);
Packit 1fb8d4
Packit 1fb8d4
	/* Check for empty rectangles */
Packit 1fb8d4
	for (i = 0; i < 3; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (!rectangle_is_empty(&emptyRectangles[i]))
Packit 1fb8d4
			goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	/* Check for non-empty rectangles */
Packit 1fb8d4
	if (rectangle_is_empty(&firstRect))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	/* Intersect 2 non-intersect rectangle, result should be empty */
Packit 1fb8d4
	if (!region16_union_rect(&region, &region, &firstRect))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_intersect_rect(&region, &region, &anotherRect))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!compareRectangles(region16_extents(&region), &expected_inter_extents, 1))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!region16_is_empty(&region))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!rectangle_is_empty(region16_extents(&intersection)))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	retCode = 0;
Packit 1fb8d4
out:
Packit 1fb8d4
	region16_uninit(&intersection);
Packit 1fb8d4
	region16_uninit(&region);
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
typedef int (*TestFunction)(void);
Packit 1fb8d4
struct UnitaryTest
Packit 1fb8d4
{
Packit 1fb8d4
	const char* name;
Packit 1fb8d4
	TestFunction func;
Packit 1fb8d4
};
Packit 1fb8d4
Packit Service 5a9772
static struct UnitaryTest tests[] = { { "Basic trivial tests", test_basic },
Packit Service 5a9772
	                                  { "R1+R3 and R3+R1", test_r1_r3 },
Packit Service 5a9772
	                                  { "R1+R5", test_r1_r5 },
Packit Service 5a9772
	                                  { "R1+R6", test_r1_r6 },
Packit Service 5a9772
	                                  { "R9+R10", test_r9_r10 },
Packit Service 5a9772
	                                  { "R1+R2+R4", test_r1_r2_r4 },
Packit Service 5a9772
	                                  { "R1+R7+R8 in many orders", test_r1_r7_r8 },
Packit Service 5a9772
	                                  { "R1+R2+R3+R4", test_r1_r2_r3_r4 },
Packit Service 5a9772
	                                  { "data from weston", test_from_weston },
Packit Service 5a9772
	                                  { "R1 & R3", test_r1_inter_r3 },
Packit Service 5a9772
	                                  { "(R1+R3)&R11 (band merge)", test_r1_r3_inter_r11 },
Packit Service 5a9772
	                                  { "norbert's case", test_norbert_case },
Packit Service 5a9772
	                                  { "norbert's case 2", test_norbert2_case },
Packit Service 5a9772
	                                  { "empty rectangle case", test_empty_rectangle },
Packit Service 5a9772
Packit Service 5a9772
	                                  { NULL, NULL } };
Packit 1fb8d4
Packit 1fb8d4
int TestFreeRDPRegion(int argc, char* argv[])
Packit 1fb8d4
{
Packit 1fb8d4
	int i, testNb = 0;
Packit 1fb8d4
	int retCode = -1;
Packit Service 5a9772
	WINPR_UNUSED(argc);
Packit Service 5a9772
	WINPR_UNUSED(argv);
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; tests[i].func; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		testNb++;
Packit 1fb8d4
		fprintf(stderr, "%d: %s\n", testNb, tests[i].name);
Packit 1fb8d4
		retCode = tests[i].func();
Packit 1fb8d4
Packit 1fb8d4
		if (retCode < 0)
Packit 1fb8d4
			break;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (retCode < 0)
Packit 1fb8d4
		fprintf(stderr, "failed for test %d\n", testNb);
Packit 1fb8d4
Packit 1fb8d4
	return retCode;
Packit 1fb8d4
}