summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-11-20 03:23:51 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-11-20 03:23:51 -0500
commitf0816ddaf4e61d9295de5b1cbe51f956db7fbd16 (patch)
tree3aa4d6351064642f37cfc4d8ee39cf140891df77
parent44dd746bb68625b2f6be77c3f80292b45defe9d7 (diff)
Round fixed-point multiplication
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.
-rw-r--r--pixman/pixman-matrix.c10
-rw-r--r--test/affine-test.c6
-rw-r--r--test/rotate-test.c2
-rw-r--r--test/scaling-test.c6
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