[Pixman] [PATCH 1/3] Round fixed-point multiplication
Søren Sandmann
sandmann at cs.au.dk
Wed Nov 21 22:57:45 PST 2012
From: Søren Sandmann Pedersen <ssp at redhat.com>
After two fixed-point numbers are multiplied, the result is shifted
into place, but up until now pixman has simply discarded the low-order
bits instead of rounding to the closest number.
Fix that by adding 0x8000 (or 0x2 in one place) before shifting and
update the test checksums to match.
---
pixman/pixman-matrix.c | 10 +++++-----
test/affine-test.c | 6 +++---
test/rotate-test.c | 2 +-
test/scaling-test.c | 6 +++---
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/pixman/pixman-matrix.c b/pixman/pixman-matrix.c
index d2ab609..cd2f1b5 100644
--- a/pixman/pixman-matrix.c
+++ b/pixman/pixman-matrix.c
@@ -62,7 +62,7 @@ pixman_transform_point_3d (const struct pixman_transform *transform,
{
partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] *
(pixman_fixed_48_16_t) vector->vector[i]);
- v += partial >> 16;
+ v += (partial + 0x8000) >> 16;
}
if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
@@ -96,16 +96,16 @@ pixman_transform_point (const struct pixman_transform *transform,
{
partial = ((pixman_fixed_32_32_t) transform->matrix[j][i] *
(pixman_fixed_32_32_t) vector->vector[i]);
- v[j] += partial >> 2;
+ v[j] += (partial + 2) >> 2;
}
}
- if (!(v[2] >> 16))
+ if (!((v[2] + 0x8000) >> 16))
return FALSE;
for (j = 0; j < 2; j++)
{
- quo = v[j] / (v[2] >> 16);
+ quo = v[j] / ((v[2] + 0x8000) >> 16);
if (quo > pixman_max_fixed_48_16 || quo < pixman_min_fixed_48_16)
return FALSE;
vector->vector[j] = (pixman_fixed_t) quo;
@@ -138,7 +138,7 @@ pixman_transform_multiply (struct pixman_transform * dst,
(pixman_fixed_32_32_t) l->matrix[dy][o] *
(pixman_fixed_32_32_t) r->matrix[o][dx];
- v += partial >> 16;
+ v += (partial + 0x8000) >> 16;
}
if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
diff --git a/test/affine-test.c b/test/affine-test.c
index 7bc28b4..daa86c8 100644
--- a/test/affine-test.c
+++ b/test/affine-test.c
@@ -310,11 +310,11 @@ test_composite (int testnum,
}
#if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x1EF2175A
+#define CHECKSUM 0x344413F0
#elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x74050F50
+#define CHECKSUM 0xC8181A76
#elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0x4362EAE8
+#define CHECKSUM 0xD672A457
#else
#define CHECKSUM 0x00000000
#endif
diff --git a/test/rotate-test.c b/test/rotate-test.c
index d63a289..a0488ef 100644
--- a/test/rotate-test.c
+++ b/test/rotate-test.c
@@ -108,6 +108,6 @@ int
main (int argc, const char *argv[])
{
return fuzzer_test_main ("rotate", 15000,
- 0x03A24D51,
+ 0x5236FD9F,
test_transform, argc, argv);
}
diff --git a/test/scaling-test.c b/test/scaling-test.c
index 2736123..0354103 100644
--- a/test/scaling-test.c
+++ b/test/scaling-test.c
@@ -380,11 +380,11 @@ test_composite (int testnum,
}
#if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x8D3A7539
+#define CHECKSUM 0x107B67ED
#elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x03A23E0C
+#define CHECKSUM 0x30EC0CF0
#elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0xE96D1A5E
+#define CHECKSUM 0x87B496BC
#else
#define CHECKSUM 0x00000000
#endif
--
1.7.4
More information about the Pixman
mailing list