summaryrefslogtreecommitdiff
path: root/goo
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2011-08-30 16:36:24 +0200
committerAlbert Astals Cid <aacid@kde.org>2011-08-30 16:43:51 +0200
commitfaaba717046ba87ef5ded614e2bcab6260a9f7c2 (patch)
treea5dc1ca187cee56b83ec29992e537b12c328341b /goo
parent73efc96eef6bd32a7c058b7dda8101f4f23c454f (diff)
xpdf303: FixedPoint improvements
Diffstat (limited to 'goo')
-rw-r--r--goo/FixedPoint.cc51
-rw-r--r--goo/FixedPoint.h15
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