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