From 5f5e752f15acff7f39c861f2defed8ca10fa041c Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Mon, 2 Aug 2021 21:48:38 -0400 Subject: Fix masked pixel fetching with wide format In __bits_image_fetch_affine_no_alpha and __bits_image_fetch_general, when `wide` is true, the mask is actually an array of argb_t instead of the array of uint32_t it was cast to, and the access to `mask[i]` does not correctly detect when the pixel is nontrivial. The code now uses a check appropriate for argb_t when `wide` is true. One caveat: this new check only skips entries when the mask pixel data is binary all zero; this misses cases like `-0.f` which would be caught by the FLOAT_IS_ZERO macro. As the mask check only appears to be a performance optimization to avoid loading inconsequential pixels, it erring on the side of loading more pixels is safe. Signed-off-by: Manuel Stoeckl --- pixman/pixman-bits-image.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 8f3d9f2..a0d9441 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -482,6 +482,7 @@ __bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, int width = iter->width; uint32_t * buffer = iter->buffer; + const uint32_t wide_zero[4] = {0}; pixman_fixed_t x, y; pixman_fixed_t ux, uy; pixman_vector_t v; @@ -513,7 +514,8 @@ __bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, for (i = 0; i < width; ++i) { - if (!mask || mask[i]) + if (!mask || (!wide && mask[i]) || + (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0)) { bits_image_fetch_pixel_filtered ( &image->bits, wide, x, y, get_pixel, buffer); @@ -636,6 +638,7 @@ __bits_image_fetch_general (pixman_iter_t *iter, get_pixel_t get_pixel = wide ? fetch_pixel_general_float : fetch_pixel_general_32; + const uint32_t wide_zero[4] = {0}; pixman_fixed_t x, y, w; pixman_fixed_t ux, uy, uw; pixman_vector_t v; @@ -670,7 +673,8 @@ __bits_image_fetch_general (pixman_iter_t *iter, { pixman_fixed_t x0, y0; - if (!mask || mask[i]) + if (!mask || (!wide && mask[i]) || + (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0)) { if (w != 0) { -- cgit v1.2.1