summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-05-08 20:37:35 +0100
committerRobin Watts <robin.watts@artifex.com>2012-05-09 10:30:38 +0100
commit2d6f26cd8b09523fa29d97436801c27bec1832f4 (patch)
tree998b7a85a950446ad406e4e24430c16dec058f43 /draw
parentfdea29f101cb085b964c24638510fd200e5ad98d (diff)
downloadmupdf-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.c16
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