diff options
author | Albert Astals Cid <aacid@kde.org> | 2011-08-30 16:36:24 +0200 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2011-08-30 16:43:51 +0200 |
commit | faaba717046ba87ef5ded614e2bcab6260a9f7c2 (patch) | |
tree | a5dc1ca187cee56b83ec29992e537b12c328341b /goo | |
parent | 73efc96eef6bd32a7c058b7dda8101f4f23c454f (diff) |
xpdf303: FixedPoint improvements
Diffstat (limited to 'goo')
-rw-r--r-- | goo/FixedPoint.cc | 51 | ||||
-rw-r--r-- | goo/FixedPoint.h | 15 |
2 files changed, 46 insertions, 20 deletions
diff --git a/goo/FixedPoint.cc b/goo/FixedPoint.cc index 79a6a9ae..26b2f0fe 100644 --- a/goo/FixedPoint.cc +++ b/goo/FixedPoint.cc @@ -82,28 +82,32 @@ FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) { } int FixedPoint::mul(int x, int y) { -#if 1 //~tmp - return ((FixPtInt64)x * y) >> fixptShift; -#else - int ah0, ah, bh, al, bl; - ah0 = x & fixptMaskH; - ah = x >> fixptShift; - al = x - ah0; - bh = y >> fixptShift; - bl = y - (bh << fixptShift); - return ah0 * bh + ah * bl + al * bh + ((al * bl) >> fixptShift); -#endif + FixPtInt64 z; + + z = ((FixPtInt64)x * y) >> fixptShift; + if (z > 0x7fffffffLL) { + return 0x7fffffff; + } else if (z < -0x80000000LL) { + return 0x80000000; + } else { + return (int)z; + } } int FixedPoint::div(int x, int y) { -#if 1 //~tmp - return ((FixPtInt64)x << fixptShift) / y; -#else -#endif + FixPtInt64 z; + + z = ((FixPtInt64)x << fixptShift) / y; + if (z > 0x7fffffffLL) { + return 0x7fffffff; + } else if (z < -0x80000000LL) { + return 0x80000000; + } else { + return (int)z; + } } GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) { -#if 1 //~tmp FixPtInt64 z; z = ((FixPtInt64)x.val << fixptShift) / y.val; @@ -113,8 +117,19 @@ GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) { } result->val = z; return gTrue; -#else -#endif +} + +GBool FixedPoint::checkDet(FixedPoint m11, FixedPoint m12, + FixedPoint m21, FixedPoint m22, + FixedPoint epsilon) { + FixPtInt64 det, e; + + det = (FixPtInt64)m11.val * (FixPtInt64)m22.val + - (FixPtInt64)m12.val * (FixPtInt64)m21.val; + e = (FixPtInt64)epsilon.val << fixptShift; + // NB: this comparison has to be >= not > because epsilon can be + // truncated to zero as a fixed point value. + return det >= e || det <= -e; } #endif // USE_FIXEDPOINT diff --git a/goo/FixedPoint.h b/goo/FixedPoint.h index 08936bc6..afe21d96 100644 --- a/goo/FixedPoint.h +++ b/goo/FixedPoint.h @@ -45,7 +45,7 @@ public: operator int() { return val >> fixptShift; } - int getRaw() { return val; } + int get16Dot16() { return val; } FixedPoint operator =(FixedPoint x) { val = x.val; return *this; } @@ -132,6 +132,11 @@ public: static int round(FixedPoint x) { return (x.val + (1 << (fixptShift - 1))) >> fixptShift; } + // Computes (x+y)/2 avoiding overflow and LSbit accuracy issues. + static FixedPoint avg(FixedPoint x, FixedPoint y) + { return make((x.val >> 1) + (y.val >> 1) + ((x.val | y.val) & 1)); } + + static FixedPoint sqrt(FixedPoint x); static FixedPoint pow(FixedPoint x, FixedPoint y); @@ -140,6 +145,12 @@ public: // overflow. static GBool divCheck(FixedPoint x, FixedPoint y, FixedPoint *result); + // Compute abs(m11*m22 - m12*m21) >= epsilon, handling the case + // where the multiplications overflow. + static GBool checkDet(FixedPoint m11, FixedPoint m12, + FixedPoint m21, FixedPoint m22, + FixedPoint epsilon); + private: static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; } @@ -147,7 +158,7 @@ private: static int mul(int x, int y); static int div(int x, int y); - int val; // 16.16 fixed point + int val; // fixed point: (n-fixptShift).(fixptShift) }; #endif // USE_FIXEDPOINT |