diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-05-08 20:37:35 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-05-09 10:30:38 +0100 |
commit | 2d6f26cd8b09523fa29d97436801c27bec1832f4 (patch) | |
tree | 998b7a85a950446ad406e4e24430c16dec058f43 /draw | |
parent | fdea29f101cb085b964c24638510fd200e5ad98d (diff) | |
download | mupdf-2d6f26cd8b09523fa29d97436801c27bec1832f4.tar.xz |
Bug 693021: Texture position overflow problems.
Keep texture position calculations in floats as long as possible, as
prematurely dropping back to ints can cause overflows in the
intermediate stages that don't nicely cancel out.
The fix for this makes 2000 or so bitmap differences, most trivial, but
with some progressions.
Diffstat (limited to 'draw')
-rw-r--r-- | draw/draw_affine.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/draw/draw_affine.c b/draw/draw_affine.c index 4e21ced0..52b8a847 100644 --- a/draw/draw_affine.c +++ b/draw/draw_affine.c @@ -653,14 +653,18 @@ fz_paint_image_imp(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap inv = fz_concat(inv, ctm); inv = fz_invert_matrix(inv); - fa = inv.a * 65536; - fb = inv.b * 65536; - fc = inv.c * 65536; - fd = inv.d * 65536; + fa = (int)(inv.a *= 65536.0f); + fb = (int)(inv.b *= 65536.0f); + fc = (int)(inv.c *= 65536.0f); + fd = (int)(inv.d *= 65536.0f); + inv.e *= 65536.0f; + inv.f *= 65536.0f; /* Calculate initial texture positions. Do a half step to start. */ - u = (fa * x) + (fc * y) + inv.e * 65536 + ((fa + fc) >> 1); - v = (fb * x) + (fd * y) + inv.f * 65536 + ((fb + fd) >> 1); + /* Bug 693021: Keep calculation in float for as long as possible to + * avoid overflow. */ + u = (int)((inv.a * x) + (inv.c * y) + inv.e + ((inv.a + inv.c) * .5f)); + v = (int)((inv.b * x) + (inv.d * y) + inv.f + ((inv.b + inv.d) * .5f)); /* RJW: The following is voodoo. No idea why it works, but it gives * the best match between scaled/unscaled/interpolated/non-interpolated |