From 51cab75b1ee9f9a117f02f146ee33d96a4c32e92 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 23 Jun 2021 17:42:59 +0200 Subject: [PATCH] assembling: Fix copying only partial tile on overhang If the tile in question was hanging over the left edge we would not be copying the full available width. Fix this and change the test to catch the error condition (by forcing a too small image and overlap both ways). Simplify the code by only selecting the starting point inside the image/frame and then just checking the both image and frame boundary in the loop. Not quite as efficient, but it really shouldn't matter too much here. --- libfprint/fpi-assembling.c | 66 +++++++++---------------------------- tests/test-fpi-assembling.c | 7 ++-- 2 files changed, 20 insertions(+), 53 deletions(-) diff --git a/libfprint/fpi-assembling.c b/libfprint/fpi-assembling.c index 6d34679..9364685 100644 --- a/libfprint/fpi-assembling.c +++ b/libfprint/fpi-assembling.c @@ -210,69 +210,36 @@ aes_blit_stripe (struct fpi_frame_asmbl_ctx *ctx, struct fpi_frame *stripe, int x, int y) { - unsigned int ix, iy; - unsigned int fx, fy; - unsigned int width, height; + unsigned int ix1, iy1; + unsigned int fx1, fy1; + unsigned int fx, fy, ix, iy; - /* Find intersection */ + /* Select starting point inside image and frame */ if (x < 0) { - width = ctx->frame_width + x; - ix = 0; - fx = -x; + ix1 = 0; + fx1 = -x; } else { - ix = x; - fx = 0; - width = ctx->frame_width; + ix1 = x; + fx1 = 0; } - if ((ix + width) > img->width) - width = img->width - ix; if (y < 0) { - iy = 0; - fy = -y; - height = ctx->frame_height + y; + iy1 = 0; + fy1 = -y; } else { - iy = y; - fy = 0; - height = ctx->frame_height; + iy1 = y; + fy1 = 0; } - if (fx > ctx->frame_width) - return; - - if (fy > ctx->frame_height) - return; - - if (ix > img->width) - return; - - if (iy > img->height) - return; - - if ((iy + height) > img->height) - height = img->height - iy; - - for (; fy < height; fy++, iy++) - { - if (x < 0) - { - ix = 0; - fx = -x; - } - else - { - ix = x; - fx = 0; - } - for (; fx < width; fx++, ix++) - img->data[ix + (iy * img->width)] = ctx->get_pixel (ctx, stripe, fx, fy); - } + for (fy = fy1, iy = iy1; fy < ctx->frame_height && iy < img->height; fy++, iy++) + for (fx = fx1, ix = ix1; fx < ctx->frame_width && ix < img->width; fx++, ix++) + img->data[ix + (iy * img->width)] = ctx->get_pixel (ctx, stripe, fx, fy); } /** @@ -298,7 +265,6 @@ fpi_assemble_frames (struct fpi_frame_asmbl_ctx *ctx, //FIXME g_return_if_fail g_return_val_if_fail (stripes != NULL, NULL); - BUG_ON (ctx->image_width < ctx->frame_width); /* No offset for 1st image */ fpi_frame = stripes->data; @@ -331,7 +297,7 @@ fpi_assemble_frames (struct fpi_frame_asmbl_ctx *ctx, /* Assemble stripes */ y = reverse ? (height - ctx->frame_height) : 0; - x = (ctx->image_width - ctx->frame_width) / 2; + x = ((int) ctx->image_width - (int) ctx->frame_width) / 2; for (l = stripes; l != NULL; l = l->next) { diff --git a/tests/test-fpi-assembling.c b/tests/test-fpi-assembling.c index 06f4652..94b8fe5 100644 --- a/tests/test-fpi-assembling.c +++ b/tests/test-fpi-assembling.c @@ -62,6 +62,7 @@ test_frame_assembling (void) int test_height; guchar *data; struct fpi_frame_asmbl_ctx ctx = { 0, }; + gint xborder = 5; g_autoptr(FpImage) fp_img = NULL; GSList *frames = NULL; @@ -79,7 +80,7 @@ test_frame_assembling (void) ctx.get_pixel = cairo_get_pixel; ctx.frame_width = width; ctx.frame_height = 20; - ctx.image_width = width; + ctx.image_width = width - 2 * xborder; g_assert (height > ctx.frame_height); @@ -118,8 +119,8 @@ test_frame_assembling (void) /* The FpImage and cairo surface need to be identical in the test area */ for (int y = 0; y < test_height; y++) - for (int x = 0; x < width; x++) - g_assert_cmpint (data[x * 4 + y * stride + 1], ==, fp_img->data[x + y * width]); + for (int x = 0; x < ctx.image_width; x++) + g_assert_cmpint (data[(x + xborder) * 4 + y * stride + 1], ==, fp_img->data[x + y * ctx.image_width]); g_slist_free_full (frames, g_free); cairo_surface_destroy (img);