1 //========================================================================
2 //
3 // FixedPoint.h
4 //
5 // Fixed point type, with C++ operators.
6 //
7 // Copyright 2004 Glyph & Cog, LLC
8 //
9 //========================================================================
10 
11 #ifndef FIXEDPOINT_H
12 #define FIXEDPOINT_H
13 
14 #include "poppler-config.h"
15 
16 #if USE_FIXEDPOINT
17 
18 #ifdef USE_GCC_PRAGMAS
19 #pragma interface
20 #endif
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "gtypes.h"
25 
26 #define fixptShift 16
27 #define fixptMaskL ((1 << fixptShift) - 1)
28 #define fixptMaskH (~fixptMaskL)
29 
30 typedef long long FixPtInt64;
31 
32 class FixedPoint {
33 public:
34 
FixedPoint()35   FixedPoint() { val = 0; }
FixedPoint(const FixedPoint & x)36   FixedPoint(const FixedPoint &x) { val = x.val; }
FixedPoint(double x)37   FixedPoint(double x) { val = (int)(x * (1 << fixptShift) + 0.5); }
FixedPoint(int x)38   FixedPoint(int x) { val = x << fixptShift; }
FixedPoint(long x)39   FixedPoint(long x) { val = x << fixptShift; }
40 
41   operator float()
42     { return (float) val * ((float)1 / (float)(1 << fixptShift)); }
43   operator double()
44     { return (double) val * (1.0 / (double)(1 << fixptShift)); }
45   operator int()
46     { return val >> fixptShift; }
47 
get16Dot16()48   int get16Dot16() { return val; }
49 
50   FixedPoint operator =(FixedPoint x) { val = x.val; return *this; }
51 
52   int operator ==(FixedPoint x) { return val == x.val; }
53   int operator ==(double x) { return *this == (FixedPoint)x; }
54   int operator ==(int x) { return *this == (FixedPoint)x; }
55   int operator ==(long x) { return *this == (FixedPoint)x; }
56 
57   int operator !=(FixedPoint x) { return val != x.val; }
58   int operator !=(double x) { return *this != (FixedPoint)x; }
59   int operator !=(int x) { return *this != (FixedPoint)x; }
60   int operator !=(long x) { return *this != (FixedPoint)x; }
61 
62   int operator <(FixedPoint x) { return val < x.val; }
63   int operator <(double x) { return *this < (FixedPoint)x; }
64   int operator <(int x) { return *this < (FixedPoint)x; }
65   int operator <(long x) { return *this < (FixedPoint)x; }
66 
67   int operator <=(FixedPoint x) { return val <= x.val; }
68   int operator <=(double x) { return *this <= (FixedPoint)x; }
69   int operator <=(int x) { return *this <= (FixedPoint)x; }
70   int operator <=(long x) { return *this <= (FixedPoint)x; }
71 
72   int operator >(FixedPoint x) { return val > x.val; }
73   int operator >(double x) { return *this > (FixedPoint)x; }
74   int operator >(int x) { return *this > (FixedPoint)x; }
75   int operator >(long x) { return *this > (FixedPoint)x; }
76 
77   int operator >=(FixedPoint x) { return val >= x.val; }
78   int operator >=(double x) { return *this >= (FixedPoint)x; }
79   int operator >=(int x) { return *this >= (FixedPoint)x; }
80   int operator >=(long x) { return *this >= (FixedPoint)x; }
81 
82   FixedPoint operator -() { return make(-val); }
83 
84   FixedPoint operator +(FixedPoint x) { return make(val + x.val); }
85   FixedPoint operator +(double x) { return *this + (FixedPoint)x; }
86   FixedPoint operator +(int x) { return *this + (FixedPoint)x; }
87   FixedPoint operator +(long x) { return *this + (FixedPoint)x; }
88 
89   FixedPoint operator +=(FixedPoint x) { val = val + x.val; return *this; }
90   FixedPoint operator +=(double x) { return *this += (FixedPoint)x; }
91   FixedPoint operator +=(int x) { return *this += (FixedPoint)x; }
92   FixedPoint operator +=(long x) { return *this += (FixedPoint)x; }
93 
94   FixedPoint operator -(FixedPoint x) { return make(val - x.val); }
95   FixedPoint operator -(double x) { return *this - (FixedPoint)x; }
96   FixedPoint operator -(int x) { return *this - (FixedPoint)x; }
97   FixedPoint operator -(long x) { return *this - (FixedPoint)x; }
98 
99   FixedPoint operator -=(FixedPoint x) { val = val - x.val; return *this; }
100   FixedPoint operator -=(double x) { return *this -= (FixedPoint)x; }
101   FixedPoint operator -=(int x) { return *this -= (FixedPoint)x; }
102   FixedPoint operator -=(long x) { return *this -= (FixedPoint)x; }
103 
104   FixedPoint operator *(FixedPoint x) { return make(mul(val, x.val)); }
105   FixedPoint operator *(double x) { return *this * (FixedPoint)x; }
106   FixedPoint operator *(int x) { return *this * (FixedPoint)x; }
107   FixedPoint operator *(long x) { return *this * (FixedPoint)x; }
108 
109   FixedPoint operator *=(FixedPoint x) { val = mul(val, x.val); return *this; }
110   FixedPoint operator *=(double x) { return *this *= (FixedPoint)x; }
111   FixedPoint operator *=(int x) { return *this *= (FixedPoint)x; }
112   FixedPoint operator *=(long x) { return *this *= (FixedPoint)x; }
113 
114   FixedPoint operator /(FixedPoint x) { return make(div(val, x.val)); }
115   FixedPoint operator /(double x) { return *this / (FixedPoint)x; }
116   FixedPoint operator /(int x) { return *this / (FixedPoint)x; }
117   FixedPoint operator /(long x) { return *this / (FixedPoint)x; }
118 
119   FixedPoint operator /=(FixedPoint x) { val = div(val, x.val); return *this; }
120   FixedPoint operator /=(double x) { return *this /= (FixedPoint)x; }
121   FixedPoint operator /=(int x) { return *this /= (FixedPoint)x; }
122   FixedPoint operator /=(long x) { return *this /= (FixedPoint)x; }
123 
abs(FixedPoint x)124   static FixedPoint abs(FixedPoint x) { return make(::abs(x.val)); }
125 
floor(FixedPoint x)126   static int floor(FixedPoint x) { return x.val >> fixptShift; }
127 
ceil(FixedPoint x)128   static int ceil(FixedPoint x)
129     { return (x.val & fixptMaskL) ? ((x.val >> fixptShift) + 1)
130 	                          : (x.val >> fixptShift); }
131 
round(FixedPoint x)132   static int round(FixedPoint x)
133     { return (x.val + (1 << (fixptShift - 1))) >> fixptShift; }
134 
135   // Computes (x+y)/2 avoiding overflow and LSbit accuracy issues.
avg(FixedPoint x,FixedPoint y)136   static FixedPoint avg(FixedPoint x, FixedPoint y)
137     { return make((x.val >> 1) + (y.val >> 1) + ((x.val | y.val) & 1)); }
138 
139 
140   static FixedPoint sqrt(FixedPoint x);
141 
142   static FixedPoint pow(FixedPoint x, FixedPoint y);
143 
144   // Compute *result = x/y; return false if there is an underflow or
145   // overflow.
146   static GBool divCheck(FixedPoint x, FixedPoint y, FixedPoint *result);
147 
148   // Compute abs(m11*m22 - m12*m21) >= epsilon, handling the case
149   // where the multiplications overflow.
150   static GBool checkDet(FixedPoint m11, FixedPoint m12,
151                        FixedPoint m21, FixedPoint m22,
152                        FixedPoint epsilon);
153 
154 private:
155 
make(int valA)156   static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; }
157 
158   static int mul(int x, int y);
159   static int div(int x, int y);
160 
161   int val;                // fixed point: (n-fixptShift).(fixptShift)
162 };
163 
164 #endif // USE_FIXEDPOINT
165 
166 #endif
167