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.
This commit is contained in:
parent
1ed2b23902
commit
51cab75b1e
2 changed files with 20 additions and 53 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue