aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-02-05 20:22:26 +0100
committerMattias Andrée <maandree@kth.se>2023-02-05 20:22:32 +0100
commitcfaad8ab623bc6aee6e4d713d6b1ffe49438d48b (patch)
treede11d9d5f9705855ba1c3fed9cee0513dfafc748
parentFix two trivial errors in draw_linear_bezier_reference and add some tests (diff)
downloadlibrifunktionsteckensnittsglyfrasteriseringsprogrambiblioteket-cfaad8ab623bc6aee6e4d713d6b1ffe49438d48b.tar.gz
librifunktionsteckensnittsglyfrasteriseringsprogrambiblioteket-cfaad8ab623bc6aee6e4d713d6b1ffe49438d48b.tar.bz2
librifunktionsteckensnittsglyfrasteriseringsprogrambiblioteket-cfaad8ab623bc6aee6e4d713d6b1ffe49438d48b.tar.xz
draw_linear_bezier_reference: fix bounds checking error
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--common.h1
-rw-r--r--draw_linear_bezier_reference.c68
2 files changed, 49 insertions, 20 deletions
diff --git a/common.h b/common.h
index 67a1c62..805ba0b 100644
--- a/common.h
+++ b/common.h
@@ -123,6 +123,7 @@ PURE_FUNCTION int doublepcmp(const void *avp, const void *bvp);
#ifdef TEST
+#include <unistd.h>
#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants"
diff --git a/draw_linear_bezier_reference.c b/draw_linear_bezier_reference.c
index c288781..451eb3a 100644
--- a/draw_linear_bezier_reference.c
+++ b/draw_linear_bezier_reference.c
@@ -56,10 +56,11 @@ draw_linear_bezier_reference(RASTER *restrict raster, double x1, double y1, doub
x = cx;
/* Make sure loop will exit when we reach the end */
- if ((xdir < 0 && x < x2) || (xdir > 0 && x > x2))
+ if ((xdir < 0 && x <= x2) || (xdir > 0 && x >= x2) ||
+ (ydir < 0 && y <= y2) || (ydir > 0 && y >= y2)) {
x = x2;
- if ((ydir < 0 && y < y2) || (ydir > 0 && y > y2))
y = y2;
+ }
}
/* Select cell to draw in */
@@ -153,6 +154,17 @@ print_raster(void)
static void
+draw(double x1, double y1, double x2, double y2)
+{
+ alarm(5);
+ draw_linear_bezier_reference(raster, x1, y1, x2, y2);
+ alarm(0);
+}
+#undef draw_linear_bezier_reference
+#define draw_linear_bezier_reference "use draw(double, double, double, double) instead"
+
+
+static void
check_horizontal(void)
{
ssize_t y, x1, x2;
@@ -160,16 +172,16 @@ check_horizontal(void)
for (y = -2; y < 12; y++) {
for (x1 = -2; x1 < 12; x1++) {
for (x2 = -2; x2 < 12; x2++) {
- draw_linear_bezier_reference(raster, x1, y, x2, y);
+ draw(x1, y, x2, y);
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, x1 + 0.25, y, x2 + 0.25, y);
+ draw(x1 + 0.25, y, x2 + 0.25, y);
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, x1, y + 0.25, x2, y + 0.25);
+ draw(x1, y + 0.25, x2, y + 0.25);
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, x1 + 0.25, y + 0.25, x2 + 0.25, y + 0.25);
+ draw(x1 + 0.25, y + 0.25, x2 + 0.25, y + 0.25);
CHECK_ZEROED();
}
}
@@ -188,7 +200,7 @@ check_vertical(void)
for (y2 = -2; y2 < 12; y2++) {
ydir = SIGNUM(y2 - y1);
- draw_linear_bezier_reference(raster, x, y1, x, y2);
+ draw(x, y1, x, y2);
for (i = 0; i < 10; i++) {
if (i < y1 && i < y2)
continue;
@@ -201,7 +213,7 @@ check_vertical(void)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, x + 0.25, y1, x + 0.25, y2);
+ draw(x + 0.25, y1, x + 0.25, y2);
for (i = 0; i < 10; i++) {
if (i < y1 && i < y2)
continue;
@@ -214,7 +226,7 @@ check_vertical(void)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, x, y1 + 0.25, x, y2 + 0.25);
+ draw(x, y1 + 0.25, x, y2 + 0.25);
for (i = 0; i < 10; i++) {
if (i < y1 + (y1 > y2) && i < y2 + (y2 > y1))
continue;
@@ -228,7 +240,7 @@ check_vertical(void)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, x + 0.25, y1 + 0.25, x + 0.25, y2 + 0.25);
+ draw(x + 0.25, y1 + 0.25, x + 0.25, y2 + 0.25);
for (i = 0; i < 10; i++) {
if (i < y1 + (y1 > y2) && i < y2 + (y2 > y1))
continue;
@@ -258,7 +270,7 @@ check_11_diagonal(ssize_t xshift, ssize_t yshift)
imax = i1 > i2 ? i1 : i2;
idir = SIGNUM(i2 - i1);
- draw_linear_bezier_reference(raster, i1 + xshift, i1 + yshift, i2 + xshift, i2 + yshift);
+ draw(i1 + xshift, i1 + yshift, i2 + xshift, i2 + yshift);
for (i = imin; i < imax; i++) {
x = i + xshift;
y = i + yshift;
@@ -273,7 +285,7 @@ check_11_diagonal(ssize_t xshift, ssize_t yshift)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, i1 + xshift, i1 + yshift + 0.25, i2 + xshift, i2 + yshift + 0.25);
+ draw(i1 + xshift, i1 + yshift + 0.25, i2 + xshift, i2 + yshift + 0.25);
for (i = imin; i < imax; i++) {
x = i + xshift;
y = i + yshift;
@@ -298,7 +310,7 @@ check_11_diagonal(ssize_t xshift, ssize_t yshift)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, i1 + xshift + 0.25, i1 + yshift, i2 + xshift + 0.25, i2 + yshift);
+ draw(i1 + xshift + 0.25, i1 + yshift, i2 + xshift + 0.25, i2 + yshift);
for (i = imin; i < imax; i++) {
x = i + xshift;
y = i + yshift;
@@ -323,8 +335,7 @@ check_11_diagonal(ssize_t xshift, ssize_t yshift)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, i1 + xshift + 0.25, i1 + yshift + 0.25,
- i2 + xshift + 0.25, i2 + yshift + 0.25);
+ draw(i1 + xshift + 0.25, i1 + yshift + 0.25, i2 + xshift + 0.25, i2 + yshift + 0.25);
for (i = imin; i < imax; i++) {
x = i + xshift;
y = i + yshift;
@@ -364,7 +375,7 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift)
imax = i1 > i2 ? i1 : i2;
ydir = -SIGNUM(i2 - i1);
- draw_linear_bezier_reference(raster, i1 + xshift, i2 + yshift, i2 + xshift, i1 + yshift);
+ draw(i1 + xshift, i2 + yshift, i2 + xshift, i1 + yshift);
for (i = imin; i < imax; i++) {
x = i + xshift;
y = imax - i + imin + yshift - 1;
@@ -379,7 +390,7 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, i1 + xshift, i2 + yshift + 0.25, i2 + xshift, i1 + yshift + 0.25);
+ draw(i1 + xshift, i2 + yshift + 0.25, i2 + xshift, i1 + yshift + 0.25);
for (i = imin; i < imax; i++) {
x = i + xshift;
y = imax - i + imin + yshift - 1;
@@ -404,7 +415,7 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, i1 + xshift + 0.25, i2 + yshift, i2 + xshift + 0.25, i1 + yshift);
+ draw(i1 + xshift + 0.25, i2 + yshift, i2 + xshift + 0.25, i1 + yshift);
for (i = imin; i < imax; i++) {
x = i + xshift;
y = imax - i + imin + yshift - 1;
@@ -429,8 +440,7 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift)
}
CHECK_ZEROED();
- draw_linear_bezier_reference(raster, i1 + xshift + 0.25, i2 + yshift + 0.25,
- i2 + xshift + 0.25, i1 + yshift + 0.25);
+ draw(i1 + xshift + 0.25, i2 + yshift + 0.25, i2 + xshift + 0.25, i1 + yshift + 0.25);
for (i = imin; i < imax; i++) {
x = i + xshift;
y = imax - i + imin + yshift - 1;
@@ -469,11 +479,25 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift)
}
+static void
+try_random_line(void)
+{
+ double x1 = (double)rand() / (double)RAND_MAX;
+ double y1 = (double)rand() / (double)RAND_MAX;
+ double x2 = (double)rand() / (double)RAND_MAX;
+ double y2 = (double)rand() / (double)RAND_MAX;
+ draw(x1, y1, x2, y2);
+}
+
+
int
main(void)
{
+ size_t i;
+
raster = rtgrpblib_create_raster(10, 10);
ASSERT(raster);
+ srand((unsigned)(uintptr_t)raster);
check_horizontal();
check_vertical();
@@ -498,6 +522,10 @@ main(void)
check_11_antidiagonal(-2, 2);
check_11_antidiagonal(-2, -2);
+ for (i = 0; i < 100000UL; i++)
+ try_random_line();
+ rtgrpblib_reset_raster(raster, 10, 10);
+
free(raster);
return 0;
}