diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-11-20 03:23:51 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-11-20 03:23:51 -0500 |
commit | f0816ddaf4e61d9295de5b1cbe51f956db7fbd16 (patch) | |
tree | 3aa4d6351064642f37cfc4d8ee39cf140891df77 | |
parent | 44dd746bb68625b2f6be77c3f80292b45defe9d7 (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.c | 10 | ||||
-rw-r--r-- | test/affine-test.c | 6 | ||||
-rw-r--r-- | test/rotate-test.c | 2 | ||||
-rw-r--r-- | 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 |